Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Don't write chunked responses to HTTP/1.0 clients #1234

Closed
indexzero opened this issue Jun 26, 2011 · 16 comments
Closed

Don't write chunked responses to HTTP/1.0 clients #1234

indexzero opened this issue Jun 26, 2011 · 16 comments
Labels

Comments

@indexzero
Copy link

This is a follow up to this bug on node-http-proxy. The behavior can be seen as follows:

  $ cd /path/to/node-http-proxy
  $ forever start examples/standalone-proxy-server.js
  $ curl -0 -v http://localhost:8004/
  * About to connect() to localhost port 8004 (#0)
*   Trying ::1... Connection refused
*   Trying fe80::1... Connection refused
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8004 (#0)
> GET / HTTP/1.0
> User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3
> Host: localhost:8004
> Accept: */*
> 
< HTTP/1.1 200 OK
< content-type: text/plain
< connection: close
< transfer-encoding: chunked
< 
request successfully proxied to: /
{
  "user-agent": "curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3",
  "host": "localhost:8004",
  "accept": "*/*",
  "x-forwarded-for": "127.0.0.1",
  "x-forwarded-port": "53575",
  "x-forwarded-proto": "http",
  "connection": "close"
* Closing connection #0
}

The source of this bug seems to be squarely in the ServerResponse object. I don't know how much things have changed in v0.5.0 but the statusLine written to all outgoing requests is hard-coded to HTTP/1.1. There is probably more to it, but for starters it seems like the ServerResponse object should infer the version of the HTTP protocol to use from the associated ServerRequest.

bnoordhuis added a commit to bnoordhuis/node that referenced this issue Jun 29, 2011
bnoordhuis added a commit to bnoordhuis/node that referenced this issue Jun 29, 2011
@bnoordhuis
Copy link
Member

Bug fix and test cases. Merge!

One semi-surprising datum is that the two HTTP/1.1 chunks emitted by the server arrive as a single TCP packet on the client. Is this the kernel being clever? Because I don't think it's node doing the buffering. Anyway.

@ry
Copy link

ry commented Jul 5, 2011

should respond with http/1.1 and but without chunked. terminate message with eof.

@bnoordhuis
Copy link
Member

I think we can revert 8dc8773 with 1539385 because http.js doesn't seem to be broken any more. Tests pass (as do probes with netcat and curl) on both master and v0.4. Weird, because they sure failed on June 29.

Floby pushed a commit to Floby/node that referenced this issue Jul 8, 2011
@mnot
Copy link

mnot commented Jul 9, 2011

To be clear - Node should always use HTTP/1.1 in its status line, no matter what the client says (as long as Node is HTTP/1.1 conformant, of course).

However, it shouldn't chunk a response to a 1.0 client.

@koichik
Copy link

koichik commented Jul 9, 2011

Node's HTTP server is already implemented like that @mnot says.
https://github.com/joyent/node/blob/master/lib/http.js#L770-773

But Node's HTTP client supports only HTTP/1.1.
https://github.com/joyent/node/blob/master/lib/http.js#L918

Therefore node-http-proxy always sends HTTP/1.1 request to the actual server, doesn't it?
I think this problem occurs by this scenario:

  • client sends HTTP/1.0 request to node-http-proxy.
  • node-http-proxy sends HTTP/1.1 request to actual server.
  • actual server sends HTTP/1.1 (chunked) response to node-http-proxy.
  • node-http-proxy sends HTTP/1.1 (chunked) response to client.

Node HTTP client should support for HTTP/1.0?

@koichik
Copy link

koichik commented Jul 9, 2011

No, it is not necessary.
If client was HTTP/1.0, node-http-proxy should remove 'transfer-encoding' header from actual server's response before send it to client (https://github.com/nodejitsu/node-http-proxy/blob/master/lib/node-http-proxy.js#L523)
like this:

    if ((req.httpVersionMajor < 1 || req.httpVersionMinor < 1) &&
        response.headers['transfer-encoding']) {
      delete response.headers['transfer-encoding'];
    }
    res.writeHead(response.statusCode, response.headers);

@mnot
Copy link

mnot commented Jul 10, 2011

While it's at it, node-http-client needs to delete all "hop-by-hop" headers, in both directions; see:
http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3

@ry
Copy link

ry commented Jul 10, 2011

3e2a2a7 was reverted b62ecdc

@ry
Copy link

ry commented Jul 10, 2011

@koichik - it also needs to modify the response that it's sending - remove the chunk frames and terminate the message with EOF (since it does not know the content-length)

@koichik
Copy link

koichik commented Jul 10, 2011

@ry - It is not necessary. Because http.ClieantResponse (receives from actual server) emits stripped data, not raw chunked frame. And http.ServerResponse (sends to client) does not Keep-Alive, Content-Length is not needed.

@koichik
Copy link

koichik commented Jul 26, 2011

@indexzero Can this be closed?

@indexzero
Copy link
Author

@ry @koichik Did this land in 0.4.x or 0.5.x?

@koichik
Copy link

koichik commented Oct 7, 2011

By default, Node does not send chunked response to HTTP/1.0 client.
If and only if a user (node-http-proxy) specifies Transfer-Encoding explicitly, Node will do so.

So, I think that node-http-proxy should not set Transfer-Encoding header (and other hop-by-hop headers) for HTTP/1.0 client.

@indexzero
Copy link
Author

@koichik Ok. But is this fix available in 0.4.x? Or is it only available in 0.5.x?

@koichik
Copy link

koichik commented Oct 7, 2011

Since v0.1.21 (c5d8238) :-)

@koichik
Copy link

koichik commented Nov 17, 2011

Closed by http-party/node-http-proxy#125

@koichik koichik closed this as completed Nov 17, 2011
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants