[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[Libevent-users] Re: Corrupted http request flags?



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.tijuana@xxxxxxxxx> 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