Skip to content
This repository

Cannot use connect.compress() middleware with http-proxy #316

Closed
fmarier opened this Issue October 16, 2012 · 2 comments

2 participants

Francois Marier Douglas Christopher Wilson
Francois Marier

Looking at the middleware example that comes with http-proxy:

https://github.com/nodejitsu/node-http-proxy/blob/1df2b30e84f078d86e744601bd6fc59381a1c7b3/examples/middleware/gzip-middleware.js

I decided to write my own program which makes use of connect.compress() but is otherwise the same as the example that comes with http-proxy:

https://github.com/fmarier/node-compressed-http-proxy/blob/master/compress-example.js

Unfortunately, it doesn't work because the compress middleware looks at the headers before they are written out in order to decide whether or not a resource should be compressed. I can force compress to always compress everything by calling it like this:

connect.compress({filter: function () {return true;}})

but that's of course not a good idea since images will get gzipped too.

The result is that proxied content is never compressed by connect.compress().

Francois Marier fmarier referenced this issue from a commit October 16, 2012
Commit has since been removed from the repository and is no longer available.
Francois Marier fmarier referenced this issue from a commit in fmarier/node-http-proxy October 17, 2012
Francois Marier Set headers prior to calling writeHead() (fixes #316)
This allows the connect.compress() middleware to work on proxied
requests.

If this header is not manually set then the compress middleware
will be invoked in the writeHead() call:

  https://github.com/nodejitsu/node-http-proxy/blob/1df2b30e84f078d86e744601bd6fc59381a1c7b3/lib/node-http-proxy/http-proxy.js#L260

before the header has been written. Therefore it will perform its
content-type check:

  https://github.com/senchalabs/connect/blob/7b5621b8dd4d9d82296b9b5d7bf3bea10de37a6c/lib/middleware/compress.js#L94

and so the check will fail and compression will be disabled.

Futhermore, even if that check were bypassed, compress() would be
unable to delete the content-length header:

  https://github.com/senchalabs/connect/blob/7b5621b8dd4d9d82296b9b5d7bf3bea10de37a6c/lib/middleware/compress.js#L123

because by then it wouldn't exist (it will be written after that
header event has been processed by compress). The affect of that
bug is that connections with keep-alive will stall for several
minutes because the browser is waiting for more data (based on
the orignal content-length header, set prior to compression).
8c999c0
Douglas Christopher Wilson

i.m.o. this is a bug in connect, as it is perfectly valid to send an object of headers with writeHead. connect patches the writeHead to emit a header event on the response object. The compress middleware is listening to that event to see if it should compress the response, but yet it seems like connect's own documentation suggests that the event is used to add headers just before they are written to the socket, meaning that compress may handle it's header event before something else listening to the event adds a Content-Type header and so compress will miss it. FWIW the header event is not part of node core, it is just something connect patches ServerResponse with.

Francois Marier

@dougwilson is right, it is a problem in connect itself: senchalabs/connect#524

Francois Marier fmarier closed this October 22, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.