Forum thread start:
http://archives.seul.org/libevent/users/Dec-2011/msg00001.html
I ran into a problem when the underlying socket for a evhttp_connection times out and later a new socket is created. Currently, the existing bufferevent is layered on top of the new TCP connection. This fails to trigger a new SSL handshake, leaving the client unable to communicate with the server on that connection.
I've written up a patch that allows evhttp to work for HTTPS. Here's a rundown of what it does:
1) adds the evhttp_connection_base_bufferevent_factory_new() API call that takes a callback function to create new bufferevents.
2) adds the callback (and the user-supplied void * argument to the callback) to the evhttp_connection struct
3) if the callback is set, calls it to generate a new bufferevent for the connection in evhttp_connection_connect(). I added a flag that tracks whether the bufferevent has been used yet so we can avoid regenerating bufferevents spuriously.
4) resets the bufferevent file descriptor to -1 before freeing it to ensure the bufferevent won't prematurely close our file descriptors if it happens to have it's FREE_ON_CLOSE flag set. This was a problem since we re-use file descriptor numbers, and a just-allocated fd=7 could get incorrectly freed if the old, timed-out fd was also 7 and we free the old bufferevent. The patch solves this problem for the case where a bufferevent callback is not used, too.
I have discovered that (4) (resetting the bufferevent fd to -1) doesn't really work, as the bufferevent_openssl doesn't actually reset its file descriptor, but rather just uses the one from the previous event. This led to warnings that invalid file descriptors were being accessed. I updated the patch to properly reset the file descriptor at the appropriate time -- in reset_connection(). The only downside to this change is now if the bufferevent factory callback fails, we don't send an error back to the user. Presumably, though, the callback will know it has failed and will take appropriate action internally.
implements discussed functionality
closing and rewriting (with updated patch) for the Patches tracker