mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
fix memory leaks in the regression tools; add another close detection test that validates that there are no dangling connections on the server
svn:r969
This commit is contained in:
parent
f1728d94eb
commit
ebcf5efcfe
@ -827,6 +827,7 @@ test_free_active_base(void)
|
|||||||
event_base_free(base1);
|
event_base_free(base1);
|
||||||
test_ok = 1;
|
test_ok = 1;
|
||||||
cleanup_test();
|
cleanup_test();
|
||||||
|
event_base_free(global_base);
|
||||||
global_base = event_init();
|
global_base = event_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1259,6 +1260,7 @@ test_evbuffer_readln(void)
|
|||||||
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
|
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
|
||||||
if (cp)
|
if (cp)
|
||||||
goto done;
|
goto done;
|
||||||
|
free(cp);
|
||||||
evbuffer_validate(evb);
|
evbuffer_validate(evb);
|
||||||
evbuffer_add(evb, "\n", 1);
|
evbuffer_add(evb, "\n", 1);
|
||||||
evbuffer_validate(evb);
|
evbuffer_validate(evb);
|
||||||
@ -1266,6 +1268,7 @@ test_evbuffer_readln(void)
|
|||||||
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
|
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
|
||||||
if (!cp || sz != strlen(cp) || strcmp(cp, "More"))
|
if (!cp || sz != strlen(cp) || strcmp(cp, "More"))
|
||||||
goto done;
|
goto done;
|
||||||
|
free(cp);
|
||||||
if (EVBUFFER_LENGTH(evb) != 0)
|
if (EVBUFFER_LENGTH(evb) != 0)
|
||||||
goto done;
|
goto done;
|
||||||
evbuffer_validate(evb);
|
evbuffer_validate(evb);
|
||||||
@ -1290,11 +1293,13 @@ test_evbuffer_readln(void)
|
|||||||
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
|
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
|
||||||
if (cp)
|
if (cp)
|
||||||
goto done;
|
goto done;
|
||||||
|
free(cp);
|
||||||
evbuffer_add(evb, "\n", 1);
|
evbuffer_add(evb, "\n", 1);
|
||||||
evbuffer_validate(evb);
|
evbuffer_validate(evb);
|
||||||
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
|
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
|
||||||
if (!cp || sz != strlen(cp) || strcmp(cp, "Text"))
|
if (!cp || sz != strlen(cp) || strcmp(cp, "Text"))
|
||||||
goto done;
|
goto done;
|
||||||
|
free(cp);
|
||||||
evbuffer_validate(evb);
|
evbuffer_validate(evb);
|
||||||
|
|
||||||
/* Test CRLF_STRICT - across boundaries*/
|
/* Test CRLF_STRICT - across boundaries*/
|
||||||
@ -1330,12 +1335,14 @@ test_evbuffer_readln(void)
|
|||||||
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
|
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
|
||||||
if (cp)
|
if (cp)
|
||||||
goto done;
|
goto done;
|
||||||
|
free(cp);
|
||||||
evbuffer_validate(evb);
|
evbuffer_validate(evb);
|
||||||
evbuffer_add(evb, "\n", 1);
|
evbuffer_add(evb, "\n", 1);
|
||||||
evbuffer_validate(evb);
|
evbuffer_validate(evb);
|
||||||
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
|
cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
|
||||||
if (!cp || sz != strlen(cp) || strcmp(cp, "More"))
|
if (!cp || sz != strlen(cp) || strcmp(cp, "More"))
|
||||||
goto done;
|
goto done;
|
||||||
|
free(cp); cp = NULL;
|
||||||
evbuffer_validate(evb);
|
evbuffer_validate(evb);
|
||||||
if (EVBUFFER_LENGTH(evb) != 0)
|
if (EVBUFFER_LENGTH(evb) != 0)
|
||||||
goto done;
|
goto done;
|
||||||
@ -2258,6 +2265,10 @@ main (int argc, char **argv)
|
|||||||
err = WSAStartup( wVersionRequested, &wsaData );
|
err = WSAStartup( wVersionRequested, &wsaData );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||||
|
return (1);
|
||||||
|
#endif
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
|
||||||
test_methods();
|
test_methods();
|
||||||
|
@ -74,6 +74,7 @@ static void http_post_cb(struct evhttp_request *req, void *arg);
|
|||||||
static void http_put_cb(struct evhttp_request *req, void *arg);
|
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_delete_cb(struct evhttp_request *req, void *arg);
|
||||||
static void http_delay_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 void http_dispatcher_cb(struct evhttp_request *req, void *arg);
|
||||||
|
|
||||||
static struct evhttp *
|
static struct evhttp *
|
||||||
@ -103,6 +104,7 @@ http_setup(short *pport, struct event_base *base)
|
|||||||
evhttp_set_cb(myhttp, "/putit", http_put_cb, NULL);
|
evhttp_set_cb(myhttp, "/putit", http_put_cb, NULL);
|
||||||
evhttp_set_cb(myhttp, "/deleteit", http_delete_cb, NULL);
|
evhttp_set_cb(myhttp, "/deleteit", http_delete_cb, NULL);
|
||||||
evhttp_set_cb(myhttp, "/delay", http_delay_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);
|
evhttp_set_cb(myhttp, "/", http_dispatcher_cb, NULL);
|
||||||
|
|
||||||
*pport = port;
|
*pport = port;
|
||||||
@ -277,7 +279,7 @@ http_chunked_trickle_cb(evutil_socket_t fd, short events, void *arg)
|
|||||||
struct chunk_req_state *state = arg;
|
struct chunk_req_state *state = arg;
|
||||||
struct timeval when = { 0, 0 };
|
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);
|
evhttp_send_reply_chunk(state->req, evb);
|
||||||
evbuffer_free(evb);
|
evbuffer_free(evb);
|
||||||
|
|
||||||
@ -419,6 +421,19 @@ http_delay_cb(struct evhttp_request *req, void *arg)
|
|||||||
event_once(-1, EV_TIMEOUT, http_delay_reply, req, &tv);
|
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
|
* HTTP DELETE test, just piggyback on the basic test
|
||||||
*/
|
*/
|
||||||
@ -1293,14 +1308,17 @@ http_failure_test(void)
|
|||||||
static void
|
static void
|
||||||
close_detect_done(struct evhttp_request *req, void *arg)
|
close_detect_done(struct evhttp_request *req, void *arg)
|
||||||
{
|
{
|
||||||
|
struct timeval tv;
|
||||||
if (req == NULL || req->response_code != HTTP_OK) {
|
if (req == NULL || req->response_code != HTTP_OK) {
|
||||||
|
|
||||||
fprintf(stderr, "FAILED\n");
|
fprintf(stderr, "FAILED\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
test_ok = 1;
|
test_ok = 1;
|
||||||
event_loopexit(NULL);
|
|
||||||
|
timerclear(&tv);
|
||||||
|
tv.tv_sec = 3;
|
||||||
|
event_loopexit(&tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1327,7 +1345,7 @@ close_detect_cb(struct evhttp_request *req, void *arg)
|
|||||||
struct evhttp_connection *evcon = arg;
|
struct evhttp_connection *evcon = arg;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
if (req->response_code != HTTP_OK) {
|
if (req != NULL && req->response_code != HTTP_OK) {
|
||||||
|
|
||||||
fprintf(stderr, "FAILED\n");
|
fprintf(stderr, "FAILED\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -1336,20 +1354,21 @@ close_detect_cb(struct evhttp_request *req, void *arg)
|
|||||||
timerclear(&tv);
|
timerclear(&tv);
|
||||||
tv.tv_sec = 3; /* longer than the http time out */
|
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);
|
event_once(-1, EV_TIMEOUT, close_detect_launch, evcon, &tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
http_close_detection(void)
|
http_close_detection(int with_delay)
|
||||||
{
|
{
|
||||||
short port = -1;
|
short port = -1;
|
||||||
struct evhttp_connection *evcon = NULL;
|
struct evhttp_connection *evcon = NULL;
|
||||||
struct evhttp_request *req = NULL;
|
struct evhttp_request *req = NULL;
|
||||||
|
|
||||||
test_ok = 0;
|
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);
|
http = http_setup(&port, NULL);
|
||||||
|
|
||||||
@ -1362,6 +1381,8 @@ http_close_detection(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delayed_client = evcon;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, we want to schedule a request to the HTTP
|
* At this point, we want to schedule a request to the HTTP
|
||||||
* server using our make request method.
|
* server using our make request method.
|
||||||
@ -1373,7 +1394,8 @@ http_close_detection(void)
|
|||||||
evhttp_add_header(req->output_headers, "Host", "somehost");
|
evhttp_add_header(req->output_headers, "Host", "somehost");
|
||||||
|
|
||||||
/* We give ownership of the request to the connection */
|
/* 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");
|
fprintf(stdout, "FAILED\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -1385,6 +1407,12 @@ http_close_detection(void)
|
|||||||
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_connection_free(evcon);
|
||||||
evhttp_free(http);
|
evhttp_free(http);
|
||||||
|
|
||||||
@ -1449,7 +1477,8 @@ fail:
|
|||||||
static void
|
static void
|
||||||
http_base_test(void)
|
http_base_test(void)
|
||||||
{
|
{
|
||||||
struct bufferevent *bev;
|
struct event_base *tmp;
|
||||||
|
struct bufferevent *bev;
|
||||||
int fd;
|
int fd;
|
||||||
const char *http_request;
|
const char *http_request;
|
||||||
short port = -1;
|
short port = -1;
|
||||||
@ -1463,7 +1492,7 @@ http_base_test(void)
|
|||||||
* create another bogus base - which is being used by all subsequen
|
* create another bogus base - which is being used by all subsequen
|
||||||
* tests - yuck!
|
* tests - yuck!
|
||||||
*/
|
*/
|
||||||
event_init();
|
tmp = event_init();
|
||||||
|
|
||||||
http = http_setup(&port, base);
|
http = http_setup(&port, base);
|
||||||
|
|
||||||
@ -1490,7 +1519,7 @@ http_base_test(void)
|
|||||||
evhttp_free(http);
|
evhttp_free(http);
|
||||||
|
|
||||||
event_base_free(base);
|
event_base_free(base);
|
||||||
base = NULL;
|
base = tmp;
|
||||||
|
|
||||||
if (test_ok != 2) {
|
if (test_ok != 2) {
|
||||||
fprintf(stdout, "FAILED\n");
|
fprintf(stdout, "FAILED\n");
|
||||||
@ -1576,8 +1605,8 @@ http_incomplete_test(int use_timeout)
|
|||||||
evutil_gettimeofday(&tv_end, NULL);
|
evutil_gettimeofday(&tv_end, NULL);
|
||||||
evutil_timersub(&tv_end, &tv_start, &tv_end);
|
evutil_timersub(&tv_end, &tv_start, &tv_end);
|
||||||
|
|
||||||
|
bufferevent_free(bev);
|
||||||
if (use_timeout) {
|
if (use_timeout) {
|
||||||
bufferevent_free(bev);
|
|
||||||
EVUTIL_CLOSESOCKET(fd);
|
EVUTIL_CLOSESOCKET(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1692,6 +1721,8 @@ http_chunked_errorcb(struct bufferevent *bev, short what, void *arg)
|
|||||||
free((char *)header);
|
free((char *)header);
|
||||||
|
|
||||||
test_ok = 2;
|
test_ok = 2;
|
||||||
|
|
||||||
|
evhttp_request_free(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -1774,6 +1805,8 @@ http_chunk_out_test(void)
|
|||||||
|
|
||||||
event_dispatch();
|
event_dispatch();
|
||||||
|
|
||||||
|
bufferevent_free(bev);
|
||||||
|
|
||||||
evutil_gettimeofday(&tv_end, NULL);
|
evutil_gettimeofday(&tv_end, NULL);
|
||||||
evutil_timersub(&tv_end, &tv_start, &tv_end);
|
evutil_timersub(&tv_end, &tv_start, &tv_end);
|
||||||
|
|
||||||
@ -2312,6 +2345,7 @@ http_negative_content_length_test(void)
|
|||||||
|
|
||||||
event_dispatch();
|
event_dispatch();
|
||||||
|
|
||||||
|
evhttp_connection_free(evcon);
|
||||||
evhttp_free(http);
|
evhttp_free(http);
|
||||||
|
|
||||||
if (test_ok != 1) {
|
if (test_ok != 1) {
|
||||||
@ -2334,7 +2368,8 @@ http_suite(void)
|
|||||||
http_connection_test(0 /* not-persistent */);
|
http_connection_test(0 /* not-persistent */);
|
||||||
http_connection_test(1 /* persistent */);
|
http_connection_test(1 /* persistent */);
|
||||||
http_virtual_host_test();
|
http_virtual_host_test();
|
||||||
http_close_detection();
|
http_close_detection(0 /* with delay */);
|
||||||
|
http_close_detection(1 /* with delay */);
|
||||||
http_post_test();
|
http_post_test();
|
||||||
http_put_test();
|
http_put_test();
|
||||||
http_delete_test();
|
http_delete_test();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user