Here's a follow-up with a regression test (attached.)
Elliot
Elliot Foster wrote:
Another quick fix for the dispatch callback, for when it goes through
available callbacks looking for a match. The problem is that if the
request URI has an argument, the comparison is done on the bytes before
the url parameter separator. The result is that the lookup will result
in mismatches, especially for a request URI like '/?some_arg=some_val'
that will match the first callback found.
Two potential fixes are attached, one that modifies the string to
replace the argument separator with a null char before the strcmp, and
another that checks for a null char in the potential match (at the same
offset as the argument separator.)
Thanks,
Elliot
------------------------------------------------------------------------
_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkey.org/mailman/listinfo/libevent-users
diff -Naur libevent-1.3c-orig/test/regress_http.c libevent-1.3c/test/regress_http.c
--- libevent-1.3c-orig/test/regress_http.c 2007-08-02 08:23:07.000000000 -0700
+++ libevent-1.3c/test/regress_http.c 2007-08-02 12:01:22.000000000 -0700
@@ -64,6 +64,7 @@
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);
struct evhttp *
http_setup(short *pport)
@@ -87,6 +88,7 @@
/* 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);
@@ -321,6 +323,103 @@
}
/*
+ * 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_post_test();
http_failure_test();
http_highport_test();
+ http_dispatcher_test();
}
_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkey.org/mailman/listinfo/libevent-users