In my project, a https server is needed. I added the https feature based on 2.0.10-stable release.
diff -ur libevent-2.0.10-stable-orig/http.c libevent-2.0.10-stable/http.c --- libevent-2.0.10-stable-orig/http.c 2010-12-15 14:02:25.000000000 -0500 +++ libevent-2.0.10-stable/http.c 2011-05-04 07:24:29.000000000 -0400 @@ -79,6 +79,7 @@ #ifdef _EVENT_HAVE_FCNTL_H #include <fcntl.h> #endif +#include <openssl/ssl.h> #undef timeout_pending #undef timeout_initialized @@ -93,6 +94,7 @@ #include "event2/http_compat.h" #include "event2/util.h" #include "event2/listener.h" +#include "event2/bufferevent_ssl.h" #include "log-internal.h" #include "util-internal.h" #include "http-internal.h" @@ -1278,6 +1283,8 @@ evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT); } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) { evhttp_connection_fail(evcon, EVCON_HTTP_EOF); + } else if (what & BEV_EVENT_CONNECTED) { + return; } else { evhttp_connection_fail(evcon, EVCON_HTTP_BUFFER_ERROR); } @@ -2018,6 +2025,65 @@ return (NULL); } +struct evhttp_connection * +evhttps_connection_base_new(struct event_base *base, struct evdns_base *dnsbase, + const char *address, unsigned short port, void *ssl_ctx, evutil_socket_t fd) +{ + struct evhttp_connection *evcon = NULL; + SSL *ssl; + + event_debug(("Attempting connection to %s:%d\n", address, port)); + + if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) { + event_warn("%s: calloc failed", __func__); + goto error; + } + + evcon->fd = fd; + evcon->port = port; + + evcon->max_headers_size = EV_SIZE_MAX; + evcon->max_body_size = EV_SIZE_MAX; + + evcon->timeout = -1; + evcon->retry_cnt = evcon->retry_max = 0; + + if ((evcon->address = mm_strdup(address)) == NULL) { + event_warn("%s: strdup failed", __func__); + goto error; + } + + ssl = SSL_new(ssl_ctx); + evcon->bufev = bufferevent_openssl_socket_new(base, fd, + ssl, BUFFEREVENT_SSL_ACCEPTING, + BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); + if (evcon->bufev == NULL) { + event_warn("%s: bufferevent_new failed", __func__); + goto error; + } + + bufferevent_setcb(evcon->bufev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon); + + evcon->state = EVCON_DISCONNECTED; + TAILQ_INIT(&evcon->requests); + + if (base != NULL) { + evcon->base = base; + } + + event_deferred_cb_init(&evcon->read_more_deferred_cb, + evhttp_deferred_read_cb, evcon); + + evcon->dns_base = dnsbase; + + return (evcon); + +error: + if (evcon != NULL) + evhttp_connection_free(evcon); + return (NULL); +} + void evhttp_connection_set_base(struct evhttp_connection *evcon, struct event_base *base) @@ -2965,6 +3031,18 @@ return (0); } +int +evhttps_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port, void *ssl_ctx) +{ + struct evhttp_bound_socket *bound; + + http->ssl_ctx = ssl_ctx; + bound = evhttp_bind_socket_with_handle(http, address, port); + if (bound == NULL) + return (-1); + return (0); +} + struct evhttp_bound_socket * evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port) { @@ -3160,6 +3238,9 @@ mm_free(alias->alias); mm_free(alias); } + + if (http->ssl_ctx != NULL) + SSL_CTX_free(http->ssl_ctx); mm_free(http); } @@ -3551,8 +3632,13 @@ __func__, hostname, portname, fd)); /* we need a connection object to put the http request on */ - evcon = evhttp_connection_base_new( - http->base, NULL, hostname, atoi(portname)); + if (http->ssl_ctx) { + evcon = evhttps_connection_base_new( + http->base, NULL, hostname, atoi(portname), http->ssl_ctx, fd); + } else { + evcon = evhttp_connection_base_new( + http->base, NULL, hostname, atoi(portname)); + } mm_free(hostname); mm_free(portname); if (evcon == NULL) @@ -3563,10 +3649,11 @@ evcon->flags |= EVHTTP_CON_INCOMING; evcon->state = EVCON_READING_FIRSTLINE; - - evcon->fd = fd; - - bufferevent_setfd(evcon->bufev, fd); + + if (NULL == http->ssl_ctx) { + evcon->fd = fd; + bufferevent_setfd(evcon->bufev, fd); + } return (evcon); } diff -ur libevent-2.0.10-stable-orig/http-internal.h libevent-2.0.10-stable/http-internal.h --- libevent-2.0.10-stable-orig/http-internal.h 2010-11-29 19:55:48.000000000 -0500 +++ libevent-2.0.10-stable/http-internal.h 2011-05-04 07:25:56.000000000 -0400 @@ -21,6 +21,9 @@ #define HTTP_PREFIX "http://" #define HTTP_DEFAULTPORT 80 +#define HTTPS_PREFIX "https://" +#define HTTPS_DEFAULTPORT 443 + enum message_read_status { ALL_DATA_READ = 1, MORE_DATA_EXPECTED = 0, @@ -151,7 +154,7 @@ /* NULL if this server is not a vhost */ char *vhost_pattern; - + void *ssl_ctx; int timeout; size_t default_max_headers_size; diff -ur libevent-2.0.10-stable-orig/include/event2/http.h libevent-2.0.10-stable/include/event2/http.h --- libevent-2.0.10-stable-orig/include/event2/http.h 2010-12-10 12:43:18.000000000 -0500 +++ libevent-2.0.10-stable/include/event2/http.h 2011-05-02 00:40:17.000000000 -0400 @@ -91,8 +91,8 @@ * @return 0 on success, -1 on failure. * @see evhttp_accept_socket() */ -int evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port); - + int evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port); + int evhttps_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port, void *ssl_ctx); /** * Like evhttp_bind_socket(), but returns a handle for referencing the socket. * If it's good, hope it can be added into future release. Thanks,