It wasn't a bug of course... just for the record the explanation is below. By the way, I was looking at the your regression test for keep-alive. I don't think it is appropriate. It's in 'regress_http.c', function 'http_chunked_test' the comment is : /* make two requests to check the keepalive behavior */
However making two requests can be successful even when the server is NOT keeping the connection alive (that's the behavior I was getting). I was sending 3 consecutive requests, the server was replying to the first one and then shutting down the connection. So this test is going to succeed even if the keep-alive header is ignored by the server, which makes the test sort of useless.. About the "corrupted" request flag, I had no idea of the following HTTP detail: > /* determine if it's a proxy request */ if (strlen(req->uri) > 0 && req->uri[0] != '/') req->flags |= EVHTTP_PROXY_REQUEST; By asking for '/foo' instead of 'foo' the connection is indeed kept alive. M On Tue, Jul 27, 2010 at 10:27 AM, Marco <marco.tiju...@gmail.com> wrote: > I'm trying to understand why a simple http server closes the connection > after each answer, even if i set the keepalive header. > I might have found a bug, but you guys should check.. > > On the client side, i generate simple requests as following: > > r1 = evhttp_request_new(client_handle_response, NULL); > > evhttp_add_header(r1->output_headers, "TestRequestType", "R1"); > > evhttp_add_header(r1->output_headers, "Connection", "keep-alive"); > > assert(!(r1->flags & EVHTTP_PROXY_REQUEST)) // <<< NOTICE THIS > > evhttp_make_request(client_chan, r1, EVHTTP_REQ_GET, "foo"); > > > On the server side, just to be sure, I re-add the keepalive > >> const char * request_id = evhttp_find_header(req->input_headers, >> "TestRequestType"); > > evhttp_add_header(req->output_headers, "TestRequestType", request_id); > > evhttp_add_header(req->output_headers, "Connection", "keep-alive"); > > evhttp_send_reply(req, HTTP_OK, "OK!", req->output_buffer); > > > However the connection is always closed. > The internal is_keepalive function returns 1, however is_connection_close > returns 1 too, and that's probably the problem. > > From http.c, line 400 > > static int > > evhttp_is_connection_close(int flags, struct evkeyvalq* headers) > > { > > if (flags & EVHTTP_PROXY_REQUEST) { > > /* proxy connection */ > > const char *connection = evhttp_find_header(headers, "Proxy-Connection"); > > return (connection == NULL || strcasecmp(connection, "keep-alive") != 0); > > } else { > > const char *connection = evhttp_find_header(headers, "Connection"); > > return (connection != NULL && strcasecmp(connection, "close") == 0); > > } > > } > > > Running with GDB reveals that the FIRST case is executed, i.e. it enters > the IF rather than the ELSE. > So somehow EVHTTP_PROXY_REQUEST is set in the request flags. > > I'm (almost) sure the client is NOT setting this flag, as you can see from > the assert() in the client code. > > Is this my fault or is it a bug? > I'm using the latest stable from the website 1.4.14b-stable on MacOSX 10.6 > >