event_base_free(base1);
test_ok = 1;
cleanup_test();
+ event_base_free(global_base);
global_base = event_init();
}
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
if (cp)
goto done;
+ free(cp);
evbuffer_validate(evb);
evbuffer_add(evb, "\n", 1);
evbuffer_validate(evb);
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
if (!cp || sz != strlen(cp) || strcmp(cp, "More"))
goto done;
+ free(cp);
if (EVBUFFER_LENGTH(evb) != 0)
goto done;
evbuffer_validate(evb);
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
if (cp)
goto done;
+ free(cp);
evbuffer_add(evb, "\n", 1);
evbuffer_validate(evb);
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
if (!cp || sz != strlen(cp) || strcmp(cp, "Text"))
goto done;
+ free(cp);
evbuffer_validate(evb);
/* Test CRLF_STRICT - across boundaries*/
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
if (cp)
goto done;
+ free(cp);
evbuffer_validate(evb);
evbuffer_add(evb, "\n", 1);
evbuffer_validate(evb);
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
if (!cp || sz != strlen(cp) || strcmp(cp, "More"))
goto done;
+ free(cp); cp = NULL;
evbuffer_validate(evb);
if (EVBUFFER_LENGTH(evb) != 0)
goto done;
err = WSAStartup( wVersionRequested, &wsaData );
#endif
+#ifndef WIN32
+ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
+ return (1);
+#endif
setvbuf(stdout, NULL, _IONBF, 0);
test_methods();
static void http_put_cb(struct evhttp_request *req, void *arg);
static void http_delete_cb(struct evhttp_request *req, void *arg);
static void http_delay_cb(struct evhttp_request *req, void *arg);
+static void http_large_delay_cb(struct evhttp_request *req, void *arg);
static void http_dispatcher_cb(struct evhttp_request *req, void *arg);
static struct evhttp *
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, "/", http_dispatcher_cb, NULL);
*pport = port;
struct chunk_req_state *state = arg;
struct timeval when = { 0, 0 };
- evbuffer_add_printf(evb, CHUNKS[state->i]);
+ evbuffer_add_printf(evb, "%s", CHUNKS[state->i]);
evhttp_send_reply_chunk(state->req, evb);
evbuffer_free(evb);
event_once(-1, EV_TIMEOUT, http_delay_reply, req, &tv);
}
+static struct evhttp_connection *delayed_client;
+
+static void
+http_large_delay_cb(struct evhttp_request *req, void *arg)
+{
+ struct timeval tv;
+ timerclear(&tv);
+ tv.tv_sec = 3;
+
+ event_once(-1, EV_TIMEOUT, http_delay_reply, req, &tv);
+ evhttp_connection_fail(delayed_client, EVCON_HTTP_EOF);
+}
+
/*
* HTTP DELETE test, just piggyback on the basic test
*/
static void
close_detect_done(struct evhttp_request *req, void *arg)
{
+ struct timeval tv;
if (req == NULL || req->response_code != HTTP_OK) {
-
fprintf(stderr, "FAILED\n");
exit(1);
}
test_ok = 1;
- event_loopexit(NULL);
+
+ timerclear(&tv);
+ tv.tv_sec = 3;
+ event_loopexit(&tv);
}
static void
struct evhttp_connection *evcon = arg;
struct timeval tv;
- if (req->response_code != HTTP_OK) {
+ if (req != NULL && req->response_code != HTTP_OK) {
fprintf(stderr, "FAILED\n");
exit(1);
timerclear(&tv);
tv.tv_sec = 3; /* longer than the http time out */
- /* launch a new request on the persistent connection in 6 seconds */
+ /* launch a new request on the persistent connection in 3 seconds */
event_once(-1, EV_TIMEOUT, close_detect_launch, evcon, &tv);
}
static void
-http_close_detection(void)
+http_close_detection(int with_delay)
{
short port = -1;
struct evhttp_connection *evcon = NULL;
struct evhttp_request *req = NULL;
test_ok = 0;
- fprintf(stdout, "Testing Connection Close Detection: ");
+ fprintf(stdout, "Testing Connection Close Detection%s: ",
+ with_delay ? " (with delay)" : "");
http = http_setup(&port, NULL);
exit(1);
}
+ delayed_client = evcon;
+
/*
* At this point, we want to schedule a request to the HTTP
* server using our make request method.
evhttp_add_header(req->output_headers, "Host", "somehost");
/* We give ownership of the request to the connection */
- if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) {
+ if (evhttp_make_request(evcon,
+ req, EVHTTP_REQ_GET, with_delay ? "/largedelay" : "/test") == -1) {
fprintf(stdout, "FAILED\n");
exit(1);
}
exit(1);
}
+ /* at this point, the http server should have no connection */
+ if (TAILQ_FIRST(&http->connections) != NULL) {
+ fprintf(stdout, "FAILED (left connections)\n");
+ exit(1);
+ }
+
evhttp_connection_free(evcon);
evhttp_free(http);
static void
http_base_test(void)
{
- struct bufferevent *bev;
+ struct event_base *tmp;
+ struct bufferevent *bev;
int fd;
const char *http_request;
short port = -1;
* create another bogus base - which is being used by all subsequen
* tests - yuck!
*/
- event_init();
+ tmp = event_init();
http = http_setup(&port, base);
evhttp_free(http);
event_base_free(base);
- base = NULL;
+ base = tmp;
if (test_ok != 2) {
fprintf(stdout, "FAILED\n");
evutil_gettimeofday(&tv_end, NULL);
evutil_timersub(&tv_end, &tv_start, &tv_end);
+ bufferevent_free(bev);
if (use_timeout) {
- bufferevent_free(bev);
EVUTIL_CLOSESOCKET(fd);
}
free((char *)header);
test_ok = 2;
+
+ evhttp_request_free(req);
}
out:
event_dispatch();
+ bufferevent_free(bev);
+
evutil_gettimeofday(&tv_end, NULL);
evutil_timersub(&tv_end, &tv_start, &tv_end);
event_dispatch();
+ evhttp_connection_free(evcon);
evhttp_free(http);
if (test_ok != 1) {
http_connection_test(0 /* not-persistent */);
http_connection_test(1 /* persistent */);
http_virtual_host_test();
- http_close_detection();
+ http_close_detection(0 /* with delay */);
+ http_close_detection(1 /* with delay */);
http_post_test();
http_put_test();
http_delete_test();