Merge branch 'release/0.3.5'
diff --git a/CMakeLists.txt b/CMakeLists.txt index 708128f..589c7e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -4,7 +4,7 @@ set(PROJECT_MAJOR_VERSION 0) set(PROJECT_MINOR_VERSION 3) -set(PROJECT_PATCH_VERSION 4) +set(PROJECT_PATCH_VERSION 5) set (PROJECT_VERSION ${PROJECT_MAJOR_VERSION}.${PROJECT_MINOR_VERSION}.${PROJECT_PATCH_VERSION}) set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules)
diff --git a/ChangeLog b/ChangeLog index 077c9d3..58882d3 100644 --- a/ChangeLog +++ b/ChangeLog
@@ -1,3 +1,35 @@ +v0.3.5 + - Added evhtp_request_t accessors + + evbuf_t * evhtp_request_get_input(evhtp_request_t *); + evbuf_t * evhtp_request_get_output(evhtp_request_t *); + evbase_t * evhtp_request_get_evbase(evhtp_request_t *); + evserv_t * evhtp_request_get_listener(evhtp_request_t *); + evhtp_method evhtp_request_get_method(evhtp_request_t *); + evhtp_proto evhtp_request_get_proto(evhtp_request_t *); + evhtp_conn_t * evhtp_request_get_conn(evhtp_request_t *); + evhtp_hdrs_t * evhtp_request_get_headers_in(evhtp_request_t *); + evhtp_hdrs_t * evhtp_request_get_headers_out(evhtp_request_t *); + evhtp_callback_cb evhtp_request_get_cb(evhtp_request_t *); + void * evhtp_request_get_cbarg(evhtp_request_t *); + int evhtp_request_get_sock(evhtp_request_t *); + const char * evhtp_request_get_path(evhtp_request_t *); + const char * evhtp_request_get_uri(evhtp_request_t *); + const char * evhtp_request_method_str(evhtp_request_t *); + int evhtp_request_get_matched_soff(evhtp_request_t *); + int evhtp_request_get_matched_eoff(evhtp_request_t *); + int64_t evhtp_request_get_content_length(evhtp_request_t *); + + - Better callback return error and response handling. + * Callbacks which return an evhtp_res code now must use + EVHTP_RES_*, where each EVHTP_RES_* definition is a HTTP + status code. For example "return EVHTP_RES_400;" will + send a 404 error to the client, along with terminating + the parser. + + - All static functions prefixed with _htp_* are now just static htp_ + - Various small bugfixes. + v0.3.4 - Added optional OpenSSL support (with optional threading abstractions). * In order to properly enable SSL for your server two things must happen:
diff --git a/evhtp.c b/evhtp.c index 5b43fee..9813133 100644 --- a/evhtp.c +++ b/evhtp.c
@@ -11,6 +11,7 @@ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> +#include <assert.h> #include "http_parser.h" #include "onigposix.h" @@ -125,6 +126,7 @@ evhtp_request_t * request; http_parser * parser; int sock; + evhtp_res err; evhtp_cflags flags; evbase_t * evbase; evbev_t * bev; @@ -145,124 +147,127 @@ #define _HTP_DEFSERVER "libevht" #define _HTP_DEFCHUNKED "chunked" -#ifdef DEBUG -#define __QUOTE(x) # x -#define _QUOTE(x) __QUOTE(x) +#ifdef HTP_DEBUG +#define __QUOTE(x) # x +#define _QUOTE(x) __QUOTE(x) -#define evhtp_log_debug(fmt, ...) do { \ +#define evhtp_log_debug(fmt, ...) do { \ fprintf(stdout, __FILE__ "[" _QUOTE(__LINE__) "] %s: " \ - fmt "\n", __func__, ## __VA_ARGS__); \ + fmt "\n", __func__, ## __VA_ARGS__); \ fflush(stdout); \ } while (0) #else -#define evhtp_log_debug(fmt, ...) do {} while (0) +#define evhtp_log_debug(fmt, ...) do {} while (0) #endif -#define _htp_conn_hook(c) (c)->hooks -#define _htp_conn_has_hook(c, n) (_htp_conn_hook(c) && _htp_conn_hook(c)->n) -#define _htp_conn_hook_cbarg(c, n) _htp_conn_hook(c)->n ## _cbargs -#define _htp_conn_hook_call(c, n, ...) _htp_conn_hook(c)->n(c->request, __VA_ARGS__, _htp_conn_hook_cbarg(c, n)) -#define _htp_conn_hook_set(c, n, f, a) do { \ - _htp_conn_hook(c)->n = f; \ - _htp_conn_hook_cbarg(c, n) = a; \ +#define htp_conn_hook(c) (c)->hooks +#define htp_conn_has_hook(c, n) (htp_conn_hook(c) && htp_conn_hook(c)->n) +#define htp_conn_hook_cbarg(c, n) htp_conn_hook(c)->n ## _cbargs +#define htp_conn_hook_call(c, n, ...) htp_conn_hook(c)->n(c->request, __VA_ARGS__, htp_conn_hook_cbarg(c, n)) +#define htp_conn_hook_set(c, n, f, a) do { \ + htp_conn_hook(c)->n = f; \ + htp_conn_hook_cbarg(c, n) = a; \ } while (0) #define CRLF "\r\n" -static evhtp_proto _htp_proto(char major, char minor); -static evhtp_callback_t * _htp_callbacks_find_callback(evhtp_callbacks_t *, const char *); -static evhtp_callback_t * _htp_callbacks_find_callback_woffsets(evhtp_callbacks_t *, const char *, int *, int *); -static void _htp_recv_cb(evbev_t * bev, void * arg); -static void _htp_err_cb(evbev_t * bev, short events, void * arg); -static evhtp_request_t * _htp_request_new(evhtp_conn_t * conn); +static evhtp_proto htp_proto(char major, char minor); +static evhtp_callback_t * htp_callbacks_find_callback(evhtp_callbacks_t *, const char *); +static evhtp_callback_t * htp_callbacks_find_callback_woffsets(evhtp_callbacks_t *, const char *, int *, int *); +static void htp_recv_cb(evbev_t * bev, void * arg); +static void htp_err_cb(evbev_t * bev, short events, void * arg); +static evhtp_request_t * htp_request_new(evhtp_conn_t * conn); static int ssl_num_locks; static evhtp_mutex_t ** ssl_locks; -static evhtp_status -_htp_run_on_expect_hook(evhtp_conn_t * conn, const char * expt_val) { - evhtp_status status = EVHTP_CODE_CONTINUE; +static evhtp_res +htp_run_on_expect_hook(evhtp_conn_t * conn, const char * expt_val) { + evhtp_res status = EVHTP_RES_CONTINUE; evhtp_log_debug("enter"); - if (_htp_conn_has_hook(conn, _on_expect)) { - status = _htp_conn_hook_call(conn, _on_expect, expt_val); + if (htp_conn_has_hook(conn, _on_expect)) { + status = htp_conn_hook_call(conn, _on_expect, expt_val); } return status; } static evhtp_res -_htp_run_hdr_hook(evhtp_conn_t * conn, evhtp_hdr_t * hdr) { +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); + + if (htp_conn_has_hook(conn, _hdr)) { + res = htp_conn_hook_call(conn, _hdr, hdr); } return res; } static evhtp_res -_htp_run_hdrs_hook(evhtp_conn_t * conn, evhtp_hdrs_t * hdrs) { +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); + if (htp_conn_has_hook(conn, _hdrs)) { + res = htp_conn_hook_call(conn, _hdrs, hdrs); } return res; } static evhtp_res -_htp_run_path_hook(evhtp_conn_t * conn, const char * path) { +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); + + if (htp_conn_has_hook(conn, _path)) { + res = htp_conn_hook_call(conn, _path, path); } return res; } static evhtp_res -_htp_run_uri_hook(evhtp_conn_t * conn, const char * uri) { +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); + if (htp_conn_has_hook(conn, _uri)) { + res = htp_conn_hook_call(conn, _uri, uri); } return res; } static evhtp_res -_htp_run_read_hook(evhtp_conn_t * conn, const char * data, size_t sz) { +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); + if (htp_conn_has_hook(conn, _read)) { + res = htp_conn_hook_call(conn, _read, data, sz); } return res; } static int -_htp_start_cb(http_parser * p) { +htp_start_cb(http_parser * p) { evhtp_conn_t * conn = p->data; evhtp_log_debug("enter"); - conn->request = _htp_request_new(conn); + + conn->request = htp_request_new(conn); return 0; } static int -_htp_end_cb(http_parser * p) { +htp_end_cb(http_parser * p) { evhtp_conn_t * conn = NULL; evhtp_request_t * request = NULL; @@ -278,7 +283,7 @@ } static int -_htp_query_str_cb(http_parser * p, const char * buf, size_t len) { +htp_query_str_cb(http_parser * p, const char * buf, size_t len) { /* evhtp_conn_t * conn = p->data; */ evhtp_log_debug("len = %" PRIoMAX " buf = '%.*s'", len, (int)len, buf); @@ -287,7 +292,7 @@ } static int -_htp_uri_cb(http_parser * p, const char * buf, size_t len) { +htp_uri_cb(http_parser * p, const char * buf, size_t len) { evhtp_conn_t * conn; evhtp_request_t * request; @@ -300,7 +305,8 @@ memcpy(request->uri, buf, len); - if (_htp_run_uri_hook(conn, request->uri) != EVHTP_RES_OK) { + if (htp_run_uri_hook(conn, request->uri) != EVHTP_RES_OK) { + conn->err = 1; return -1; } @@ -308,7 +314,7 @@ } static int -_htp_fragment_cb(http_parser * p, const char * buf, size_t len) { +htp_fragment_cb(http_parser * p, const char * buf, size_t len) { /* evhtp_conn_t * conn = p->data; */ evhtp_log_debug("len = %" PRIoMAX " buf = '%.*s", len, (int)len, buf); @@ -317,7 +323,7 @@ } static int -_htp_header_key_cb(http_parser * p, const char * buf, size_t len) { +htp_header_key_cb(http_parser * p, const char * buf, size_t len) { evhtp_hdr_t * hdr; evhtp_conn_t * conn; @@ -336,7 +342,7 @@ } static int -_htp_header_val_cb(http_parser * p, const char * buf, size_t len) { +htp_header_val_cb(http_parser * p, const char * buf, size_t len) { evhtp_hdr_t * hdr = NULL; evhtp_conn_t * conn = NULL; evhtp_request_t * req = NULL; @@ -353,7 +359,8 @@ memcpy(hdr->val, buf, len); - if (_htp_run_hdr_hook(conn, hdr) != EVHTP_RES_OK) { + if (htp_run_hdr_hook(conn, hdr) != EVHTP_RES_OK) { + conn->err = 1; return -1; } @@ -361,7 +368,7 @@ } static int -_htp_headers_complete_cb(http_parser * p) { +htp_headers_complete_cb(http_parser * p) { evhtp_conn_t * conn; evhtp_log_debug("enter"); @@ -370,22 +377,24 @@ conn->request->method = p->method; conn->request->major = p->http_major; conn->request->minor = p->http_minor; - conn->request->proto = _htp_proto(p->http_major, p->http_minor); + conn->request->proto = htp_proto(p->http_major, p->http_minor); - if (_htp_run_hdrs_hook(conn, &conn->request->headers_in) != EVHTP_RES_OK) { + if (htp_run_hdrs_hook(conn, &conn->request->headers_in) != EVHTP_RES_OK) { + conn->err = 1; return -1; } if (evhtp_hdr_find(&conn->request->headers_in, _HTP_CONTLEN)) { const char * expt_val; evbuf_t * buf; - evhtp_status status; + evhtp_res status; if (!(expt_val = evhtp_hdr_find(&conn->request->headers_in, _HTP_EXPECT))) { return 0; } - if ((status = _htp_run_on_expect_hook(conn, expt_val)) != EVHTP_CODE_CONTINUE) { + if ((status = htp_run_on_expect_hook(conn, expt_val)) != EVHTP_RES_CONTINUE) { + conn->err = 1; evhtp_send_reply(conn->request, status, "no", NULL); return -1; } @@ -400,29 +409,27 @@ } static int -_htp_path_cb(http_parser * p, const char * buf, size_t len) { +htp_path_cb(http_parser * p, const char * buf, size_t len) { evhtp_conn_t * conn = NULL; evhtp_request_t * request = NULL; evhtp_callback_t * cb = NULL; - /* printf("on_path size: %llu\n", len); */ - evhtp_log_debug("enter"); + conn = p->data; request = conn->request; - request->path = malloc(len + 1); request->path[len] = '\0'; memcpy(request->path, buf, len); - cb = _htp_callbacks_find_callback_woffsets(conn->htp->callbacks, - request->path, - &request->matched_soff, - &request->matched_eoff); - + cb = htp_callbacks_find_callback_woffsets(conn->htp->callbacks, + request->path, + &request->matched_soff, + &request->matched_eoff); if (cb == NULL) { if (conn->htp->default_cb == NULL) { + evhtp_send_reply(request, EVHTP_RES_400, "NOT FOUND", NULL); return -1; } @@ -433,7 +440,8 @@ request->cbarg = cb->cbarg; } - if (_htp_run_path_hook(conn, conn->request->path) != EVHTP_RES_OK) { + if (htp_run_path_hook(conn, conn->request->path) != EVHTP_RES_OK) { + conn->err = 1; return -1; } @@ -441,13 +449,15 @@ } static int -_htp_body_cb(http_parser * p, const char * buf, size_t len) { +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) { + evbuffer_add(evhtp_request_get_input(conn->request), buf, len); + + if (htp_run_read_hook(conn, buf, len) != EVHTP_RES_OK) { + conn->err = 1; return -1; } @@ -455,7 +465,7 @@ } static inline unsigned int -_htp_thash(const char * key) { +htp_thash(const char * key) { unsigned int h = 0; for (; *key; key++) { @@ -466,7 +476,7 @@ } static evhtp_callback_t * -_htp_callback_new(const void * uri, callback_type_t type, evhtp_callback_cb cb, void * cbarg) { +htp_callback_new(const void * uri, callback_type_t type, evhtp_callback_cb cb, void * cbarg) { evhtp_callback_t * htp_cb; evhtp_log_debug("enter"); @@ -479,8 +489,8 @@ switch (type) { case callback_type_uri: - htp_cb->hash = _htp_thash(uri); - htp_cb->val.uri = strdup((const char *)uri); + htp_cb->hash = htp_thash(uri); + htp_cb->val.uri = strdup((const char *)uri); break; case callback_type_regex: htp_cb->val.regex = (regex_t *)malloc(sizeof(regex_t)); @@ -501,7 +511,7 @@ } static evhtp_callbacks_t * -_htp_callbacks_new(unsigned int buckets) { +htp_callbacks_new(unsigned int buckets) { evhtp_callbacks_t * htp_cbs; evhtp_log_debug("enter"); @@ -522,19 +532,18 @@ } static evhtp_callback_t * -_htp_callbacks_find_callback_woffsets(evhtp_callbacks_t * cbs, - const char * uri, - int * start_offset, - int * end_offset) { +htp_callbacks_find_callback_woffsets(evhtp_callbacks_t * cbs, + const char * uri, + int * start_offset, + int * end_offset) { evhtp_callback_t * cb; unsigned int hash; - evhtp_log_debug("enter"); if (cbs == NULL) { return NULL; } - hash = _htp_thash(uri); + hash = htp_thash(uri); cb = cbs->callbacks[hash & (cbs->buckets - 1)]; while (cb != NULL) { @@ -566,7 +575,7 @@ } static evhtp_callback_t * -_htp_callbacks_find_callback(evhtp_callbacks_t * cbs, const char * uri) { +htp_callbacks_find_callback(evhtp_callbacks_t * cbs, const char * uri) { evhtp_callback_t * cb; unsigned int hash; @@ -576,7 +585,7 @@ return NULL; } - hash = _htp_thash(uri); + hash = htp_thash(uri); cb = cbs->callbacks[hash & (cbs->buckets - 1)]; while (cb != NULL) { @@ -603,7 +612,7 @@ } static int -_htp_callbacks_add_callback(evhtp_callbacks_t * cbs, evhtp_callback_t * cb) { +htp_callbacks_add_callback(evhtp_callbacks_t * cbs, evhtp_callback_t * cb) { unsigned int hkey; evhtp_log_debug("enter"); @@ -630,7 +639,7 @@ } void -_htp_conn_free(evhtp_conn_t * conn) { +htp_conn_free(evhtp_conn_t * conn) { if (conn == NULL) { return; } @@ -659,10 +668,10 @@ free(conn); -} /* _htp_conn_free */ +} /* htp_conn_free */ static evhtp_conn_t * -_htp_conn_new(evhtp_t * htp) { +htp_conn_new(evhtp_t * htp) { evhtp_conn_t * conn; evhtp_log_debug("enter"); @@ -690,7 +699,7 @@ } static void -_htp_conn_reset(evhtp_conn_t * conn) { +htp_conn_reset(evhtp_conn_t * conn) { http_parser_init(conn->parser, HTTP_REQUEST); evhtp_log_debug("enter"); @@ -702,11 +711,11 @@ 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_setcb(conn->bev, htp_recv_cb, NULL, htp_err_cb, conn); } static int -_htp_conn_get_sock(evhtp_conn_t * conn) { +htp_conn_get_sock(evhtp_conn_t * conn) { if (conn == NULL) { return -1; } @@ -716,7 +725,7 @@ } static evserv_t * -_htp_conn_get_listener(evhtp_conn_t * conn) { +htp_conn_get_listener(evhtp_conn_t * conn) { if (conn == NULL) { return NULL; } @@ -726,7 +735,7 @@ } static evbase_t * -_htp_conn_get_evbase(evhtp_conn_t * conn) { +htp_conn_get_evbase(evhtp_conn_t * conn) { if (conn == NULL) { return NULL; } @@ -736,7 +745,7 @@ } static int -_htp_resp_can_have_content(evhtp_status code) { +htp_resp_can_have_content(evhtp_res code) { evhtp_log_debug("enter"); if (code >= 100) { if (code < 300) { @@ -748,10 +757,10 @@ } static void -_htp_recv_cb(evbev_t * bev, void * arg) { +htp_recv_cb(evbev_t * bev, void * arg) { evbuf_t * ibuf; evhtp_conn_t * conn; - char * read_buf; + void * read_buf; size_t nread; size_t avail; @@ -759,9 +768,13 @@ conn = (evhtp_conn_t *)arg; ibuf = bufferevent_get_input(bev); avail = evbuffer_get_length(ibuf); - read_buf = (char *)evbuffer_pullup(ibuf, avail); + read_buf = evbuffer_pullup(ibuf, avail); - nread = http_parser_execute(conn->parser, &conn->htp->psets, read_buf, avail); + nread = http_parser_execute(conn->parser, &conn->htp->psets, (char *)read_buf, avail); + + if (conn->err != 0) { + return htp_conn_free(conn); + } evhtp_log_debug("nread = %zu", nread); @@ -773,7 +786,7 @@ } static void -_htp_err_cb(evbev_t * bev, short events, void * arg) { +htp_err_cb(evbev_t * bev, short events, void * arg) { evhtp_conn_t * conn; evhtp_log_debug("events = %x", events); @@ -781,12 +794,15 @@ if (events & (BEV_EVENT_ERROR | BEV_EVENT_EOF)) { conn = (evhtp_conn_t *)arg; - return _htp_conn_free(conn); + evhtp_log_debug("leaving...."); + return htp_conn_free(conn); } + + evhtp_log_debug("leaving...."); } static int -_htp_hdr_output(evhtp_hdr_t * hdr, void * arg) { +htp_hdr_output(evhtp_hdr_t * hdr, void * arg) { evbuf_t * buf = (evbuf_t *)arg; @@ -799,7 +815,7 @@ } static void -_htp_exec_in_thr(evthr_t * thr, void * arg, void * shared) { +htp_exec_in_thr(evthr_t * thr, void * arg, void * shared) { evhtp_t * htp; evhtp_conn_t * conn; @@ -816,14 +832,14 @@ #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); + conn->sock, conn->ssl, BUFFEREVENT_SSL_ACCEPTING, + BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); SSL_set_app_data(conn->ssl, conn); #endif } - bufferevent_setcb(conn->bev, _htp_recv_cb, NULL, _htp_err_cb, conn); + bufferevent_setcb(conn->bev, htp_recv_cb, NULL, htp_err_cb, conn); bufferevent_enable(conn->bev, EV_READ); bufferevent_disable(conn->bev, EV_WRITE); @@ -835,14 +851,14 @@ } static void -_htp_accept_cb(evserv_t * serv, int fd, struct sockaddr * s, int sl, void * arg) { +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; - conn = _htp_conn_new(htp); + htp = (evhtp_t *)arg; + conn = htp_conn_new(htp); conn->evbase = htp->evbase; conn->sock = fd; @@ -851,7 +867,7 @@ } if (htp->pool != NULL) { - evthr_pool_defer(htp->pool, _htp_exec_in_thr, conn); + evthr_pool_defer(htp->pool, htp_exec_in_thr, conn); return; } @@ -861,8 +877,8 @@ #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); + conn->sock, conn->ssl, BUFFEREVENT_SSL_ACCEPTING, + BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); SSL_set_app_data(conn->ssl, conn); #else @@ -872,20 +888,21 @@ bufferevent_disable(conn->bev, EV_WRITE); bufferevent_enable(conn->bev, EV_READ); - bufferevent_setcb(conn->bev, _htp_recv_cb, NULL, _htp_err_cb, conn); + 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 */ +} /* htp_accept_cb */ static void -_htp_set_kalive_hdr(evhtp_hdrs_t * hdrs, evhtp_proto proto, int kalive) { +htp_set_kalive_hdr(evhtp_hdrs_t * hdrs, evhtp_proto proto, int kalive) { + evhtp_log_debug("enter"); + if (hdrs == NULL) { return; } - evhtp_log_debug("enter"); if (kalive && proto == EVHTP_PROTO_1_0) { return evhtp_hdr_add(hdrs, evhtp_hdr_new(_HTP_CONN, _HTP_DEFKALIVE)); } @@ -896,7 +913,7 @@ } static void -_htp_reply_set_content_hdrs(evhtp_request_t * req, size_t len) { +htp_reply_set_content_hdrs(evhtp_request_t * req, size_t len) { const char * content_len_hval; const char * content_type_hval; @@ -931,60 +948,62 @@ if (content_type_hval == NULL) { evhtp_hdr_add(&req->headers_out, evhtp_hdr_new(_HTP_CONTYPE, _HTP_DEFCONTYPE)); } -} /* _htp_reply_set_content_hdrs */ +} /* htp_reply_set_content_hdrs */ -static evhtp_status -_htp_code_parent(evhtp_status code) { +static evhtp_res +htp_code_parent(evhtp_res code) { evhtp_log_debug("enter"); if (code > 599 || code < 100) { - return EVHTP_CODE_SCREWEDUP; + return EVHTP_RES_SCREWEDUP; } if (code >= 100 && code < 200) { - return EVHTP_CODE_100; + return EVHTP_RES_100; } if (code >= 200 && code < 300) { - return EVHTP_CODE_200; + return EVHTP_RES_200; } if (code >= 300 && code < 400) { - return EVHTP_CODE_300; + return EVHTP_RES_300; } if (code >= 400 && code < 500) { - return EVHTP_CODE_400; + return EVHTP_RES_400; } - return EVHTP_CODE_500; + return EVHTP_RES_500; } static int -_htp_should_close_based_on_cflags(evhtp_cflags flags, evhtp_status code) { +htp_should_close_based_on_cflags(evhtp_cflags flags, evhtp_res code) { int res = 0; evhtp_log_debug("enter"); - switch (_htp_code_parent(code)) { - case EVHTP_CODE_100: + + switch (htp_code_parent(code)) { + case EVHTP_RES_100: res = (flags & EVHTP_CLOSE_ON_100); break; - case EVHTP_CODE_200: + case EVHTP_RES_200: res = (flags & EVHTP_CLOSE_ON_200); break; - case EVHTP_CODE_300: + case EVHTP_RES_300: res = (flags & EVHTP_CLOSE_ON_300); break; - case EVHTP_CODE_400: - if (code == EVHTP_CODE_EXPECTFAIL && flags & EVHTP_CLOSE_ON_EXPECT_ERR) { + case EVHTP_RES_400: + if (code == EVHTP_RES_EXPECTFAIL && flags & EVHTP_CLOSE_ON_EXPECT_ERR) { res = 1; } else { res = (flags & EVHTP_CLOSE_ON_400); } break; - case EVHTP_CODE_500: + case EVHTP_RES_500: res = (flags & EVHTP_CLOSE_ON_500); break; - case EVHTP_CODE_SCREWEDUP: + case EVHTP_RES_SCREWEDUP: + default: res = 1; break; } /* switch */ @@ -993,7 +1012,7 @@ } static int -_htp_should_keep_alive(evhtp_request_t * req, evhtp_status code) { +htp_should_keep_alive(evhtp_request_t * req, evhtp_res code) { evhtp_conn_t * conn = req->conn; evhtp_log_debug("enter"); @@ -1002,7 +1021,7 @@ return 0; } - if (_htp_should_close_based_on_cflags(conn->flags, code)) { + if (htp_should_close_based_on_cflags(conn->flags, code)) { /* one of the user-set flags has informed us to close, thus * do not keep alive */ return 0; @@ -1014,7 +1033,7 @@ } static inline int -_htp_is_http_1_1x(char major, char minor) { +htp_is_http_1_1x(char major, char minor) { evhtp_log_debug("enter"); if (major >= 1 && minor >= 1) { return 1; @@ -1024,7 +1043,7 @@ } static inline int -_htp_is_http_1_0x(char major, char minor) { +htp_is_http_1_0x(char major, char minor) { if (major >= 1 && minor <= 0) { return 1; } @@ -1033,36 +1052,36 @@ } static evhtp_proto -_htp_proto(char major, char minor) { - if (_htp_is_http_1_0x(major, minor)) { +htp_proto(char major, char minor) { + if (htp_is_http_1_0x(major, minor)) { return EVHTP_PROTO_1_0; } - if (_htp_is_http_1_1x(major, minor)) { + if (htp_is_http_1_1x(major, minor)) { return EVHTP_PROTO_1_1; } return EVHTP_PROTO_INVALID; } -#define _htp_set_status_buf(buf, major, minor, code) do { \ +#define htp_set_status_buf(buf, major, minor, code) do { \ evbuffer_add_printf(buf, "HTTP/%d.%d %d DERP\r\n", major, minor, code); \ } while (0) -#define _htp_set_header_buf(buf, hdrs) do { \ - evhtp_hdrs_for_each(hdrs, _htp_hdr_output, buf); \ +#define htp_set_header_buf(buf, hdrs) do { \ + evhtp_hdrs_for_each(hdrs, htp_hdr_output, buf); \ } while (0) -#define _htp_set_server_hdr(hdrs, name) do { \ +#define htp_set_server_hdr(hdrs, name) do { \ evhtp_hdr_add(hdrs, evhtp_hdr_new(_HTP_SERVER, name)); \ } while (0) -#define _htp_set_crlf_buf(buf) do { \ +#define htp_set_crlf_buf(buf) do { \ evbuffer_add_reference(buf, CRLF, 2, NULL, NULL); \ } while (0) void -_htp_set_body_buf(evbuf_t * dst, evbuf_t * src) { +htp_set_body_buf(evbuf_t * dst, evbuf_t * src) { if (dst == NULL) { return; } @@ -1074,7 +1093,7 @@ } static void -_htp_resp_fini_cb(evbev_t * bev, void * arg) { +htp_resp_fini_cb(evbev_t * bev, void * arg) { evhtp_request_t * req; evhtp_conn_t * conn; int keepalive; @@ -1086,14 +1105,14 @@ conn = req->conn; if (keepalive) { - return _htp_conn_reset(conn); + return htp_conn_reset(conn); } else { - return _htp_conn_free(conn); + return htp_conn_free(conn); } } static void -_htp_resp_err_cb(evbev_t * bev, short events, void * arg) { +htp_resp_err_cb(evbev_t * bev, short events, void * arg) { evhtp_request_t * req; evhtp_conn_t * conn; @@ -1102,27 +1121,30 @@ req = (evhtp_request_t *)arg; conn = req->conn; - return _htp_conn_free(conn); + return htp_conn_free(conn); } static void -_htp_stream_fini_cb(evbev_t * bev, void * arg) { +htp_stream_fini_cb(evbev_t * bev, void * arg) { evhtp_request_t * req; evhtp_conn_t * conn; + evbuf_t * buf; evhtp_log_debug("enter"); + req = (evhtp_request_t *)arg; conn = req->conn; + buf = evhtp_request_get_output(req); switch (req->stream_cb(req, req->stream_cbarg)) { case EVHTP_RES_OK: - bufferevent_write_buffer(conn->bev, req->buffer_out); + bufferevent_write_buffer(conn->bev, buf); return; case EVHTP_RES_DONE: if (req->chunked) { - evbuffer_add_reference(req->buffer_out, "0\r\n\r\n", 5, NULL, NULL); - bufferevent_setcb(conn->bev, NULL, _htp_resp_fini_cb, _htp_resp_err_cb, req); - bufferevent_write_buffer(conn->bev, req->buffer_out); + evbuffer_add_reference(buf, "0\r\n\r\n", 5, NULL, NULL); + bufferevent_setcb(conn->bev, NULL, htp_resp_fini_cb, htp_resp_err_cb, req); + bufferevent_write_buffer(conn->bev, buf); return; } break; @@ -1131,58 +1153,60 @@ break; } - return _htp_resp_fini_cb(conn->bev, arg); + return htp_resp_fini_cb(conn->bev, arg); } void -evhtp_send_reply(evhtp_request_t * req, evhtp_status code, const char * r, evbuf_t * b) { +evhtp_send_reply(evhtp_request_t * req, evhtp_res code, const char * r, evbuf_t * b) { evhtp_conn_t * conn; + evbuf_t * obuf; evhtp_log_debug("enter"); + conn = req->conn; - req->keepalive = _htp_should_keep_alive(req, code); + obuf = evhtp_request_get_output(req); + req->keepalive = htp_should_keep_alive(req, code); - if (req->buffer_out == NULL) { - req->buffer_out = evbuffer_new(); - } + assert(obuf != NULL); - if (_htp_resp_can_have_content(code)) { - _htp_reply_set_content_hdrs(req, b ? evbuffer_get_length(b) : 0); + if (htp_resp_can_have_content(code)) { + 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); } } - _htp_set_kalive_hdr(&req->headers_out, req->proto, req->keepalive); - _htp_set_server_hdr(&req->headers_out, evhtp_get_server_name(conn->htp)); + htp_set_kalive_hdr(&req->headers_out, req->proto, req->keepalive); + htp_set_server_hdr(&req->headers_out, evhtp_get_server_name(conn->htp)); - _htp_set_status_buf(req->buffer_out, req->major, req->minor, code); - _htp_set_header_buf(req->buffer_out, &req->headers_out); - _htp_set_crlf_buf(req->buffer_out); - _htp_set_body_buf(req->buffer_out, b); + htp_set_status_buf(obuf, req->major, req->minor, code); + htp_set_header_buf(obuf, &req->headers_out); + htp_set_crlf_buf(obuf); + htp_set_body_buf(obuf, b); 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); + bufferevent_setcb(conn->bev, NULL, htp_resp_fini_cb, htp_resp_err_cb, req); + bufferevent_write_buffer(conn->bev, obuf); } /* evhtp_send_reply */ void -evhtp_send_reply_stream(evhtp_request_t * req, evhtp_status code, evhtp_stream_cb cb, void * arg) { +evhtp_send_reply_stream(evhtp_request_t * req, evhtp_res code, evhtp_stream_cb cb, void * arg) { evhtp_conn_t * conn; + evbuf_t * obuf; evhtp_log_debug("enter"); - conn = req->conn; - if (req->buffer_out == NULL) { - req->buffer_out = evbuffer_new(); - } + conn = req->conn; + obuf = evhtp_request_get_output(req); + + assert(obuf != NULL); if (req->proto == EVHTP_PROTO_1_1) { - req->keepalive = _htp_should_keep_alive(req, code); + req->keepalive = htp_should_keep_alive(req, code); if (!evhtp_hdr_find(&req->headers_out, _HTP_TRANSENC)) { evhtp_hdr_add(&req->headers_out, evhtp_hdr_new(_HTP_TRANSENC, _HTP_DEFCHUNKED)); @@ -1197,12 +1221,12 @@ evhtp_hdr_add(&req->headers_out, evhtp_hdr_new(_HTP_CONTYPE, _HTP_DEFCONTYPE)); } - _htp_set_kalive_hdr(&req->headers_out, req->proto, req->keepalive); - _htp_set_server_hdr(&req->headers_out, evhtp_get_server_name(conn->htp)); + htp_set_kalive_hdr(&req->headers_out, req->proto, req->keepalive); + htp_set_server_hdr(&req->headers_out, evhtp_get_server_name(conn->htp)); - _htp_set_status_buf(req->buffer_out, req->major, req->minor, code); - _htp_set_header_buf(req->buffer_out, &req->headers_out); - _htp_set_crlf_buf(req->buffer_out); + htp_set_status_buf(obuf, req->major, req->minor, code); + htp_set_header_buf(obuf, &req->headers_out); + htp_set_crlf_buf(obuf); req->stream_cb = cb; req->stream_cbarg = arg; @@ -1211,16 +1235,19 @@ 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); + bufferevent_setcb(conn->bev, NULL, htp_stream_fini_cb, htp_resp_err_cb, req); + bufferevent_write_buffer(conn->bev, obuf); } /* evhtp_send_reply_stream */ void evhtp_request_make_chunk(evhtp_request_t * req, evbuf_t * buf) { + evbuf_t * obuf = evhtp_request_get_output(req); + 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); + + evbuffer_add_printf(obuf, "%" PRIxMAX "\r\n", evbuffer_get_length(buf)); + evbuffer_add_buffer(obuf, buf); + evbuffer_add_reference(obuf, CRLF, 2, NULL, NULL); } void @@ -1231,11 +1258,11 @@ case EVHTP_PROTO_1_1: return evhtp_request_make_chunk(req, buf); case EVHTP_PROTO_1_0: - evbuffer_add_buffer(req->buffer_out, buf); + evbuffer_add_buffer(evhtp_request_get_output(req), buf); req->keepalive = 0; break; default: - return _htp_conn_free(req->conn); + return htp_conn_free(req->conn); } } @@ -1255,22 +1282,22 @@ switch (type) { case EVHTP_HOOK_HDRS_READ: - _htp_conn_hook_set(conn, _hdrs, cb, cbarg); + htp_conn_hook_set(conn, _hdrs, cb, cbarg); break; case EVHTP_HOOK_HDR_READ: - _htp_conn_hook_set(conn, _hdr, cb, cbarg); + htp_conn_hook_set(conn, _hdr, cb, cbarg); break; case EVHTP_HOOK_PATH_READ: - _htp_conn_hook_set(conn, _read, cb, cbarg); + htp_conn_hook_set(conn, _read, cb, cbarg); break; case EVHTP_HOOK_URI_READ: - _htp_conn_hook_set(conn, _uri, cb, cbarg); + htp_conn_hook_set(conn, _uri, cb, cbarg); break; case EVHTP_HOOK_READ: - _htp_conn_hook_set(conn, _read, cb, cbarg); + htp_conn_hook_set(conn, _read, cb, cbarg); break; case EVHTP_HOOK_ON_EXPECT: - _htp_conn_hook_set(conn, _on_expect, cb, cbarg); + htp_conn_hook_set(conn, _on_expect, cb, cbarg); break; case EVHTP_HOOK_COMPLETE: break; @@ -1288,18 +1315,18 @@ evhtp_log_debug("enter"); if (htp->callbacks == NULL) { - htp->callbacks = _htp_callbacks_new(1024); + htp->callbacks = htp_callbacks_new(1024); } else { - if (_htp_callbacks_find_callback(htp->callbacks, uri)) { + if (htp_callbacks_find_callback(htp->callbacks, uri)) { return -1; } } - if (!(htp_cb = _htp_callback_new(uri, callback_type_uri, cb, cbarg))) { + if (!(htp_cb = htp_callback_new(uri, callback_type_uri, cb, cbarg))) { return -1; } - if (!_htp_callbacks_add_callback(htp->callbacks, htp_cb)) { + if (!htp_callbacks_add_callback(htp->callbacks, htp_cb)) { return -1; } @@ -1313,14 +1340,14 @@ evhtp_log_debug("enter"); if (htp->callbacks == NULL) { - htp->callbacks = _htp_callbacks_new(1024); + htp->callbacks = htp_callbacks_new(1024); } - if (!(htp_cb = _htp_callback_new(pat, callback_type_regex, cb, arg))) { + if (!(htp_cb = htp_callback_new(pat, callback_type_regex, cb, arg))) { return -1; } - if (!_htp_callbacks_add_callback(htp->callbacks, htp_cb)) { + if (!htp_callbacks_add_callback(htp->callbacks, htp_cb)) { return -1; } @@ -1345,9 +1372,10 @@ 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)); + 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 @@ -1489,6 +1517,51 @@ return 0; } +const char * +evhtp_request_get_path(evhtp_request_t * request) { + return (const char *)request->path; +} + +const char * +evhtp_request_get_uri(evhtp_request_t * request) { + return (const char *)request->uri; +} + +int +evhtp_request_get_matched_soff(evhtp_request_t * request) { + return request->matched_soff; +} + +int +evhtp_request_get_matched_eoff(evhtp_request_t * request) { + return request->matched_eoff; +} + +evhtp_method +evhtp_request_get_method(evhtp_request_t * request) { + return request->method; +} + +evhtp_proto +evhtp_request_get_proto(evhtp_request_t * request) { + return request->proto; +} + +evhtp_conn_t * +evhtp_request_get_conn(evhtp_request_t * request) { + return request->conn; +} + +evhtp_hdrs_t * +evhtp_request_get_headers_in(evhtp_request_t * request) { + return &request->headers_in; +} + +evhtp_hdrs_t * +evhtp_request_get_headers_out(evhtp_request_t * request) { + return &request->headers_out; +} + evbuf_t * evhtp_request_get_input(evhtp_request_t * request) { return request->buffer_in; @@ -1499,6 +1572,31 @@ return request->buffer_out; } +evhtp_callback_cb +evhtp_request_get_cb(evhtp_request_t * request) { + return request->cb; +} + +void * +evhtp_request_get_cbarg(evhtp_request_t * request) { + return request->cbarg; +} + +const char * +evhtp_request_method_str(evhtp_request_t * request) { + return evhtp_method_str(request->method); +} + +int64_t +evhtp_request_content_length(evhtp_request_t * request) { + return request->conn->parser->content_length; +} + +const char * +evhtp_method_str(evhtp_method method) { + return http_method_str(method); +} + evbase_t * evhtp_request_get_evbase(evhtp_request_t * request) { evhtp_log_debug("enter"); @@ -1507,7 +1605,7 @@ return NULL; } - return _htp_conn_get_evbase(request->conn); + return htp_conn_get_evbase(request->conn); } int @@ -1517,7 +1615,7 @@ return -1; } - return _htp_conn_get_sock(request->conn); + return htp_conn_get_sock(request->conn); } evserv_t * @@ -1528,7 +1626,7 @@ return NULL; } - return _htp_conn_get_listener(request->conn); + return htp_conn_get_listener(request->conn); } evhtp_hdr_t * @@ -1547,7 +1645,7 @@ } static evhtp_request_t * -_htp_request_new(evhtp_conn_t * conn) { +htp_request_new(evhtp_conn_t * conn) { evhtp_request_t * request; evhtp_log_debug("enter"); @@ -1616,7 +1714,7 @@ } static void -_htp_ssl_scache_builtin_expire(int fd, short what, void * arg) { +htp_ssl_scache_builtin_expire(int fd, short what, void * arg) { htp_scache_ent_t * ent; htp_scache_t * scache; @@ -1672,8 +1770,8 @@ 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); + 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); @@ -1713,7 +1811,7 @@ } static int -_htp_ssl_add_scache_ent(evhtp_ssl_t * ssl, evhtp_ssl_sess_t * sess) { +htp_ssl_add_scache_ent(evhtp_ssl_t * ssl, evhtp_ssl_sess_t * sess) { evhtp_conn_t * conn; evhtp_ssl_cfg * scfg; int slen; @@ -1739,7 +1837,7 @@ } static evhtp_ssl_sess_t * -_htp_ssl_get_scache_ent(evhtp_ssl_t * ssl, unsigned char * sid, int sid_len, int * copy) { +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; @@ -1760,7 +1858,7 @@ } static void -_htp_ssl_del_scache_ent(evhtp_ssl_ctx_t * ctx, evhtp_ssl_sess_t * sess) { +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; @@ -1813,11 +1911,11 @@ 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); + 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_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) { @@ -1830,12 +1928,12 @@ #endif static unsigned long -_htp_ssl_get_thr_id(void) { +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) { +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]); @@ -1860,8 +1958,8 @@ pthread_mutex_init(ssl_locks[i], NULL); } - CRYPTO_set_id_callback(_htp_ssl_get_thr_id); - CRYPTO_set_locking_callback(_htp_ssl_thr_lock); + CRYPTO_set_id_callback(htp_ssl_get_thr_id); + CRYPTO_set_locking_callback(htp_ssl_thr_lock); } if (!(htp->pool = evthr_pool_new(nthreads, htp))) { @@ -1883,18 +1981,18 @@ } htp->server_name = _HTP_DEFSERVER; - htp->psets.on_message_begin = _htp_start_cb; - htp->psets.on_path = _htp_path_cb; - htp->psets.on_query_string = _htp_query_str_cb; - htp->psets.on_url = _htp_uri_cb; - htp->psets.on_fragment = _htp_fragment_cb; - htp->psets.on_header_field = _htp_header_key_cb; - htp->psets.on_header_value = _htp_header_val_cb; - htp->psets.on_headers_complete = _htp_headers_complete_cb; - htp->psets.on_body = _htp_body_cb; - htp->psets.on_message_complete = _htp_end_cb; + htp->psets.on_message_begin = htp_start_cb; + htp->psets.on_path = htp_path_cb; + htp->psets.on_query_string = htp_query_str_cb; + htp->psets.on_url = htp_uri_cb; + htp->psets.on_fragment = htp_fragment_cb; + htp->psets.on_header_field = htp_header_key_cb; + htp->psets.on_header_value = htp_header_val_cb; + htp->psets.on_headers_complete = htp_headers_complete_cb; + htp->psets.on_body = htp_body_cb; + htp->psets.on_message_complete = htp_end_cb; - htp->evbase = evbase; + htp->evbase = evbase ? : event_base_new(); evhtp_log_debug("created new instance");
diff --git a/evhtp.h b/evhtp.h index 05ac75b..9e625ab 100644 --- a/evhtp.h +++ b/evhtp.h
@@ -17,7 +17,7 @@ #include <openssl/rand.h> #endif -#define EVHTP_VERSION "0.3.4" +#define EVHTP_VERSION "0.3.5" struct evhtp; struct evhtp_hdrs; @@ -26,7 +26,6 @@ struct evhtp_conn; struct evhtp_request; -typedef unsigned evhtp_status; typedef unsigned char evhtp_cflags; typedef struct evbuffer evbuf_t; typedef struct event event_t; @@ -48,7 +47,7 @@ typedef struct evhtp_hdr evhtp_hdr_t; typedef struct evhtp_hdrs evhtp_hdrs_t; -typedef enum evhtp_res evhtp_res; +typedef uint16_t evhtp_res; typedef enum evhtp_hook_type evhtp_hook_type; typedef enum http_method evhtp_method; typedef enum evhtp_proto evhtp_proto; @@ -63,16 +62,9 @@ typedef evhtp_res (*evhtp_hook_path)(evhtp_request_t *, const char *, void *); typedef evhtp_res (*evhtp_hook_uri)(evhtp_request_t *, const char *, void *); typedef evhtp_res (*evhtp_hook_read)(evhtp_request_t *, const char *, size_t, void *); -typedef evhtp_status (*evhtp_hook_on_expect)(evhtp_request_t *, const char *, void *); +typedef evhtp_res (*evhtp_hook_on_expect)(evhtp_request_t *, const char *, void *); typedef evhtp_res (*evhtp_stream_cb)(evhtp_request_t *, void *); -enum evhtp_res { - EVHTP_RES_OK = 0, - EVHTP_RES_ERROR, - EVHTP_RES_MORE, - EVHTP_RES_DONE -}; - #define EVHTP_CLOSE_ON_EXPECT_ERR (1 << 1) #define EVHTP_CLOSE_ON_100 (1 << 2) #define EVHTP_CLOSE_ON_200 (1 << 3) @@ -80,63 +72,64 @@ #define EVHTP_CLOSE_ON_400 (1 << 5) #define EVHTP_CLOSE_ON_500 (1 << 6) -#define EVHTP_CODE_SCREWEDUP 1 +#define EVHTP_RES_SCREWEDUP 1 +#define EVHTP_RES_DONE 2 -#define EVHTP_CODE_100 100 -#define EVHTP_CODE_CONTINUE 100 -#define EVHTP_CODE_SWITCH_PROTO 101 -#define EVHTP_CODE_PROCESSING 102 -#define EVHTP_CODE_URI_TOOLONG 122 +#define EVHTP_RES_100 100 +#define EVHTP_RES_CONTINUE 100 +#define EVHTP_RES_SWITCH_PROTO 101 +#define EVHTP_RES_PROCESSING 102 +#define EVHTP_RES_URI_TOOLONG 122 -#define EVHTP_CODE_200 200 -#define EVHTP_CODE_OK 200 -#define EVHTP_CODE_CREATED 201 -#define EVHTP_CODE_ACCEPTED 202 -#define EVHTP_CODE_NAUTHINFO 203 -#define EVHTP_CODE_NOCONTENT 204 -#define EVHTP_CODE_RSTCONTENT 205 -#define EVHTP_CODE_PARTIAL 206 -#define EVHTP_CODE_MSTATUS 207 -#define EVHTP_CODE_IMUSED 226 +#define EVHTP_RES_200 200 +#define EVHTP_RES_OK 200 +#define EVHTP_RES_CREATED 201 +#define EVHTP_RES_ACCEPTED 202 +#define EVHTP_RES_NAUTHINFO 203 +#define EVHTP_RES_NOCONTENT 204 +#define EVHTP_RES_RSTCONTENT 205 +#define EVHTP_RES_PARTIAL 206 +#define EVHTP_RES_MSTATUS 207 +#define EVHTP_RES_IMUSED 226 -#define EVHTP_CODE_300 300 -#define EVHTP_CODE_MCHOICE 300 -#define EVHTP_CODE_MOVEDPERM 301 -#define EVHTP_CODE_FOUND 302 -#define EVHTP_CODE_SEEOTHER 303 -#define EVHTP_CODE_NOTMOD 304 -#define EVHTP_CODE_USEPROXY 305 -#define EVHTP_CODE_SWITCHPROXY 306 -#define EVHTP_CODE_TMPREDIR 307 +#define EVHTP_RES_300 300 +#define EVHTP_RES_MCHOICE 300 +#define EVHTP_RES_MOVEDPERM 301 +#define EVHTP_RES_FOUND 302 +#define EVHTP_RES_SEEOTHER 303 +#define EVHTP_RES_NOTMOD 304 +#define EVHTP_RES_USEPROXY 305 +#define EVHTP_RES_SWITCHPROXY 306 +#define EVHTP_RES_TMPREDIR 307 -#define EVHTP_CODE_400 400 -#define EVHTP_CODE_BADREQ 400 -#define EVHTP_CODE_UNAUTH 401 -#define EVHTP_CODE_PAYREQ 402 -#define EVHTP_CODE_FORBIDDEN 403 -#define EVHTP_CODE_NOTFOUND 404 -#define EVHTP_CODE_METHNALLOWED 405 -#define EVHTP_CODE_NACCEPTABLE 406 -#define EVHTP_CODE_PROXYAUTHREQ 407 -#define EVHTP_CODE_TIMEOUT 408 -#define EVHTP_CODE_CONFLICT 409 -#define EVHTP_CODE_GONE 410 -#define EVHTP_CODE_LENREQ 411 -#define EVHTP_CODE_PRECONDFAIL 412 -#define EVHTP_CODE_ENTOOLARGE 413 -#define EVHTP_CODE_URITOOLARGE 414 -#define EVHTP_CODE_UNSUPPORTED 415 -#define EVHTP_CODE_RANGENOTSC 416 -#define EVHTP_CODE_EXPECTFAIL 417 +#define EVHTP_RES_400 400 +#define EVHTP_RES_BADREQ 400 +#define EVHTP_RES_UNAUTH 401 +#define EVHTP_RES_PAYREQ 402 +#define EVHTP_RES_FORBIDDEN 403 +#define EVHTP_RES_NOTFOUND 404 +#define EVHTP_RES_METHNALLOWED 405 +#define EVHTP_RES_NACCEPTABLE 406 +#define EVHTP_RES_PROXYAUTHREQ 407 +#define EVHTP_RES_TIMEOUT 408 +#define EVHTP_RES_CONFLICT 409 +#define EVHTP_RES_GONE 410 +#define EVHTP_RES_LENREQ 411 +#define EVHTP_RES_PRECONDFAIL 412 +#define EVHTP_RES_ENTOOLARGE 413 +#define EVHTP_RES_URITOOLARGE 414 +#define EVHTP_RES_UNSUPPORTED 415 +#define EVHTP_RES_RANGENOTSC 416 +#define EVHTP_RES_EXPECTFAIL 417 -#define EVHTP_CODE_500 500 -#define EVHTP_CODE_SERVERR 500 -#define EVHTP_CODE_NOTIMPL 501 -#define EVHTP_CODE_BADGATEWAY 502 -#define EVHTP_CODE_SERVUNAVAIL 503 -#define EVHTP_CODE_GWTIMEOUT 504 -#define EVHTP_CODE_VERNSUPPORT 505 -#define EVHTP_CODE_BWEXEED 509 +#define EVHTP_RES_500 500 +#define EVHTP_RES_SERVERR 500 +#define EVHTP_RES_NOTIMPL 501 +#define EVHTP_RES_BADGATEWAY 502 +#define EVHTP_RES_SERVUNAVAIL 503 +#define EVHTP_RES_GWTIMEOUT 504 +#define EVHTP_RES_VERNSUPPORT 505 +#define EVHTP_RES_BWEXEED 509 #ifndef DISABLE_SSL typedef SSL_SESSION evhtp_ssl_sess_t; @@ -158,6 +151,9 @@ EVHTP_HOOK_COMPLETE }; +#define EVHTP_HOOK_PRE_BODY EVHTP_HOOK_HDRS_READ +#define EVHTP_HOOK_READ_BODY EVHTP_HOOK_READ + enum evhtp_proto { EVHTP_PROTO_INVALID, EVHTP_PROTO_1_0, @@ -211,7 +207,20 @@ evbuf_t * evhtp_request_get_output(evhtp_request_t *); evbase_t * evhtp_request_get_evbase(evhtp_request_t *); evserv_t * evhtp_request_get_listener(evhtp_request_t *); +evhtp_method evhtp_request_get_method(evhtp_request_t *); +evhtp_proto evhtp_request_get_proto(evhtp_request_t *); +evhtp_conn_t * evhtp_request_get_conn(evhtp_request_t *); +evhtp_hdrs_t * evhtp_request_get_headers_in(evhtp_request_t *); +evhtp_hdrs_t * evhtp_request_get_headers_out(evhtp_request_t *); +evhtp_callback_cb evhtp_request_get_cb(evhtp_request_t *); +void * evhtp_request_get_cbarg(evhtp_request_t *); int evhtp_request_get_sock(evhtp_request_t *); +const char * evhtp_request_get_path(evhtp_request_t *); +const char * evhtp_request_get_uri(evhtp_request_t *); +const char * evhtp_request_method_str(evhtp_request_t *); +int evhtp_request_get_matched_soff(evhtp_request_t *); +int evhtp_request_get_matched_eoff(evhtp_request_t *); +int64_t evhtp_request_get_content_length(evhtp_request_t *); evbase_t * evhtp_get_evbase(evhtp_t *); evserv_t * evhtp_get_listener(evhtp_t *); @@ -220,8 +229,8 @@ int evhtp_set_hook(evhtp_conn_t *, evhtp_hook_type, void * cb, void * arg); void evhtp_set_pre_accept_cb(evhtp_t *, evhtp_pre_accept, void *); void evhtp_set_post_accept_cb(evhtp_t *, evhtp_post_accept, void *); -void evhtp_send_reply(evhtp_request_t *, evhtp_status, const char *, evbuf_t *); -void evhtp_send_reply_stream(evhtp_request_t *, evhtp_status, evhtp_stream_cb, void *); +void evhtp_send_reply(evhtp_request_t *, evhtp_res, const char *, evbuf_t *); +void evhtp_send_reply_stream(evhtp_request_t *, evhtp_res, evhtp_stream_cb, void *); void evhtp_send_stream(evhtp_request_t *, evbuf_t *); void evhtp_request_make_chunk(evhtp_request_t *, evbuf_t *); @@ -238,20 +247,14 @@ void evhtp_hdr_free(evhtp_hdr_t *); const char * evhtp_version(void); +const char * evhtp_method_str(evhtp_method); int evhtp_use_threads(evhtp_t *, int); - 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); -#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__ */
diff --git a/perftest.sh b/perftest.sh index 2afa28d..ab0be0b 100755 --- a/perftest.sh +++ b/perftest.sh
@@ -14,5 +14,5 @@ echo "Running ($conns connections | $calls requests each)" -#httperf --ssl --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 httperf --server=$host --port=$port --uri=$uri --rate=1e+06 --send-buffer=4096 --recv-buffer=16384 --wsess=$conns,$calls,0
diff --git a/test.c b/test.c index 04da5cd..44e8247 100644 --- a/test.c +++ b/test.c
@@ -52,27 +52,27 @@ carg->idx = 0; carg->buf = evbuffer_new(); - evhtp_send_reply_stream(req, EVHTP_CODE_OK, _send_chunk, carg); + evhtp_send_reply_stream(req, EVHTP_RES_OK, _send_chunk, carg); } static void test_regex(evhtp_request_t * req, void * arg) { - evhtp_send_reply(req, EVHTP_CODE_OK, "REGEXOK", NULL); + evhtp_send_reply(req, EVHTP_RES_OK, "REGEXOK", NULL); } static void test_foo_cb(evhtp_request_t * req, void * arg) { - evhtp_send_reply(req, EVHTP_CODE_OK, "OK", NULL); + evhtp_send_reply(req, EVHTP_RES_OK, "OK", NULL); } static void test_500_cb(evhtp_request_t * req, void * arg) { - evhtp_send_reply(req, EVHTP_CODE_SERVERR, "no", NULL); + evhtp_send_reply(req, EVHTP_RES_SERVERR, "no", NULL); } static void test_bar_cb(evhtp_request_t * req, void * arg) { - evhtp_send_reply(req, EVHTP_CODE_OK, "OK", NULL); + evhtp_send_reply(req, EVHTP_RES_OK, "OK", NULL); } static void @@ -80,7 +80,7 @@ struct evbuffer * b = evbuffer_new(); evbuffer_add_reference(b, "derp", 4, NULL, NULL); - evhtp_send_reply(req, EVHTP_CODE_OK, "Everything is fine", b); + evhtp_send_reply(req, EVHTP_RES_OK, "Everything is fine", b); evbuffer_free(b); } @@ -120,14 +120,14 @@ return EVHTP_RES_OK; } -static evhtp_status +static evhtp_res inspect_expect(evhtp_request_t * req, const char * expct_str, void * arg) { if (strcmp(expct_str, "100-continue")) { printf("Inspecting expect failed!\n"); - return EVHTP_CODE_EXPECTFAIL; + return EVHTP_RES_EXPECTFAIL; } - return EVHTP_CODE_CONTINUE; + return EVHTP_RES_CONTINUE; } static evhtp_res