From: Niels Provos Date: Sun, 5 Aug 2007 02:15:10 +0000 (+0000) Subject: request dispatching fix from Elliot Foster X-Git-Tag: release-2.0.1-alpha~602 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8ea5ffefc32e5950beeec8db0cd862e6bd9eab76;p=libevent request dispatching fix from Elliot Foster svn:r382 --- diff --git a/http.c b/http.c index 635350f7..699fd98b 100644 --- a/http.c +++ b/http.c @@ -1808,16 +1808,22 @@ static struct evhttp_cb * evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req) { struct evhttp_cb *cb; + size_t offset = 0; /* Test for different URLs */ char *p = strchr(req->uri, '?'); + if (p != NULL) + offset = (size_t)(p - req->uri); + TAILQ_FOREACH(cb, callbacks, next) { - int res; - if (p == NULL) + int res = 0; + if (p == NULL) { res = strcmp(cb->what, req->uri) == 0; - else - res = strncmp(cb->what, req->uri, - (size_t)(p - req->uri)) == 0; + } else { + res = ((strncmp(cb->what, req->uri, offset) == 0) && + (cb->what[offset] == '\0')); + } + if (res) return (cb); } diff --git a/test/regress_http.c b/test/regress_http.c index 09a24538..5c6714c6 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -64,6 +64,7 @@ static struct evhttp *http; void http_basic_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 struct evhttp * http_setup(short *pport) @@ -87,6 +88,7 @@ http_setup(short *pport) /* Register a callback for certain types of requests */ evhttp_set_cb(myhttp, "/test", http_basic_cb, NULL); evhttp_set_cb(myhttp, "/postit", http_post_cb, NULL); + evhttp_set_cb(myhttp, "/", http_dispatcher_cb, NULL); *pport = port; return (myhttp); @@ -320,6 +322,103 @@ http_request_done(struct evhttp_request *req, void *arg) event_loopexit(NULL); } +/* + * HTTP DISPATCHER test + */ + +void +http_dispatcher_cb(struct evhttp_request *req, void *arg) +{ + + struct evbuffer *evb = evbuffer_new(); + event_debug(("%s: called\n", __func__)); + evbuffer_add_printf(evb, "DISPATCHER_TEST"); + + evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb); + + evbuffer_free(evb); +} + +void +http_dispatcher_test_done(struct evhttp_request *req, void *arg) +{ + const char *what = "DISPATCHER_TEST"; + + if (req->response_code != HTTP_OK) { + fprintf(stderr, "FAILED\n"); + exit(1); + } + + if (evhttp_find_header(req->input_headers, "Content-Type") == NULL) { + fprintf(stderr, "FAILED (content type)\n"); + exit(1); + } + + if (EVBUFFER_LENGTH(req->input_buffer) != strlen(what)) { + fprintf(stderr, "FAILED (length %zu vs %zu)\n", + EVBUFFER_LENGTH(req->input_buffer), strlen(what)); + exit(1); + } + + if (memcmp(EVBUFFER_DATA(req->input_buffer), what, strlen(what)) != 0) { + fprintf(stderr, "FAILED (data)\n"); + exit(1); + } + + test_ok = 1; + event_loopexit(NULL); +} + +void +http_dispatcher_test(void) +{ + short port = -1; + struct evhttp_connection *evcon = NULL; + struct evhttp_request *req = NULL; + + test_ok = 0; + fprintf(stdout, "Testing HTTP Dispatcher: "); + + http = http_setup(&port); + + evcon = evhttp_connection_new("127.0.0.1", port); + if (evcon == NULL) { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + /* + * At this point, we want to schedule an HTTP GET request + * server using our make request method. + */ + + req = evhttp_request_new(http_dispatcher_test_done, NULL); + if (req == NULL) { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + /* Add the information that we care about */ + evhttp_add_header(req->output_headers, "Host", "somehost"); + + if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + event_dispatch(); + + evhttp_connection_free(evcon); + evhttp_free(http); + + if (test_ok != 1) { + fprintf(stdout, "FAILED: %d\n", test_ok); + exit(1); + } + + fprintf(stdout, "OK\n"); +} + /* * HTTP POST test. */ @@ -629,4 +728,5 @@ http_suite(void) http_post_test(); http_failure_test(); http_highport_test(); + http_dispatcher_test(); }