Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Error thrown when calling write with more than 1 time(streaming) with a large data #45

Open
alFReD-NSH opened this Issue Sep 21, 2012 · 0 comments

Comments

Projects
None yet
1 participant

I realized that this happens because node sets this._headerSent to true on the first write call(happens in here) and on the second write call we try to implicitly set the header again, which throw the error.

One possible fix, is to have a variable called headerSent for example, and change the code to this:

res.write = function(chunk, encoding){
    if (!(this.headerSent || headerSent)) {
        this._implicitHeader();
        headerSent = true;
    }
    return stream
        ? stream.write(chunk, encoding)
        : write.call(res, chunk, encoding);
};

So in case if node says the header is not sent, and haven't set the header either, we set it here.

I've only tested this under node v0.6.19.

This is my test case:

/**
 * Module dependencies.
 */

var staticProvider,
        assert = require('assert'),
        should = require('should'),
        http = require('http'),
        gzippo = require('../');

try {
    staticProvider = require('connect');
} catch (e) {
    staticProvider = require('express');
}

/**
 * Path to ./test/fixtures/
 */

var fixturesPath = __dirname + '/fixtures';

module.exports = {
    'streaming request should succeed': function() {
        var app = staticProvider.createServer(
            gzippo.compress(),
            function (req, res) {
                var buffer = new Buffer(40960);
                res.writeHead(200);
                res.write(buffer);
                res.write(buffer);
                res.end();
            }
        );

        assert.response(app,
            {
                url: '/',
                headers: {
                    'Accept-Encoding':"gzip"
                }
            },
            function(res){
                var gzippedData = res.body;
                res.statusCode.should.equal(200);
                res.headers.should.have.property('content-encoding', 'gzip');
            }
        );
    };
};

Here's the error :

uncaught undefined: Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:536:11)
    at ServerResponse.setHeader (/Users/flightofficecom/repos/test/node_modules/gzippo/node_modules/connect/lib/patch.js:62:20)
    at next (/Users/flightofficecom/repos/test/node_modules/gzippo/node_modules/connect/lib/http.js:166:13)
    at next (/Users/flightofficecom/repos/test/node_modules/gzippo/node_modules/connect/lib/http.js:213:9)
    at HTTPServer.handle (/Users/flightofficecom/repos/test/node_modules/gzippo/node_modules/connect/lib/http.js:217:3)
    at HTTPServer.emit (events.js:70:17)
    at HTTPParser.onIncoming (http.js:1610:12)
    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:91:29)
    at Socket.ondata (http.js:1506:22)
    at TCP.onread (net.js:374:27)

I've found this happening we when use res.sendFile with a file more than 40kb content.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment