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,

Reply via email to