replace fnmatch with homegrown function

svn:r804
This commit is contained in:
Niels Provos 2008-05-10 05:58:17 +00:00
parent 7868ab5a43
commit 950af18679
3 changed files with 65 additions and 9 deletions

View File

@ -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)

39
http.c
View File

@ -79,10 +79,6 @@
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_FNMATCH_H
#define _GNU_SOURCE
#include <fnmatch.h>
#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;
}

View File

@ -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);