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,