From 950af186791c01636fe37ef8c3720154e48f975c Mon Sep 17 00:00:00 2001 From: Niels Provos Date: Sat, 10 May 2008 05:58:17 +0000 Subject: [PATCH] replace fnmatch with homegrown function svn:r804 --- configure.in | 4 ++-- http.c | 39 +++++++++++++++++++++++++++++++++------ test/regress_http.c | 31 ++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 9 deletions(-) diff --git a/configure.in b/configure.in index 311b89d4..bd274a6a 100644 --- a/configure.in +++ b/configure.in @@ -53,7 +53,7 @@ AM_CONDITIONAL(ZLIB_REGRESS, [test "$have_zlib" != "no"]) dnl Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h stdarg.h inttypes.h stdint.h stddef.h poll.h signal.h unistd.h sys/epoll.h sys/time.h sys/queue.h sys/event.h sys/param.h sys/ioctl.h sys/select.h sys/devpoll.h port.h netinet/in6.h sys/socket.h sys/uio.h fnmatch.h) +AC_CHECK_HEADERS(fcntl.h stdarg.h inttypes.h stdint.h stddef.h poll.h signal.h unistd.h sys/epoll.h sys/time.h sys/queue.h sys/event.h sys/param.h sys/ioctl.h sys/select.h sys/devpoll.h port.h netinet/in6.h sys/socket.h sys/uio.h) if test "x$ac_cv_header_sys_queue_h" = "xyes"; then AC_MSG_CHECKING(for TAILQ_FOREACH in sys/queue.h) AC_EGREP_CPP(yes, @@ -146,7 +146,7 @@ AC_C_INLINE AC_HEADER_TIME dnl Checks for library functions. -AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r strsep getaddrinfo getnameinfo strlcpy inet_ntop signal sigaction strtoll fnmatch) +AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r strsep getaddrinfo getnameinfo strlcpy inet_ntop signal sigaction strtoll) AC_CHECK_SIZEOF(long) diff --git a/http.c b/http.c index a8d60fa7..49e51b3f 100644 --- a/http.c +++ b/http.c @@ -79,10 +79,6 @@ #ifdef HAVE_FCNTL_H #include #endif -#ifdef HAVE_FNMATCH_H -#define _GNU_SOURCE -#include -#endif #undef timeout_pending #undef timeout_initialized @@ -1908,6 +1904,37 @@ evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req) return (NULL); } + +static int +prefix_suffix_match(const char *pattern, const char *name, int ignorecase) +{ + char c; + + while (1) { + switch (c = *pattern++) { + case '\0': + return *name == '\0'; + + case '*': + while (*name != '\0') { + if (prefix_suffix_match(pattern, name, + ignorecase)) + return (1); + ++name; + } + return (0); + default: + if (c != *name) { + if (!ignorecase || + tolower(c) != tolower(*name)) + return (0); + } + ++name; + } + } + /* NOTREACHED */ +} + static void evhttp_handle_request(struct evhttp_request *req, void *arg) { @@ -1925,8 +1952,8 @@ evhttp_handle_request(struct evhttp_request *req, void *arg) if (hostname != NULL) { struct evhttp *vhost; TAILQ_FOREACH(vhost, &http->virtualhosts, next) { - if (fnmatch(vhost->vhost_pattern, hostname, - FNM_CASEFOLD) == 0) { + if (prefix_suffix_match(vhost->vhost_pattern, hostname, + 1 /* ignorecase */)) { evhttp_handle_request(req, vhost); return; } diff --git a/test/regress_http.c b/test/regress_http.c index 75b982d6..019bb852 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -533,7 +533,7 @@ http_virtual_host_test(void) short port = -1; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; - struct evhttp *second = NULL; + struct evhttp *second = NULL, *third = NULL; test_ok = 0; fprintf(stdout, "Testing Virtual Hosts: "); @@ -543,12 +543,19 @@ http_virtual_host_test(void) /* virtual host */ second = evhttp_new(NULL); evhttp_set_cb(second, "/funnybunny", http_basic_cb, NULL); + third = evhttp_new(NULL); + evhttp_set_cb(third, "/blackcoffee", http_basic_cb, NULL); if (evhttp_add_virtual_host(http, "foo.com", second) == -1) { fprintf(stdout, "FAILED\n"); exit(1); } + if (evhttp_add_virtual_host(http, "bar.*.foo.com", third) == -1) { + fprintf(stdout, "FAILED\n"); + exit(1); + } + evcon = evhttp_connection_new("127.0.0.1", port); if (evcon == NULL) { fprintf(stdout, "FAILED\n"); @@ -597,6 +604,28 @@ http_virtual_host_test(void) exit(1); } + test_ok = 0; + + /* make a request with the right host and expect a response */ + req = evhttp_request_new(http_request_done, NULL); + + /* Add the information that we care about */ + evhttp_add_header(req->output_headers, "Host", "bar.magic.foo.com"); + + /* We give ownership of the request to the connection */ + if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, + "/blackcoffee") == -1) { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + event_dispatch(); + + if (test_ok != 1) { + fprintf(stdout, "FAILED\n"); + exit(1); + } + evhttp_connection_free(evcon); evhttp_free(http);