Node.js cuts off files when serving over HTTPS

Tag: node.js Author: num184015922 Date: 2010-09-25

I am trying to serve some JavaScript files with Node.js and for whatever reason the files are being cut off in the middle of the transmission. The code:

httpsServer = http.createServer(function(req, res) {
    var path = url.parse(req.url).pathname;

    if (path[path.length - 1] == '/') {
            path += 'index.html';
    }

    fs.readFile(root + path, function(err, data){
            if (err) return send404(res);

            res.writeHead(200, {
                'Content-Type': getMimeType(getExtension(path)),
                'Content-Length': data.length});
            res.end(data);

    });
}),

var privateKey = fs.readFileSync(settings.PRIVATE_KEY).toString();
var certificate = fs.readFileSync(settings.CERTIFICATE).toString();

var credentials = crypto.createCredentials({key: privateKey, cert: certificate});
httpsServer.setSecure(credentials);
httpsServer.listen(settings.HTTPS_PORT);

The files http://github.com/LearnBoost/Socket.IO/raw/master/socket.io.js and http://code.jquery.com/jquery-1.4.2.min.js. The first one is cut off at exactly 32KB and the second at exactly 16KB. This does not happen over HTTP, only HTTPS and only over a network (e.g.: not from localhost).

Any help would be really appreciated.

Best Answer

Instead of Content-Length: data.length you should use Content-Length: Buffer.byteLength(data, 'utf8') where Bufferis a global object (node 0.3.x) or var Buffer = require('buffer') in node 0.2.x which will save you a lot of hassle and might fix your problem with truncated answers too.

comments:

This should be marked as the correct answer. Well, this, actually: Buffer.byteLength(data, 'utf8'). Notice that "???".length == 3 while Buffer.byteLength("???", 'utf8') == 9, the correct answer in this case.
Thanks Phil, oversaw that one!

Other Answer1

I have just seen this too. Same setup - HTTPS, latest node from the git repo.

One large file (170k) never properly completing sending. I tried to switch from async to synch but it made no difference. Only thing that fixed it so far was making the file smaller. It was a big floppy jpg so it was easy to do. Problem vanished.

Other Answer2

It might be a disconnect between the default encoding for readFile and res.end(). readFile just loads the raw data if you do not specify an encoding whereas end() defaults to utf8. I'm not 100% sure but the raw data from the file could return a shorter length than the utf8 encoded string that end emits.

I tried recreating your error and failed so it might be you need to upgrade your version of node. I'm using the latest code from github.

Other Answer3

This problem should be solved in the newest version of Node.js. Can you test it out on v0.4.2?

Other Answer4

have you tried to use built-in HTTPS server? http://nodejs.org/docs/v0.4.11/api/https.html