Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'release/0.3.3'

  • Loading branch information...
commit 588a25cb17e7a6ffcac206bcd7c540dd98afecd2 2 parents bc3ae03 + 67307f1
Mark Ellzey authored
View
21 CMakeLists.txt
@@ -3,7 +3,7 @@ project(reason)
set(PROJECT_MAJOR_VERSION 0)
set(PROJECT_MINOR_VERSION 3)
-set(PROJECT_PATCH_VERSION 2)
+set(PROJECT_PATCH_VERSION 3)
set (PROJECT_VERSION ${PROJECT_MAJOR_VERSION}.${PROJECT_MINOR_VERSION}.${PROJECT_PATCH_VERSION})
set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules)
@@ -25,12 +25,15 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/http_parser
)
-set(LIBEVHTP_EXTERNAL_LIBS
- ${LIBEVENT_LIBRARY}
- ${LIBEVENT_PTHREADS_LIBRARY}
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/build
-)
+set(LIBEVHTP_EXTERNAL_LIBS ${LIBEVENT_LIBRARY} ${LIBEVENT_PTHREADS_LIBRARY} ${LIBEVENT_OPENSSL_LIBRARY})
+
+if (NOT ${LIBEVENT_PTHREADS_FOUND})
+ set(DISABLE_EVTHR 1)
+endif(NOT ${LIBEVENT_PTHREADS_FOUND})
+
+if (NOT ${LIBEVENT_OPENSSL_FOUND})
+ set (DISABLE_SSL 1)
+endif(NOT ${LIBEVENT_OPENSSL_FOUND})
if (DISABLE_EVTHR)
set(LIBEVHTP_SOURCES http_parser/http_parser.c evhtp.c)
@@ -40,7 +43,7 @@ endif(DISABLE_EVTHR)
add_library(libevhtp STATIC ${LIBEVHTP_SOURCES})
set_target_properties(libevhtp PROPERTIES OUTPUT_NAME "evhtp")
-target_link_libraries(libevhtp ${LIVEVHTP_EXTERNAL_LIBS})
+#target_link_libraries(libevhtp ${LIVEVHTP_EXTERNAL_LIBS})
add_executable(test test.c)
-target_link_libraries(test libevhtp event event_pthreads)
+target_link_libraries(test libevhtp ${LIBEVHTP_EXTERNAL_LIBS})
View
4 CMakeModules/BaseConfig.cmake
@@ -19,6 +19,10 @@ if (DISABLE_EVTHR)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDISABLE_EVTHR")
endif(DISABLE_EVTHR)
+if (DISABLE_SSL)
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDISABLE_SSL")
+endif(DISABLE_SSL)
+
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif(NOT CMAKE_BUILD_TYPE)
View
4 CMakeModules/FindLibEvent.cmake
@@ -10,6 +10,7 @@ FIND_LIBRARY(LIBEVENT_LIBRARY NAMES event)
FIND_LIBRARY(LIBEVENT_CORE_LIBRARY NAMES event_core)
FIND_LIBRARY(LIBEVENT_PTHREADS_LIBRARY NAMES event_pthreads)
FIND_LIBRARY(LIBEVENT_EXTRA_LIBRARY NAMES event_extra)
+FIND_LIBRARY(LIBEVENT_OPENSSL_LIBRARY NAMES event_openssl)
INCLUDE(FindPackageHandleStandardArgs)
@@ -17,5 +18,6 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibEvent DEFAULT_MSG LIBEVENT_LIBRARY LIBEVENT
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibEventPthreads DEFAULT_MSG LIBEVENT_PTHREADS_LIBRARY LIBEVENT_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibEventCore DEFAULT_MSG LIBEVENT_CORE_LIBRARY LIBEVENT_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibEventExtra DEFAULT_MSG LIBEVENT_EXTRA_LIBRARY LIBEVENT_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibEventOpenssl DEFAULT_MSG LIBEVENT_OPENSSL_LIBRARY LIBEVENT_INCLUDE_DIR)
-MARK_AS_ADVANCED(LIBEVENT_INCLUDE_DIR LIBEVENT_LIBRARY LIBEVENT_PTHREADS_LIBRARY LIBEVENT_CORE_LIBRARY LIBEVENT_EXTRA_LIBRARY)
+MARK_AS_ADVANCED(LIBEVENT_INCLUDE_DIR LIBEVENT_LIBRARY LIBEVENT_PTHREADS_LIBRARY LIBEVENT_OPENSSL_LIBRARY LIBEVENT_CORE_LIBRARY LIBEVENT_EXTRA_LIBRARY)
View
470 evhtp.c
@@ -5,6 +5,7 @@
#include <inttypes.h>
#include <limits.h>
#include <errno.h>
+#include <signal.h>
#include <sys/ioctl.h>
#include <sys/queue.h>
#include <sys/socket.h>
@@ -30,6 +31,10 @@ struct evhtp {
evhtp_pre_accept pre_accept_cb;
evhtp_post_accept post_accept_cb;
http_parser_settings psets;
+#ifndef DISABLE_SSL
+ evhtp_ssl_ctx_t * ssl_ctx;
+ evhtp_ssl_cfg * ssl_cfg;
+#endif
#ifndef DISABLE_EVTHR
evthr_pool_t * pool;
#else
@@ -76,6 +81,9 @@ struct evhtp_conn {
evhtp_cflags flags;
evbase_t * evbase;
evbev_t * bev;
+#ifndef DISABLE_SSL
+ evhtp_ssl_t * ssl;
+#endif
#ifndef DISABLE_EVTHR
evthr_t * thr;
#endif
@@ -99,8 +107,9 @@ struct evhtp_conn {
#define _QUOTE(x) __QUOTE(x)
#define evhtp_log_debug(fmt, ...) do { \
- fprintf(stderr, __FILE__ "[" _QUOTE(__LINE__) "] %s: " \
+ fprintf(stdout, __FILE__ "[" _QUOTE(__LINE__) "] %s: " \
fmt "\n", __func__, ## __VA_ARGS__); \
+ fflush(stdout); \
} while (0)
#else
#define evhtp_log_debug(fmt, ...) do {} while (0)
@@ -121,11 +130,19 @@ static evhtp_proto _htp_proto(char major, char minor);
static evhtp_callback_t * _htp_callbacks_find_callback(evhtp_callbacks_t *, const char *);
static void _htp_recv_cb(evbev_t * bev, void * arg);
static void _htp_err_cb(evbev_t * bev, short events, void * arg);
+#ifndef DISABLE_OPENSSL
+#ifndef DISABLE_EVTHR
+static int ssl_num_locks;
+static pthread_mutex_t ** ssl_locks;
+#endif
+#endif
static evhtp_status
_htp_run_on_expect_hook(evhtp_conn_t * conn, const char * expt_val) {
evhtp_status status = EVHTP_CODE_CONTINUE;
+ evhtp_log_debug("enter");
+
if (_htp_conn_has_hook(conn, _on_expect)) {
status = _htp_conn_hook_call(conn, _on_expect, expt_val);
}
@@ -137,6 +154,7 @@ static evhtp_res
_htp_run_hdr_hook(evhtp_conn_t * conn, evhtp_hdr_t * hdr) {
evhtp_res res = EVHTP_RES_OK;
+ evhtp_log_debug("enter");
if (_htp_conn_has_hook(conn, _hdr)) {
res = _htp_conn_hook_call(conn, _hdr, hdr);
}
@@ -148,6 +166,7 @@ static evhtp_res
_htp_run_hdrs_hook(evhtp_conn_t * conn, evhtp_hdrs_t * hdrs) {
evhtp_res res = EVHTP_RES_OK;
+ evhtp_log_debug("enter");
if (_htp_conn_has_hook(conn, _hdrs)) {
res = _htp_conn_hook_call(conn, _hdrs, hdrs);
}
@@ -159,6 +178,7 @@ static evhtp_res
_htp_run_path_hook(evhtp_conn_t * conn, const char * path) {
evhtp_res res = EVHTP_RES_OK;
+ evhtp_log_debug("enter");
if (_htp_conn_has_hook(conn, _path)) {
res = _htp_conn_hook_call(conn, _path, path);
}
@@ -170,6 +190,7 @@ static evhtp_res
_htp_run_uri_hook(evhtp_conn_t * conn, const char * uri) {
evhtp_res res = EVHTP_RES_OK;
+ evhtp_log_debug("enter");
if (_htp_conn_has_hook(conn, _uri)) {
res = _htp_conn_hook_call(conn, _uri, uri);
}
@@ -181,6 +202,7 @@ static evhtp_res
_htp_run_read_hook(evhtp_conn_t * conn, const char * data, size_t sz) {
evhtp_res res = EVHTP_RES_OK;
+ evhtp_log_debug("enter");
if (_htp_conn_has_hook(conn, _read)) {
res = _htp_conn_hook_call(conn, _read, data, sz);
}
@@ -192,6 +214,7 @@ static int
_htp_start_cb(http_parser * p) {
evhtp_conn_t * conn = p->data;
+ evhtp_log_debug("enter");
conn->request = evhtp_request_new(conn);
return 0;
}
@@ -201,6 +224,7 @@ _htp_end_cb(http_parser * p) {
evhtp_conn_t * conn = NULL;
evhtp_request_t * request = NULL;
+ evhtp_log_debug("enter");
conn = p->data;
request = conn->request;
@@ -225,6 +249,7 @@ _htp_uri_cb(http_parser * p, const char * buf, size_t len) {
evhtp_conn_t * conn;
evhtp_request_t * request;
+ evhtp_log_debug("enter");
conn = p->data;
request = conn->request;
@@ -297,6 +322,7 @@ static int
_htp_headers_complete_cb(http_parser * p) {
evhtp_conn_t * conn;
+ evhtp_log_debug("enter");
conn = p->data;
conn->request->method = p->method;
@@ -339,6 +365,7 @@ _htp_path_cb(http_parser * p, const char * buf, size_t len) {
/* printf("on_path size: %llu\n", len); */
+ evhtp_log_debug("enter");
conn = p->data;
request = conn->request;
@@ -370,6 +397,7 @@ static int
_htp_body_cb(http_parser * p, const char * buf, size_t len) {
evhtp_conn_t * conn = p->data;
+ evhtp_log_debug("enter");
evbuffer_add(conn->request->buffer_in, buf, len);
if (_htp_run_read_hook(conn, buf, len) != EVHTP_RES_OK) {
@@ -394,6 +422,7 @@ static evhtp_callback_t *
_htp_callback_new(const char * uri, evhtp_callback_cb cb, void * cbarg) {
evhtp_callback_t * htp_cb;
+ evhtp_log_debug("enter");
if (!(htp_cb = calloc(sizeof(evhtp_callback_t), sizeof(char)))) {
return NULL;
}
@@ -410,6 +439,7 @@ static evhtp_callbacks_t *
_htp_callbacks_new(unsigned int buckets) {
evhtp_callbacks_t * htp_cbs;
+ evhtp_log_debug("enter");
if (!(htp_cbs = calloc(sizeof(evhtp_callbacks_t), sizeof(char)))) {
return NULL;
}
@@ -430,6 +460,7 @@ _htp_callbacks_find_callback(evhtp_callbacks_t * cbs, const char * uri) {
evhtp_callback_t * cb;
unsigned int hash;
+ evhtp_log_debug("enter");
if (cbs == NULL) {
return NULL;
}
@@ -456,6 +487,7 @@ static int
_htp_callbacks_add_callback(evhtp_callbacks_t * cbs, evhtp_callback_t * cb) {
unsigned int hkey;
+ evhtp_log_debug("enter");
hkey = cb->hash % cbs->buckets;
if (cbs->callbacks[hkey] == NULL) {
@@ -475,9 +507,7 @@ _htp_conn_free(evhtp_conn_t * conn) {
return;
}
- if (conn->bev) {
- bufferevent_free(conn->bev);
- }
+ evhtp_log_debug("enter");
if (conn->hooks) {
free(conn->hooks);
@@ -497,18 +527,25 @@ _htp_conn_free(evhtp_conn_t * conn) {
}
#endif
+ if (conn->bev) {
+ bufferevent_free(conn->bev);
+ }
+
+
free(conn);
-}
+} /* _htp_conn_free */
static evhtp_conn_t *
_htp_conn_new(evhtp_t * htp) {
evhtp_conn_t * conn;
+ evhtp_log_debug("enter");
if (!(conn = calloc(sizeof(evhtp_conn_t), sizeof(char)))) {
return NULL;
}
conn->htp = htp;
+ conn->flags = 0;
conn->parser = malloc(sizeof(http_parser));
conn->parser->data = conn;
@@ -520,12 +557,16 @@ static void
_htp_conn_reset(evhtp_conn_t * conn) {
http_parser_init(conn->parser, HTTP_REQUEST);
+ evhtp_log_debug("enter");
+
evhtp_request_free(conn->request);
conn->request = NULL;
+ bufferevent_disable(conn->bev, EV_WRITE);
+ bufferevent_enable(conn->bev, EV_READ);
+
bufferevent_setwatermark(conn->bev, EV_READ | EV_WRITE, 0, 0);
bufferevent_setcb(conn->bev, _htp_recv_cb, NULL, _htp_err_cb, conn);
- bufferevent_enable(conn->bev, EV_READ | EV_WRITE);
}
static int
@@ -534,6 +575,7 @@ _htp_conn_get_sock(evhtp_conn_t * conn) {
return -1;
}
+ evhtp_log_debug("enter");
return conn->sock;
}
@@ -543,6 +585,7 @@ _htp_conn_get_listener(evhtp_conn_t * conn) {
return NULL;
}
+ evhtp_log_debug("enter");
return evhtp_get_listener(conn->htp);
}
@@ -552,11 +595,13 @@ _htp_conn_get_evbase(evhtp_conn_t * conn) {
return NULL;
}
+ evhtp_log_debug("enter");
return conn->evbase;
}
static int
_htp_resp_can_have_content(evhtp_status code) {
+ evhtp_log_debug("enter");
if (code >= 100) {
if (code < 300) {
return 1;
@@ -574,6 +619,7 @@ _htp_recv_cb(evbev_t * bev, void * arg) {
size_t nread;
size_t avail;
+ evhtp_log_debug("enter");
conn = (evhtp_conn_t *)arg;
ibuf = bufferevent_get_input(bev);
avail = evbuffer_get_length(ibuf);
@@ -581,15 +627,22 @@ _htp_recv_cb(evbev_t * bev, void * arg) {
nread = http_parser_execute(conn->parser, &conn->htp->psets, read_buf, avail);
evbuffer_drain(ibuf, nread);
+
+ evhtp_log_debug("nread = %d", nread);
}
static void
_htp_err_cb(evbev_t * bev, short events, void * arg) {
evhtp_conn_t * conn;
- conn = (evhtp_conn_t *)arg;
+ evhtp_log_debug("events = %x", events);
+
+ if (events & (BEV_EVENT_ERROR | BEV_EVENT_EOF)) {
+ conn = (evhtp_conn_t *)arg;
- _htp_conn_free(conn);
+ evhtp_log_debug("leaving....");
+ return _htp_conn_free(conn);
+ }
}
static int
@@ -597,6 +650,7 @@ _htp_hdr_output(evhtp_hdr_t * hdr, void * arg) {
evbuf_t * buf = (evbuf_t *)arg;
+ evhtp_log_debug("enter");
evbuffer_add(buf, hdr->key, strlen(hdr->key));
/* evbuffer_add_reference(buf, ": ", 2, NULL, NULL); */
evbuffer_add(buf, ": ", 2);
@@ -612,15 +666,32 @@ _htp_exec_in_thr(evthr_t * thr, void * arg, void * shared) {
evhtp_t * htp;
evhtp_conn_t * conn;
+ evhtp_log_debug("enter");
htp = (evhtp_t *)shared;
conn = (evhtp_conn_t *)arg;
conn->evbase = evthr_get_base(thr);
conn->thr = thr;
- conn->bev = bufferevent_socket_new(conn->evbase, conn->sock, BEV_OPT_CLOSE_ON_FREE);
+
+ if (htp->ssl_ctx == NULL) {
+ conn->bev = bufferevent_socket_new(conn->evbase, conn->sock, BEV_OPT_CLOSE_ON_FREE);
+ } else {
+#ifndef DISABLE_EVTHR
+ conn->ssl = SSL_new(htp->ssl_ctx);
+ conn->bev = bufferevent_openssl_socket_new(conn->evbase,
+ conn->sock, conn->ssl, BUFFEREVENT_SSL_ACCEPTING,
+ BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
+
+ SSL_set_app_data(conn->ssl, conn);
+#else
+ fprintf(stderr, "SSL requested but not enabled\n");
+ abort();
+#endif
+ }
bufferevent_setcb(conn->bev, _htp_recv_cb, NULL, _htp_err_cb, conn);
- bufferevent_enable(conn->bev, EV_READ | EV_WRITE);
+ bufferevent_enable(conn->bev, EV_READ);
+ bufferevent_disable(conn->bev, EV_WRITE);
if (htp->post_accept_cb) {
htp->post_accept_cb(conn, htp->post_accept_cbarg);
@@ -636,6 +707,7 @@ _htp_accept_cb(evserv_t * serv, int fd, struct sockaddr * s, int sl, void * arg)
evhtp_t * htp;
evhtp_conn_t * conn;
+ evhtp_log_debug("enter");
htp = (evhtp_t *)arg;
evutil_make_socket_nonblocking(fd);
@@ -656,14 +728,31 @@ _htp_accept_cb(evserv_t * serv, int fd, struct sockaddr * s, int sl, void * arg)
}
#endif
- conn->bev = bufferevent_socket_new(conn->evbase, fd, BEV_OPT_CLOSE_ON_FREE);
- bufferevent_setcb(conn->bev, _htp_recv_cb, NULL, NULL, conn);
- bufferevent_enable(conn->bev, EV_READ | EV_WRITE);
+ if (htp->ssl_ctx == NULL) {
+ conn->bev = bufferevent_socket_new(conn->evbase, conn->sock, BEV_OPT_CLOSE_ON_FREE);
+ } else {
+#ifndef DISABLE_SSL
+ conn->ssl = SSL_new(htp->ssl_ctx);
+ conn->bev = bufferevent_openssl_socket_new(conn->evbase,
+ conn->sock, conn->ssl, BUFFEREVENT_SSL_ACCEPTING,
+ BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
+
+ SSL_set_app_data(conn->ssl, conn);
+#else
+ fprintf(stderr, "SSL requested but not enabled\n");
+ abort();
+#endif
+ }
+
+ bufferevent_disable(conn->bev, EV_WRITE);
+ bufferevent_enable(conn->bev, EV_READ);
+
+ bufferevent_setcb(conn->bev, _htp_recv_cb, NULL, _htp_err_cb, conn);
if (htp->post_accept_cb) {
htp->post_accept_cb(conn, htp->post_accept_cbarg);
}
-}
+} /* _htp_accept_cb */
static void
_htp_set_kalive_hdr(evhtp_hdrs_t * hdrs, evhtp_proto proto, int kalive) {
@@ -671,6 +760,7 @@ _htp_set_kalive_hdr(evhtp_hdrs_t * hdrs, evhtp_proto proto, int kalive) {
return;
}
+ evhtp_log_debug("enter");
if (kalive && proto == EVHTP_PROTO_1_0) {
return evhtp_hdr_add(hdrs, evhtp_hdr_new(_HTP_CONN, _HTP_DEFKALIVE));
}
@@ -685,6 +775,7 @@ _htp_reply_set_content_hdrs(evhtp_request_t * req, size_t len) {
const char * content_len_hval;
const char * content_type_hval;
+ evhtp_log_debug("enter");
if (req == NULL) {
return;
}
@@ -719,6 +810,7 @@ _htp_reply_set_content_hdrs(evhtp_request_t * req, size_t len) {
static evhtp_status
_htp_code_parent(evhtp_status code) {
+ evhtp_log_debug("enter");
if (code > 599 || code < 100) {
return EVHTP_CODE_SCREWEDUP;
}
@@ -746,6 +838,7 @@ static int
_htp_should_close_based_on_cflags(evhtp_cflags flags, evhtp_status code) {
int res = 0;
+ evhtp_log_debug("enter");
switch (_htp_code_parent(code)) {
case EVHTP_CODE_100:
res = (flags & EVHTP_CLOSE_ON_100);
@@ -778,6 +871,7 @@ static int
_htp_should_keep_alive(evhtp_request_t * req, evhtp_status code) {
evhtp_conn_t * conn = req->conn;
+ evhtp_log_debug("enter");
if (http_should_keep_alive(conn->parser) == 0) {
/* parsed request doesn't even support keep-alive */
return 0;
@@ -796,6 +890,7 @@ _htp_should_keep_alive(evhtp_request_t * req, evhtp_status code) {
static inline int
_htp_is_http_1_1x(char major, char minor) {
+ evhtp_log_debug("enter");
if (major >= 1 && minor >= 1) {
return 1;
}
@@ -846,6 +941,7 @@ _htp_set_body_buf(evbuf_t * dst, evbuf_t * src) {
if (dst == NULL) {
return;
}
+ evhtp_log_debug("enter");
if (src && evbuffer_get_length(src)) {
evbuffer_add_buffer(dst, src);
@@ -858,6 +954,8 @@ _htp_resp_fini_cb(evbev_t * bev, void * arg) {
evhtp_conn_t * conn;
int keepalive;
+ evhtp_log_debug("enter");
+
req = (evhtp_request_t *)arg;
keepalive = req->keepalive;
conn = req->conn;
@@ -874,6 +972,8 @@ _htp_resp_err_cb(evbev_t * bev, short events, void * arg) {
evhtp_request_t * req;
evhtp_conn_t * conn;
+ evhtp_log_debug("events = %x", events);
+
req = (evhtp_request_t *)arg;
conn = req->conn;
@@ -885,6 +985,7 @@ _htp_stream_fini_cb(evbev_t * bev, void * arg) {
evhtp_request_t * req;
evhtp_conn_t * conn;
+ evhtp_log_debug("enter");
req = (evhtp_request_t *)arg;
conn = req->conn;
@@ -895,8 +996,8 @@ _htp_stream_fini_cb(evbev_t * bev, void * arg) {
case EVHTP_RES_DONE:
if (req->chunked) {
evbuffer_add_reference(req->buffer_out, "0\r\n\r\n", 5, NULL, NULL);
- bufferevent_write_buffer(conn->bev, req->buffer_out);
bufferevent_setcb(conn->bev, NULL, _htp_resp_fini_cb, _htp_resp_err_cb, req);
+ bufferevent_write_buffer(conn->bev, req->buffer_out);
return;
}
break;
@@ -912,6 +1013,7 @@ void
evhtp_send_reply(evhtp_request_t * req, evhtp_status code, const char * r, evbuf_t * b) {
evhtp_conn_t * conn;
+ evhtp_log_debug("enter");
conn = req->conn;
req->keepalive = _htp_should_keep_alive(req, code);
@@ -920,7 +1022,7 @@ evhtp_send_reply(evhtp_request_t * req, evhtp_status code, const char * r, evbuf
}
if (_htp_resp_can_have_content(code)) {
- _htp_reply_set_content_hdrs(req, evbuffer_get_length(b));
+ _htp_reply_set_content_hdrs(req, b ? evbuffer_get_length(b) : 0);
} else {
if ((b != NULL) && evbuffer_get_length(b) > 0) {
evbuffer_drain(b, -1);
@@ -935,17 +1037,19 @@ evhtp_send_reply(evhtp_request_t * req, evhtp_status code, const char * r, evbuf
_htp_set_crlf_buf(req->buffer_out);
_htp_set_body_buf(req->buffer_out, b);
- bufferevent_write_buffer(conn->bev, req->buffer_out);
bufferevent_disable(conn->bev, EV_READ);
+ bufferevent_enable(conn->bev, EV_WRITE);
bufferevent_setwatermark(conn->bev, EV_WRITE, 1, 0);
bufferevent_setcb(conn->bev, NULL, _htp_resp_fini_cb, _htp_resp_err_cb, req);
+ bufferevent_write_buffer(conn->bev, req->buffer_out);
} /* evhtp_send_reply */
void
evhtp_send_reply_stream(evhtp_request_t * req, evhtp_status code, evhtp_stream_cb cb, void * arg) {
evhtp_conn_t * conn;
+ evhtp_log_debug("enter");
conn = req->conn;
if (req->buffer_out == NULL) {
@@ -978,15 +1082,17 @@ evhtp_send_reply_stream(evhtp_request_t * req, evhtp_status code, evhtp_stream_c
req->stream_cb = cb;
req->stream_cbarg = arg;
- bufferevent_write_buffer(conn->bev, req->buffer_out);
bufferevent_disable(conn->bev, EV_READ);
+ bufferevent_enable(conn->bev, EV_WRITE);
bufferevent_setwatermark(conn->bev, EV_WRITE, 1, 0);
bufferevent_setcb(conn->bev, NULL, _htp_stream_fini_cb, _htp_resp_err_cb, req);
+ bufferevent_write_buffer(conn->bev, req->buffer_out);
} /* evhtp_send_reply_stream */
void
evhtp_request_make_chunk(evhtp_request_t * req, evbuf_t * buf) {
+ evhtp_log_debug("enter");
evbuffer_add_printf(req->buffer_out, "%" PRIxMAX "\r\n", evbuffer_get_length(buf));
evbuffer_add_buffer(req->buffer_out, buf);
evbuffer_add_reference(req->buffer_out, CRLF, 2, NULL, NULL);
@@ -994,6 +1100,7 @@ evhtp_request_make_chunk(evhtp_request_t * req, evbuf_t * buf) {
void
evhtp_send_stream(evhtp_request_t * req, evbuf_t * buf) {
+ evhtp_log_debug("enter");
switch (req->proto) {
case EVHTP_PROTO_1_1:
return evhtp_request_make_chunk(req, buf);
@@ -1008,12 +1115,14 @@ evhtp_send_stream(evhtp_request_t * req, evbuf_t * buf) {
int
evhtp_conn_set_flags(evhtp_conn_t * conn, evhtp_cflags flags) {
+ evhtp_log_debug("enter");
conn->flags |= flags;
return 0;
}
int
evhtp_set_hook(evhtp_conn_t * conn, evhtp_hook_type type, void * cb, void * cbarg) {
+ evhtp_log_debug("enter");
if (conn->hooks == NULL) {
conn->hooks = calloc(sizeof(evhtp_hooks_t), sizeof(char));
}
@@ -1050,6 +1159,7 @@ int
evhtp_set_cb(evhtp_t * htp, const char * uri, evhtp_callback_cb cb, void * cbarg) {
evhtp_callback_t * htp_cb;
+ evhtp_log_debug("enter");
if (htp->callbacks == NULL) {
htp->callbacks = _htp_callbacks_new(1024);
} else {
@@ -1071,6 +1181,7 @@ evhtp_set_cb(evhtp_t * htp, const char * uri, evhtp_callback_cb cb, void * cbarg
void
evhtp_set_gencb(evhtp_t * htp, evhtp_callback_cb cb, void * cbarg) {
+ evhtp_log_debug("enter");
htp->default_cb = cb;
htp->default_cbarg = cbarg;
}
@@ -1079,34 +1190,41 @@ void
evhtp_bind_socket(evhtp_t * htp, const char * baddr, uint16_t port) {
struct sockaddr_in sin = { 0 };
+ evhtp_log_debug("enter");
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = inet_addr(baddr);
- htp->listener = evconnlistener_new_bind(htp->evbase,
+ signal(SIGPIPE, SIG_IGN);
+
+ htp->listener = evconnlistener_new_bind(htp->evbase,
_htp_accept_cb, htp, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024,
(struct sockaddr *)&sin, sizeof(sin));
}
void
evhtp_set_pre_accept_cb(evhtp_t * htp, evhtp_pre_accept cb, void * cbarg) {
+ evhtp_log_debug("enter");
htp->pre_accept_cb = cb;
htp->pre_accept_cbarg = cbarg;
}
void
evhtp_set_post_accept_cb(evhtp_t * htp, evhtp_post_accept cb, void * cbarg) {
+ evhtp_log_debug("enter");
htp->post_accept_cb = cb;
htp->post_accept_cbarg = cbarg;
}
const char *
evhtp_hdr_get_key(evhtp_hdr_t * hdr) {
+ evhtp_log_debug("enter");
return hdr ? hdr->key : NULL;
}
const char *
evhtp_hdr_get_val(evhtp_hdr_t * hdr) {
+ evhtp_log_debug("enter");
return hdr ? hdr->val : NULL;
}
@@ -1114,6 +1232,7 @@ int
evhtp_hdrs_for_each(evhtp_hdrs_t * hdrs, evhtp_hdrs_iter_cb cb, void * arg) {
evhtp_hdr_t * hdr = NULL;
+ evhtp_log_debug("enter");
if (hdrs == NULL || cb == NULL) {
return -1;
}
@@ -1131,6 +1250,7 @@ evhtp_hdrs_for_each(evhtp_hdrs_t * hdrs, evhtp_hdrs_iter_cb cb, void * arg) {
void
evhtp_hdr_add(evhtp_hdrs_t * hdrs, evhtp_hdr_t * hdr) {
+ evhtp_log_debug("enter");
TAILQ_INSERT_TAIL(hdrs, hdr, next);
}
@@ -1138,6 +1258,7 @@ const char *
evhtp_hdr_find(evhtp_hdrs_t * hdrs, const char * key) {
evhtp_hdr_t * hdr = NULL;
+ evhtp_log_debug("enter");
TAILQ_FOREACH(hdr, hdrs, next) {
if (!strcasecmp(hdr->key, key)) {
return hdr->val;
@@ -1149,6 +1270,8 @@ evhtp_hdr_find(evhtp_hdrs_t * hdrs, const char * key) {
void
evhtp_request_free(evhtp_request_t * req) {
+ evhtp_log_debug("enter");
+
if (req == NULL) {
return;
}
@@ -1177,6 +1300,8 @@ evhtp_request_free(evhtp_request_t * req) {
void
evhtp_hdr_free(evhtp_hdr_t * hdr) {
+ evhtp_log_debug("enter");
+
if (hdr == NULL) {
return;
}
@@ -1197,10 +1322,14 @@ evhtp_hdrs_free(evhtp_hdrs_t * hdrs) {
evhtp_hdr_t * hdr;
evhtp_hdr_t * save;
+ evhtp_log_debug("enter");
+
if (hdrs == NULL) {
return;
}
+ hdr = NULL;
+
for (hdr = TAILQ_FIRST(hdrs); hdr != NULL; hdr = save) {
save = TAILQ_NEXT(hdr, next);
TAILQ_REMOVE(hdrs, hdr, next);
@@ -1210,6 +1339,7 @@ evhtp_hdrs_free(evhtp_hdrs_t * hdrs) {
int
evhtp_set_server_name(evhtp_t * htp, char * n) {
+ evhtp_log_debug("enter");
if (htp == NULL || n == NULL) {
return -1;
}
@@ -1220,6 +1350,7 @@ evhtp_set_server_name(evhtp_t * htp, char * n) {
evbase_t *
evhtp_request_get_evbase(evhtp_request_t * request) {
+ evhtp_log_debug("enter");
if (request == NULL) {
return NULL;
}
@@ -1229,6 +1360,7 @@ evhtp_request_get_evbase(evhtp_request_t * request) {
int
evhtp_request_get_sock(evhtp_request_t * request) {
+ evhtp_log_debug("enter");
if (request == NULL) {
return -1;
}
@@ -1238,6 +1370,7 @@ evhtp_request_get_sock(evhtp_request_t * request) {
evserv_t *
evhtp_request_get_listener(evhtp_request_t * request) {
+ evhtp_log_debug("enter");
if (request == NULL) {
return NULL;
}
@@ -1249,6 +1382,7 @@ evhtp_hdr_t *
evhtp_hdr_new(char * key, char * val) {
evhtp_hdr_t * hdr;
+ evhtp_log_debug("enter");
hdr = malloc(sizeof(evhtp_hdr_t));
hdr->key = key;
hdr->val = val;
@@ -1262,12 +1396,14 @@ evhtp_request_t *
evhtp_request_new(evhtp_conn_t * conn) {
evhtp_request_t * request;
+ evhtp_log_debug("enter");
if (!(request = calloc(sizeof(evhtp_request_t), sizeof(char)))) {
return NULL;
}
- request->conn = conn;
- request->buffer_in = evbuffer_new();
+ request->conn = conn;
+ request->buffer_in = evbuffer_new();
+ request->buffer_out = evbuffer_new();
TAILQ_INIT(&request->headers_out);
TAILQ_INIT(&request->headers_in);
@@ -1277,22 +1413,312 @@ evhtp_request_new(evhtp_conn_t * conn) {
evbase_t *
evhtp_get_evbase(evhtp_t * htp) {
+ evhtp_log_debug("enter");
return htp ? htp->evbase : NULL;
}
char *
evhtp_get_server_name(evhtp_t * htp) {
+ evhtp_log_debug("enter");
return htp ? htp->server_name : NULL;
}
evserv_t *
evhtp_get_listener(evhtp_t * htp) {
+ evhtp_log_debug("enter");
return htp ? htp->listener : NULL;
}
+#ifndef DISABLE_SSL
+typedef struct htp_scache htp_scache_t;
+typedef struct htp_scache_ent htp_scache_ent_t;
+
+static int s_server_session_id_context = 1;
+
+struct htp_scache_ent {
+ htp_scache_t * scache;
+ unsigned long hash;
+ unsigned char * id;
+ unsigned char * der;
+ int id_len;
+ int der_len;
+ evhtp_ssl_sess_t * sess;
+ event_t * timeout_ev;
+
+ TAILQ_ENTRY(htp_scache_ent) next;
+};
+
+TAILQ_HEAD(htp_scache, htp_scache_ent);
+
+evhtp_ssl_cfg *
+evhtp_get_ssl_cfg(evhtp_t * htp) {
+ return htp->ssl_cfg;
+}
+
+evhtp_ssl_cfg *
+evhtp_conn_get_ssl_cfg(evhtp_conn_t * conn) {
+ return evhtp_get_ssl_cfg(conn->htp);
+}
+
+static void
+_htp_ssl_scache_builtin_expire(int fd, short what, void * arg) {
+ htp_scache_ent_t * ent;
+ htp_scache_t * scache;
+
+ printf("expire cache ent\n");
+
+ ent = (htp_scache_ent_t *)arg;
+ scache = ent->scache;
+
+ TAILQ_REMOVE(scache, ent, next);
+
+ event_free(ent->timeout_ev);
+
+ free(ent->id);
+ free(ent->der);
+ free(ent->sess);
+
+ free(ent);
+}
+
+int
+evhtp_ssl_scache_builtin_add(evhtp_conn_t * conn, unsigned char * id, int len, evhtp_ssl_sess_t * sess) {
+ evhtp_ssl_cfg * scfg;
+ htp_scache_ent_t * cache_ent;
+ htp_scache_t * scache;
+ unsigned char * der_ptr;
+ struct timeval tv;
+
+ if (!(scfg = evhtp_conn_get_ssl_cfg(conn))) {
+ return 0;
+ }
+
+ if (!(scache = (htp_scache_t *)scfg->args)) {
+ return 0;
+ }
+
+ if (!(cache_ent = calloc(sizeof(htp_scache_ent_t), sizeof(char)))) {
+ return 0;
+ }
+
+ cache_ent->id_len = len;
+ cache_ent->der_len = i2d_SSL_SESSION(sess, NULL);
+ cache_ent->id = malloc(len);
+ cache_ent->der = malloc(cache_ent->der_len);
+ cache_ent->scache = scache;
+
+ der_ptr = cache_ent->der;
+
+ memcpy(cache_ent->id, id, len);
+ i2d_SSL_SESSION(sess, &der_ptr);
+
+ /* set expire timeout event, XXX: abstract the timeout API allowing the API
+ * to create the proper timeout events instead of the user */
+ tv.tv_sec = scfg->scache_timeout;
+ tv.tv_usec = 0;
+
+ cache_ent->timeout_ev = evtimer_new(_htp_conn_get_evbase(conn),
+ _htp_ssl_scache_builtin_expire, (void *)cache_ent);
+
+ evtimer_add(cache_ent->timeout_ev, &tv);
+
+ TAILQ_INSERT_TAIL(scache, cache_ent, next);
+ return 1;
+} /* evhtp_ssl_scache_builtin_add */
+
+evhtp_ssl_sess_t *
+evhtp_ssl_scache_builtin_get(evhtp_conn_t * conn, unsigned char * id, int len) {
+ evhtp_ssl_cfg * scfg;
+ htp_scache_t * scache;
+ htp_scache_ent_t * ent;
+
+ scfg = evhtp_conn_get_ssl_cfg(conn);
+ scache = (htp_scache_t *)scfg->args;
+
+ TAILQ_FOREACH(ent, scache, next) {
+ if (len == ent->id_len && !memcmp(ent->id, id, len)) {
+ const unsigned char * p = ent->der;
+
+ return d2i_SSL_SESSION(NULL, &p, ent->der_len);
+ }
+ }
+
+ return NULL;
+}
+
+void *
+evhtp_ssl_scache_builtin_init(evhtp_t * htp) {
+ htp_scache_t * scache;
+
+ printf("hi.\n");
+
+ scache = malloc(sizeof(htp_scache_t));
+
+ TAILQ_INIT(scache);
+
+ return (void *)scache;
+}
+
+static int
+_htp_ssl_add_scache_ent(evhtp_ssl_t * ssl, evhtp_ssl_sess_t * sess) {
+ evhtp_conn_t * conn;
+ evhtp_ssl_cfg * scfg;
+ int slen;
+ unsigned char * sid;
+
+ conn = (evhtp_conn_t *)SSL_get_app_data(ssl);
+ scfg = evhtp_conn_get_ssl_cfg(conn);
+
+ if (!scfg) {
+ return 0;
+ }
+
+ sid = sess->session_id;
+ slen = sess->session_id_length;
+
+ SSL_set_timeout(sess, scfg->scache_timeout);
+
+ if (scfg->scache_add) {
+ return (scfg->scache_add)(conn, sid, slen, sess);
+ }
+
+ return 0;
+}
+
+static evhtp_ssl_sess_t *
+_htp_ssl_get_scache_ent(evhtp_ssl_t * ssl, unsigned char * sid, int sid_len, int * copy) {
+ evhtp_conn_t * conn;
+ evhtp_t * htp;
+ evhtp_ssl_cfg * scfg;
+ evhtp_ssl_sess_t * sess;
+
+ conn = (evhtp_conn_t *)SSL_get_app_data(ssl);
+ htp = conn->htp;
+ scfg = htp->ssl_cfg;
+ sess = NULL;
+
+ if (scfg->scache_get) {
+ sess = (scfg->scache_get)(conn, sid, sid_len);
+ }
+
+ *copy = 0;
+
+ return sess;
+}
+
+static void
+_htp_ssl_del_scache_ent(evhtp_ssl_ctx_t * ctx, evhtp_ssl_sess_t * sess) {
+ evhtp_t * htp;
+ evhtp_ssl_cfg * scfg;
+ unsigned char * sid;
+ unsigned int slen;
+
+ htp = (evhtp_t *)SSL_CTX_get_app_data(ctx);
+ scfg = htp->ssl_cfg;
+
+ sid = sess->session_id;
+ slen = sess->session_id_length;
+
+ if (scfg->scache_del) {
+ scfg->scache_del(htp, sid, slen);
+ }
+}
+
+int
+evhtp_use_ssl(evhtp_t * htp, evhtp_ssl_cfg * cfg) {
+ long cache_mode;
+
+ if (!cfg || !htp || !cfg->pemfile) {
+ return -1;
+ }
+
+ SSL_load_error_strings();
+ SSL_library_init();
+ RAND_status();
+
+ htp->ssl_cfg = cfg;
+ htp->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
+
+ SSL_CTX_set_options(htp->ssl_ctx, cfg->ssl_opts);
+
+ if (cfg->ciphers) {
+ SSL_CTX_set_cipher_list(htp->ssl_ctx, cfg->ciphers);
+ }
+
+ if (cfg->cafile) {
+ SSL_CTX_load_verify_locations(htp->ssl_ctx, cfg->cafile, NULL);
+ }
+
+ if (cfg->enable_scache) {
+ cache_mode = SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL |
+ SSL_SESS_CACHE_NO_INTERNAL_LOOKUP;
+ } else {
+ cache_mode = SSL_SESS_CACHE_OFF;
+ }
+
+ SSL_CTX_use_certificate_file(htp->ssl_ctx, cfg->pemfile, SSL_FILETYPE_PEM);
+ SSL_CTX_use_PrivateKey_file(htp->ssl_ctx, cfg->privfile ? : cfg->pemfile, SSL_FILETYPE_PEM);
+ SSL_CTX_set_session_cache_mode(htp->ssl_ctx, cache_mode);
+ SSL_CTX_set_session_id_context(htp->ssl_ctx, (void*)&s_server_session_id_context,
+ sizeof s_server_session_id_context);
+
+ SSL_CTX_sess_set_new_cb(htp->ssl_ctx, _htp_ssl_add_scache_ent);
+ SSL_CTX_sess_set_get_cb(htp->ssl_ctx, _htp_ssl_get_scache_ent);
+ SSL_CTX_sess_set_remove_cb(htp->ssl_ctx, _htp_ssl_del_scache_ent);
+ SSL_CTX_set_app_data(htp->ssl_ctx, htp);
+
+ if (cfg->scache_init) {
+ cfg->args = (cfg->scache_init)(htp);
+ }
+
+ return 0;
+} /* evhtp_use_ssl */
+
+#endif
+
+
#ifndef DISABLE_EVTHR
+
+#ifndef DISABLE_SSL
+static unsigned long
+_htp_ssl_get_thr_id(void) {
+ return (unsigned long)pthread_self();
+}
+
+static void
+_htp_ssl_thr_lock(int mode, int type, const char * file, int line) {
+ if (type < ssl_num_locks) {
+ if (mode & CRYPTO_LOCK) {
+ pthread_mutex_lock(ssl_locks[type]);
+ } else {
+ pthread_mutex_unlock(ssl_locks[type]);
+ }
+ }
+}
+
+#endif
+
int
evhtp_use_threads(evhtp_t * htp, int nthreads) {
+ evhtp_log_debug("enter");
+
+#ifndef DISABLE_SSL
+ if (htp->ssl_ctx != NULL) {
+ int i;
+
+ ssl_num_locks = CRYPTO_num_locks();
+ ssl_locks = malloc(ssl_num_locks * sizeof(pthread_mutex_t *));
+
+ for (i = 0; i < ssl_num_locks; i++) {
+ ssl_locks[i] = malloc(sizeof(pthread_mutex_t));
+ pthread_mutex_init(ssl_locks[i], NULL);
+ }
+
+ CRYPTO_set_id_callback(_htp_ssl_get_thr_id);
+ CRYPTO_set_locking_callback(_htp_ssl_thr_lock);
+ }
+#endif
+
if (!(htp->pool = evthr_pool_new(nthreads, htp))) {
return -1;
}
@@ -1307,6 +1733,8 @@ evhtp_t *
evhtp_new(evbase_t * evbase) {
evhtp_t * htp;
+ evhtp_log_debug("enter");
+
if (!(htp = calloc(sizeof(evhtp_t), sizeof(char)))) {
return NULL;
}
View
46 evhtp.h
@@ -10,7 +10,14 @@
#include <event.h>
#include <event2/listener.h>
-#define EVHTP_VERSION "0.3.2"
+#ifndef DISABLE_SSL
+#include <event2/bufferevent_ssl.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#endif
+
+#define EVHTP_VERSION "0.3.3"
struct evhtp;
struct evhtp_hdrs;
@@ -34,7 +41,6 @@ typedef struct evhtp_hooks evhtp_hooks_t;
typedef struct evhtp_hdr evhtp_hdr_t;
typedef struct evhtp_hdrs evhtp_hdrs_t;
-
typedef enum evhtp_res evhtp_res;
typedef enum evhtp_hook_type evhtp_hook_type;
typedef enum http_method evhtp_method;
@@ -173,6 +179,34 @@ struct evhtp_request {
evbuf_t * buffer_out;
};
+#ifndef DISABLE_SSL
+typedef SSL_SESSION evhtp_ssl_sess_t;
+typedef SSL evhtp_ssl_t;
+typedef SSL_CTX evhtp_ssl_ctx_t;
+
+typedef int (*evhtp_ssl_scache_add_cb)(evhtp_conn_t *, unsigned char *, int, evhtp_ssl_sess_t *);
+typedef evhtp_ssl_sess_t * (*evhtp_ssl_scache_get_cb)(evhtp_conn_t *, unsigned char * id, int len);
+typedef void (*evhtp_ssl_scache_del_cb)(evhtp_t *, unsigned char *, unsigned int len);
+typedef void * (*evhtp_ssl_scache_init_cb)(evhtp_t *);
+
+typedef struct evhtp_ssl_cfg evhtp_ssl_cfg;
+
+struct evhtp_ssl_cfg {
+ char * pemfile;
+ char * privfile;
+ char * cafile;
+ char * ciphers;
+ long ssl_opts;
+ char enable_scache;
+ long scache_timeout;
+ evhtp_ssl_scache_init_cb scache_init;
+ evhtp_ssl_scache_add_cb scache_add;
+ evhtp_ssl_scache_get_cb scache_get;
+ evhtp_ssl_scache_del_cb scache_del;
+ void * args;
+};
+#endif
+
evhtp_t * evhtp_new(evbase_t *);
evhtp_request_t * evhtp_request_new(evhtp_conn_t *);
@@ -217,5 +251,13 @@ const char * evhtp_version(void);
int evhtp_use_threads(evhtp_t *, int);
#endif
+#ifndef DISABLE_SSL
+int evhtp_use_ssl(evhtp_t *, evhtp_ssl_cfg *);
+
+void * evhtp_ssl_scache_builtin_init(evhtp_t *);
+int evhtp_ssl_scache_builtin_add(evhtp_conn_t *, unsigned char *, int, evhtp_ssl_sess_t *);
+evhtp_ssl_sess_t * evhtp_ssl_scache_builtin_get(evhtp_conn_t *, unsigned char *, int);
+#endif
+
#endif /* __EVHTP_H__ */
View
2  perftest.sh
@@ -13,5 +13,5 @@ conns=$4
calls=$5
echo "Running ($conns connections | $calls requests each)"
-httperf --server=$host --port=$port --uri=$uri --rate=1e+06 --send-buffer=4096 --recv-buffer=16384 --wsess=$conns,$calls,0
+httperf --ssl --server=$host --port=$port --uri=$uri --rate=1e+06 --send-buffer=4096 --recv-buffer=16384 --wsess=$conns,$calls,0
View
83 test.c
@@ -19,6 +19,8 @@ int num_threads = 0;
#endif
char * bind_addr = "0.0.0.0";
uint16_t bind_port = 8081;
+char * ssl_pem = NULL;
+char * ssl_ca = NULL;
struct _chunkarg {
uint8_t idx;
@@ -144,19 +146,46 @@ set_my_handlers(evhtp_conn_t * conn, void * arg) {
return EVHTP_RES_OK;
}
-#ifndef DISABLE_EVTHR
-const char * optstr = "htn:a:p:r:";
-#else
-const char * optstr = "ha:p:r:";
+#ifndef DISABLE_SSL
+static int
+_new_cache(evhtp_conn_t * conn, unsigned char * id, int id_len, evhtp_ssl_sess_t * sess) {
+ printf("new cache %d!\n", id_len);
+ return 0;
+}
+
+static evhtp_ssl_sess_t *
+_get_cache(evhtp_conn_t * conn, unsigned char * id, int id_len) {
+ printf("get_cache\n");
+ return NULL;
+}
+
+static void
+_del_cache(evhtp_t * htp, unsigned char * id, unsigned int id_len) {
+ printf("del_cache\n");
+}
+
+static void *
+_init_cache(evhtp_t * htp) {
+ printf("init_cache\n");
+ return (void *)malloc(5);
+}
+
#endif
-const char * help =
+
+const char * optstr = "htn:a:p:r:s:c:";
+
+const char * help =
"Options: \n"
" -h : This help text\n"
#ifndef DISABLE_EVTHR
" -t : Run requests in a thread (default: off)\n"
" -n <int> : Number of threads (default: 0 if -t is off, 4 if -t is on)\n"
#endif
+#ifndef DISABLE_SSL
+ " -s <pem> : Enable SSL and PEM (default: NULL)\n"
+ " -c <ca> : CA cert file (default: NULL\n"
+#endif
" -r <str> : Document root (default: .)\n"
" -a <str> : Bind Address (default: 0.0.0.0)\n"
" -p <int> : Bind Port (default: 8081)\n";
@@ -189,6 +218,14 @@ parse_args(int argc, char ** argv) {
num_threads = atoi(optarg);
break;
#endif
+#ifndef DISABLE_SSL
+ case 's':
+ ssl_pem = strdup(optarg);
+ break;
+ case 'c':
+ ssl_ca = strdup(optarg);
+ break;
+#endif
default:
printf("Unknown opt %s\n", optarg);
return -1;
@@ -202,7 +239,7 @@ parse_args(int argc, char ** argv) {
#endif
return 0;
-}
+} /* parse_args */
int
main(int argc, char ** argv) {
@@ -222,12 +259,6 @@ main(int argc, char ** argv) {
evbase = event_base_new();
htp = evhtp_new(evbase);
-#ifndef DISABLE_EVTHR
- if (use_threads) {
- evhtp_use_threads(htp, num_threads);
- }
-#endif
-
evhtp_set_server_name(htp, "Hi there!");
evhtp_set_cb(htp, "/ref", test_default_cb, "fjdkls");
evhtp_set_cb(htp, "/foo", test_foo_cb, "bar");
@@ -237,9 +268,35 @@ main(int argc, char ** argv) {
evhtp_set_gencb(htp, test_default_cb, "foobarbaz");
evhtp_set_post_accept_cb(htp, set_my_handlers, NULL);
+#ifndef DISABLE_SSL
+ if (ssl_pem != NULL) {
+ evhtp_ssl_cfg scfg = {
+ .pemfile = ssl_pem,
+ .privfile = ssl_pem,
+ .cafile = ssl_ca,
+ .ciphers = "RC4+RSA:HIGH:+MEDIUM:+LOW",
+ .ssl_opts = SSL_OP_NO_SSLv2,
+ .enable_scache = 1,
+ .scache_timeout = 1024,
+ .scache_init = evhtp_ssl_scache_builtin_init,
+ .scache_add = evhtp_ssl_scache_builtin_add,
+ .scache_get = evhtp_ssl_scache_builtin_get,
+ .scache_del = _del_cache,
+ };
+
+ evhtp_use_ssl(htp, &scfg);
+ }
+#endif
+
+#ifndef DISABLE_EVTHR
+ if (use_threads) {
+ evhtp_use_threads(htp, num_threads);
+ }
+#endif
+
evhtp_bind_socket(htp, bind_addr, bind_port);
event_base_loop(evbase, 0);
return 0;
-}
+} /* main */
Please sign in to comment.
Something went wrong with that request. Please try again.