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 diff --git a/buffer.c b/buffer.c index 0e6c7762..52ab6357 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 @@ -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 { @@ -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]; } @@ -1495,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 */ @@ -1595,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; } } @@ -1618,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); @@ -1793,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; @@ -1840,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; } @@ -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 @@ -1957,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); @@ -2090,10 +2093,10 @@ 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 -= 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; @@ -2558,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)) @@ -2760,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/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-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_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_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..b12121c2 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); @@ -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); @@ -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/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/evdns.c b/evdns.c index 4eb07a9a..4d25cd3d 100644 --- a/evdns.c +++ b/evdns.c @@ -1171,7 +1171,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; @@ -1346,8 +1346,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)) @@ -1508,7 +1508,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; @@ -1539,25 +1539,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; + memcpy(buf + j, start, label_len); + j += (int) label_len; 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; + memcpy(buf + j, start, label_len); + j += (int) label_len; /* hop over the '.' */ name++; } @@ -1587,7 +1587,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 */ @@ -1908,8 +1908,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)) @@ -2942,7 +2942,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); @@ -2956,7 +2956,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; } @@ -3019,7 +3019,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; @@ -3429,7 +3429,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-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/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/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/evutil.c b/evutil.c index 9bf0d92d..46c8333d 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 /** @@ -125,13 +125,18 @@ 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; } 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 +#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; 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 4e3485c2..07ad2ea6 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 : (int)n); } diff --git a/http-internal.h b/http-internal.h index 932f1c03..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 */ @@ -145,6 +148,10 @@ struct evhttp { size_t default_max_headers_size; ev_uint64_t default_max_body_size; + /* 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. */ void (*gencb)(struct evhttp_request *req, void *); diff --git a/http.c b/http.c index 2a1cb670..9c98563f 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 @@ -240,7 +248,8 @@ html_replace(char ch, char *buf) char * evhttp_htmlescape(const char *html) { - int i, new_size = 0, old_size = strlen(html); + size_t i; + size_t new_size = 0, old_size = strlen(html); char *escaped_html, *p; char scratch_space[2]; @@ -249,7 +258,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) { @@ -288,6 +297,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; @@ -342,8 +363,16 @@ 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); + + /* 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. */ @@ -470,9 +499,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 +511,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 @@ -762,7 +790,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) { @@ -1305,6 +1333,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 @@ -1321,17 +1365,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)) { @@ -1379,24 +1414,22 @@ 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 { + 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) { - req->major = 1; - req->minor = 0; - } else if (strcmp(version, "HTTP/1.1") == 0) { - 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)); + if (evhttp_parse_http_version(version, req) < 0) return (-1); - } if ((req->uri = mm_strdup(uri)) == NULL) { event_debug(("%s: mm_strdup", __func__)); @@ -2057,6 +2090,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. */ @@ -2074,7 +2113,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 +2208,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; @@ -2179,6 +2218,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); @@ -2666,11 +2707,18 @@ 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 %x (allowed: %x)\n", + (unsigned)req->type, (unsigned)http->allowed_methods)); + evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL); + return; + } + /* handle potential virtual hosts */ hostname = evhttp_find_header(req->input_headers, "Host"); if (hostname != NULL) { @@ -2856,6 +2904,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); @@ -2988,6 +3041,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, ev_uint16_t methods) +{ + http->allowed_methods = methods; +} + int evhttp_set_cb(struct evhttp *http, const char *uri, void (*cb)(struct evhttp_request *, void *), void *cbarg) @@ -3171,6 +3230,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) { @@ -3371,7 +3436,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 +3628,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; diff --git a/include/event2/http.h b/include/event2/http.h index d8a716ae..6452628d 100644 --- a/include/event2/http.h +++ b/include/event2/http.h @@ -57,6 +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 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; @@ -183,6 +186,19 @@ 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, 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 + + @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, ev_uint16_t methods); + /** Set a callback for a specified URI @@ -327,13 +343,23 @@ 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, - 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 */ @@ -391,7 +417,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); @@ -466,11 +492,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 */ 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; 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 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 44c16fdc..4f4a8303 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 */ @@ -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..f7498306 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -53,10 +53,7 @@ #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" #include "event2/buffer.h" #include "event2/bufferevent.h" #include "log-internal.h" @@ -67,7 +64,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"; @@ -110,16 +107,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); } @@ -127,7 +124,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 */ @@ -223,12 +220,13 @@ 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); 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,17 +236,21 @@ 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++; out: evhttp_request_free(req); bufferevent_disable(bev, EV_READ); - if (base) - event_base_loopexit(base, NULL); - else - event_loopexit(NULL); + if (exit_base) + event_base_loopexit(exit_base, NULL); + else if (my_base) + event_base_loopexit(my_base, NULL); + else { + fprintf(stderr, "No way to exit loop!\n"); + exit(1); + } } } @@ -266,32 +268,32 @@ static void http_errorcb(struct bufferevent *bev, short what, void *arg) { test_ok = -2; - event_loopexit(NULL); + event_base_loopexit(arg, NULL); } 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 */ @@ -308,6 +310,7 @@ static char const* const CHUNKS[] = { }; struct chunk_req_state { + struct event_base *base; struct evhttp_request *req; int i; }; @@ -324,7 +327,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); @@ -341,9 +344,10 @@ 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"); + if (strcmp(evhttp_request_get_uri(req), "/streamed") == 0) { + evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Length", "39"); } /* generate a chunked/streamed reply */ @@ -351,7 +355,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 +369,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 +380,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 +391,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 +403,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 +417,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 +429,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 +459,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 @@ -461,7 +467,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); @@ -492,7 +498,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; } @@ -500,7 +506,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; @@ -510,7 +516,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++; @@ -526,12 +532,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; @@ -539,10 +546,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) @@ -552,9 +558,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 */ @@ -563,9 +569,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); @@ -581,9 +587,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 */ @@ -596,9 +602,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); @@ -617,7 +623,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); } @@ -629,10 +635,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); } @@ -648,8 +654,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 +664,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 +681,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); @@ -686,11 +693,130 @@ http_delete_test(void) ; } +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)); + + event_base_dispatch(data->base); + + 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 *); 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 +824,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); + exit_base = data->base; /* * At this point, we want to schedule a request to the HTTP * server using our make request method. @@ -713,7 +840,7 @@ _http_connection_test(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) { @@ -721,7 +848,7 @@ _http_connection_test(int persistent) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); tt_assert(test_ok); @@ -731,29 +858,29 @@ _http_connection_test(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) { 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"); + 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) { @@ -761,7 +888,7 @@ _http_connection_test(int persistent) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -771,14 +898,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 +914,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 +924,10 @@ http_connection_async_test(void) ev_uint16_t portnum = 0; char address[64]; - tt_assert(regress_dnsserver(base, &portnum, search_table)); + exit_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 +937,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); /* @@ -821,7 +950,7 @@ http_connection_async_test(void) 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) { @@ -829,7 +958,7 @@ http_connection_async_test(void) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); tt_assert(test_ok); @@ -839,28 +968,28 @@ http_connection_async_test(void) 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) { 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"); + 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) { @@ -868,7 +997,7 @@ http_connection_async_test(void) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -892,30 +1021,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; + exit_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); /* @@ -926,7 +1060,7 @@ http_cancel_test(void) 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"), @@ -936,9 +1070,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); @@ -948,27 +1082,27 @@ http_cancel_test(void) 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"), !=, -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"); + 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"), !=, -1); - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -982,52 +1116,57 @@ 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); } test_ok = 1; - event_loopexit(NULL); + EVUTIL_ASSERT(exit_base); + event_base_loopexit(exit_base, NULL); } 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); } test_ok = 1; - event_loopexit(NULL); + EVUTIL_ASSERT(arg); + event_base_loopexit(arg, 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); + exit_base = data->base; + + http = http_setup(&port, data->base); /* virtual host */ second = evhttp_new(NULL); @@ -1043,14 +1182,14 @@ 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"); + 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, @@ -1058,7 +1197,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); @@ -1068,7 +1207,7 @@ http_virtual_host_test(void) 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, @@ -1077,7 +1216,7 @@ http_virtual_host_test(void) exit(1); } - event_dispatch(); + event_base_dispatch(data->base); tt_assert(test_ok == 1); @@ -1087,7 +1226,7 @@ http_virtual_host_test(void) 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, @@ -1095,7 +1234,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) @@ -1112,35 +1251,36 @@ http_virtual_host_test(void) 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); } test_ok = 1; - event_loopexit(NULL); + EVUTIL_ASSERT(arg); + event_base_loopexit(arg, NULL); } /* @@ -1163,45 +1303,47 @@ 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) { + 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); } 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 */ @@ -1212,17 +1354,17 @@ 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 */ - 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"); } - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -1240,17 +1382,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,18 +1401,18 @@ 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 */ - 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"); } - event_dispatch(); + event_base_dispatch(data->base); evhttp_connection_free(evcon); evhttp_free(http); @@ -1286,20 +1429,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); } @@ -1316,36 +1459,37 @@ 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"); 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); } test_ok = 1; - event_loopexit(NULL); + event_base_loopexit(base, NULL); } /* @@ -1357,35 +1501,36 @@ 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 */ - 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"); } - event_dispatch(); + event_base_dispatch(data->base); evhttp_connection_free(evcon); evhttp_free(http); @@ -1402,20 +1547,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); } @@ -1431,6 +1576,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) { @@ -1438,31 +1584,31 @@ 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); } test_ok = 1; - event_loopexit(NULL); + event_base_loopexit(base, NULL); } static void @@ -1472,7 +1618,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 +1626,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 +1636,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); @@ -1519,26 +1666,27 @@ 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; 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"); + 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) { @@ -1550,9 +1698,10 @@ 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) { + if (req != NULL && evhttp_request_get_response_code(req) != HTTP_OK) { tt_abort_msg("Failed"); } @@ -1560,26 +1709,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; @@ -1591,7 +1741,7 @@ _http_close_detection(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, @@ -1600,7 +1750,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,30 +1762,32 @@ _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 -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"); @@ -2210,15 +2362,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 = @@ -2252,7 +2404,7 @@ static void http_incomplete_readcb(struct bufferevent *bev, void *arg) { test_ok = -1; - event_loopexit(NULL); + event_base_loopexit(exit_base,NULL); } static void @@ -2262,7 +2414,7 @@ http_incomplete_errorcb(struct bufferevent *bev, short what, void *arg) test_ok++; else test_ok = -2; - event_loopexit(NULL); + event_base_loopexit(exit_base,NULL); } static void @@ -2281,7 +2433,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 +2441,17 @@ _http_incomplete_test(int use_timeout) ev_uint16_t port = 0; struct timeval tv_start, tv_end; + exit_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 +2464,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 +2488,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); } /* @@ -2367,7 +2521,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; @@ -2376,11 +2530,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; @@ -2440,7 +2594,7 @@ http_chunked_errorcb(struct bufferevent *bev, short what, void *arg) } out: - event_loopexit(NULL); + event_base_loopexit(arg, NULL); } static void @@ -2456,23 +2610,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"); @@ -2480,12 +2634,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; @@ -2495,17 +2650,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" @@ -2517,7 +2673,7 @@ http_chunk_out_test(void) evutil_gettimeofday(&tv_start, NULL); - event_dispatch(); + event_base_dispatch(data->base); bufferevent_free(bev); @@ -2529,16 +2685,16 @@ 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"); + 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, @@ -2546,7 +2702,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); } @@ -2559,17 +2715,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); /* @@ -2581,7 +2739,7 @@ http_stream_out_test(void) (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") @@ -2589,7 +2747,7 @@ http_stream_out_test(void) tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -2603,30 +2761,30 @@ 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); } - 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; @@ -2634,9 +2792,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); @@ -2647,7 +2806,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", @@ -2671,23 +2830,23 @@ _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); } 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); - event_loopexit(NULL); + event_base_loopexit(arg, NULL); } static void @@ -2698,18 +2857,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 */ @@ -2717,7 +2877,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: @@ -2730,41 +2890,44 @@ 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: - 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); @@ -2776,11 +2939,11 @@ 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 */ - 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) { @@ -2788,7 +2951,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); @@ -2803,11 +2966,11 @@ 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 */ - 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) { @@ -2815,7 +2978,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); @@ -2832,11 +2995,11 @@ 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 */ - 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) { @@ -2848,10 +3011,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); @@ -2895,8 +3059,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; @@ -2904,14 +3069,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" @@ -2925,7 +3090,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: @@ -2946,21 +3111,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); /* @@ -2968,17 +3134,17 @@ 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"); + 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) { tt_abort_msg("Couldn't make request"); } - event_dispatch(); + event_base_dispatch(data->base); end: if (evcon) @@ -2992,14 +3158,15 @@ 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_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; @@ -3007,9 +3174,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 */ @@ -3020,39 +3187,39 @@ 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); 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"); } - 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"); + 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) { 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); - evhttp_add_header(req->output_headers, "Host", "somehost"); - evbuffer_add_printf(req->output_buffer, "%s", long_str); + req = evhttp_request_new(http_data_length_constraints_test_done, data->base); + 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"); } - event_dispatch(); + event_base_dispatch(data->base); test_ok = 1; end: @@ -3067,11 +3234,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) @@ -3083,7 +3251,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; } @@ -3094,7 +3262,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 @@ -3121,7 +3291,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 @@ -3141,17 +3311,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); @@ -3159,10 +3331,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; @@ -3175,10 +3349,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; @@ -3194,44 +3368,46 @@ 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 }, + { "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 }, { "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_LEGACY(bad_request), - HTTP_LEGACY(incomplete), - HTTP_LEGACY(incomplete_timeout), - { "terminate_chunked", run_legacy_test_fn, - TT_ISOLATED|TT_LEGACY, &legacy_setup, - http_terminate_chunked_test }, + HTTP(basic), + HTTP(cancel), + HTTP(virtual_host), + HTTP(post), + HTTP(put), + HTTP(delete), + HTTP(allowed_methods), + HTTP(failure), + HTTP(connection), + HTTP(persist_connection), + HTTP(connection_async), + HTTP(close_detection), + HTTP(close_detection_delay), + HTTP(bad_request), + HTTP(incomplete), + HTTP(incomplete_timeout), + 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 }; 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/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-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 fd226193..90b40938 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; @@ -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 8d1b0ab8..0ea4d971 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; @@ -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"); diff --git a/win32select.c b/win32select.c index af8c6206..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, size_t 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)))