From f817bfa4d37448f21d6f753769f6ad91d113dd7c Mon Sep 17 00:00:00 2001 From: Dimitre Piskyulev Date: Wed, 27 Oct 2010 17:31:52 -0400 Subject: [PATCH 01/31] Fix some ints to evutil_socket_t; make tests pass on win64. --- event-internal.h | 2 +- test/regress_util.c | 6 +++--- test/test-eof.c | 2 +- test/test-weof.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/event-internal.h b/event-internal.h index 669ae2b0..50e1e4d2 100644 --- a/event-internal.h +++ b/event-internal.h @@ -267,7 +267,7 @@ struct event_base { int is_notify_pending; /** A socketpair used by some th_notify functions to wake up the main * thread. */ - int th_notify_fd[2]; + evutil_socket_t th_notify_fd[2]; /** An event used by some th_notify functions to wake up the main * thread. */ struct event th_notify; diff --git a/test/regress_util.c b/test/regress_util.c index 4eea2e9c..fc263bcf 100644 --- a/test/regress_util.c +++ b/test/regress_util.c @@ -602,7 +602,7 @@ end: } struct example_struct { - long a; + const char *a; const char *b; long c; }; @@ -612,11 +612,11 @@ test_evutil_upcast(void *arg) { struct example_struct es1; const char **cp; - es1.a = 5; + es1.a = "World"; es1.b = "Hello"; es1.c = -99; - tt_int_op(evutil_offsetof(struct example_struct, b), ==, sizeof(long)); + tt_int_op(evutil_offsetof(struct example_struct, b), ==, sizeof(char*)); cp = &es1.b; tt_ptr_op(EVUTIL_UPCAST(cp, struct example_struct, b), ==, &es1); diff --git a/test/test-eof.c b/test/test-eof.c index fd226193..3d4be93d 100644 --- a/test/test-eof.c +++ b/test/test-eof.c @@ -62,7 +62,7 @@ main(int argc, char **argv) { struct event ev; const char *test = "test string"; - int pair[2]; + evutil_socket_t pair[2]; #ifdef WIN32 WORD wVersionRequested; diff --git a/test/test-weof.c b/test/test-weof.c index 8d1b0ab8..2423d217 100644 --- a/test/test-weof.c +++ b/test/test-weof.c @@ -33,7 +33,7 @@ #define __func__ _EVENT___func__ #endif -int pair[2]; +evutil_socket_t pair[2]; int test_okay = 1; int called = 0; From 1ae82cd8c6aba98d21342d242facd1bb5e461555 Mon Sep 17 00:00:00 2001 From: Dimitre Piskyulev Date: Wed, 27 Oct 2010 17:32:41 -0400 Subject: [PATCH 02/31] Set _EVENT_SIZEOF_VOID_P correctly on win32 and win64 --- WIN32-Code/event2/event-config.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/WIN32-Code/event2/event-config.h b/WIN32-Code/event2/event-config.h index e2b25c60..ca3f60f0 100644 --- a/WIN32-Code/event2/event-config.h +++ b/WIN32-Code/event2/event-config.h @@ -317,6 +317,13 @@ #define _EVENT_SIZEOF_SIZE_T 4 #endif +/* The size of `void *', as computed by sizeof. */ +#ifdef _WIN64 +#define _EVENT_SIZEOF_VOID_P 8 +#else +#define _EVENT_SIZEOF_VOID_P 4 +#endif + /* Define to 1 if you have the ANSI C header files. */ #define _EVENT_STDC_HEADERS 1 From b81217f78dc511782451e793b0505624d8159499 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 27 Oct 2010 17:37:32 -0400 Subject: [PATCH 03/31] Fix signal handler types for win64. --- event.c | 6 +++--- signal.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/event.c b/event.c index 7e71ec2b..37217729 100644 --- a/event.c +++ b/event.c @@ -824,7 +824,7 @@ event_reinit(struct event_base *base) if (evmap_io_add(base, ev->ev_fd, ev) == -1) res = -1; } else if (ev->ev_events & EV_SIGNAL) { - if (evmap_signal_add(base, ev->ev_fd, ev) == -1) + if (evmap_signal_add(base, (int)ev->ev_fd, ev) == -1) res = -1; } } @@ -1995,7 +1995,7 @@ event_add_internal(struct event *ev, const struct timeval *tv, if (ev->ev_events & (EV_READ|EV_WRITE)) res = evmap_io_add(base, ev->ev_fd, ev); else if (ev->ev_events & EV_SIGNAL) - res = evmap_signal_add(base, ev->ev_fd, ev); + res = evmap_signal_add(base, (int)ev->ev_fd, ev); if (res != -1) event_queue_insert(base, ev, EVLIST_INSERTED); if (res == 1) { @@ -2173,7 +2173,7 @@ event_del_internal(struct event *ev) if (ev->ev_events & (EV_READ|EV_WRITE)) res = evmap_io_del(base, ev->ev_fd, ev); else - res = evmap_signal_del(base, ev->ev_fd, ev); + res = evmap_signal_del(base, (int)ev->ev_fd, ev); if (res == 1) { /* evmap says we need to notify the main thread. */ notify = 1; diff --git a/signal.c b/signal.c index 4a5763ab..ec27ea88 100644 --- a/signal.c +++ b/signal.c @@ -87,8 +87,8 @@ #define __cdecl #endif -static int evsig_add(struct event_base *, int, short, short, void *); -static int evsig_del(struct event_base *, int, short, short, void *); +static int evsig_add(struct event_base *, evutil_socket_t, short, short, void *); +static int evsig_del(struct event_base *, evutil_socket_t, short, short, void *); static const struct eventop evsigops = { "signal", @@ -278,7 +278,7 @@ _evsig_set_handler(struct event_base *base, } static int -evsig_add(struct event_base *base, int evsignal, short old, short events, void *p) +evsig_add(struct event_base *base, evutil_socket_t evsignal, short old, short events, void *p) { struct evsig_info *sig = &base->sig; (void)p; @@ -301,8 +301,8 @@ evsig_add(struct event_base *base, int evsignal, short old, short events, void * evsig_base_fd = base->sig.ev_signal_pair[0]; EVSIGBASE_UNLOCK(); - event_debug(("%s: %d: changing signal handler", __func__, evsignal)); - if (_evsig_set_handler(base, evsignal, evsig_handler) == -1) { + event_debug(("%s: %d: changing signal handler", __func__, (int)evsignal)); + if (_evsig_set_handler(base, (int)evsignal, evsig_handler) == -1) { goto err; } @@ -355,7 +355,7 @@ _evsig_restore_handler(struct event_base *base, int evsignal) } static int -evsig_del(struct event_base *base, int evsignal, short old, short events, void *p) +evsig_del(struct event_base *base, evutil_socket_t evsignal, short old, short events, void *p) { EVUTIL_ASSERT(evsignal >= 0 && evsignal < NSIG); @@ -366,7 +366,7 @@ evsig_del(struct event_base *base, int evsignal, short old, short events, void * --base->sig.ev_n_signals_added; EVSIGBASE_UNLOCK(); - return (_evsig_restore_handler(base, evsignal)); + return (_evsig_restore_handler(base, (int)evsignal)); } static void __cdecl From 598d13360918e557d1ce5e37078364f4ddd24e36 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 27 Oct 2010 22:57:53 -0400 Subject: [PATCH 04/31] Try to clear up more size_t vs int/long issues. --- bufferevent-internal.h | 8 ++++---- bufferevent_ratelim.c | 12 ++++++------ bufferevent_sock.c | 4 ++-- evutil_rand.c | 5 ++++- win32select.c | 2 +- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/bufferevent-internal.h b/bufferevent-internal.h index b7b598fa..c2b9643e 100644 --- a/bufferevent-internal.h +++ b/bufferevent-internal.h @@ -378,11 +378,11 @@ int _bufferevent_generic_adj_timeouts(struct bufferevent *bev); /* ==== For rate-limiting. */ int _bufferevent_decrement_write_buckets(struct bufferevent_private *bev, - int bytes); + ev_ssize_t bytes); int _bufferevent_decrement_read_buckets(struct bufferevent_private *bev, - int bytes); -int _bufferevent_get_read_max(struct bufferevent_private *bev); -int _bufferevent_get_write_max(struct bufferevent_private *bev); + ev_ssize_t bytes); +ev_ssize_t _bufferevent_get_read_max(struct bufferevent_private *bev); +ev_ssize_t _bufferevent_get_write_max(struct bufferevent_private *bev); #ifdef __cplusplus } diff --git a/bufferevent_ratelim.c b/bufferevent_ratelim.c index 1f3b4175..85904e82 100644 --- a/bufferevent_ratelim.c +++ b/bufferevent_ratelim.c @@ -192,11 +192,11 @@ static int _bev_group_suspend_writing(struct bufferevent_rate_limit_group *g); the maximum amount we should read if is_read. Return that maximum, or 0 if our bucket is wholly exhausted. */ -static inline int +static inline ev_ssize_t _bufferevent_get_rlim_max(struct bufferevent_private *bev, int is_write) { /* needs lock on bev. */ - int max_so_far = is_write?MAX_TO_WRITE_EVER:MAX_TO_READ_EVER; + ev_ssize_t max_so_far = is_write?MAX_TO_WRITE_EVER:MAX_TO_READ_EVER; #define LIM(x) \ (is_write ? (x).write_limit : (x).read_limit) @@ -255,20 +255,20 @@ _bufferevent_get_rlim_max(struct bufferevent_private *bev, int is_write) return max_so_far; } -int +ev_ssize_t _bufferevent_get_read_max(struct bufferevent_private *bev) { return _bufferevent_get_rlim_max(bev, 0); } -int +ev_ssize_t _bufferevent_get_write_max(struct bufferevent_private *bev) { return _bufferevent_get_rlim_max(bev, 1); } int -_bufferevent_decrement_read_buckets(struct bufferevent_private *bev, int bytes) +_bufferevent_decrement_read_buckets(struct bufferevent_private *bev, ev_ssize_t bytes) { /* XXXXX Make sure all users of this function check its return value */ int r = 0; @@ -300,7 +300,7 @@ _bufferevent_decrement_read_buckets(struct bufferevent_private *bev, int bytes) } int -_bufferevent_decrement_write_buckets(struct bufferevent_private *bev, int bytes) +_bufferevent_decrement_write_buckets(struct bufferevent_private *bev, ev_ssize_t bytes) { /* XXXXX Make sure all users of this function check its return value */ int r = 0; diff --git a/bufferevent_sock.c b/bufferevent_sock.c index 70902524..43768110 100644 --- a/bufferevent_sock.c +++ b/bufferevent_sock.c @@ -127,7 +127,7 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg) struct evbuffer *input; int res = 0; short what = BEV_EVENT_READING; - int howmuch = -1, readmax=-1; + ev_ssize_t howmuch = -1, readmax=-1; _bufferevent_incref_and_lock(bufev); @@ -449,7 +449,7 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai, } /* XXX use the other addrinfos? */ - r = bufferevent_socket_connect(bev, ai->ai_addr, ai->ai_addrlen); + r = bufferevent_socket_connect(bev, ai->ai_addr, (int)ai->ai_addrlen); _bufferevent_decref_and_unlock(bev); evutil_freeaddrinfo(ai); } diff --git a/evutil_rand.c b/evutil_rand.c index 4e3485c2..15e4850d 100644 --- a/evutil_rand.c +++ b/evutil_rand.c @@ -34,6 +34,8 @@ #include "event2/event-config.h" +#include + #include "util-internal.h" #include "evthread-internal.h" @@ -118,6 +120,7 @@ evutil_secure_rng_get_bytes(void *buf, size_t n) void evutil_secure_rng_add_bytes(const char *buf, size_t n) { - arc4random_addrandom((unsigned char*)buf, n); + arc4random_addrandom((unsigned char*)buf, + n>(size_t)INT_MAX ? INT_MAX : n); } diff --git a/win32select.c b/win32select.c index af8c6206..98734b41 100644 --- a/win32select.c +++ b/win32select.c @@ -97,7 +97,7 @@ struct eventop win32ops = { #define FD_SET_ALLOC_SIZE(n) ((sizeof(struct win_fd_set) + ((n)-1)*sizeof(SOCKET))) static int -realloc_fd_sets(struct win32op *op, size_t new_size) +realloc_fd_sets(struct win32op *op, int new_size) { size_t size; From b6a158ca22359831475e4cb10498063f72b07823 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 1 Nov 2010 11:48:57 -0400 Subject: [PATCH 05/31] Rename "size" variables in win32select that were really fd counts. --- win32select.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/win32select.c b/win32select.c index 98734b41..70e7e6e8 100644 --- a/win32select.c +++ b/win32select.c @@ -66,7 +66,7 @@ struct idx_info { }; struct win32op { - int fd_setsz; + unsigned num_fds_in_fd_sets; int resize_out_sets; struct win_fd_set *readset_in; struct win_fd_set *writeset_in; @@ -97,21 +97,21 @@ struct eventop win32ops = { #define FD_SET_ALLOC_SIZE(n) ((sizeof(struct win_fd_set) + ((n)-1)*sizeof(SOCKET))) static int -realloc_fd_sets(struct win32op *op, int new_size) +grow_fd_sets(struct win32op *op, unsigned new_num_fds) { size_t size; - EVUTIL_ASSERT(new_size >= op->readset_in->fd_count && - new_size >= op->writeset_in->fd_count); - EVUTIL_ASSERT(new_size >= 1); + EVUTIL_ASSERT(new_num_fds >= op->readset_in->fd_count && + new_num_fds >= op->writeset_in->fd_count); + EVUTIL_ASSERT(new_num_fds >= 1); - size = FD_SET_ALLOC_SIZE(new_size); + size = FD_SET_ALLOC_SIZE(new_num_fds); if (!(op->readset_in = mm_realloc(op->readset_in, size))) return (-1); if (!(op->writeset_in = mm_realloc(op->writeset_in, size))) return (-1); op->resize_out_sets = 1; - op->fd_setsz = new_size; + op->num_fds_in_fd_sets = new_num_fds; return (0); } @@ -126,8 +126,8 @@ do_fd_set(struct win32op *op, struct idx_info *ent, evutil_socket_t s, int read) if (ent->write_pos_plus1 > 0) return (0); } - if ((int)set->fd_count == op->fd_setsz) { - if (realloc_fd_sets(op, op->fd_setsz*2)) + if (set->fd_count == op->num_fds_in_fd_sets) { + if (grow_fd_sets(op, op->num_fds_in_fd_sets*2)) return (-1); /* set pointer will have changed and needs reiniting! */ set = read ? op->readset_in : op->writeset_in; @@ -180,7 +180,7 @@ win32_init(struct event_base *_base) size_t size; if (!(winop = mm_calloc(1, sizeof(struct win32op)))) return NULL; - winop->fd_setsz = NEVENT; + winop->num_fds_in_fd_sets = NEVENT; size = FD_SET_ALLOC_SIZE(NEVENT); if (!(winop->readset_in = mm_malloc(size))) goto err; @@ -279,7 +279,7 @@ win32_dispatch(struct event_base *base, struct timeval *tv) SOCKET s; if (win32op->resize_out_sets) { - size_t size = FD_SET_ALLOC_SIZE(win32op->fd_setsz); + size_t size = FD_SET_ALLOC_SIZE(win32op->num_fds_in_fd_sets); if (!(win32op->readset_out = mm_realloc(win32op->readset_out, size))) return (-1); if (!(win32op->exset_out = mm_realloc(win32op->exset_out, size))) From 7484df61c981fc33db2152f75ddac689791b9929 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 1 Nov 2010 13:43:43 -0400 Subject: [PATCH 06/31] Fix even more win64 warnings --- buffer_iocp.c | 8 ++++++-- bufferevent_async.c | 7 +++++-- bufferevent_sock.c | 6 +++--- evbuffer-internal.h | 6 ++++-- evutil.c | 13 +++++++++---- evutil_rand.c | 2 +- test/regress_buffer.c | 6 +++--- 7 files changed, 31 insertions(+), 17 deletions(-) diff --git a/buffer_iocp.c b/buffer_iocp.c index ae57f222..67c89c2a 100644 --- a/buffer_iocp.c +++ b/buffer_iocp.c @@ -201,10 +201,14 @@ evbuffer_launch_write(struct evbuffer *buf, ev_ssize_t at_most, _evbuffer_chain_pin(chain, EVBUFFER_MEM_PINNED_W); if ((size_t)at_most > chain->off) { - b->len = chain->off; + /* XXXX Cast is safe for now, since win32 has no + mmaped chains. But later, we need to have this + add more WSAbufs if chain->off is greater than + ULONG_MAX */ + b->len = (unsigned long)chain->off; at_most -= chain->off; } else { - b->len = at_most; + b->len = (unsigned long)at_most; ++i; break; } diff --git a/bufferevent_async.c b/bufferevent_async.c index fb23d15a..b7284fda 100644 --- a/bufferevent_async.c +++ b/bufferevent_async.c @@ -194,7 +194,9 @@ bev_async_consider_writing(struct bufferevent_async *beva) at_most = evbuffer_get_length(bev->output); /* XXXX This over-commits. */ - limit = _bufferevent_get_write_max(&beva->bev); + /* This is safe so long as bufferevent_get_write_max never returns + * more than INT_MAX. That's true for now. XXXX */ + limit = (int)_bufferevent_get_write_max(&beva->bev); if (at_most >= (size_t)limit && limit >= 0) at_most = limit; @@ -248,7 +250,8 @@ bev_async_consider_reading(struct bufferevent_async *beva) } /* XXXX This over-commits. */ - limit = _bufferevent_get_read_max(&beva->bev); + /* XXXX see also not above on cast on _bufferevent_get_write_max() */ + limit = (int)_bufferevent_get_read_max(&beva->bev); if (at_most >= (size_t)limit && limit >= 0) at_most = limit; diff --git a/bufferevent_sock.c b/bufferevent_sock.c index 43768110..b12121c2 100644 --- a/bufferevent_sock.c +++ b/bufferevent_sock.c @@ -152,13 +152,13 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg) } readmax = _bufferevent_get_read_max(bufev_p); if (howmuch < 0 || howmuch > readmax) /* The use of -1 for "unlimited" - * uglifies this code. */ + * uglifies this code. XXXX */ howmuch = readmax; if (bufev_p->read_suspended) goto done; evbuffer_unfreeze(input, 0); - res = evbuffer_read(input, fd, howmuch); + res = evbuffer_read(input, fd, (int)howmuch); /* XXXX evbuffer_read would do better to take and return ev_ssize_t */ evbuffer_freeze(input, 0); if (res == -1) { @@ -203,7 +203,7 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg) int res = 0; short what = BEV_EVENT_WRITING; int connected = 0; - int atmost = -1; + ev_ssize_t atmost = -1; _bufferevent_incref_and_lock(bufev); diff --git a/evbuffer-internal.h b/evbuffer-internal.h index 719e85dd..7fc8b914 100644 --- a/evbuffer-internal.h +++ b/evbuffer-internal.h @@ -161,7 +161,7 @@ struct evbuffer_chain { /** unused space at the beginning of buffer or an offset into a * file for sendfile buffers. */ - off_t misalign; + ev_off_t misalign; /** Offset into buffer + misalign at which to start writing. * In other words, the total number of bytes actually stored @@ -262,8 +262,10 @@ int _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch, /* Helper macro: copies an evbuffer_iovec in ei to a win32 WSABUF in i. */ #define WSABUF_FROM_EVBUFFER_IOV(i,ei) do { \ (i)->buf = (ei)->iov_base; \ - (i)->len = (ei)->iov_len; \ + (i)->len = (unsigned long)(ei)->iov_len; \ } while (0) +/* XXXX the cast above is safe for now, but not if we allow mmaps on win64. + * See note in buffer_iocp's launch_write function */ /** Set the parent bufferevent object for buf to bev */ void evbuffer_set_parent(struct evbuffer *buf, struct bufferevent *bev); diff --git a/evutil.c b/evutil.c index 9bf0d92d..6c34d6b1 100644 --- a/evutil.c +++ b/evutil.c @@ -83,8 +83,8 @@ #define open _open #define read _read #define close _close -#define fstat _fstat -#define stat _stat +#define fstat _fstati64 +#define stat _stati64 #endif /** @@ -131,7 +131,12 @@ evutil_read_file(const char *filename, char **content_out, size_t *len_out, return -2; } read_so_far = 0; - while ((r = read(fd, mem+read_so_far, st.st_size - read_so_far)) > 0) { +#ifdef WIN32 +#define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x)) +#else +#defien N_TO_READ(x) (x) +#endif + while ((r = read(fd, mem+read_so_far, N_TO_READ(st.st_size - read_so_far))) > 0) { read_so_far += r; if (read_so_far >= (size_t)st.st_size) break; @@ -1717,7 +1722,7 @@ evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int * if (!(cp = strchr(ip_as_string, ']'))) { return -1; } - len = cp-(ip_as_string + 1); + len = (int) ( cp-(ip_as_string + 1) ); if (len > (int)sizeof(buf)-1) { return -1; } diff --git a/evutil_rand.c b/evutil_rand.c index 15e4850d..07ad2ea6 100644 --- a/evutil_rand.c +++ b/evutil_rand.c @@ -121,6 +121,6 @@ void evutil_secure_rng_add_bytes(const char *buf, size_t n) { arc4random_addrandom((unsigned char*)buf, - n>(size_t)INT_MAX ? INT_MAX : n); + n>(size_t)INT_MAX ? INT_MAX : (int)n); } diff --git a/test/regress_buffer.c b/test/regress_buffer.c index 44c16fdc..a4b9b31f 100644 --- a/test/regress_buffer.c +++ b/test/regress_buffer.c @@ -139,17 +139,17 @@ evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, si a += chain->buffer_len; u += chain->off; if (chain->next && chain->next->off) - w += chain->buffer_len - (chain->misalign + chain->off); + w += (size_t)(chain->buffer_len - (chain->misalign + chain->off)); chain = chain->next; } /* subsequent nonempty chains */ while (chain && chain->off) { ++n; a += chain->buffer_len; - w += chain->misalign; + w += (size_t)chain->misalign; u += chain->off; if (chain->next && chain->next->off) - w += chain->buffer_len - (chain->misalign + chain->off); + w += (size_t) (chain->buffer_len - (chain->misalign + chain->off)); chain = chain->next; } /* subsequent empty chains */ From 545a61145ca8ae38c3d19f5404ff3be18c275308 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 1 Nov 2010 13:59:04 -0400 Subject: [PATCH 07/31] Fix even more win64 warnings: buffer, event_tagging, http, evdns, evrpc --- buffer.c | 39 ++++++++++++++++++++++----------------- evdns.c | 34 +++++++++++++++++----------------- event_tagging.c | 10 ++++++---- evrpc.c | 2 +- http.c | 9 +++++---- 5 files changed, 51 insertions(+), 43 deletions(-) diff --git a/buffer.c b/buffer.c index 0e6c7762..35d98d4e 100644 --- a/buffer.c +++ b/buffer.c @@ -146,7 +146,7 @@ static struct evbuffer_chain *evbuffer_expand_singlechain(struct evbuffer *buf, #ifdef WIN32 static int evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd, - int howmuch); + ev_ssize_t howmuch); #else #define evbuffer_readfile evbuffer_read #endif @@ -1025,6 +1025,7 @@ done: /* reads data from the src buffer to the dst buffer, avoids memcpy as * possible. */ +/* XXXX should return ev_ssize_t */ int evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst, size_t datlen) @@ -1054,7 +1055,7 @@ evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst, if (datlen >= src->total_len) { datlen = src->total_len; evbuffer_add_buffer(dst, src); - result = datlen; + result = (int)datlen; /*XXXX should return ev_ssize_t*/ goto done; } @@ -1102,7 +1103,7 @@ evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst, evbuffer_invoke_callbacks(dst); evbuffer_invoke_callbacks(src); } - result = nread; + result = (int)nread;/*XXXX should change return type */ done: EVBUFFER_UNLOCK2(src, dst); @@ -1231,11 +1232,11 @@ evbuffer_readline(struct evbuffer *buffer) return evbuffer_readln(buffer, NULL, EVBUFFER_EOL_ANY); } -static inline int +static inline ev_ssize_t evbuffer_strchr(struct evbuffer_ptr *it, const char chr) { struct evbuffer_chain *chain = it->_internal.chain; - unsigned i = it->_internal.pos_in_chain; + size_t i = it->_internal.pos_in_chain; while (chain != NULL) { char *buffer = (char *)chain->buffer + chain->misalign; char *cp = memchr(buffer+i, chr, chain->off-i); @@ -1280,11 +1281,11 @@ find_eol_char(char *s, size_t len) #undef CHUNK_SZ } -static int +static ev_ssize_t evbuffer_find_eol_char(struct evbuffer_ptr *it) { struct evbuffer_chain *chain = it->_internal.chain; - unsigned i = it->_internal.pos_in_chain; + size_t i = it->_internal.pos_in_chain; while (chain != NULL) { char *buffer = (char *)chain->buffer + chain->misalign; char *cp = find_eol_char(buffer+i, chain->off-i); @@ -1308,7 +1309,7 @@ evbuffer_strspn( { int count = 0; struct evbuffer_chain *chain = ptr->_internal.chain; - unsigned i = ptr->_internal.pos_in_chain; + size_t i = ptr->_internal.pos_in_chain; if (!chain) return -1; @@ -1346,7 +1347,7 @@ static inline char evbuffer_getchr(struct evbuffer_ptr *it) { struct evbuffer_chain *chain = it->_internal.chain; - int off = it->_internal.pos_in_chain; + size_t off = it->_internal.pos_in_chain; return chain->buffer[chain->misalign + off]; } @@ -1910,11 +1911,13 @@ evbuffer_expand(struct evbuffer *buf, size_t datlen) #define IOV_TYPE struct iovec #define IOV_PTR_FIELD iov_base #define IOV_LEN_FIELD iov_len +#define IOV_LEN_TYPE size_t #else #define NUM_WRITE_IOVEC 16 #define IOV_TYPE WSABUF #define IOV_PTR_FIELD buf #define IOV_LEN_FIELD len +#define IOV_LEN_TYPE unsigned long #endif #endif #define NUM_READ_IOVEC 4 @@ -2093,7 +2096,7 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch) ev_ssize_t space = CHAIN_SPACE_LEN(*chainp); if (space < remaining) { (*chainp)->off += space; - remaining -= space; + remaining -= (int)space; } else { (*chainp)->off += remaining; buf->last_with_datap = chainp; @@ -2118,7 +2121,7 @@ done: #ifdef WIN32 static int -evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd, int howmuch) +evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd, ev_ssize_t howmuch) { int result; int nchains, n; @@ -2142,16 +2145,16 @@ evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd, int howmuch) result = -1; goto done; } - n = read(fd, v[0].iov_base, v[0].iov_len); + n = read((int)fd, v[0].iov_base, (unsigned int)v[0].iov_len); if (n <= 0) { result = n; goto done; } - v[0].iov_len = n; + v[0].iov_len = (IOV_LEN_TYPE) n; /* XXXX another problem with big n.*/ if (nchains > 1) { - n = read(fd, v[1].iov_base, v[1].iov_len); + n = read((int)fd, v[1].iov_base, (unsigned int)v[1].iov_len); if (n <= 0) { - result = v[0].iov_len; + result = (unsigned long) v[0].iov_len; evbuffer_commit_space(buf, v, 1); goto done; } @@ -2190,10 +2193,12 @@ evbuffer_write_iovec(struct evbuffer *buffer, evutil_socket_t fd, #endif iov[i].IOV_PTR_FIELD = (void *) (chain->buffer + chain->misalign); if ((size_t)howmuch >= chain->off) { - iov[i++].IOV_LEN_FIELD = chain->off; + /* XXXcould be problematic when windows supports mmap*/ + iov[i++].IOV_LEN_FIELD = (IOV_LEN_TYPE)chain->off; howmuch -= chain->off; } else { - iov[i++].IOV_LEN_FIELD = howmuch; + /* XXXcould be problematic when windows supports mmap*/ + iov[i++].IOV_LEN_FIELD = (IOV_LEN_TYPE)howmuch; break; } chain = chain->next; diff --git a/evdns.c b/evdns.c index 0d1d32e4..123e947c 100644 --- a/evdns.c +++ b/evdns.c @@ -1148,7 +1148,7 @@ request_parse(u8 *packet, int length, struct evdns_server_port *port, struct soc goto err; GET16(type); GET16(class); - namelen = strlen(tmp_name); + namelen = (int)strlen(tmp_name); q = mm_malloc(sizeof(struct evdns_server_question) + namelen); if (!q) goto err; @@ -1323,8 +1323,8 @@ server_port_flush(struct evdns_server_port *port) struct server_request *req = port->pending_replies; ASSERT_LOCKED(port); while (req) { - int r = sendto(port->socket, req->response, req->response_len, 0, - (struct sockaddr*) &req->addr, req->addrlen); + int r = sendto(port->socket, req->response, (int)req->response_len, 0, + (struct sockaddr*) &req->addr, (ev_socklen_t)req->addrlen); if (r < 0) { int err = evutil_socket_geterror(port->socket); if (EVUTIL_ERR_RW_RETRIABLE(err)) @@ -1485,7 +1485,7 @@ dnslabel_table_add(struct dnslabel_table *table, const char *label, off_t pos) /* */ static off_t dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j, - const char *name, const int name_len, + const char *name, const size_t name_len, struct dnslabel_table *table) { const char *end = name + name_len; int ref = 0; @@ -1516,25 +1516,25 @@ dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j, } name = strchr(name, '.'); if (!name) { - const unsigned int label_len = end - start; + const size_t label_len = end - start; if (label_len > 63) return -1; if ((size_t)(j+label_len+1) > buf_len) return -2; if (table) dnslabel_table_add(table, start, j); - buf[j++] = label_len; + buf[j++] = (ev_uint8_t)label_len; memcpy(buf + j, start, end - start); - j += end - start; + j += (int)(end - start); break; } else { /* append length of the label. */ - const unsigned int label_len = name - start; + const size_t label_len = name - start; if (label_len > 63) return -1; if ((size_t)(j+label_len+1) > buf_len) return -2; if (table) dnslabel_table_add(table, start, j); - buf[j++] = label_len; + buf[j++] = (ev_uint8_t)label_len; memcpy(buf + j, start, name - start); - j += name - start; + j += (int)(name - start); /* hop over the '.' */ name++; } @@ -1564,7 +1564,7 @@ evdns_request_len(const size_t name_len) { /* */ /* Returns the amount of space used. Negative on error. */ static int -evdns_request_data_build(const char *const name, const int name_len, +evdns_request_data_build(const char *const name, const size_t name_len, const u16 trans_id, const u16 type, const u16 class, u8 *const buf, size_t buf_len) { off_t j = 0; /* current offset into buf */ @@ -1885,8 +1885,8 @@ evdns_server_request_respond(struct evdns_server_request *_req, int err) goto done; } - r = sendto(port->socket, req->response, req->response_len, 0, - (struct sockaddr*) &req->addr, req->addrlen); + r = sendto(port->socket, req->response, (int)req->response_len, 0, + (struct sockaddr*) &req->addr, (ev_socklen_t)req->addrlen); if (r<0) { int sock_err = evutil_socket_geterror(port->socket); if (EVUTIL_ERR_RW_RETRIABLE(sock_err)) @@ -2907,7 +2907,7 @@ evdns_search_clear(void) { static void search_postfix_add(struct evdns_base *base, const char *domain) { - int domain_len; + size_t domain_len; struct search_domain *sdomain; while (domain[0] == '.') domain++; domain_len = strlen(domain); @@ -2921,7 +2921,7 @@ search_postfix_add(struct evdns_base *base, const char *domain) { if (!sdomain) return; memcpy( ((u8 *) sdomain) + sizeof(struct search_domain), domain, domain_len); sdomain->next = base->global_search_state->head; - sdomain->len = domain_len; + sdomain->len = (int) domain_len; base->global_search_state->head = sdomain; } @@ -2984,7 +2984,7 @@ search_set_from_hostname(struct evdns_base *base) { /* warning: returns malloced string */ static char * search_make_new(const struct search_state *const state, int n, const char *const base_name) { - const int base_len = strlen(base_name); + const size_t base_len = strlen(base_name); const char need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1; struct search_domain *dom; @@ -3394,7 +3394,7 @@ evdns_get_default_hosts_filename(void) char path[MAX_PATH+1]; static const char hostfile[] = "\\drivers\\etc\\hosts"; char *path_out; - int len_out; + size_t len_out; if (! SHGetSpecialFolderPathA(NULL, path, CSIDL_SYSTEM, 0)) return NULL; diff --git a/event_tagging.c b/event_tagging.c index 009d9b27..aaded70a 100644 --- a/event_tagging.c +++ b/event_tagging.c @@ -256,7 +256,8 @@ evtag_marshal_buffer(struct evbuffer *evbuf, ev_uint32_t tag, struct evbuffer *data) { evtag_encode_tag(evbuf, tag); - evtag_encode_int(evbuf, evbuffer_get_length(data)); + /* XXX support more than UINT32_MAX data */ + evtag_encode_int(evbuf, (ev_uint32_t)evbuffer_get_length(data)); evbuffer_add_buffer(evbuf, data); } @@ -287,7 +288,8 @@ evtag_marshal_int64(struct evbuffer *evbuf, ev_uint32_t tag, void evtag_marshal_string(struct evbuffer *buf, ev_uint32_t tag, const char *string) { - evtag_marshal(buf, tag, string, strlen(string)); + /* TODO support strings longer than UINT32_MAX ? */ + evtag_marshal(buf, tag, string, (ev_uint32_t)strlen(string)); } void @@ -302,7 +304,7 @@ evtag_marshal_timeval(struct evbuffer *evbuf, ev_uint32_t tag, struct timeval *t #define DECODE_INT_INTERNAL(number, maxnibbles, pnumber, evbuf, offset) \ do { \ ev_uint8_t *data; \ - int len = evbuffer_get_length(evbuf) - offset; \ + ev_ssize_t len = evbuffer_get_length(evbuf) - offset; \ int nibbles = 0; \ \ if (len <= 0) \ @@ -329,7 +331,7 @@ do { \ \ *pnumber = number; \ \ - return (len); \ + return (int)(len); \ } while (0) /* Internal: decode an integer from an evbuffer, without draining it. diff --git a/evrpc.c b/evrpc.c index 91e9a5f2..9d692994 100644 --- a/evrpc.c +++ b/evrpc.c @@ -210,7 +210,7 @@ static char * evrpc_construct_uri(const char *uri) { char *constructed_uri; - int constructed_uri_len; + size_t constructed_uri_len; constructed_uri_len = strlen(EVRPC_URI_PREFIX) + strlen(uri) + 1; if ((constructed_uri = mm_malloc(constructed_uri_len)) == NULL) diff --git a/http.c b/http.c index 2a1cb670..5222aeff 100644 --- a/http.c +++ b/http.c @@ -240,7 +240,8 @@ html_replace(char ch, char *buf) char * evhttp_htmlescape(const char *html) { - int i, new_size = 0, old_size = strlen(html); + int i; + size_t new_size = 0, old_size = strlen(html); char *escaped_html, *p; char scratch_space[2]; @@ -762,7 +763,7 @@ evhttp_connection_done(struct evhttp_connection *evcon) static enum message_read_status evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf) { - int len; + ev_ssize_t len; while ((len = evbuffer_get_length(buf)) > 0) { if (req->ntoread < 0) { @@ -3371,7 +3372,7 @@ bind_socket_ai(struct evutil_addrinfo *ai, int reuse) evutil_make_listen_socket_reuseable(fd); if (ai != NULL) { - r = bind(fd, ai->ai_addr, ai->ai_addrlen); + r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen); if (r == -1) goto out; } @@ -3563,7 +3564,7 @@ bracket_addr_ok(const char *s, const char *eos) } else { /* IPv6, or junk */ char buf[64]; - int n_chars = eos-s-2; + ev_ssize_t n_chars = eos-s-2; struct in6_addr in6; if (n_chars >= 64) /* way too long */ return 0; From f8095d64e21d7abd16649a65080fd077bf0f0488 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 1 Nov 2010 14:15:34 -0400 Subject: [PATCH 08/31] Fix a typo in 7484df61c981fc33db2~ --- evutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evutil.c b/evutil.c index 6c34d6b1..d5d18fff 100644 --- a/evutil.c +++ b/evutil.c @@ -134,7 +134,7 @@ evutil_read_file(const char *filename, char **content_out, size_t *len_out, #ifdef WIN32 #define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x)) #else -#defien N_TO_READ(x) (x) +#define N_TO_READ(x) (x) #endif while ((r = read(fd, mem+read_so_far, N_TO_READ(st.st_size - read_so_far))) > 0) { read_so_far += r; From 74a91e5aafcb62f9518615dbc1021dfde113e001 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 1 Nov 2010 14:16:39 -0400 Subject: [PATCH 09/31] fix signed/unsigned warnings in http.c --- http.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http.c b/http.c index 5222aeff..f13c22e0 100644 --- a/http.c +++ b/http.c @@ -240,7 +240,7 @@ html_replace(char ch, char *buf) char * evhttp_htmlescape(const char *html) { - int i; + size_t i; size_t new_size = 0, old_size = strlen(html); char *escaped_html, *p; char scratch_space[2]; @@ -250,7 +250,7 @@ evhttp_htmlescape(const char *html) p = escaped_html = mm_malloc(new_size + 1); if (escaped_html == NULL) { - event_warn("%s: malloc(%d)", __func__, new_size + 1); + event_warn("%s: malloc(%ld)", __func__, (long)(new_size + 1)); return (NULL); } for (i = 0; i < old_size; ++i) { From a3245afec2a7c7035cf62bdb67bab482e5986a8c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 1 Nov 2010 14:23:33 -0400 Subject: [PATCH 10/31] Fix win32 build in response to fixes from win64 build. --- buffer.c | 28 ++++++++++++++-------------- evutil.c | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/buffer.c b/buffer.c index 35d98d4e..52ab6357 100644 --- a/buffer.c +++ b/buffer.c @@ -572,7 +572,7 @@ evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size, goto done; vec[0].iov_base = CHAIN_SPACE_PTR(chain); - vec[0].iov_len = CHAIN_SPACE_LEN(chain); + vec[0].iov_len = (size_t) CHAIN_SPACE_LEN(chain); EVUTIL_ASSERT(size<0 || (size_t)vec[0].iov_len >= (size_t)size); n = 1; } else { @@ -1496,7 +1496,7 @@ evbuffer_add(struct evbuffer *buf, const void *data_in, size_t datlen) } if ((chain->flags & EVBUFFER_IMMUTABLE) == 0) { - remain = chain->buffer_len - chain->misalign - chain->off; + remain = (size_t)(chain->buffer_len - chain->misalign - chain->off); if (remain >= datlen) { /* there's enough space to hold all the data in the * current last chain */ @@ -1596,11 +1596,11 @@ evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen) /* we can only fit some of the data. */ memcpy(chain->buffer, (char*)data + datlen - chain->misalign, - chain->misalign); - chain->off += chain->misalign; - buf->total_len += chain->misalign; - buf->n_add_for_cb += chain->misalign; - datlen -= chain->misalign; + (size_t)chain->misalign); + chain->off += (size_t)chain->misalign; + buf->total_len += (size_t)chain->misalign; + buf->n_add_for_cb += (size_t)chain->misalign; + datlen -= (size_t)chain->misalign; chain->misalign = 0; } } @@ -1619,7 +1619,7 @@ evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen) memcpy(tmp->buffer + tmp->misalign, data, datlen); buf->total_len += datlen; - buf->n_add_for_cb += chain->misalign; + buf->n_add_for_cb += (size_t)chain->misalign; out: evbuffer_invoke_callbacks(buf); @@ -1794,7 +1794,7 @@ _evbuffer_expand_fast(struct evbuffer *buf, size_t datlen, int n) * space we have in the first n. */ for (chain = *buf->last_with_datap; chain; chain = chain->next) { if (chain->off) { - size_t space = CHAIN_SPACE_LEN(chain); + size_t space = (size_t) CHAIN_SPACE_LEN(chain); EVUTIL_ASSERT(chain == *buf->last_with_datap); if (space) { avail += space; @@ -1841,7 +1841,7 @@ _evbuffer_expand_fast(struct evbuffer *buf, size_t datlen, int n) rmv_all = 1; avail = 0; } else { - avail = CHAIN_SPACE_LEN(chain); + avail = (size_t) CHAIN_SPACE_LEN(chain); chain = chain->next; } @@ -1960,7 +1960,7 @@ _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch, chain = *firstchainp; for (i = 0; i < n_vecs_avail && so_far < (size_t)howmuch; ++i) { - size_t avail = CHAIN_SPACE_LEN(chain); + size_t avail = (size_t) CHAIN_SPACE_LEN(chain); if (avail > (howmuch - so_far) && exact) avail = howmuch - so_far; vecs[i].iov_base = CHAIN_SPACE_PTR(chain); @@ -2093,7 +2093,7 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch) #ifdef USE_IOVEC_IMPL remaining = n; for (i=0; i < nvecs; ++i) { - ev_ssize_t space = CHAIN_SPACE_LEN(*chainp); + ev_ssize_t space = (ev_ssize_t) CHAIN_SPACE_LEN(*chainp); if (space < remaining) { (*chainp)->off += space; remaining -= (int)space; @@ -2563,7 +2563,7 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap) space = chain->buffer_len - used; #endif buffer = (char*) CHAIN_SPACE_PTR(chain); - space = CHAIN_SPACE_LEN(chain); + space = (size_t) CHAIN_SPACE_LEN(chain); #ifndef va_copy #define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list)) @@ -2765,7 +2765,7 @@ evbuffer_add_file(struct evbuffer *outbuf, int fd, * can abort without side effects if the read fails. */ while (length) { - read = evbuffer_readfile(tmp, fd, length); + read = evbuffer_readfile(tmp, fd, (ev_ssize_t)length); if (read == -1) { evbuffer_free(tmp); return (-1); diff --git a/evutil.c b/evutil.c index d5d18fff..46c8333d 100644 --- a/evutil.c +++ b/evutil.c @@ -125,7 +125,7 @@ evutil_read_file(const char *filename, char **content_out, size_t *len_out, close(fd); return -2; } - mem = mm_malloc(st.st_size + 1); + mem = mm_malloc((size_t)st.st_size + 1); if (!mem) { close(fd); return -2; From ba014569991ead06594e3418705ad42e4818cb33 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 2 Nov 2010 12:42:35 -0400 Subject: [PATCH 11/31] Use the label_len local variable in evdns instead of recalculating it over and over --- evdns.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/evdns.c b/evdns.c index 123e947c..4a36218d 100644 --- a/evdns.c +++ b/evdns.c @@ -1522,8 +1522,8 @@ dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j, if (table) dnslabel_table_add(table, start, j); buf[j++] = (ev_uint8_t)label_len; - memcpy(buf + j, start, end - start); - j += (int)(end - start); + memcpy(buf + j, start, label_len); + j += (int) label_len; break; } else { /* append length of the label. */ @@ -1533,8 +1533,8 @@ dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j, if (table) dnslabel_table_add(table, start, j); buf[j++] = (ev_uint8_t)label_len; - memcpy(buf + j, start, name - start); - j += (int)(name - start); + memcpy(buf + j, start, label_len); + j += (int) label_len; /* hop over the '.' */ name++; } From aa5f55face7347a7fa766ff37534d9413486fcfe Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Tue, 2 Nov 2010 13:50:57 -0400 Subject: [PATCH 12/31] reset "chunked" flag when sending non-chunked reply --- http.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http.c b/http.c index 2a1cb670..3a567227 100644 --- a/http.c +++ b/http.c @@ -2179,6 +2179,8 @@ evhttp_send_reply_start(struct evhttp_request *req, int code, evhttp_add_header(req->output_headers, "Transfer-Encoding", "chunked"); req->chunked = 1; + } else { + req->chunked = 0; } evhttp_make_header(req->evcon, req); evhttp_write_buffer(req->evcon, NULL, NULL); From 647e094ca2ff90da79bfc3081848f50583d2042c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 2 Nov 2010 15:19:12 -0400 Subject: [PATCH 13/31] Replace exact-version checks for HTTP/1.1 with >= or < checks --- http.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/http.c b/http.c index 3a567227..ac5e547a 100644 --- a/http.c +++ b/http.c @@ -149,6 +149,14 @@ fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, #endif +#define REQ_VERSION_BEFORE(req, major_v, minor_v) \ + ((req)->major < (major_v) || \ + ((req)->major == (major_v) && (req)->minor < (minor_v))) + +#define REQ_VERSION_ATLEAST(req, major_v, minor_v) \ + ((req)->major > (major_v) || \ + ((req)->major == (major_v) && (req)->minor >= (minor_v))) + #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) #endif @@ -470,9 +478,8 @@ evhttp_make_header_response(struct evhttp_connection *evcon, req->major, req->minor, req->response_code, req->response_code_line); - /* XXX shouldn't these check for >= rather than == ? - NM */ if (req->major == 1) { - if (req->minor == 1) + if (req->minor >= 1) evhttp_maybe_add_date_header(req->output_headers); /* @@ -483,7 +490,7 @@ evhttp_make_header_response(struct evhttp_connection *evcon, evhttp_add_header(req->output_headers, "Connection", "keep-alive"); - if ((req->minor == 1 || is_keepalive) && + if ((req->minor >= 1 || is_keepalive) && evhttp_response_needs_body(req)) { /* * we need to add the content length if the @@ -1392,10 +1399,16 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line) req->major = 1; req->minor = 1; } else { - /* XXX So, http/1.2 kills us? Is that right? -NM */ - event_debug(("%s: bad version %s on request %p from %s", - __func__, version, req, req->remote_host)); - return (-1); + int major, minor; + char ch; + int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch); + if (n > 2 || major > 1) { + event_debug(("%s: bad version %s on request %p from %s", + __func__, version, req, req->remote_host)); + return (-1); + } + req->major = major; + req->minor = minor; } if ((req->uri = mm_strdup(uri)) == NULL) { @@ -2074,7 +2087,7 @@ evhttp_send_done(struct evhttp_connection *evcon, void *arg) TAILQ_REMOVE(&evcon->requests, req, next); need_close = - (req->minor == 0 && + (REQ_VERSION_BEFORE(req, 1, 1) && !evhttp_is_connection_keepalive(req->input_headers))|| evhttp_is_connection_close(req->flags, req->input_headers) || evhttp_is_connection_close(req->flags, req->output_headers); @@ -2169,7 +2182,7 @@ evhttp_send_reply_start(struct evhttp_request *req, int code, { evhttp_response_code(req, code, reason); if (evhttp_find_header(req->output_headers, "Content-Length") == NULL && - req->major == 1 && req->minor == 1 && + REQ_VERSION_ATLEAST(req, 1, 1) && evhttp_response_needs_body(req)) { /* * prefer HTTP/1.1 chunked encoding to closing the connection; From 8505a7449cfb6bca91daee1c4d9bae80be92fa26 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 3 Nov 2010 13:55:20 -0400 Subject: [PATCH 14/31] Start porting http tests to not use legacy interfaces --- test/regress_http.c | 279 +++++++++++++++++++++++++------------------- 1 file changed, 159 insertions(+), 120 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index e9e9e654..a876b130 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -110,16 +110,16 @@ http_setup(ev_uint16_t *pport, struct event_base *base) return NULL; /* Register a callback for certain types of requests */ - evhttp_set_cb(myhttp, "/test", http_basic_cb, NULL); - evhttp_set_cb(myhttp, "/chunked", http_chunked_cb, NULL); - evhttp_set_cb(myhttp, "/streamed", http_chunked_cb, NULL); - evhttp_set_cb(myhttp, "/postit", http_post_cb, NULL); - evhttp_set_cb(myhttp, "/putit", http_put_cb, NULL); - evhttp_set_cb(myhttp, "/deleteit", http_delete_cb, NULL); - evhttp_set_cb(myhttp, "/delay", http_delay_cb, NULL); - evhttp_set_cb(myhttp, "/largedelay", http_large_delay_cb, NULL); - evhttp_set_cb(myhttp, "/badrequest", http_badreq_cb, NULL); - evhttp_set_cb(myhttp, "/", http_dispatcher_cb, NULL); + evhttp_set_cb(myhttp, "/test", http_basic_cb, base); + evhttp_set_cb(myhttp, "/chunked", http_chunked_cb, base); + evhttp_set_cb(myhttp, "/streamed", http_chunked_cb, base); + evhttp_set_cb(myhttp, "/postit", http_post_cb, base); + evhttp_set_cb(myhttp, "/putit", http_put_cb, base); + evhttp_set_cb(myhttp, "/deleteit", http_delete_cb, base); + evhttp_set_cb(myhttp, "/delay", http_delay_cb, base); + evhttp_set_cb(myhttp, "/largedelay", http_large_delay_cb, base); + evhttp_set_cb(myhttp, "/badrequest", http_badreq_cb, base); + evhttp_set_cb(myhttp, "/", http_dispatcher_cb, base); return (myhttp); } @@ -223,6 +223,7 @@ static void http_readcb(struct bufferevent *bev, void *arg) { const char *what = BASIC_REQUEST_BODY; + struct event_base *my_base = arg; if (evbuffer_contains(bufferevent_get_input(bev), what)) { struct evhttp_request *req = evhttp_request_new(NULL, NULL); @@ -247,6 +248,8 @@ http_readcb(struct bufferevent *bev, void *arg) bufferevent_disable(bev, EV_READ); if (base) event_base_loopexit(base, NULL); + else if (my_base) + event_base_loopexit(my_base, NULL); else event_loopexit(NULL); } @@ -351,7 +354,7 @@ http_chunked_cb(struct evhttp_request *req, void *arg) /* but trickle it across several iterations to ensure we're not * assuming it comes all at once */ - event_base_once(NULL, -1, EV_TIMEOUT, http_chunked_trickle_cb, state, &when); + event_base_once(arg, -1, EV_TIMEOUT, http_chunked_trickle_cb, state, &when); } static void @@ -365,8 +368,9 @@ http_complete_write(evutil_socket_t fd, short what, void *arg) } static void -http_basic_test(void) +http_basic_test(void *arg) { + struct basic_test_data *data = arg; struct timeval tv; struct bufferevent *bev; evutil_socket_t fd; @@ -375,7 +379,7 @@ http_basic_test(void) test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); /* bind to a second socket */ if (http_bind(http, &port2) == -1) { @@ -386,9 +390,9 @@ http_basic_test(void) fd = http_connect("127.0.0.1", port); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(data->base, fd, 0); bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, NULL); + http_errorcb, data->base); /* first half of the http request */ http_request = @@ -398,9 +402,10 @@ http_basic_test(void) bufferevent_write(bev, http_request, strlen(http_request)); evutil_timerclear(&tv); tv.tv_usec = 10000; - event_base_once(NULL, -1, EV_TIMEOUT, http_complete_write, bev, &tv); + event_base_once(data->base, + -1, EV_TIMEOUT, http_complete_write, bev, &tv); - event_dispatch(); + event_base_dispatch(data->base); tt_assert(test_ok == 3); @@ -411,9 +416,9 @@ http_basic_test(void) fd = http_connect("127.0.0.1", port2); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(data->base, fd, 0); bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, NULL); + http_errorcb, data->base); http_request = "GET /test HTTP/1.1\r\n" @@ -423,7 +428,7 @@ http_basic_test(void) bufferevent_write(bev, http_request, strlen(http_request)); - event_dispatch(); + event_base_dispatch(data->base); bufferevent_free(bev); evutil_closesocket(fd); @@ -453,7 +458,7 @@ http_delay_cb(struct evhttp_request *req, void *arg) tv.tv_sec = 0; tv.tv_usec = 200 * 1000; - event_base_once(NULL, -1, EV_TIMEOUT, http_delay_reply, req, &tv); + event_base_once(arg, -1, EV_TIMEOUT, http_delay_reply, req, &tv); } static void @@ -617,7 +622,7 @@ http_large_delay_cb(struct evhttp_request *req, void *arg) evutil_timerclear(&tv); tv.tv_sec = 3; - event_base_once(NULL, -1, EV_TIMEOUT, http_delay_reply, req, &tv); + event_base_once(arg, -1, EV_TIMEOUT, http_delay_reply, req, &tv); evhttp_connection_fail(delayed_client, EVCON_HTTP_EOF); } @@ -648,8 +653,9 @@ http_delete_cb(struct evhttp_request *req, void *arg) } static void -http_delete_test(void) +http_delete_test(void *arg) { + struct basic_test_data *data = arg; struct bufferevent *bev; evutil_socket_t fd; const char *http_request; @@ -657,14 +663,14 @@ http_delete_test(void) test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); fd = http_connect("127.0.0.1", port); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(data->base, fd, 0); bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, NULL); + http_errorcb, data->base); http_request = "DELETE /deleteit HTTP/1.1\r\n" @@ -674,7 +680,7 @@ http_delete_test(void) bufferevent_write(bev, http_request, strlen(http_request)); - event_dispatch(); + event_base_dispatch(data->base); bufferevent_free(bev); evutil_closesocket(fd); @@ -690,7 +696,7 @@ static void http_request_done(struct evhttp_request *, void *); static void http_request_empty_done(struct evhttp_request *, void *); static void -_http_connection_test(int persistent) +_http_connection_test(struct basic_test_data *data, int persistent) { ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; @@ -698,13 +704,14 @@ _http_connection_test(int persistent) test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); - tt_assert(evhttp_connection_get_base(evcon) == NULL); + tt_assert(evhttp_connection_get_base(evcon) == data->base); + base = data->base; /* * At this point, we want to schedule a request to the HTTP * server using our make request method. @@ -721,7 +728,7 @@ _http_connection_test(int persistent) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); tt_assert(test_ok); @@ -745,12 +752,12 @@ _http_connection_test(int persistent) tt_abort_msg("couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); /* make another request: request empty reply */ test_ok = 0; - req = evhttp_request_new(http_request_empty_done, NULL); + req = evhttp_request_new(http_request_empty_done, data->base); /* Add the information that we care about */ evhttp_add_header(req->output_headers, "Empty", "itis"); @@ -761,7 +768,7 @@ _http_connection_test(int persistent) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -771,14 +778,14 @@ _http_connection_test(int persistent) } static void -http_connection_test(void) +http_connection_test(void *arg) { - _http_connection_test(0); + _http_connection_test(arg, 0); } static void -http_persist_connection_test(void) +http_persist_connection_test(void *arg) { - _http_connection_test(1); + _http_connection_test(arg, 1); } static struct regress_dns_server_table search_table[] = { @@ -787,8 +794,9 @@ static struct regress_dns_server_table search_table[] = { }; static void -http_connection_async_test(void) +http_connection_async_test(void *arg) { + struct basic_test_data *data = arg; ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; @@ -796,9 +804,10 @@ http_connection_async_test(void) ev_uint16_t portnum = 0; char address[64]; - tt_assert(regress_dnsserver(base, &portnum, search_table)); + base = data->base; + tt_assert(regress_dnsserver(data->base, &portnum, search_table)); - dns_base = evdns_base_new(base, 0/* init name servers */); + dns_base = evdns_base_new(data->base, 0/* init name servers */); tt_assert(dns_base); /* Add ourself as the only nameserver, and make sure we really are @@ -808,9 +817,9 @@ http_connection_async_test(void) test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); - evcon = evhttp_connection_base_new(base, dns_base, "127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, dns_base, "127.0.0.1", port); tt_assert(evcon); /* @@ -829,7 +838,7 @@ http_connection_async_test(void) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); tt_assert(test_ok); @@ -852,12 +861,12 @@ http_connection_async_test(void) tt_abort_msg("couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); /* make another request: request empty reply */ test_ok = 0; - req = evhttp_request_new(http_request_empty_done, NULL); + req = evhttp_request_new(http_request_empty_done, data->base); /* Add the information that we care about */ evhttp_add_header(req->output_headers, "Empty", "itis"); @@ -868,7 +877,7 @@ http_connection_async_test(void) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -892,30 +901,35 @@ http_do_cancel(evutil_socket_t fd, short what, void *arg) { struct evhttp_request *req = arg; struct timeval tv; + struct event_base *base; evutil_timerclear(&tv); tv.tv_sec = 0; tv.tv_usec = 500 * 1000; + base = evhttp_connection_get_base(evhttp_request_get_connection(req)); evhttp_cancel_request(req); - event_loopexit(&tv); + event_base_loopexit(base, &tv); ++test_ok; } static void -http_cancel_test(void) +http_cancel_test(void *arg) { + struct basic_test_data *data = arg; ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; struct timeval tv; + base = data->base; + test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); /* @@ -936,9 +950,9 @@ http_cancel_test(void) tv.tv_sec = 0; tv.tv_usec = 100 * 1000; - event_base_once(NULL, -1, EV_TIMEOUT, http_do_cancel, req, &tv); + event_base_once(data->base, -1, EV_TIMEOUT, http_do_cancel, req, &tv); - event_dispatch(); + event_base_dispatch(data->base); tt_int_op(test_ok, ==, 2); @@ -954,12 +968,12 @@ http_cancel_test(void) tt_int_op(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test"), !=, -1); - event_dispatch(); + event_base_dispatch(data->base); /* make another request: request empty reply */ test_ok = 0; - req = evhttp_request_new(http_request_empty_done, NULL); + req = evhttp_request_new(http_request_empty_done, data->base); /* Add the information that we care about */ evhttp_add_header(req->output_headers, "Empty", "itis"); @@ -968,7 +982,7 @@ http_cancel_test(void) tt_int_op(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test"), !=, -1); - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -1003,7 +1017,10 @@ http_request_done(struct evhttp_request *req, void *arg) } test_ok = 1; - event_loopexit(NULL); + if (base) + event_base_loopexit(base, NULL); + else + event_loopexit(NULL); } static void @@ -1015,19 +1032,25 @@ http_request_expect_error(struct evhttp_request *req, void *arg) } test_ok = 1; - event_loopexit(NULL); + if (arg) + event_base_loopexit(arg, NULL); + else + event_loopexit(NULL); } /* test virtual hosts */ static void -http_virtual_host_test(void) +http_virtual_host_test(void *arg) { + struct basic_test_data *data = arg; ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; struct evhttp *second = NULL, *third = NULL; - http = http_setup(&port, NULL); + base = data->base; + + http = http_setup(&port, data->base); /* virtual host */ second = evhttp_new(NULL); @@ -1043,11 +1066,11 @@ http_virtual_host_test(void) tt_abort_msg("Couldn't add wildcarded vhost"); } - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); /* make a request with a different host and expect an error */ - req = evhttp_request_new(http_request_expect_error, NULL); + req = evhttp_request_new(http_request_expect_error, data->base); /* Add the information that we care about */ evhttp_add_header(req->output_headers, "Host", "somehost"); @@ -1058,7 +1081,7 @@ http_virtual_host_test(void) tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); tt_assert(test_ok == 1); @@ -1077,7 +1100,7 @@ http_virtual_host_test(void) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); tt_assert(test_ok == 1); @@ -1095,7 +1118,7 @@ http_virtual_host_test(void) tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); tt_assert(test_ok == 1) @@ -1140,7 +1163,10 @@ http_request_empty_done(struct evhttp_request *req, void *arg) } test_ok = 1; - event_loopexit(NULL); + if (arg) + event_base_loopexit(arg, NULL); + else + event_loopexit(NULL); } /* @@ -1240,17 +1266,18 @@ void http_postrequest_done(struct evhttp_request *, void *); #define POST_DATA "Okay. Not really printf" static void -http_post_test(void) +http_post_test(void *arg) { + struct basic_test_data *data = arg; ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); /* @@ -1258,7 +1285,7 @@ http_post_test(void) * server using our make request method. */ - req = evhttp_request_new(http_postrequest_done, NULL); + req = evhttp_request_new(http_postrequest_done, data->base); tt_assert(req); /* Add the information that we care about */ @@ -1269,7 +1296,7 @@ http_post_test(void) tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); evhttp_connection_free(evcon); evhttp_free(http); @@ -1316,6 +1343,7 @@ void http_postrequest_done(struct evhttp_request *req, void *arg) { const char *what = BASIC_REQUEST_BODY; + struct event_base *base = arg; if (req == NULL) { fprintf(stderr, "FAILED (timeout)\n"); @@ -1345,7 +1373,7 @@ http_postrequest_done(struct evhttp_request *req, void *arg) } test_ok = 1; - event_loopexit(NULL); + event_base_loopexit(base, NULL); } /* @@ -1357,24 +1385,25 @@ void http_putrequest_done(struct evhttp_request *, void *); #define PUT_DATA "Hi, I'm some PUT data" static void -http_put_test(void) +http_put_test(void *arg) { + struct basic_test_data *data = arg; ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); /* * Schedule the HTTP PUT request */ - req = evhttp_request_new(http_putrequest_done, NULL); + req = evhttp_request_new(http_putrequest_done, data->base); tt_assert(req); /* Add the information that we care about */ @@ -1385,7 +1414,7 @@ http_put_test(void) tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); evhttp_connection_free(evcon); evhttp_free(http); @@ -1431,6 +1460,7 @@ http_put_cb(struct evhttp_request *req, void *arg) void http_putrequest_done(struct evhttp_request *req, void *arg) { + struct event_base *base = arg; const char *what = "That ain't funny"; if (req == NULL) { @@ -1462,7 +1492,7 @@ http_putrequest_done(struct evhttp_request *req, void *arg) } test_ok = 1; - event_loopexit(NULL); + event_base_loopexit(base, NULL); } static void @@ -1472,7 +1502,7 @@ http_failure_readcb(struct bufferevent *bev, void *arg) if (evbuffer_contains(bufferevent_get_input(bev), what)) { test_ok = 2; bufferevent_disable(bev, EV_READ); - event_loopexit(NULL); + event_base_loopexit(arg, NULL); } } @@ -1480,8 +1510,9 @@ http_failure_readcb(struct bufferevent *bev, void *arg) * Testing that the HTTP server can deal with a malformed request. */ static void -http_failure_test(void) +http_failure_test(void *arg) { + struct basic_test_data *data = arg; struct bufferevent *bev; evutil_socket_t fd; const char *http_request; @@ -1489,20 +1520,20 @@ http_failure_test(void) test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); fd = http_connect("127.0.0.1", port); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(data->base, fd, 0); bufferevent_setcb(bev, http_failure_readcb, http_writecb, - http_errorcb, NULL); + http_errorcb, data->base); http_request = "illegal request\r\n"; bufferevent_write(bev, http_request, strlen(http_request)); - event_dispatch(); + event_base_dispatch(data->base); bufferevent_free(bev); evutil_closesocket(fd); @@ -1526,16 +1557,17 @@ close_detect_done(struct evhttp_request *req, void *arg) end: evutil_timerclear(&tv); tv.tv_sec = 3; - event_loopexit(&tv); + event_base_loopexit(arg, &tv); } static void close_detect_launch(evutil_socket_t fd, short what, void *arg) { struct evhttp_connection *evcon = arg; + struct event_base *base = evhttp_connection_get_base(evcon); struct evhttp_request *req; - req = evhttp_request_new(close_detect_done, NULL); + req = evhttp_request_new(close_detect_done, base); /* Add the information that we care about */ evhttp_add_header(req->output_headers, "Host", "somehost"); @@ -1550,6 +1582,7 @@ static void close_detect_cb(struct evhttp_request *req, void *arg) { struct evhttp_connection *evcon = arg; + struct event_base *base = evhttp_connection_get_base(evcon); struct timeval tv; if (req != NULL && req->response_code != HTTP_OK) { @@ -1560,26 +1593,27 @@ close_detect_cb(struct evhttp_request *req, void *arg) tv.tv_sec = 3; /* longer than the http time out */ /* launch a new request on the persistent connection in 3 seconds */ - event_base_once(NULL, -1, EV_TIMEOUT, close_detect_launch, evcon, &tv); + event_base_once(base, -1, EV_TIMEOUT, close_detect_launch, evcon, &tv); end: ; } static void -_http_close_detection(int with_delay) +_http_close_detection(struct basic_test_data *data, int with_delay) { ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); /* 2 second timeout */ evhttp_set_timeout(http, 1); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, + "127.0.0.1", port); tt_assert(evcon); delayed_client = evcon; @@ -1600,7 +1634,7 @@ _http_close_detection(int with_delay) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); /* at this point, the http server should have no connection */ tt_assert(TAILQ_FIRST(&http->connections) == NULL); @@ -1612,14 +1646,14 @@ _http_close_detection(int with_delay) evhttp_free(http); } static void -http_close_detection_test(void) +http_close_detection_test(void *arg) { - _http_close_detection(0); + _http_close_detection(arg, 0); } static void -http_close_detection_delay_test(void) +http_close_detection_delay_test(void *arg) { - _http_close_detection(1); + _http_close_detection(arg, 1); } static void @@ -2252,7 +2286,7 @@ static void http_incomplete_readcb(struct bufferevent *bev, void *arg) { test_ok = -1; - event_loopexit(NULL); + event_base_loopexit(base,NULL); } static void @@ -2262,7 +2296,7 @@ http_incomplete_errorcb(struct bufferevent *bev, short what, void *arg) test_ok++; else test_ok = -2; - event_loopexit(NULL); + event_base_loopexit(base,NULL); } static void @@ -2281,7 +2315,7 @@ http_incomplete_writecb(struct bufferevent *bev, void *arg) } static void -_http_incomplete_test(int use_timeout) +_http_incomplete_test(struct basic_test_data *data, int use_timeout) { struct bufferevent *bev; evutil_socket_t fd; @@ -2289,15 +2323,17 @@ _http_incomplete_test(int use_timeout) ev_uint16_t port = 0; struct timeval tv_start, tv_end; + base = data->base; + test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); evhttp_set_timeout(http, 1); fd = http_connect("127.0.0.1", port); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(data->base, fd, 0); bufferevent_setcb(bev, http_incomplete_readcb, http_incomplete_writecb, http_incomplete_errorcb, use_timeout ? NULL : &fd); @@ -2310,7 +2346,7 @@ _http_incomplete_test(int use_timeout) evutil_gettimeofday(&tv_start, NULL); - event_dispatch(); + event_base_dispatch(data->base); evutil_gettimeofday(&tv_end, NULL); evutil_timersub(&tv_end, &tv_start, &tv_end); @@ -2334,14 +2370,14 @@ _http_incomplete_test(int use_timeout) ; } static void -http_incomplete_test(void) +http_incomplete_test(void *arg) { - _http_incomplete_test(0); + _http_incomplete_test(arg, 0); } static void -http_incomplete_timeout_test(void) +http_incomplete_timeout_test(void *arg) { - _http_incomplete_test(1); + _http_incomplete_test(arg, 1); } /* @@ -3194,6 +3230,9 @@ http_terminate_chunked_test(void) { #name, run_legacy_test_fn, TT_ISOLATED|TT_LEGACY, &legacy_setup, \ http_##name##_test } +#define HTTP(name) \ + { #name, http_##name##_test, TT_ISOLATED, &basic_setup, NULL } + struct testcase_t http_testcases[] = { { "primitives", http_primitives, 0, NULL, NULL }, { "base", http_base_test, TT_FORK|TT_NEED_BASE, NULL, NULL }, @@ -3201,21 +3240,21 @@ struct testcase_t http_testcases[] = { { "parse_query", http_parse_query_test, 0, NULL, NULL }, { "parse_uri", http_parse_uri_test, 0, NULL, NULL }, { "uriencode", http_uriencode_test, 0, NULL, NULL }, - HTTP_LEGACY(basic), - HTTP_LEGACY(cancel), - HTTP_LEGACY(virtual_host), - HTTP_LEGACY(post), - HTTP_LEGACY(put), - HTTP_LEGACY(delete), - HTTP_LEGACY(failure), - HTTP_LEGACY(connection), - HTTP_LEGACY(persist_connection), - HTTP_LEGACY(connection_async), - HTTP_LEGACY(close_detection), - HTTP_LEGACY(close_detection_delay), + HTTP(basic), + HTTP(cancel), + HTTP(virtual_host), + HTTP(post), + HTTP(put), + HTTP(delete), + HTTP(failure), + HTTP(connection), + HTTP(persist_connection), + HTTP(connection_async), + HTTP(close_detection), + HTTP(close_detection_delay), HTTP_LEGACY(bad_request), - HTTP_LEGACY(incomplete), - HTTP_LEGACY(incomplete_timeout), + HTTP(incomplete), + HTTP(incomplete_timeout), { "terminate_chunked", run_legacy_test_fn, TT_ISOLATED|TT_LEGACY, &legacy_setup, http_terminate_chunked_test }, From 353402a87ad41788997d4100bbf00bfc21693b4c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 3 Nov 2010 14:13:20 -0400 Subject: [PATCH 15/31] Rename the confusing "base" static variable in regress_http.c --- test/regress_http.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index a876b130..f0a7806a 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -67,7 +67,7 @@ static struct evhttp *http; /* set if a test needs to call loopexit on a base */ -static struct event_base *base; +static struct event_base *exit_base; static char const BASIC_REQUEST_BODY[] = "This is funny"; @@ -246,8 +246,8 @@ http_readcb(struct bufferevent *bev, void *arg) out: evhttp_request_free(req); bufferevent_disable(bev, EV_READ); - if (base) - event_base_loopexit(base, NULL); + if (exit_base) + event_base_loopexit(exit_base, NULL); else if (my_base) event_base_loopexit(my_base, NULL); else @@ -711,7 +711,7 @@ _http_connection_test(struct basic_test_data *data, int persistent) tt_assert(evhttp_connection_get_base(evcon) == data->base); - base = data->base; + exit_base = data->base; /* * At this point, we want to schedule a request to the HTTP * server using our make request method. @@ -804,7 +804,7 @@ http_connection_async_test(void *arg) ev_uint16_t portnum = 0; char address[64]; - base = data->base; + exit_base = data->base; tt_assert(regress_dnsserver(data->base, &portnum, search_table)); dns_base = evdns_base_new(data->base, 0/* init name servers */); @@ -923,7 +923,7 @@ http_cancel_test(void *arg) struct evhttp_request *req = NULL; struct timeval tv; - base = data->base; + exit_base = data->base; test_ok = 0; @@ -1017,8 +1017,8 @@ http_request_done(struct evhttp_request *req, void *arg) } test_ok = 1; - if (base) - event_base_loopexit(base, NULL); + if (exit_base) + event_base_loopexit(exit_base, NULL); else event_loopexit(NULL); } @@ -1048,7 +1048,7 @@ http_virtual_host_test(void *arg) struct evhttp_request *req = NULL; struct evhttp *second = NULL, *third = NULL; - base = data->base; + exit_base = data->base; http = http_setup(&port, data->base); @@ -2286,7 +2286,7 @@ static void http_incomplete_readcb(struct bufferevent *bev, void *arg) { test_ok = -1; - event_base_loopexit(base,NULL); + event_base_loopexit(exit_base,NULL); } static void @@ -2296,7 +2296,7 @@ http_incomplete_errorcb(struct bufferevent *bev, short what, void *arg) test_ok++; else test_ok = -2; - event_base_loopexit(base,NULL); + event_base_loopexit(exit_base,NULL); } static void @@ -2323,7 +2323,7 @@ _http_incomplete_test(struct basic_test_data *data, int use_timeout) ev_uint16_t port = 0; struct timeval tv_start, tv_end; - base = data->base; + exit_base = data->base; test_ok = 0; From 9bb8239375b78a7be65ce17b4545159590894dc3 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 3 Nov 2010 14:31:23 -0400 Subject: [PATCH 16/31] Convert the rest of the http tests to be non-legacy unit tests. --- test/regress_http.c | 240 ++++++++++++++++++++++++-------------------- 1 file changed, 132 insertions(+), 108 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index f0a7806a..36e74e8c 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -311,6 +311,7 @@ static char const* const CHUNKS[] = { }; struct chunk_req_state { + struct event_base *base; struct evhttp_request *req; int i; }; @@ -327,7 +328,7 @@ http_chunked_trickle_cb(evutil_socket_t fd, short events, void *arg) evbuffer_free(evb); if (++state->i < (int) (sizeof(CHUNKS)/sizeof(CHUNKS[0]))) { - event_base_once(NULL, -1, EV_TIMEOUT, + event_base_once(state->base, -1, EV_TIMEOUT, http_chunked_trickle_cb, state, &when); } else { evhttp_send_reply_end(state->req); @@ -344,6 +345,7 @@ http_chunked_cb(struct evhttp_request *req, void *arg) memset(state, 0, sizeof(struct chunk_req_state)); state->req = req; + state->base = arg; if (strcmp(evhttp_request_uri(req), "/streamed") == 0) { evhttp_add_header(req->output_headers, "Content-Length", "39"); @@ -531,12 +533,13 @@ static void http_badreq_successcb(evutil_socket_t fd, short what, void *arg) { event_debug(("%s: called (what=%04x, arg=%p)", __func__, what, arg)); - event_loopexit(NULL); + event_base_loopexit(exit_base, NULL); } static void -http_bad_request_test(void) +http_bad_request_test(void *arg) { + struct basic_test_data *data = arg; struct timeval tv; struct bufferevent *bev = NULL; evutil_socket_t fd; @@ -544,10 +547,9 @@ http_bad_request_test(void) ev_uint16_t port=0, port2=0; test_ok = 0; + exit_base = data->base; - /* fprintf(stdout, "Testing \"Bad Request\" on connection close: "); */ - - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); /* bind to a second socket */ if (http_bind(http, &port2) == -1) @@ -557,9 +559,9 @@ http_bad_request_test(void) fd = http_connect("127.0.0.1", port); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(data->base, fd, 0); bufferevent_setcb(bev, http_badreq_readcb, http_writecb, - http_badreq_errorcb, NULL); + http_badreq_errorcb, data->base); bufferevent_enable(bev, EV_READ); /* real NULL request */ @@ -568,9 +570,9 @@ http_bad_request_test(void) shutdown(fd, SHUT_WR); timerclear(&tv); tv.tv_usec = 10000; - event_base_once(NULL, -1, EV_TIMEOUT, http_badreq_successcb, bev, &tv); + event_base_once(data->base, -1, EV_TIMEOUT, http_badreq_successcb, bev, &tv); - event_dispatch(); + event_base_dispatch(data->base); bufferevent_free(bev); evutil_closesocket(fd); @@ -586,9 +588,9 @@ http_bad_request_test(void) fd = http_connect("127.0.0.1", port2); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(data->base, fd, 0); bufferevent_setcb(bev, http_badreq_readcb, http_writecb, - http_badreq_errorcb, NULL); + http_badreq_errorcb, data->base); bufferevent_enable(bev, EV_READ); /* first half of the http request */ @@ -601,9 +603,9 @@ http_bad_request_test(void) timerclear(&tv); tv.tv_usec = 10000; - event_base_once(NULL, -1, EV_TIMEOUT, http_badreq_successcb, bev, &tv); + event_base_once(data->base, -1, EV_TIMEOUT, http_badreq_successcb, bev, &tv); - event_dispatch(); + event_base_dispatch(data->base); tt_int_op(test_ok, ==, 2); @@ -1189,6 +1191,7 @@ http_dispatcher_cb(struct evhttp_request *req, void *arg) static void http_dispatcher_test_done(struct evhttp_request *req, void *arg) { + struct event_base *base = arg; const char *what = "DISPATCHER_TEST"; if (req->response_code != HTTP_OK) { @@ -1213,21 +1216,22 @@ http_dispatcher_test_done(struct evhttp_request *req, void *arg) } test_ok = 1; - event_loopexit(NULL); + event_base_loopexit(base, NULL); } static void -http_dispatcher_test(void) +http_dispatcher_test(void *arg) { + struct basic_test_data *data = arg; ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); /* also bind to local host */ @@ -1238,7 +1242,7 @@ http_dispatcher_test(void) * server using our make request method. */ - req = evhttp_request_new(http_dispatcher_test_done, NULL); + req = evhttp_request_new(http_dispatcher_test_done, data->base); tt_assert(req); /* Add the information that we care about */ @@ -1248,7 +1252,7 @@ http_dispatcher_test(void) tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -1657,19 +1661,21 @@ http_close_detection_delay_test(void *arg) } static void -http_highport_test(void) +http_highport_test(void *arg) { + struct basic_test_data *data = arg; int i = -1; struct evhttp *myhttp = NULL; /* Try a few different ports */ for (i = 0; i < 50; ++i) { - myhttp = evhttp_start("127.0.0.1", 65535 - i); - if (myhttp != NULL) { + myhttp = evhttp_new(data->base); + if (evhttp_bind_socket(myhttp, "127.0.0.1", 65535 - i) == 0) { test_ok = 1; evhttp_free(myhttp); return; } + evhttp_free(myhttp); } tt_fail_msg("Couldn't get a high port"); @@ -2476,7 +2482,7 @@ http_chunked_errorcb(struct bufferevent *bev, short what, void *arg) } out: - event_loopexit(NULL); + event_base_loopexit(arg, NULL); } static void @@ -2516,12 +2522,13 @@ http_chunked_request_done(struct evhttp_request *req, void *arg) } test_ok = 1; - event_loopexit(NULL); + event_base_loopexit(arg, NULL); } static void -http_chunk_out_test(void) +http_chunk_out_test(void *arg) { + struct basic_test_data *data = arg; struct bufferevent *bev; evutil_socket_t fd; const char *http_request; @@ -2531,17 +2538,18 @@ http_chunk_out_test(void) struct evhttp_request *req = NULL; int i; + exit_base = data->base; test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); fd = http_connect("127.0.0.1", port); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(data->base, fd, 0); bufferevent_setcb(bev, http_chunked_readcb, http_chunked_writecb, - http_chunked_errorcb, NULL); + http_chunked_errorcb, data->base); http_request = "GET /chunked HTTP/1.1\r\n" @@ -2553,7 +2561,7 @@ http_chunk_out_test(void) evutil_gettimeofday(&tv_start, NULL); - event_dispatch(); + event_base_dispatch(data->base); bufferevent_free(bev); @@ -2565,13 +2573,13 @@ http_chunk_out_test(void) tt_int_op(test_ok, ==, 2); /* now try again with the regular connection object */ - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); /* make two requests to check the keepalive behavior */ for (i = 0; i < 2; i++) { test_ok = 0; - req = evhttp_request_new(http_chunked_request_done, NULL); + req = evhttp_request_new(http_chunked_request_done,data->base); /* Add the information that we care about */ evhttp_add_header(req->output_headers, "Host", "somehost"); @@ -2582,7 +2590,7 @@ http_chunk_out_test(void) tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); tt_assert(test_ok == 1); } @@ -2595,17 +2603,19 @@ http_chunk_out_test(void) } static void -http_stream_out_test(void) +http_stream_out_test(void *arg) { + struct basic_test_data *data = arg; ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; test_ok = 0; + exit_base = data->base; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); /* @@ -2625,7 +2635,7 @@ http_stream_out_test(void) tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -2655,14 +2665,14 @@ http_stream_in_done(struct evhttp_request *req, void *arg) exit(1); } - event_loopexit(NULL); + event_base_loopexit(exit_base, NULL); } /** * Makes a request and reads the response in chunks. */ static void -_http_stream_in_test(char const *url, +_http_stream_in_test(struct basic_test_data *data, char const *url, size_t expected_len, char const *expected) { struct evhttp_connection *evcon; @@ -2670,9 +2680,10 @@ _http_stream_in_test(char const *url, struct evhttp_request *req = NULL; ev_uint16_t port = 0; - http = http_setup(&port, NULL); + exit_base = data->base; + http = http_setup(&port, data->base); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL,"127.0.0.1", port); tt_assert(evcon); req = evhttp_request_new(http_stream_in_done, reply); @@ -2683,7 +2694,7 @@ _http_stream_in_test(char const *url, tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); if (evbuffer_get_length(reply) != expected_len) { TT_DIE(("reply length %lu; expected %lu; FAILED (%s)\n", @@ -2707,12 +2718,12 @@ _http_stream_in_test(char const *url, } static void -http_stream_in_test(void) +http_stream_in_test(void *arg) { - _http_stream_in_test("/chunked", 13 + 18 + 8, + _http_stream_in_test(arg, "/chunked", 13 + 18 + 8, "This is funnybut not hilarious.bwv 1052"); - _http_stream_in_test("/test", strlen(BASIC_REQUEST_BODY), + _http_stream_in_test(arg, "/test", strlen(BASIC_REQUEST_BODY), BASIC_REQUEST_BODY); } @@ -2723,7 +2734,7 @@ http_stream_in_cancel_chunk(struct evhttp_request *req, void *arg) end: evhttp_cancel_request(req); - event_loopexit(NULL); + event_base_loopexit(arg, NULL); } static void @@ -2734,18 +2745,19 @@ http_stream_in_cancel_done(struct evhttp_request *req, void *arg) } static void -http_stream_in_cancel_test(void) +http_stream_in_cancel_test(void *arg) { + struct basic_test_data *data = arg; struct evhttp_connection *evcon; struct evhttp_request *req = NULL; ev_uint16_t port = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); - req = evhttp_request_new(http_stream_in_cancel_done, NULL); + req = evhttp_request_new(http_stream_in_cancel_done, data->base); evhttp_request_set_chunked_cb(req, http_stream_in_cancel_chunk); /* We give ownership of the request to the connection */ @@ -2753,7 +2765,7 @@ http_stream_in_cancel_test(void) tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); test_ok = 1; end: @@ -2775,32 +2787,35 @@ http_connection_retry_done(struct evhttp_request *req, void *arg) test_ok = 1; end: - event_loopexit(NULL); + event_base_loopexit(arg,NULL); } +static struct event_base *http_make_web_server_base=NULL; static void http_make_web_server(evutil_socket_t fd, short what, void *arg) { ev_uint16_t port = *(ev_uint16_t*)arg; - http = http_setup(&port, NULL); + http = http_setup(&port, http_make_web_server_base); } static void -http_connection_retry_test(void) +http_connection_retry_test(void *arg) { + struct basic_test_data *data = arg; ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; struct timeval tv, tv_start, tv_end; + exit_base = data->base; test_ok = 0; /* auto detect a port */ - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); evhttp_free(http); http = NULL; - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); evhttp_connection_set_timeout(evcon, 1); @@ -2812,7 +2827,7 @@ http_connection_retry_test(void) * server using our make request method. */ - req = evhttp_request_new(http_connection_retry_done, NULL); + req = evhttp_request_new(http_connection_retry_done, data->base); tt_assert(req); /* Add the information that we care about */ @@ -2824,7 +2839,7 @@ http_connection_retry_test(void) } evutil_gettimeofday(&tv_start, NULL); - event_dispatch(); + event_base_dispatch(data->base); evutil_gettimeofday(&tv_end, NULL); evutil_timersub(&tv_end, &tv_start, &tv_end); tt_int_op(tv_end.tv_sec, <, 1); @@ -2839,7 +2854,7 @@ http_connection_retry_test(void) evhttp_connection_set_timeout(evcon, 1); evhttp_connection_set_retries(evcon, 1); - req = evhttp_request_new(http_connection_retry_done, NULL); + req = evhttp_request_new(http_connection_retry_done, data->base); tt_assert(req); /* Add the information that we care about */ @@ -2851,7 +2866,7 @@ http_connection_retry_test(void) } evutil_gettimeofday(&tv_start, NULL); - event_dispatch(); + event_base_dispatch(data->base); evutil_gettimeofday(&tv_end, NULL); evutil_timersub(&tv_end, &tv_start, &tv_end); tt_int_op(tv_end.tv_sec, >, 1); @@ -2868,7 +2883,7 @@ http_connection_retry_test(void) evhttp_connection_set_timeout(evcon, 1); evhttp_connection_set_retries(evcon, 3); - req = evhttp_request_new(http_dispatcher_test_done, NULL); + req = evhttp_request_new(http_dispatcher_test_done, data->base); tt_assert(req); /* Add the information that we care about */ @@ -2884,10 +2899,11 @@ http_connection_retry_test(void) */ evutil_timerclear(&tv); tv.tv_sec = 1; - event_base_once(NULL, -1, EV_TIMEOUT, http_make_web_server, &port, &tv); + http_make_web_server_base = data->base; + event_base_once(data->base, -1, EV_TIMEOUT, http_make_web_server, &port, &tv); evutil_gettimeofday(&tv_start, NULL); - event_dispatch(); + event_base_dispatch(data->base); evutil_gettimeofday(&tv_end, NULL); evutil_timersub(&tv_end, &tv_start, &tv_end); @@ -2931,8 +2947,9 @@ http_primitives(void *ptr) } static void -http_multi_line_header_test(void) +http_multi_line_header_test(void *arg) { + struct basic_test_data *data = arg; struct bufferevent *bev= NULL; evutil_socket_t fd = -1; const char *http_start_request; @@ -2940,14 +2957,14 @@ http_multi_line_header_test(void) test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); fd = http_connect("127.0.0.1", port); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(data->base, fd, 0); bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, NULL); + http_errorcb, data->base); http_start_request = "GET /test HTTP/1.1\r\n" @@ -2961,7 +2978,7 @@ http_multi_line_header_test(void) bufferevent_write(bev, http_start_request, strlen(http_start_request)); - event_dispatch(); + event_base_dispatch(data->base); tt_int_op(test_ok, ==, 4); end: @@ -2982,21 +2999,22 @@ http_request_bad(struct evhttp_request *req, void *arg) } test_ok = 1; - event_loopexit(NULL); + event_base_loopexit(arg, NULL); } static void -http_negative_content_length_test(void) +http_negative_content_length_test(void *arg) { + struct basic_test_data *data = arg; ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); /* @@ -3004,7 +3022,7 @@ http_negative_content_length_test(void) * server using our make request method. */ - req = evhttp_request_new(http_request_bad, NULL); + req = evhttp_request_new(http_request_bad, data->base); /* Cause the response to have a negative content-length */ evhttp_add_header(req->output_headers, "X-Negative", "makeitso"); @@ -3014,7 +3032,7 @@ http_negative_content_length_test(void) tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -3030,12 +3048,13 @@ http_data_length_constraints_test_done(struct evhttp_request *req, void *arg) tt_assert(req); tt_int_op(req->response_code, ==, HTTP_BADREQUEST); end: - event_loopexit(NULL); + event_base_loopexit(arg, NULL); } static void -http_data_length_constraints_test(void) +http_data_length_constraints_test(void *arg) { + struct basic_test_data *data = arg; ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; @@ -3043,9 +3062,9 @@ http_data_length_constraints_test(void) test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); - evcon = evhttp_connection_new("127.0.0.1", port); + evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); /* also bind to local host */ @@ -3056,7 +3075,7 @@ http_data_length_constraints_test(void) * server using our make request method. */ - req = evhttp_request_new(http_data_length_constraints_test_done, NULL); + req = evhttp_request_new(http_data_length_constraints_test_done, data->base); tt_assert(req); memset(long_str, 'a', 8192); @@ -3069,9 +3088,9 @@ http_data_length_constraints_test(void) if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); - req = evhttp_request_new(http_data_length_constraints_test_done, NULL); + req = evhttp_request_new(http_data_length_constraints_test_done, data->base); tt_assert(req); evhttp_add_header(req->output_headers, "Host", "somehost"); @@ -3079,16 +3098,16 @@ http_data_length_constraints_test(void) if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, long_str) == -1) { tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); evhttp_set_max_body_size(http, 8190); - req = evhttp_request_new(http_data_length_constraints_test_done, NULL); + req = evhttp_request_new(http_data_length_constraints_test_done, data->base); evhttp_add_header(req->output_headers, "Host", "somehost"); evbuffer_add_printf(req->output_buffer, "%s", long_str); if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/") == -1) { tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); test_ok = 1; end: @@ -3103,11 +3122,12 @@ http_data_length_constraints_test(void) */ struct terminate_state { + struct event_base *base; struct evhttp_request *req; struct bufferevent *bev; evutil_socket_t fd; int gotclosecb: 1; -} terminate_state; +}; static void terminate_chunked_trickle_cb(evutil_socket_t fd, short events, void *arg) @@ -3119,7 +3139,7 @@ terminate_chunked_trickle_cb(evutil_socket_t fd, short events, void *arg) if (evhttp_request_get_connection(state->req) == NULL) { test_ok = 1; evhttp_request_free(state->req); - event_loopexit(NULL); + event_base_loopexit(state->base,NULL); return; } @@ -3130,7 +3150,9 @@ terminate_chunked_trickle_cb(evutil_socket_t fd, short events, void *arg) tv.tv_sec = 0; tv.tv_usec = 3000; - event_base_once(NULL, -1, EV_TIMEOUT, terminate_chunked_trickle_cb, arg, &tv); + EVUTIL_ASSERT(state); + EVUTIL_ASSERT(state->base); + event_base_once(state->base, -1, EV_TIMEOUT, terminate_chunked_trickle_cb, arg, &tv); } static void @@ -3157,7 +3179,7 @@ terminate_chunked_cb(struct evhttp_request *req, void *arg) tv.tv_sec = 0; tv.tv_usec = 3000; - event_base_once(NULL, -1, EV_TIMEOUT, terminate_chunked_trickle_cb, arg, &tv); + event_base_once(state->base, -1, EV_TIMEOUT, terminate_chunked_trickle_cb, arg, &tv); } static void @@ -3177,17 +3199,19 @@ terminate_readcb(struct bufferevent *bev, void *arg) static void -http_terminate_chunked_test(void) +http_terminate_chunked_test(void *arg) { + struct basic_test_data *data = arg; struct bufferevent *bev = NULL; struct timeval tv; const char *http_request; ev_uint16_t port = 0; evutil_socket_t fd = -1; + struct terminate_state terminate_state; test_ok = 0; - http = http_setup(&port, NULL); + http = http_setup(&port, data->base); evhttp_del_cb(http, "/test"); tt_assert(evhttp_set_cb(http, "/test", terminate_chunked_cb, &terminate_state) == 0); @@ -3195,10 +3219,12 @@ http_terminate_chunked_test(void) fd = http_connect("127.0.0.1", port); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(data->base, fd, 0); bufferevent_setcb(bev, terminate_readcb, http_writecb, - http_errorcb, NULL); + http_errorcb, data->base); + memset(&terminate_state, 0, sizeof(terminate_state)); + terminate_state.base = data->base; terminate_state.fd = fd; terminate_state.bev = bev; terminate_state.gotclosecb = 0; @@ -3211,10 +3237,10 @@ http_terminate_chunked_test(void) bufferevent_write(bev, http_request, strlen(http_request)); evutil_timerclear(&tv); tv.tv_usec = 10000; - event_base_once(NULL, -1, EV_TIMEOUT, terminate_chunked_client, &terminate_state, + event_base_once(data->base, -1, EV_TIMEOUT, terminate_chunked_client, &terminate_state, &tv); - event_dispatch(); + event_base_dispatch(data->base); if (terminate_state.gotclosecb == 0) test_ok = 0; @@ -3252,25 +3278,23 @@ struct testcase_t http_testcases[] = { HTTP(connection_async), HTTP(close_detection), HTTP(close_detection_delay), - HTTP_LEGACY(bad_request), + HTTP(bad_request), HTTP(incomplete), HTTP(incomplete_timeout), - { "terminate_chunked", run_legacy_test_fn, - TT_ISOLATED|TT_LEGACY, &legacy_setup, - http_terminate_chunked_test }, + HTTP(terminate_chunked), - HTTP_LEGACY(highport), - HTTP_LEGACY(dispatcher), - HTTP_LEGACY(multi_line_header), - HTTP_LEGACY(negative_content_length), - HTTP_LEGACY(chunk_out), - HTTP_LEGACY(stream_out), + HTTP(highport), + HTTP(dispatcher), + HTTP(multi_line_header), + HTTP(negative_content_length), + HTTP(chunk_out), + HTTP(stream_out), - HTTP_LEGACY(stream_in), - HTTP_LEGACY(stream_in_cancel), + HTTP(stream_in), + HTTP(stream_in_cancel), - HTTP_LEGACY(connection_retry), - HTTP_LEGACY(data_length_constraints), + HTTP(connection_retry), + HTTP(data_length_constraints), END_OF_TESTCASES }; From c91622d18cb4dda945d92b983a712d1c3a37b45e Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 3 Nov 2010 15:04:44 -0400 Subject: [PATCH 17/31] Stop using event_compat.h in regress_http --- test/regress_http.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index 36e74e8c..2f351f71 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -53,7 +53,6 @@ #include "event2/dns.h" #include "event2/event.h" -#include "event2/event_compat.h" #include "event2/http.h" #include "event2/http_compat.h" #include "event2/http_struct.h" @@ -250,8 +249,10 @@ http_readcb(struct bufferevent *bev, void *arg) event_base_loopexit(exit_base, NULL); else if (my_base) event_base_loopexit(my_base, NULL); - else - event_loopexit(NULL); + else { + fprintf(stderr, "No way to exit loop!\n"); + exit(1); + } } } @@ -269,7 +270,7 @@ static void http_errorcb(struct bufferevent *bev, short what, void *arg) { test_ok = -2; - event_loopexit(NULL); + event_base_loopexit(arg, NULL); } static void @@ -499,7 +500,7 @@ http_badreq_readcb(struct bufferevent *bev, void *arg) if (evbuffer_contains(bufferevent_get_input(bev), bad_request)) { TT_FAIL(("%s:bad request detected", __func__)); bufferevent_disable(bev, EV_READ); - event_loopexit(NULL); + event_base_loopexit(arg, NULL); return; } @@ -1019,10 +1020,8 @@ http_request_done(struct evhttp_request *req, void *arg) } test_ok = 1; - if (exit_base) - event_base_loopexit(exit_base, NULL); - else - event_loopexit(NULL); + EVUTIL_ASSERT(exit_base); + event_base_loopexit(exit_base, NULL); } static void @@ -1034,10 +1033,8 @@ http_request_expect_error(struct evhttp_request *req, void *arg) } test_ok = 1; - if (arg) - event_base_loopexit(arg, NULL); - else - event_loopexit(NULL); + EVUTIL_ASSERT(arg); + event_base_loopexit(arg, NULL); } /* test virtual hosts */ @@ -1165,10 +1162,8 @@ http_request_empty_done(struct evhttp_request *req, void *arg) } test_ok = 1; - if (arg) - event_base_loopexit(arg, NULL); - else - event_loopexit(NULL); + EVUTIL_ASSERT(arg); + event_base_loopexit(arg, NULL); } /* @@ -2250,15 +2245,15 @@ http_base_test(void *ptr) ev_uint16_t port = 0; test_ok = 0; - base = event_init(); + base = event_base_new(); http = http_setup(&port, base); fd = http_connect("127.0.0.1", port); /* Stupid thing to send a request */ - bev = bufferevent_socket_new(NULL, fd, 0); + bev = bufferevent_socket_new(base, fd, 0); bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, NULL); + http_errorcb, base); bufferevent_base_set(base, bev); http_request = @@ -3261,7 +3256,7 @@ http_terminate_chunked_test(void *arg) struct testcase_t http_testcases[] = { { "primitives", http_primitives, 0, NULL, NULL }, - { "base", http_base_test, TT_FORK|TT_NEED_BASE, NULL, NULL }, + { "base", http_base_test, TT_FORK, NULL, NULL }, { "bad_headers", http_bad_header_test, 0, NULL, NULL }, { "parse_query", http_parse_query_test, 0, NULL, NULL }, { "parse_uri", http_parse_uri_test, 0, NULL, NULL }, From 22e0a9b2e8f752bfdcff7b0d96065c2da391bf03 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 3 Nov 2010 15:12:08 -0400 Subject: [PATCH 18/31] Add evhttp_response_code to remove one more reason to include http_struct.h --- http.c | 6 ++++++ include/event2/http.h | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/http.c b/http.c index 2a1cb670..aafb509d 100644 --- a/http.c +++ b/http.c @@ -3171,6 +3171,12 @@ evhttp_request_get_command(const struct evhttp_request *req) { return (req->type); } +int +evhttp_request_get_response_code(const struct evhttp_request *req) +{ + return req->response_code; +} + /** Returns the input headers */ struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req) { diff --git a/include/event2/http.h b/include/event2/http.h index d8a716ae..e0fdefe0 100644 --- a/include/event2/http.h +++ b/include/event2/http.h @@ -466,11 +466,13 @@ int evhttp_make_request(struct evhttp_connection *evcon, */ void evhttp_cancel_request(struct evhttp_request *req); - /** Returns the request URI */ const char *evhttp_request_get_uri(const struct evhttp_request *req); /** Returns the request command */ enum evhttp_cmd_type evhttp_request_get_command(const struct evhttp_request *req); + +int evhttp_request_get_response_code(const struct evhttp_request *req); + /** Returns the input headers */ struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req); /** Returns the output headers */ From 0b137f452ee4516d479ea61ae54d458888cfa8e9 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 3 Nov 2010 15:14:29 -0400 Subject: [PATCH 19/31] Stop accessing http request struct directly from in the unit tests. --- test/regress_http.c | 195 ++++++++++++++++++++++---------------------- 1 file changed, 97 insertions(+), 98 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index 2f351f71..e93f041d 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -55,7 +55,6 @@ #include "event2/event.h" #include "event2/http.h" #include "event2/http_compat.h" -#include "event2/http_struct.h" #include "event2/buffer.h" #include "event2/bufferevent.h" #include "log-internal.h" @@ -228,7 +227,7 @@ http_readcb(struct bufferevent *bev, void *arg) struct evhttp_request *req = evhttp_request_new(NULL, NULL); enum message_read_status done; - req->kind = EVHTTP_RESPONSE; + //req->kind = EVHTTP_RESPONSE; done = evhttp_parse_firstline(req, bufferevent_get_input(bev)); if (done != ALL_DATA_READ) goto out; @@ -238,7 +237,7 @@ http_readcb(struct bufferevent *bev, void *arg) goto out; if (done == 1 && - evhttp_find_header(req->input_headers, + evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") != NULL) test_ok++; @@ -277,25 +276,25 @@ static void http_basic_cb(struct evhttp_request *req, void *arg) { struct evbuffer *evb = evbuffer_new(); - int empty = evhttp_find_header(req->input_headers, "Empty") != NULL; + int empty = evhttp_find_header(evhttp_request_get_input_headers(req), "Empty") != NULL; event_debug(("%s: called\n", __func__)); evbuffer_add_printf(evb, BASIC_REQUEST_BODY); /* For multi-line headers test */ { const char *multi = - evhttp_find_header(req->input_headers,"X-multi"); + evhttp_find_header(evhttp_request_get_input_headers(req),"X-multi"); if (multi) { if (strcmp("END", multi + strlen(multi) - 3) == 0) test_ok++; - if (evhttp_find_header(req->input_headers, "X-Last")) + if (evhttp_find_header(evhttp_request_get_input_headers(req), "X-Last")) test_ok++; } } /* injecting a bad content-length */ - if (evhttp_find_header(req->input_headers, "X-Negative")) - evhttp_add_header(req->output_headers, + if (evhttp_find_header(evhttp_request_get_input_headers(req), "X-Negative")) + evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Length", "-100"); /* allow sending of an empty reply */ @@ -349,7 +348,7 @@ http_chunked_cb(struct evhttp_request *req, void *arg) state->base = arg; if (strcmp(evhttp_request_uri(req), "/streamed") == 0) { - evhttp_add_header(req->output_headers, "Content-Length", "39"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Length", "39"); } /* generate a chunked/streamed reply */ @@ -469,7 +468,7 @@ http_badreq_cb(struct evhttp_request *req, void *arg) { struct evbuffer *buf = evbuffer_new(); - evhttp_add_header(req->output_headers, "Content-Type", "text/xml; charset=UTF-8"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "text/xml; charset=UTF-8"); evbuffer_add_printf(buf, "Hello, %s!", "127.0.0.1"); evhttp_send_reply(req, HTTP_OK, "OK", buf); @@ -508,7 +507,7 @@ http_badreq_readcb(struct bufferevent *bev, void *arg) struct evhttp_request *req = evhttp_request_new(NULL, NULL); enum message_read_status done; - req->kind = EVHTTP_RESPONSE; + //req->kind = EVHTTP_RESPONSE; done = evhttp_parse_firstline(req, bufferevent_get_input(bev)); if (done != ALL_DATA_READ) goto out; @@ -518,7 +517,7 @@ http_badreq_readcb(struct bufferevent *bev, void *arg) goto out; if (done == 1 && - evhttp_find_header(req->input_headers, + evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") != NULL) test_ok++; @@ -637,10 +636,10 @@ static void http_delete_cb(struct evhttp_request *req, void *arg) { struct evbuffer *evb = evbuffer_new(); - int empty = evhttp_find_header(req->input_headers, "Empty") != NULL; + int empty = evhttp_find_header(evhttp_request_get_input_headers(req), "Empty") != NULL; /* Expecting a DELETE request */ - if (req->type != EVHTTP_REQ_DELETE) { + if (evhttp_request_get_command(req) != EVHTTP_REQ_DELETE) { fprintf(stdout, "FAILED (delete type)\n"); exit(1); } @@ -723,7 +722,7 @@ _http_connection_test(struct basic_test_data *data, int persistent) req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { @@ -741,14 +740,14 @@ _http_connection_test(struct basic_test_data *data, int persistent) req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* * if our connections are not supposed to be persistent; request * a close from the server. */ if (!persistent) - evhttp_add_header(req->output_headers, "Connection", "close"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Connection", "close"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { @@ -763,7 +762,7 @@ _http_connection_test(struct basic_test_data *data, int persistent) req = evhttp_request_new(http_request_empty_done, data->base); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Empty", "itis"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Empty", "itis"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { @@ -833,7 +832,7 @@ http_connection_async_test(void *arg) req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { @@ -851,13 +850,13 @@ http_connection_async_test(void *arg) req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* * if our connections are not supposed to be persistent; request * a close from the server. */ - evhttp_add_header(req->output_headers, "Connection", "close"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Connection", "close"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { @@ -872,7 +871,7 @@ http_connection_async_test(void *arg) req = evhttp_request_new(http_request_empty_done, data->base); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Empty", "itis"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Empty", "itis"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { @@ -943,7 +942,7 @@ http_cancel_test(void *arg) req = evhttp_request_new(http_request_never_call, NULL); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* We give ownership of the request to the connection */ tt_int_op(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/delay"), @@ -965,7 +964,7 @@ http_cancel_test(void *arg) req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* We give ownership of the request to the connection */ tt_int_op(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test"), @@ -979,7 +978,7 @@ http_cancel_test(void *arg) req = evhttp_request_new(http_request_empty_done, data->base); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Empty", "itis"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Empty", "itis"); /* We give ownership of the request to the connection */ tt_int_op(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test"), @@ -999,22 +998,22 @@ http_request_done(struct evhttp_request *req, void *arg) { const char *what = arg; - if (req->response_code != HTTP_OK) { + if (evhttp_request_get_response_code(req) != HTTP_OK) { fprintf(stderr, "FAILED\n"); exit(1); } - if (evhttp_find_header(req->input_headers, "Content-Type") == NULL) { + if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") == NULL) { fprintf(stderr, "FAILED\n"); exit(1); } - if (evbuffer_get_length(req->input_buffer) != strlen(what)) { + if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(what)) { fprintf(stderr, "FAILED\n"); exit(1); } - if (evbuffer_datacmp(req->input_buffer, what) != 0) { + if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), what) != 0) { fprintf(stderr, "FAILED\n"); exit(1); } @@ -1027,7 +1026,7 @@ http_request_done(struct evhttp_request *req, void *arg) static void http_request_expect_error(struct evhttp_request *req, void *arg) { - if (req->response_code == HTTP_OK) { + if (evhttp_request_get_response_code(req) == HTTP_OK) { fprintf(stderr, "FAILED\n"); exit(1); } @@ -1072,7 +1071,7 @@ http_virtual_host_test(void *arg) req = evhttp_request_new(http_request_expect_error, data->base); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, @@ -1090,7 +1089,7 @@ http_virtual_host_test(void *arg) req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "foo.com"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "foo.com"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, @@ -1109,7 +1108,7 @@ http_virtual_host_test(void *arg) req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "bar.magic.foo.com"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "bar.magic.foo.com"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, @@ -1134,29 +1133,29 @@ http_virtual_host_test(void *arg) static void http_request_empty_done(struct evhttp_request *req, void *arg) { - if (req->response_code != HTTP_OK) { + if (evhttp_request_get_response_code(req) != HTTP_OK) { fprintf(stderr, "FAILED\n"); exit(1); } - if (evhttp_find_header(req->input_headers, "Date") == NULL) { + if (evhttp_find_header(evhttp_request_get_input_headers(req), "Date") == NULL) { fprintf(stderr, "FAILED\n"); exit(1); } - if (evhttp_find_header(req->input_headers, "Content-Length") == NULL) { + if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Length") == NULL) { fprintf(stderr, "FAILED\n"); exit(1); } - if (strcmp(evhttp_find_header(req->input_headers, "Content-Length"), + if (strcmp(evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Length"), "0")) { fprintf(stderr, "FAILED\n"); exit(1); } - if (evbuffer_get_length(req->input_buffer) != 0) { + if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != 0) { fprintf(stderr, "FAILED\n"); exit(1); } @@ -1189,23 +1188,23 @@ http_dispatcher_test_done(struct evhttp_request *req, void *arg) struct event_base *base = arg; const char *what = "DISPATCHER_TEST"; - if (req->response_code != HTTP_OK) { + if (evhttp_request_get_response_code(req) != HTTP_OK) { fprintf(stderr, "FAILED\n"); exit(1); } - if (evhttp_find_header(req->input_headers, "Content-Type") == NULL) { + if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") == NULL) { fprintf(stderr, "FAILED (content type)\n"); exit(1); } - if (evbuffer_get_length(req->input_buffer) != strlen(what)) { + if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(what)) { fprintf(stderr, "FAILED (length %lu vs %lu)\n", - (unsigned long)evbuffer_get_length(req->input_buffer), (unsigned long)strlen(what)); + (unsigned long)evbuffer_get_length(evhttp_request_get_input_buffer(req)), (unsigned long)strlen(what)); exit(1); } - if (evbuffer_datacmp(req->input_buffer, what) != 0) { + if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), what) != 0) { fprintf(stderr, "FAILED (data)\n"); exit(1); } @@ -1241,7 +1240,7 @@ http_dispatcher_test(void *arg) tt_assert(req); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { tt_abort_msg("Couldn't make request"); @@ -1288,8 +1287,8 @@ http_post_test(void *arg) tt_assert(req); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); - evbuffer_add_printf(req->output_buffer, POST_DATA); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); + evbuffer_add_printf(evhttp_request_get_output_buffer(req), POST_DATA); if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/postit") == -1) { tt_abort_msg("Couldn't make request"); @@ -1312,20 +1311,20 @@ http_post_cb(struct evhttp_request *req, void *arg) event_debug(("%s: called\n", __func__)); /* Yes, we are expecting a post request */ - if (req->type != EVHTTP_REQ_POST) { + if (evhttp_request_get_command(req) != EVHTTP_REQ_POST) { fprintf(stdout, "FAILED (post type)\n"); exit(1); } - if (evbuffer_get_length(req->input_buffer) != strlen(POST_DATA)) { + if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(POST_DATA)) { fprintf(stdout, "FAILED (length: %lu vs %lu)\n", - (unsigned long) evbuffer_get_length(req->input_buffer), (unsigned long) strlen(POST_DATA)); + (unsigned long) evbuffer_get_length(evhttp_request_get_input_buffer(req)), (unsigned long) strlen(POST_DATA)); exit(1); } - if (evbuffer_datacmp(req->input_buffer, POST_DATA) != 0) { + if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), POST_DATA) != 0) { fprintf(stdout, "FAILED (data)\n"); - fprintf(stdout, "Got :%s\n", evbuffer_pullup(req->input_buffer,-1)); + fprintf(stdout, "Got :%s\n", evbuffer_pullup(evhttp_request_get_input_buffer(req),-1)); fprintf(stdout, "Want:%s\n", POST_DATA); exit(1); } @@ -1349,24 +1348,24 @@ http_postrequest_done(struct evhttp_request *req, void *arg) exit(1); } - if (req->response_code != HTTP_OK) { + if (evhttp_request_get_response_code(req) != HTTP_OK) { fprintf(stderr, "FAILED (response code)\n"); exit(1); } - if (evhttp_find_header(req->input_headers, "Content-Type") == NULL) { + if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") == NULL) { fprintf(stderr, "FAILED (content type)\n"); exit(1); } - if (evbuffer_get_length(req->input_buffer) != strlen(what)) { + if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(what)) { fprintf(stderr, "FAILED (length %lu vs %lu)\n", - (unsigned long)evbuffer_get_length(req->input_buffer), (unsigned long)strlen(what)); + (unsigned long)evbuffer_get_length(evhttp_request_get_input_buffer(req)), (unsigned long)strlen(what)); exit(1); } - if (evbuffer_datacmp(req->input_buffer, what) != 0) { + if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), what) != 0) { fprintf(stderr, "FAILED (data)\n"); exit(1); } @@ -1406,8 +1405,8 @@ http_put_test(void *arg) tt_assert(req); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "someotherhost"); - evbuffer_add_printf(req->output_buffer, PUT_DATA); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "someotherhost"); + evbuffer_add_printf(evhttp_request_get_output_buffer(req), PUT_DATA); if (evhttp_make_request(evcon, req, EVHTTP_REQ_PUT, "/putit") == -1) { tt_abort_msg("Couldn't make request"); @@ -1430,20 +1429,20 @@ http_put_cb(struct evhttp_request *req, void *arg) event_debug(("%s: called\n", __func__)); /* Expecting a PUT request */ - if (req->type != EVHTTP_REQ_PUT) { + if (evhttp_request_get_command(req) != EVHTTP_REQ_PUT) { fprintf(stdout, "FAILED (put type)\n"); exit(1); } - if (evbuffer_get_length(req->input_buffer) != strlen(PUT_DATA)) { + if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(PUT_DATA)) { fprintf(stdout, "FAILED (length: %lu vs %lu)\n", - (unsigned long)evbuffer_get_length(req->input_buffer), (unsigned long)strlen(PUT_DATA)); + (unsigned long)evbuffer_get_length(evhttp_request_get_input_buffer(req)), (unsigned long)strlen(PUT_DATA)); exit(1); } - if (evbuffer_datacmp(req->input_buffer, PUT_DATA) != 0) { + if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), PUT_DATA) != 0) { fprintf(stdout, "FAILED (data)\n"); - fprintf(stdout, "Got :%s\n", evbuffer_pullup(req->input_buffer,-1)); + fprintf(stdout, "Got :%s\n", evbuffer_pullup(evhttp_request_get_input_buffer(req),-1)); fprintf(stdout, "Want:%s\n", PUT_DATA); exit(1); } @@ -1467,25 +1466,25 @@ http_putrequest_done(struct evhttp_request *req, void *arg) exit(1); } - if (req->response_code != HTTP_OK) { + if (evhttp_request_get_response_code(req) != HTTP_OK) { fprintf(stderr, "FAILED (response code)\n"); exit(1); } - if (evhttp_find_header(req->input_headers, "Content-Type") == NULL) { + if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") == NULL) { fprintf(stderr, "FAILED (content type)\n"); exit(1); } - if (evbuffer_get_length(req->input_buffer) != strlen(what)) { + if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(what)) { fprintf(stderr, "FAILED (length %lu vs %lu)\n", - (unsigned long)evbuffer_get_length(req->input_buffer), (unsigned long)strlen(what)); + (unsigned long)evbuffer_get_length(evhttp_request_get_input_buffer(req)), (unsigned long)strlen(what)); exit(1); } - if (evbuffer_datacmp(req->input_buffer, what) != 0) { + if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), what) != 0) { fprintf(stderr, "FAILED (data)\n"); exit(1); } @@ -1549,7 +1548,7 @@ close_detect_done(struct evhttp_request *req, void *arg) { struct timeval tv; tt_assert(req); - tt_assert(req->response_code == HTTP_OK); + tt_assert(evhttp_request_get_response_code(req) == HTTP_OK); test_ok = 1; @@ -1569,7 +1568,7 @@ close_detect_launch(evutil_socket_t fd, short what, void *arg) req = evhttp_request_new(close_detect_done, base); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { @@ -1584,7 +1583,7 @@ close_detect_cb(struct evhttp_request *req, void *arg) struct event_base *base = evhttp_connection_get_base(evcon); struct timeval tv; - if (req != NULL && req->response_code != HTTP_OK) { + if (req != NULL && evhttp_request_get_response_code(req) != HTTP_OK) { tt_abort_msg("Failed"); } @@ -1624,7 +1623,7 @@ _http_close_detection(struct basic_test_data *data, int with_delay) req = evhttp_request_new(close_detect_cb, evcon); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, @@ -2404,7 +2403,7 @@ http_chunked_errorcb(struct bufferevent *bev, short what, void *arg) const char *header; enum message_read_status done; - req->kind = EVHTTP_RESPONSE; + //req->kind = EVHTTP_RESPONSE; done = evhttp_parse_firstline(req, bufferevent_get_input(bev)); if (done != ALL_DATA_READ) goto out; @@ -2413,11 +2412,11 @@ http_chunked_errorcb(struct bufferevent *bev, short what, void *arg) if (done != ALL_DATA_READ) goto out; - header = evhttp_find_header(req->input_headers, "Transfer-Encoding"); + header = evhttp_find_header(evhttp_request_get_input_headers(req), "Transfer-Encoding"); if (header == NULL || strcmp(header, "chunked")) goto out; - header = evhttp_find_header(req->input_headers, "Connection"); + header = evhttp_find_header(evhttp_request_get_input_headers(req), "Connection"); if (header == NULL || strcmp(header, "close")) goto out; @@ -2493,23 +2492,23 @@ http_chunked_writecb(struct bufferevent *bev, void *arg) static void http_chunked_request_done(struct evhttp_request *req, void *arg) { - if (req->response_code != HTTP_OK) { + if (evhttp_request_get_response_code(req) != HTTP_OK) { fprintf(stderr, "FAILED\n"); exit(1); } - if (evhttp_find_header(req->input_headers, + if (evhttp_find_header(evhttp_request_get_input_headers(req), "Transfer-Encoding") == NULL) { fprintf(stderr, "FAILED\n"); exit(1); } - if (evbuffer_get_length(req->input_buffer) != 13 + 18 + 8) { + if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != 13 + 18 + 8) { fprintf(stderr, "FAILED\n"); exit(1); } - if (strncmp((char *)evbuffer_pullup(req->input_buffer, 13 + 18 + 8), + if (strncmp((char *)evbuffer_pullup(evhttp_request_get_input_buffer(req), 13 + 18 + 8), "This is funnybut not hilarious.bwv 1052", 13 + 18 + 8)) { fprintf(stderr, "FAILED\n"); @@ -2577,7 +2576,7 @@ http_chunk_out_test(void *arg) req = evhttp_request_new(http_chunked_request_done,data->base); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, @@ -2622,7 +2621,7 @@ http_stream_out_test(void *arg) (void *)"This is funnybut not hilarious.bwv 1052"); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/streamed") @@ -2644,18 +2643,18 @@ http_stream_in_chunk(struct evhttp_request *req, void *arg) { struct evbuffer *reply = arg; - if (req->response_code != HTTP_OK) { + if (evhttp_request_get_response_code(req) != HTTP_OK) { fprintf(stderr, "FAILED\n"); exit(1); } - evbuffer_add_buffer(reply, req->input_buffer); + evbuffer_add_buffer(reply, evhttp_request_get_input_buffer(req)); } static void http_stream_in_done(struct evhttp_request *req, void *arg) { - if (evbuffer_get_length(req->input_buffer) != 0) { + if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != 0) { fprintf(stderr, "FAILED\n"); exit(1); } @@ -2725,7 +2724,7 @@ http_stream_in_test(void *arg) static void http_stream_in_cancel_chunk(struct evhttp_request *req, void *arg) { - tt_int_op(req->response_code, ==, HTTP_OK); + tt_int_op(evhttp_request_get_response_code(req), ==, HTTP_OK); end: evhttp_cancel_request(req); @@ -2773,12 +2772,12 @@ static void http_connection_retry_done(struct evhttp_request *req, void *arg) { tt_assert(req); - tt_int_op(req->response_code, !=, HTTP_OK); - if (evhttp_find_header(req->input_headers, "Content-Type") != NULL) { + tt_int_op(evhttp_request_get_response_code(req), !=, HTTP_OK); + if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") != NULL) { tt_abort_msg("(content type)\n"); } - tt_uint_op(evbuffer_get_length(req->input_buffer), ==, 0); + tt_uint_op(evbuffer_get_length(evhttp_request_get_input_buffer(req)), ==, 0); test_ok = 1; end: @@ -2826,7 +2825,7 @@ http_connection_retry_test(void *arg) tt_assert(req); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { @@ -2853,7 +2852,7 @@ http_connection_retry_test(void *arg) tt_assert(req); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { @@ -2882,7 +2881,7 @@ http_connection_retry_test(void *arg) tt_assert(req); /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { @@ -3020,7 +3019,7 @@ http_negative_content_length_test(void *arg) req = evhttp_request_new(http_request_bad, data->base); /* Cause the response to have a negative content-length */ - evhttp_add_header(req->output_headers, "X-Negative", "makeitso"); + evhttp_add_header(evhttp_request_get_output_headers(req), "X-Negative", "makeitso"); /* We give ownership of the request to the connection */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { @@ -3041,7 +3040,7 @@ static void http_data_length_constraints_test_done(struct evhttp_request *req, void *arg) { tt_assert(req); - tt_int_op(req->response_code, ==, HTTP_BADREQUEST); + tt_int_op(evhttp_request_get_response_code(req), ==, HTTP_BADREQUEST); end: event_base_loopexit(arg, NULL); } @@ -3077,8 +3076,8 @@ http_data_length_constraints_test(void *arg) long_str[8191] = '\0'; /* Add the information that we care about */ evhttp_set_max_headers_size(http, 8191); - evhttp_add_header(req->output_headers, "Host", "somehost"); - evhttp_add_header(req->output_headers, "Longheader", long_str); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Longheader", long_str); if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { tt_abort_msg("Couldn't make request"); @@ -3087,7 +3086,7 @@ http_data_length_constraints_test(void *arg) req = evhttp_request_new(http_data_length_constraints_test_done, data->base); tt_assert(req); - evhttp_add_header(req->output_headers, "Host", "somehost"); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); /* GET /?arg=verylongvalue HTTP/1.1 */ if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, long_str) == -1) { @@ -3097,8 +3096,8 @@ http_data_length_constraints_test(void *arg) evhttp_set_max_body_size(http, 8190); req = evhttp_request_new(http_data_length_constraints_test_done, data->base); - evhttp_add_header(req->output_headers, "Host", "somehost"); - evbuffer_add_printf(req->output_buffer, "%s", long_str); + evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); + evbuffer_add_printf(evhttp_request_get_output_buffer(req), "%s", long_str); if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/") == -1) { tt_abort_msg("Couldn't make request"); } From 985430aed122a8c61ca7260779940d523f78ce23 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 3 Nov 2010 15:17:57 -0400 Subject: [PATCH 20/31] Remove need for http_compat.h in http tests --- test/regress_http.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index e93f041d..bf82a8b5 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -54,7 +54,6 @@ #include "event2/event.h" #include "event2/http.h" -#include "event2/http_compat.h" #include "event2/buffer.h" #include "event2/bufferevent.h" #include "log-internal.h" @@ -347,7 +346,7 @@ http_chunked_cb(struct evhttp_request *req, void *arg) state->req = req; state->base = arg; - if (strcmp(evhttp_request_uri(req), "/streamed") == 0) { + if (strcmp(evhttp_request_get_uri(req), "/streamed") == 0) { evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Length", "39"); } From 34b84b972775db759f5c2da301967cb288439e93 Mon Sep 17 00:00:00 2001 From: Christopher Davis Date: Wed, 3 Nov 2010 14:38:45 -0700 Subject: [PATCH 21/31] Fix more wn64 warnings. --- test/regress.c | 14 +++++++------- test/regress.h | 2 +- test/regress_buffer.c | 7 ++++--- test/regress_bufferevent.c | 2 +- test/regress_et.c | 2 +- test/regress_http.c | 2 +- test/regress_main.c | 4 ++-- test/test-changelist.c | 2 +- test/test-eof.c | 2 +- test/test-weof.c | 2 +- 10 files changed, 20 insertions(+), 19 deletions(-) diff --git a/test/regress.c b/test/regress.c index 71327559..01adaa33 100644 --- a/test/regress.c +++ b/test/regress.c @@ -94,8 +94,8 @@ static struct timeval tcalled; #endif #ifdef WIN32 -#define write(fd,buf,len) send((fd),(buf),(len),0) -#define read(fd,buf,len) recv((fd),(buf),(len),0) +#define write(fd,buf,len) send((fd),(buf),(int)(len),0) +#define read(fd,buf,len) recv((fd),(buf),(int)(len),0) #endif struct basic_cb_args @@ -1272,7 +1272,7 @@ test_event_base_new(void *ptr) struct event ev1; struct basic_cb_args args; - int towrite = strlen(TEST1)+1; + int towrite = (int)strlen(TEST1)+1; int len = write(data->pair[0], TEST1, towrite); if (len < 0) @@ -1646,9 +1646,9 @@ evtag_int_test(void *ptr) for (i = 0; i < TEST_MAX_INT; i++) { int oldlen, newlen; - oldlen = EVBUFFER_LENGTH(tmp); + oldlen = (int)EVBUFFER_LENGTH(tmp); evtag_encode_int(tmp, integers[i]); - newlen = EVBUFFER_LENGTH(tmp); + newlen = (int)EVBUFFER_LENGTH(tmp); TT_BLATHER(("encoded 0x%08x with %d bytes", (unsigned)integers[i], newlen - oldlen)); big_int = integers[i]; @@ -1723,9 +1723,9 @@ evtag_tag_encoding(void *ptr) for (i = 0; i < TEST_MAX_INT; i++) { int oldlen, newlen; - oldlen = EVBUFFER_LENGTH(tmp); + oldlen = (int)EVBUFFER_LENGTH(tmp); evtag_encode_tag(tmp, integers[i]); - newlen = EVBUFFER_LENGTH(tmp); + newlen = (int)EVBUFFER_LENGTH(tmp); TT_BLATHER(("encoded 0x%08x with %d bytes", (unsigned)integers[i], newlen - oldlen)); } diff --git a/test/regress.h b/test/regress.h index ddaadec7..3cbd7cd2 100644 --- a/test/regress.h +++ b/test/regress.h @@ -62,7 +62,7 @@ extern int called; extern struct event_base *global_base; extern int in_legacy_test_wrapper; -evutil_socket_t regress_make_tmpfile(const void *data, size_t datalen); +int regress_make_tmpfile(const void *data, size_t datalen); struct basic_test_data { struct event_base *base; diff --git a/test/regress_buffer.c b/test/regress_buffer.c index a4b9b31f..4f4a8303 100644 --- a/test/regress_buffer.c +++ b/test/regress_buffer.c @@ -491,7 +491,7 @@ test_evbuffer_expand(void *ptr) buf = evbuffer_new(); evbuffer_add(buf, data, 400); { - int n = buf->first->buffer_len - buf->first->off - 1; + int n = (int)(buf->first->buffer_len - buf->first->off - 1); tt_assert(n < (int)sizeof(data)); evbuffer_add(buf, data, n); } @@ -595,7 +595,8 @@ test_evbuffer_add_file(void *ptr) const char *data = "this is what we add as file system data."; size_t datalen; const char *compare; - evutil_socket_t fd = -1, pair[2] = {-1, -1}; + int fd = -1; + evutil_socket_t pair[2] = {-1, -1}; int r=0, n_written=0; /* Add a test for a big file. XXXX */ @@ -645,7 +646,7 @@ test_evbuffer_add_file(void *ptr) tt_int_op(n_written, ==, datalen); evbuffer_validate(src); - tt_int_op(evbuffer_read(src, pair[1], strlen(data)), ==, datalen); + tt_int_op(evbuffer_read(src, pair[1], (int)strlen(data)), ==, datalen); evbuffer_validate(src); compare = (char *)evbuffer_pullup(src, datalen); tt_assert(compare != NULL); diff --git a/test/regress_bufferevent.c b/test/regress_bufferevent.c index d12fe27e..a120e516 100644 --- a/test/regress_bufferevent.c +++ b/test/regress_bufferevent.c @@ -189,7 +189,7 @@ static void wm_readcb(struct bufferevent *bev, void *arg) { struct evbuffer *evbuf = evbuffer_new(); - int len = evbuffer_get_length(bev->input); + int len = (int)evbuffer_get_length(bev->input); static int nread; assert(len >= 10 && len <= 20); diff --git a/test/regress_et.c b/test/regress_et.c index 94123499..1ab92313 100644 --- a/test/regress_et.c +++ b/test/regress_et.c @@ -97,7 +97,7 @@ test_edgetriggered(void *et) called = was_et = 0; - send(pair[0], test, strlen(test)+1, 0); + send(pair[0], test, (int)strlen(test)+1, 0); shutdown(pair[0], SHUT_WR); /* Initalize the event library */ diff --git a/test/regress_http.c b/test/regress_http.c index e9e9e654..96ad5103 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -127,7 +127,7 @@ http_setup(ev_uint16_t *pport, struct event_base *base) #define NI_MAXSERV 1024 #endif -static int +static evutil_socket_t http_connect(const char *address, u_short port) { /* Stupid code for connecting */ diff --git a/test/regress_main.c b/test/regress_main.c index ca41333a..d4265dbb 100644 --- a/test/regress_main.c +++ b/test/regress_main.c @@ -107,7 +107,7 @@ static void dnslogcb(int w, const char *m) } /* creates a temporary file with the data in it */ -evutil_socket_t +int regress_make_tmpfile(const void *data, size_t datalen) { #ifndef WIN32 @@ -147,7 +147,7 @@ regress_make_tmpfile(const void *data, size_t datalen) if (tries == 0) return (-1); written = 0; - WriteFile(h, data, datalen, &written, NULL); + WriteFile(h, data, (DWORD)datalen, &written, NULL); /* Closing the fd returned by this function will indeed close h. */ return _open_osfhandle((intptr_t)h,_O_RDONLY); #endif diff --git a/test/test-changelist.c b/test/test-changelist.c index 7a328f20..f854a2d3 100644 --- a/test/test-changelist.c +++ b/test/test-changelist.c @@ -143,7 +143,7 @@ main(int argc, char **argv) struct event* timeout; struct event_base* base; - int pair[2]; + evutil_socket_t pair[2]; int res; struct timeval tv; struct cpu_usage_timer timer; diff --git a/test/test-eof.c b/test/test-eof.c index 3d4be93d..90b40938 100644 --- a/test/test-eof.c +++ b/test/test-eof.c @@ -78,7 +78,7 @@ main(int argc, char **argv) return (1); - send(pair[0], test, strlen(test)+1, 0); + send(pair[0], test, (int)strlen(test)+1, 0); shutdown(pair[0], SHUT_WR); /* Initalize the event library */ diff --git a/test/test-weof.c b/test/test-weof.c index 2423d217..0ea4d971 100644 --- a/test/test-weof.c +++ b/test/test-weof.c @@ -43,7 +43,7 @@ write_cb(evutil_socket_t fd, short event, void *arg) const char *test = "test string"; int len; - len = send(fd, test, strlen(test) + 1, 0); + len = send(fd, test, (int)strlen(test) + 1, 0); printf("%s: write %d%s\n", __func__, len, len ? "" : " - means EOF"); From 75a73414a402005ddc2d2adde5a3acffc00d6382 Mon Sep 17 00:00:00 2001 From: Felix Nawothnig Date: Thu, 4 Nov 2010 11:25:35 -0400 Subject: [PATCH 22/31] Define enumerators for all HTTP methods, including PATCH from RFC5789 This patch defines enumerators for all HTTP methods that exist (including PATCH introduced in RFC 5789). It also makes them bit-masky (that's not a word, is it?), breaking binary- but not source-code compatibility. evhttp now stores a bitmask specifying for which methods requests to dispatch and which ones to reject with "405 Method Not Allowed". By default that's the ones we currently have (GET, POST, HEAD, PUT, DELETE), thereby keeping functional compatibility (besides the minor change that one of the other methods will now cause 405 instead of 400. But I believe that could even be considered a bug-fix). evhttp is extended by evhttp_set_allowed_methods() with which the user can change that bitmask. no regressions here and my test-app still works. Haven't yet actually tested any of the new methods. What's obviously missing here is the special logic for the methods: OPTIONS: We should be fine here - I believe our current dispatch logic should work fine. Some convenience functions would be fine though. TRACE: I'm pretty certain we should never dispatch this to the callbacks and simply implement the necessary functionality built-in. CONNECT: Pretty straight-forward to implement (and considering the framework in which we implement it very efficient too). Should probably go built-in. PATCH: Except for checking the RFC against our pre-dispatch logic (there just might be some "MUST not have Some-Header" lurking somewhere) there is nothing to be done here, this is completely up to the user. Nothing to do. --- http-internal.h | 3 +++ http.c | 37 ++++++++++++++++++++++++++++++++++++- include/event2/http.h | 26 +++++++++++++++++++++----- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/http-internal.h b/http-internal.h index 932f1c03..5b3f6397 100644 --- a/http-internal.h +++ b/http-internal.h @@ -145,6 +145,9 @@ struct evhttp { size_t default_max_headers_size; ev_uint64_t default_max_body_size; + /* bitmask of all allowed methods */ + short allowed_methods; + /* Fallback callback if all the other callbacks for this connection don't match. */ void (*gencb)(struct evhttp_request *req, void *); diff --git a/http.c b/http.c index d3d82fe7..70e0d13d 100644 --- a/http.c +++ b/http.c @@ -288,6 +288,18 @@ evhttp_method(enum evhttp_cmd_type type) case EVHTTP_REQ_DELETE: method = "DELETE"; break; + case EVHTTP_REQ_OPTIONS: + method = "OPTIONS"; + break; + case EVHTTP_REQ_TRACE: + method = "TRACE"; + break; + case EVHTTP_REQ_CONNECT: + method = "CONNECT"; + break; + case EVHTTP_REQ_PATCH: + method = "PATCH"; + break; default: method = NULL; break; @@ -1379,6 +1391,12 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line) req->type = EVHTTP_REQ_PUT; } else if (strcmp(method, "DELETE") == 0) { req->type = EVHTTP_REQ_DELETE; + } else if (strcmp(method, "OPTIONS") == 0) { + req->type = EVHTTP_REQ_OPTIONS; + } else if (strcmp(method, "TRACE") == 0) { + req->type = EVHTTP_REQ_TRACE; + } else if (strcmp(method, "PATCH") == 0) { + req->type = EVHTTP_REQ_PATCH; } else { event_debug(("%s: bad method %s on request %p from %s", __func__, method, req, req->remote_host)); @@ -2668,11 +2686,17 @@ evhttp_handle_request(struct evhttp_request *req, void *arg) /* we have a new request on which the user needs to take action */ req->userdone = 0; - if (req->uri == NULL) { + if (req->type == 0 || req->uri == NULL) { evhttp_send_error(req, HTTP_BADREQUEST, NULL); return; } + if ((http->allowed_methods & req->type) == 0) { + event_debug(("Rejecting disallowed method %d (allowed: %d)\n", req->type, http->allowed_methods)); + evhttp_send_error(req, HTTP_BADMETHOD, NULL); + return; + } + /* handle potential virtual hosts */ hostname = evhttp_find_header(req->input_headers, "Host"); if (hostname != NULL) { @@ -2858,6 +2882,11 @@ evhttp_new_object(void) http->timeout = -1; evhttp_set_max_headers_size(http, EV_SIZE_MAX); evhttp_set_max_body_size(http, EV_SIZE_MAX); + evhttp_set_allowed_methods(http, EVHTTP_REQ_GET | + EVHTTP_REQ_POST | + EVHTTP_REQ_HEAD | + EVHTTP_REQ_PUT | + EVHTTP_REQ_DELETE); TAILQ_INIT(&http->sockets); TAILQ_INIT(&http->callbacks); @@ -2990,6 +3019,12 @@ evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size) http->default_max_body_size = max_body_size; } +void +evhttp_set_allowed_methods(struct evhttp* http, short methods) +{ + http->allowed_methods = methods; +} + int evhttp_set_cb(struct evhttp *http, const char *uri, void (*cb)(struct evhttp_request *, void *), void *cbarg) diff --git a/include/event2/http.h b/include/event2/http.h index e0fdefe0..45d3b245 100644 --- a/include/event2/http.h +++ b/include/event2/http.h @@ -57,6 +57,7 @@ struct event_base; #define HTTP_NOTMODIFIED 304 /**< page was not modified from last */ #define HTTP_BADREQUEST 400 /**< invalid http request was made */ #define HTTP_NOTFOUND 404 /**< could not find content for uri */ +#define HTTP_BADMETHOD 405 /**< method not allowed */ #define HTTP_SERVUNAVAIL 503 /**< the server is not available */ struct evhttp; @@ -183,6 +184,17 @@ void evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_siz /** XXX Document. */ void evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size); +/** + Sets the what HTTP methods are supported in requests accepted by this server. + If not supported they will generate a "405 Method not allowed" response. + + By default this includes the following methods: GET, POST, HEAD, PUT, DELETE + + @param http the http server on which to set the methods + @param methods bit mask constructed from evhttp_cmd_type values +*/ +void evhttp_set_allowed_methods(struct evhttp* http, short methods); + /** Set a callback for a specified URI @@ -329,11 +341,15 @@ void evhttp_send_reply_end(struct evhttp_request *req); /** the different request types supported by evhttp */ enum evhttp_cmd_type { - EVHTTP_REQ_GET, - EVHTTP_REQ_POST, - EVHTTP_REQ_HEAD, - EVHTTP_REQ_PUT, - EVHTTP_REQ_DELETE + EVHTTP_REQ_GET = 1 << 0, + EVHTTP_REQ_POST = 1 << 1, + EVHTTP_REQ_HEAD = 1 << 2, + EVHTTP_REQ_PUT = 1 << 3, + EVHTTP_REQ_DELETE = 1 << 4, + EVHTTP_REQ_OPTIONS = 1 << 5, + EVHTTP_REQ_TRACE = 1 << 6, + EVHTTP_REQ_CONNECT = 1 << 7, + EVHTTP_REQ_PATCH = 1 << 8 }; /** a request object can represent either a request or a reply */ From f5b391e22eb119304877b3829f32a241a0688fa3 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 4 Nov 2010 11:53:34 -0400 Subject: [PATCH 23/31] Tweak interface for allowed methods --- http-internal.h | 5 +++-- http.c | 15 ++++++++------- include/event2/http.h | 18 ++++++++++++++---- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/http-internal.h b/http-internal.h index 5b3f6397..b320e2d6 100644 --- a/http-internal.h +++ b/http-internal.h @@ -145,8 +145,9 @@ struct evhttp { size_t default_max_headers_size; ev_uint64_t default_max_body_size; - /* bitmask of all allowed methods */ - short allowed_methods; + /* Bitmask of all HTTP methods that we accept and pass to user + * callbacks. */ + ev_uint16_t allowed_methods; /* Fallback callback if all the other callbacks for this connection don't match. */ diff --git a/http.c b/http.c index 70e0d13d..3aeecc9d 100644 --- a/http.c +++ b/http.c @@ -1396,7 +1396,7 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line) } else if (strcmp(method, "TRACE") == 0) { req->type = EVHTTP_REQ_TRACE; } else if (strcmp(method, "PATCH") == 0) { - req->type = EVHTTP_REQ_PATCH; + req->type = EVHTTP_REQ_PATCH; } else { event_debug(("%s: bad method %s on request %p from %s", __func__, method, req, req->remote_host)); @@ -2692,8 +2692,9 @@ evhttp_handle_request(struct evhttp_request *req, void *arg) } if ((http->allowed_methods & req->type) == 0) { - event_debug(("Rejecting disallowed method %d (allowed: %d)\n", req->type, http->allowed_methods)); - evhttp_send_error(req, HTTP_BADMETHOD, NULL); + event_debug(("Rejecting disallowed method %x (allowed: %x)\n", + (unsigned)req->type, (unsigned)http->allowed_methods)); + evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL); return; } @@ -2883,9 +2884,9 @@ evhttp_new_object(void) evhttp_set_max_headers_size(http, EV_SIZE_MAX); evhttp_set_max_body_size(http, EV_SIZE_MAX); evhttp_set_allowed_methods(http, EVHTTP_REQ_GET | - EVHTTP_REQ_POST | - EVHTTP_REQ_HEAD | - EVHTTP_REQ_PUT | + EVHTTP_REQ_POST | + EVHTTP_REQ_HEAD | + EVHTTP_REQ_PUT | EVHTTP_REQ_DELETE); TAILQ_INIT(&http->sockets); @@ -3020,7 +3021,7 @@ evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size) } void -evhttp_set_allowed_methods(struct evhttp* http, short methods) +evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods) { http->allowed_methods = methods; } diff --git a/include/event2/http.h b/include/event2/http.h index 45d3b245..27dd7811 100644 --- a/include/event2/http.h +++ b/include/event2/http.h @@ -57,7 +57,9 @@ struct event_base; #define HTTP_NOTMODIFIED 304 /**< page was not modified from last */ #define HTTP_BADREQUEST 400 /**< invalid http request was made */ #define HTTP_NOTFOUND 404 /**< could not find content for uri */ -#define HTTP_BADMETHOD 405 /**< method not allowed */ +#define HTTP_BADMETHOD 405 /**< method not allowed for this uri */ +#define HTTP_INTERNAL 500 /**< internal error */ +#define HTTP_NOTIMPLEMENTED 501 /**< not implemented */ #define HTTP_SERVUNAVAIL 503 /**< the server is not available */ struct evhttp; @@ -185,7 +187,9 @@ void evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_siz void evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size); /** - Sets the what HTTP methods are supported in requests accepted by this server. + Sets the what HTTP methods are supported in requests accepted by this + server, and passed to user callbacks. + If not supported they will generate a "405 Method not allowed" response. By default this includes the following methods: GET, POST, HEAD, PUT, DELETE @@ -193,7 +197,7 @@ void evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size); @param http the http server on which to set the methods @param methods bit mask constructed from evhttp_cmd_type values */ -void evhttp_set_allowed_methods(struct evhttp* http, short methods); +void evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods); /** Set a callback for a specified URI @@ -339,7 +343,13 @@ void evhttp_send_reply_end(struct evhttp_request *req); * Interfaces for making requests */ -/** the different request types supported by evhttp */ +/** The different request types supported by evhttp. These are as specified + * in RFC2616, except for PATCH which is specified by RFC5789. + * + * By default, only some of these methods are accepted and passed to user + * callbacks; use evhttp_set_allowed_methods() to change which methods + * are allowed. + */ enum evhttp_cmd_type { EVHTTP_REQ_GET = 1 << 0, EVHTTP_REQ_POST = 1 << 1, From 536311a46b407902ca0ee52d504c327ec54cfdf1 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 4 Nov 2010 12:39:41 -0400 Subject: [PATCH 24/31] evhttp: Return 501 when we get an unrecognized method, not 400. --- http-internal.h | 3 +++ http.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/http-internal.h b/http-internal.h index b320e2d6..e32511e3 100644 --- a/http-internal.h +++ b/http-internal.h @@ -41,6 +41,9 @@ struct evbuffer; struct addrinfo; struct evhttp_request; +/* Indicates an unknown request method. */ +#define _EVHTTP_REQ_UNKNOWN (1<<15) + enum evhttp_connection_state { EVCON_DISCONNECTED, /**< not currently connected not trying either*/ EVCON_CONNECTING, /**< tries to currently connect */ diff --git a/http.c b/http.c index 3aeecc9d..57d832f0 100644 --- a/http.c +++ b/http.c @@ -1398,9 +1398,11 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line) } else if (strcmp(method, "PATCH") == 0) { req->type = EVHTTP_REQ_PATCH; } else { + req->type = _EVHTTP_REQ_UNKNOWN; event_debug(("%s: bad method %s on request %p from %s", __func__, method, req, req->remote_host)); - return (-1); + /* No error yet; we'll give a better error later when + * we see that req->type is unsupported. */ } if (strcmp(version, "HTTP/1.0") == 0) { From 75e3320efd318634ec367327e4e286fa68178179 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 4 Nov 2010 12:41:13 -0400 Subject: [PATCH 25/31] Units test for unexpected evhttp methods. --- test/regress_http.c | 122 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/test/regress_http.c b/test/regress_http.c index bf82a8b5..c0cca956 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -693,6 +693,127 @@ http_delete_test(void *arg) ; } +static void +http_allowed_methods_eventcb(struct bufferevent *bev, short what, void *arg) +{ + char **output = arg; + if ((what & (BEV_EVENT_ERROR|BEV_EVENT_EOF))) { + char buf[4096]; + int n; + n = evbuffer_remove(bufferevent_get_input(bev), buf, + sizeof(buf)-1); + if (n >= 0) { + buf[n]='\0'; + if (*output) + free(*output); + *output = strdup(buf); + } + event_base_loopexit(exit_base, NULL); + } +} + +static void +http_allowed_methods_test(void *arg) +{ + struct basic_test_data *data = arg; + struct bufferevent *bev1, *bev2, *bev3; + evutil_socket_t fd1, fd2, fd3; + const char *http_request; + char *result1=NULL, *result2=NULL, *result3=NULL; + ev_uint16_t port = 0; + + exit_base = data->base; + test_ok = 0; + + http = http_setup(&port, data->base); + + fd1 = http_connect("127.0.0.1", port); + + /* GET is out; PATCH is in. */ + evhttp_set_allowed_methods(http, EVHTTP_REQ_PATCH); + + /* Stupid thing to send a request */ + bev1 = bufferevent_socket_new(data->base, fd1, 0); + bufferevent_enable(bev1, EV_READ|EV_WRITE); + bufferevent_setcb(bev1, NULL, NULL, + http_allowed_methods_eventcb, &result1); + + http_request = + "GET /index.html HTTP/1.1\r\n" + "Host: somehost\r\n" + "Connection: close\r\n" + "\r\n"; + + bufferevent_write(bev1, http_request, strlen(http_request)); + + puts("A"); + event_base_dispatch(data->base); + puts("AA"); + + fd2 = http_connect("127.0.0.1", port); + + bev2 = bufferevent_socket_new(data->base, fd2, 0); + bufferevent_enable(bev2, EV_READ|EV_WRITE); + bufferevent_setcb(bev2, NULL, NULL, + http_allowed_methods_eventcb, &result2); + + http_request = + "PATCH /test HTTP/1.1\r\n" + "Host: somehost\r\n" + "Connection: close\r\n" + "\r\n"; + + bufferevent_write(bev2, http_request, strlen(http_request)); + + event_base_dispatch(data->base); + + fd3 = http_connect("127.0.0.1", port); + + bev3 = bufferevent_socket_new(data->base, fd3, 0); + bufferevent_enable(bev3, EV_READ|EV_WRITE); + bufferevent_setcb(bev3, NULL, NULL, + http_allowed_methods_eventcb, &result3); + + http_request = + "FLOOP /test HTTP/1.1\r\n" + "Host: somehost\r\n" + "Connection: close\r\n" + "\r\n"; + + bufferevent_write(bev3, http_request, strlen(http_request)); + + event_base_dispatch(data->base); + + bufferevent_free(bev1); + bufferevent_free(bev2); + bufferevent_free(bev3); + evutil_closesocket(fd1); + evutil_closesocket(fd2); + evutil_closesocket(fd3); + + evhttp_free(http); + + /* Method known but disallowed */ + tt_assert(result1); + tt_assert(!strncmp(result1, "HTTP/1.1 501 ", strlen("HTTP/1.1 501 "))); + + /* Method known and allowed */ + tt_assert(result2); + tt_assert(!strncmp(result2, "HTTP/1.1 200 ", strlen("HTTP/1.1 200 "))); + + /* Method unknown */ + tt_assert(result3); + tt_assert(!strncmp(result3, "HTTP/1.1 501 ", strlen("HTTP/1.1 501 "))); + + end: + if (result1) + free(result1); + if (result2) + free(result2); + if (result3) + free(result3); +} + static void http_request_done(struct evhttp_request *, void *); static void http_request_empty_done(struct evhttp_request *, void *); @@ -3265,6 +3386,7 @@ struct testcase_t http_testcases[] = { HTTP(post), HTTP(put), HTTP(delete), + HTTP(allowed_methods), HTTP(failure), HTTP(connection), HTTP(persist_connection), From c76640b5c29390ca3a11eba6614bf51a92e7a2ca Mon Sep 17 00:00:00 2001 From: Felix Nawothnig Date: Tue, 1 Jun 2010 04:45:55 +0200 Subject: [PATCH 26/31] Don't disable reading from the HTTP connection after sending the request to be notified of connection-close in time --- http.c | 1 - 1 file changed, 1 deletion(-) diff --git a/http.c b/http.c index d3d82fe7..e6b5825c 100644 --- a/http.c +++ b/http.c @@ -342,7 +342,6 @@ evhttp_write_buffer(struct evhttp_connection *evcon, evcon->cb = cb; evcon->cb_arg = arg; - bufferevent_disable(evcon->bufev, EV_READ); bufferevent_enable(evcon->bufev, EV_WRITE); } From 05124879d34731eafe8a31698c943c0f5e7e24bf Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 4 Nov 2010 14:05:08 -0400 Subject: [PATCH 27/31] Never call evhttp_readcb while writing. --- http.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/http.c b/http.c index e6b5825c..0bde6e32 100644 --- a/http.c +++ b/http.c @@ -343,6 +343,15 @@ evhttp_write_buffer(struct evhttp_connection *evcon, evcon->cb_arg = arg; bufferevent_enable(evcon->bufev, EV_WRITE); + + /* Disable the read callback: we don't actually care about data; + * we only care about close detection. (We don't disable reading, + * since we *do* want to learn about any close events.) */ + bufferevent_setcb(evcon->bufev, + NULL, /*read*/ + evhttp_write_cb, + evhttp_error_cb, + evcon); } /** Helper: returns true iff evconn is in any connected state. */ @@ -2056,6 +2065,12 @@ evhttp_start_read(struct evhttp_connection *evcon) bufferevent_disable(evcon->bufev, EV_WRITE); bufferevent_enable(evcon->bufev, EV_READ); evcon->state = EVCON_READING_FIRSTLINE; + /* Reset the bufferevent callbacks */ + bufferevent_setcb(evcon->bufev, + evhttp_read_cb, + evhttp_write_cb, + evhttp_error_cb, + evcon); /* If there's still data pending, process it next time through the * loop. Don't do it now; that could get recusive. */ From 229714d123824d686bece18e6d2d157ed401abd4 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 4 Nov 2010 16:04:28 -0400 Subject: [PATCH 28/31] Fix a mistake in http documentation found by Julien Blache --- include/event2/http.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/event2/http.h b/include/event2/http.h index e0fdefe0..c3875f3e 100644 --- a/include/event2/http.h +++ b/include/event2/http.h @@ -391,7 +391,7 @@ int evhttp_request_is_owned(struct evhttp_request *req); /** * Returns the connection object associated with the request or NULL * - * The server needs to either free the request explicitly or call + * The user needs to either free the request explicitly or call * evhttp_send_reply_end(). */ struct evhttp_connection *evhttp_request_get_connection(struct evhttp_request *req); From 52aa419bf69bc2f46f203800919abcfc25ea98fe Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 4 Nov 2010 15:40:44 -0500 Subject: [PATCH 29/31] Set SO_UPDATE_ACCEPT_CONTEXT on sockets from AcceptEx so that shutdown() can work Based on patch (and lots of debugging work) by Kelly Brock. --- listener.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/listener.c b/listener.c index 5a521985..32d5b768 100644 --- a/listener.c +++ b/listener.c @@ -526,6 +526,8 @@ start_accepting(struct accepting_socket *as) goto report_err; } + /* XXXX It turns out we need to do this again later. Does this call + * have any effect? */ setsockopt(s, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&as->lev->fd, sizeof(&as->lev->fd)); @@ -609,6 +611,12 @@ accepted_socket_invoke_user_cb(struct deferred_cb *dcb, void *arg) sock = as->s; cb = lev->cb; as->s = INVALID_SOCKET; + + /* We need to call this so getsockname, getpeername, and + * shutdown work correctly on the accepted socket. */ + /* XXXX handle error? */ + setsockopt(as->s, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, + (char *)&as->lev->fd, sizeof(&as->lev->fd)); } data = lev->user_data; From 3db6bc007949366e89cb83efa5027ea9da9af102 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 9 Nov 2010 10:03:00 -0500 Subject: [PATCH 30/31] Remove some debugging puts() calls from allow_methods test --- test/regress_http.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index c0cca956..2ef4e29b 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -746,9 +746,7 @@ http_allowed_methods_test(void *arg) bufferevent_write(bev1, http_request, strlen(http_request)); - puts("A"); event_base_dispatch(data->base); - puts("AA"); fd2 = http_connect("127.0.0.1", port); From a38140be18b764e98b899ed435b61ea2aa6447bc Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 9 Nov 2010 10:14:32 -0500 Subject: [PATCH 31/31] Refactor http version parsing into a single function Based on a suggestion by Chris Davis to make evhttp_parse_response_line tolerate odd versions too. --- http.c | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/http.c b/http.c index ac5e547a..7b50eec9 100644 --- a/http.c +++ b/http.c @@ -1312,6 +1312,22 @@ evhttp_valid_response_code(int code) return (1); } +static int +evhttp_parse_http_version(const char *version, struct evhttp_request *req) +{ + int major, minor; + char ch; + int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch); + if (n > 2 || major > 1) { + event_debug(("%s: bad version %s on message %p from %s", + __func__, version, req, req->remote_host)); + return (-1); + } + req->major = major; + req->minor = minor; + return (0); +} + /* Parses the status line of a web server */ static int @@ -1328,17 +1344,8 @@ evhttp_parse_response_line(struct evhttp_request *req, char *line) if (line != NULL) readable = line; - if (strcmp(protocol, "HTTP/1.0") == 0) { - req->major = 1; - req->minor = 0; - } else if (strcmp(protocol, "HTTP/1.1") == 0) { - req->major = 1; - req->minor = 1; - } else { - event_debug(("%s: bad protocol \"%s\"", - __func__, protocol)); + if (evhttp_parse_http_version(protocol, req) < 0) return (-1); - } req->response_code = atoi(number); if (!evhttp_valid_response_code(req->response_code)) { @@ -1392,24 +1399,8 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line) return (-1); } - if (strcmp(version, "HTTP/1.0") == 0) { - req->major = 1; - req->minor = 0; - } else if (strcmp(version, "HTTP/1.1") == 0) { - req->major = 1; - req->minor = 1; - } else { - int major, minor; - char ch; - int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch); - if (n > 2 || major > 1) { - event_debug(("%s: bad version %s on request %p from %s", - __func__, version, req, req->remote_host)); - return (-1); - } - req->major = major; - req->minor = minor; - } + if (evhttp_parse_http_version(version, req) < 0) + return (-1); if ((req->uri = mm_strdup(uri)) == NULL) { event_debug(("%s: mm_strdup", __func__));