diff options
Diffstat (limited to 'third_party/libevent/test/regress_http.c')
-rw-r--r-- | third_party/libevent/test/regress_http.c | 122 |
1 files changed, 112 insertions, 10 deletions
diff --git a/third_party/libevent/test/regress_http.c b/third_party/libevent/test/regress_http.c index 7dc763c..1e2a1eb 100644 --- a/third_party/libevent/test/regress_http.c +++ b/third_party/libevent/test/regress_http.c @@ -42,7 +42,7 @@ #include <sys/queue.h> #ifndef WIN32 #include <sys/socket.h> -#include <sys/signal.h> +#include <signal.h> #include <unistd.h> #include <netdb.h> #endif @@ -70,6 +70,7 @@ void http_basic_cb(struct evhttp_request *req, void *arg); static void http_chunked_cb(struct evhttp_request *req, void *arg); void http_post_cb(struct evhttp_request *req, void *arg); void http_dispatcher_cb(struct evhttp_request *req, void *arg); +static void http_large_delay_cb(struct evhttp_request *req, void *arg); static struct evhttp * http_setup(short *pport, struct event_base *base) @@ -94,6 +95,7 @@ http_setup(short *pport, struct event_base *base) evhttp_set_cb(myhttp, "/test", http_basic_cb, NULL); evhttp_set_cb(myhttp, "/chunked", http_chunked_cb, NULL); evhttp_set_cb(myhttp, "/postit", http_post_cb, NULL); + evhttp_set_cb(myhttp, "/largedelay", http_large_delay_cb, NULL); evhttp_set_cb(myhttp, "/", http_dispatcher_cb, NULL); *pport = port; @@ -375,6 +377,31 @@ http_basic_test(void) fprintf(stdout, "OK\n"); } +static struct evhttp_connection *delayed_client; + +static void +http_delay_reply(int fd, short what, void *arg) +{ + struct evhttp_request *req = arg; + + evhttp_send_reply(req, HTTP_OK, "Everything is fine", NULL); + + ++test_ok; +} + +static void +http_large_delay_cb(struct evhttp_request *req, void *arg) +{ + struct timeval tv; + timerclear(&tv); + tv.tv_sec = 3; + + event_once(-1, EV_TIMEOUT, http_delay_reply, req, &tv); + + /* here we close the client connection which will cause an EOF */ + evhttp_connection_fail(delayed_client, EVCON_HTTP_EOF); +} + void http_request_done(struct evhttp_request *, void *); void http_request_empty_done(struct evhttp_request *, void *); @@ -819,6 +846,7 @@ http_failure_test(void) static void close_detect_done(struct evhttp_request *req, void *arg) { + struct timeval tv; if (req == NULL || req->response_code != HTTP_OK) { fprintf(stderr, "FAILED\n"); @@ -826,7 +854,11 @@ close_detect_done(struct evhttp_request *req, void *arg) } test_ok = 1; - event_loopexit(NULL); + + timerclear(&tv); + tv.tv_sec = 3; /* longer than the http time out */ + + event_loopexit(&tv); } static void @@ -853,7 +885,7 @@ close_detect_cb(struct evhttp_request *req, void *arg) struct evhttp_connection *evcon = arg; struct timeval tv; - if (req->response_code != HTTP_OK) { + if (req != NULL && req->response_code != HTTP_OK) { fprintf(stderr, "FAILED\n"); exit(1); @@ -868,14 +900,15 @@ close_detect_cb(struct evhttp_request *req, void *arg) static void -http_close_detection(void) +http_close_detection(int with_delay) { short port = -1; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; test_ok = 0; - fprintf(stdout, "Testing Connection Close Detection: "); + fprintf(stdout, "Testing Connection Close Detection%s: ", + with_delay ? " (with delay)" : ""); http = http_setup(&port, NULL); @@ -888,6 +921,8 @@ http_close_detection(void) exit(1); } + delayed_client = evcon; + /* * At this point, we want to schedule a request to the HTTP * server using our make request method. @@ -899,7 +934,8 @@ http_close_detection(void) evhttp_add_header(req->output_headers, "Host", "somehost"); /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { + if (evhttp_make_request(evcon, + req, EVHTTP_REQ_GET, with_delay ? "/largedelay" : "/test") == -1) { fprintf(stdout, "FAILED\n"); exit(1); } @@ -911,6 +947,12 @@ http_close_detection(void) exit(1); } + /* at this point, the http server should have no connection */ + if (TAILQ_FIRST(&http->connections) != NULL) { + fprintf(stdout, "FAILED (left connections)\n"); + exit(1); + } + evhttp_connection_free(evcon); evhttp_free(http); @@ -953,13 +995,16 @@ http_bad_header_test(void) if (evhttp_add_header(&headers, "One\r", "Two") != -1) goto fail; - + if (evhttp_add_header(&headers, "One", "Two") != 0) + goto fail; + if (evhttp_add_header(&headers, "One", "Two\r\n Three") != 0) + goto fail; + if (evhttp_add_header(&headers, "One\r", "Two") != -1) + goto fail; if (evhttp_add_header(&headers, "One\n", "Two") != -1) goto fail; - if (evhttp_add_header(&headers, "One", "Two\r") != -1) goto fail; - if (evhttp_add_header(&headers, "One", "Two\n") != -1) goto fail; @@ -972,6 +1017,61 @@ fail: exit(1); } +static int validate_header( + const struct evkeyvalq* headers, + const char *key, const char *value) +{ + const char *real_val = evhttp_find_header(headers, key); + if (real_val == NULL) + return (-1); + if (strcmp(real_val, value) != 0) + return (-1); + return (0); +} + +static void +http_parse_query_test(void) +{ + struct evkeyvalq headers; + + fprintf(stdout, "Testing HTTP query parsing: "); + + TAILQ_INIT(&headers); + + evhttp_parse_query("http://www.test.com/?q=test", &headers); + if (validate_header(&headers, "q", "test") != 0) + goto fail; + evhttp_clear_headers(&headers); + + evhttp_parse_query("http://www.test.com/?q=test&foo=bar", &headers); + if (validate_header(&headers, "q", "test") != 0) + goto fail; + if (validate_header(&headers, "foo", "bar") != 0) + goto fail; + evhttp_clear_headers(&headers); + + evhttp_parse_query("http://www.test.com/?q=test+foo", &headers); + if (validate_header(&headers, "q", "test foo") != 0) + goto fail; + evhttp_clear_headers(&headers); + + evhttp_parse_query("http://www.test.com/?q=test%0Afoo", &headers); + if (validate_header(&headers, "q", "test\nfoo") != 0) + goto fail; + evhttp_clear_headers(&headers); + + evhttp_parse_query("http://www.test.com/?q=test%0Dfoo", &headers); + if (validate_header(&headers, "q", "test\rfoo") != 0) + goto fail; + evhttp_clear_headers(&headers); + + fprintf(stdout, "OK\n"); + return; +fail: + fprintf(stdout, "FAILED\n"); + exit(1); +} + static void http_base_test(void) { @@ -1358,10 +1458,12 @@ http_suite(void) { http_base_test(); http_bad_header_test(); + http_parse_query_test(); http_basic_test(); http_connection_test(0 /* not-persistent */); http_connection_test(1 /* persistent */); - http_close_detection(); + http_close_detection(0 /* with delay */); + http_close_detection(1 /* with delay */); http_post_test(); http_failure_test(); http_highport_test(); |