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

Re: [Libevent-users] Re: evhttp: persistent connections over ssl with chunked transfer encoding bug?



On Thu, Dec 22, 2011 at 5:12 PM, Catalin Patulea <catalinp@xxxxxxxxxx> wrote:
> I'll be digging into this to try to figure out what's going on.
Seems like bev_ssl flushes data to SSL_write and notifies back more
eagerly than bev_sock, which is confusing evhttp_send_reply_end.

evhttp_send_reply_end tries to write the last chunk and get notified
(send_done) when it's been written:

evhttp_send_reply_end(struct evhttp_request *req) {
<...>
	if (req->chunked) {
		evbuffer_add(output, "0\r\n\r\n", 5);
		evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);

evhttp_write_buffer is basically:
	/* Set call back */
	evcon->cb = cb;
	evcon->cb_arg = arg;

	bufferevent_enable(evcon->bufev, EV_WRITE);

The problem is that bev_ssl flushes the write and fires the write
callback from within evbuffer_add, which is too early. When
write_buffer does enable(EV_WRITE), no data is being flushed anymore,
so the event never gets fired.

bev_sock just asks to be notified for fd writability, and returns.
write_buffer gets the chance to prepare a callback. Then the bev_sock
writecb actually flushes the evbuffer to write(2).

If it is deemed acceptable for a bev to flush and cb from
evbuffer_add, then maybe bev_ssl should also fire a write_cb upon
enable(EV_WRITE) when everything has already been flushed.

Otherwise (and it seems most of evhttp is built on this assumption),
bev_ssl should never flush anything unless it's being called from the
event loop.
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.