Skip to content

HTTP client strange behavior when server responds immediately without reading request body #9085

Description

In the example below an HTTP server doesn't read the the request body, but returns the response immediately. If the client sends large data (e.g. 10,000,000 bytes) ECONNRESET error is emitted at client-side but on small data (e.g. 1,000,000 bytes) the programs runs silently.

var crypto = require('crypto'),
    http = require('http')

var port = 8080

var server = http.createServer((req, res) => {
    res.end(crypto.randomBytes(10000))
})
server.listen(port, () => {
    var req = http.request({
        port: port,
        method: 'post',
    })
    req.end(crypto.randomBytes(10000000)) // <- play this value, remove zeros, then add
})

I think the client still sends data after receiving the response. Thus the client violates HTTP request syntax and the connection gets reset. Is this the expected behavior? If so what's the correct way of handling this?

Activity

  1. added
    httpIssues and PRs related to the http subsystem.
    on Oct 13, 2016
  2. bnoordhuis commented on Oct 14, 2016

    @bnoordhuis
    Member

    I'm curious, what would you expect to happen? This is basically a no-win situation for the client.

  3. bnoordhuis commented on Oct 14, 2016

    @bnoordhuis
    Member

    I expect the server to send Connection: close header and close the TCP connection.

    Why? Keep-alive is the default in HTTP/1.1. If you want the server to send a Connection header, you should add it explicitly.

    Let's make sure we are on the same page. Is your bug report against the built-in HTTP server or the client?

  4. bnoordhuis commented on Oct 16, 2016

    @bnoordhuis
    Member

    Okay, I think I see what you mean. There are a couple of things here:

    1. The HTTP server is somewhat anti-social (but not in violation of the spec) in that it accepts but ignores the POST body. Most servers would reply with a 4xx status to signal that they don't want/expect a POST request.
    2. The HTTP client sends a Connection: close header that the server dutifully mirrors in its response. This may be a bug in the node.js client because I can see no reason why it should always send that header. In fact, it's detrimental to performance when multiple requests are made. /cc @nodejs/http
    3. If the client sends a Connection: keep-alive header, HTTP keep-alive will be enabled and you can listen for the 'end' event on the client's response object.
    4. You can however never completely prevent a server from closing the connection on you while you are still busy sending the request. You will always need to add an 'error' event listener and be prepared for ECONNRESET or EPIPE errors.

    EDIT: Fixed typo in bullet point 4: s/response/request/

  5. bnoordhuis commented on Oct 17, 2016

    @bnoordhuis
    Member

    Yes, that's correct.

  6. ghost closed this as completedon Oct 17, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    httpIssues and PRs related to the http subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions