vmrob
vmrob

Reputation: 3046

HTTP response connection reset?

I'm writing up a simple web server that implements select components of the http 1.1 protocol and thus far I have a tcp server that serves a static web page to all tcp connections it receives. I feel like there might be a race condition or some other event happening that I'm not aware of.

Here's the essence of the code in question:

char hello[] =
    "HTTP/1.1 200 OK\r\n"
    // "Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT\r\n"
    // "Content-Length: 131\r\n"
    // "Connection: close\r\n"
    "\r\n"
    "<html>\n"
    "<head>\n"
    "  <title>An Example Page</title>\n"
    "</head>\n"
    "<body>\n"
    "  Hello World, this is a very simple HTML document.\n"
    "</body>\n"
    "</html>\n";

while(true) {
    addrlen = sizeof(peer);
    sockd2 = ::accept(_sockd, (sockaddr*)&peer, &addrlen);
    if (sockd2 == -1) {
        perror("Wrong connection");
        continue;
    }
    write(sockd2, hello, sizeof(hello));
    // close(sockd2);
}

I'm using Google Chrome to connect to localhost:8080 and as is above, the page loads just fine.

If I uncomment the close call and Connection: close line, the page won't load and instead the developer console reads Failed to load resource: net::ERR_CONNECTION_RESET.

If I do the above but also uncomment one of the other http header lines, it loads.

What's going on?

Upvotes: 4

Views: 5867

Answers (1)

user207421
user207421

Reputation: 310980

There is no 'race condition' here. This is a network error.

The problem is that you're not reading the request and not terminating the response correctly.

When the browser writes to a connection that you have already closed, your end issues a TCP RST, which is 'connection reset'.

Read the request. And you must either close the socket or send a content-length header.

You need to read the HTTP 1.1 RFC. It isn't as trivial as you seem to think.

Upvotes: 4

Related Questions