mirror of
https://github.com/libevent/libevent.git
synced 2025-01-09 00:56:20 +08:00
Fix crashing http server when callback do not reply in place from *gencb*
This is the second hunk of the first patch 5ff8eb26371c4dc56f384b2de35bea2d87814779 ("Fix crashing http server when callback do not reply in place") Fixes: #567
This commit is contained in:
parent
3f19c5eb83
commit
306747e51c
4
http.c
4
http.c
@ -3421,6 +3421,8 @@ 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;
|
||||
|
||||
bufferevent_disable(req->evcon->bufev, EV_READ);
|
||||
|
||||
if (req->type == 0 || req->uri == NULL) {
|
||||
evhttp_send_error(req, req->response_code, NULL);
|
||||
return;
|
||||
@ -3440,8 +3442,6 @@ evhttp_handle_request(struct evhttp_request *req, void *arg)
|
||||
}
|
||||
|
||||
if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
|
||||
bufferevent_disable(req->evcon->bufev, EV_READ);
|
||||
|
||||
(*cb->cb)(req, cb->cbarg);
|
||||
return;
|
||||
}
|
||||
|
@ -129,7 +129,8 @@ https_bev(struct event_base *base, void *arg)
|
||||
}
|
||||
#endif
|
||||
static struct evhttp *
|
||||
http_setup(ev_uint16_t *pport, struct event_base *base, int mask)
|
||||
http_setup_gencb(ev_uint16_t *pport, struct event_base *base, int mask,
|
||||
void (*cb)(struct evhttp_request *, void *), void *cbarg)
|
||||
{
|
||||
struct evhttp *myhttp;
|
||||
|
||||
@ -145,6 +146,8 @@ http_setup(ev_uint16_t *pport, struct event_base *base, int mask)
|
||||
}
|
||||
#endif
|
||||
|
||||
evhttp_set_gencb(myhttp, cb, cbarg);
|
||||
|
||||
/* Register a callback for certain types of requests */
|
||||
evhttp_set_cb(myhttp, "/test", http_basic_cb, myhttp);
|
||||
evhttp_set_cb(myhttp, "/timeout", http_timeout_cb, myhttp);
|
||||
@ -161,6 +164,9 @@ http_setup(ev_uint16_t *pport, struct event_base *base, int mask)
|
||||
evhttp_set_cb(myhttp, "/", http_dispatcher_cb, base);
|
||||
return (myhttp);
|
||||
}
|
||||
static struct evhttp *
|
||||
http_setup(ev_uint16_t *pport, struct event_base *base, int mask)
|
||||
{ return http_setup_gencb(pport, base, mask, NULL, NULL); }
|
||||
|
||||
#ifndef NI_MAXSERV
|
||||
#define NI_MAXSERV 1024
|
||||
@ -4526,44 +4532,68 @@ http_request_own_test(void *arg)
|
||||
test_ok = 1;
|
||||
}
|
||||
|
||||
static void http_run_bev_request(struct event_base *base, int port,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
struct bufferevent *bev = NULL;
|
||||
va_list ap;
|
||||
evutil_socket_t fd;
|
||||
struct evbuffer *out;
|
||||
|
||||
fd = http_connect("127.0.0.1", port);
|
||||
|
||||
/* Stupid thing to send a request */
|
||||
bev = create_bev(base, fd, 0);
|
||||
bufferevent_setcb(bev, http_readcb, http_writecb,
|
||||
http_errorcb, base);
|
||||
out = bufferevent_get_output(bev);
|
||||
|
||||
va_start(ap, fmt);
|
||||
evbuffer_add_vprintf(out, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
event_base_dispatch(base);
|
||||
|
||||
bufferevent_free(bev);
|
||||
}
|
||||
static void
|
||||
http_request_extra_body_test(void *arg)
|
||||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct bufferevent *bev = NULL;
|
||||
evutil_socket_t fd;
|
||||
ev_uint16_t port = 0;
|
||||
int i;
|
||||
struct evhttp *http = http_setup(&port, data->base, 0);
|
||||
struct evbuffer *out, *body = NULL;
|
||||
struct evhttp *http =
|
||||
http_setup_gencb(&port, data->base, 0, http_timeout_cb, NULL);
|
||||
struct evbuffer *body = NULL;
|
||||
|
||||
exit_base = data->base;
|
||||
test_ok = 0;
|
||||
|
||||
fd = http_connect("127.0.0.1", port);
|
||||
|
||||
/* Stupid thing to send a request */
|
||||
bev = create_bev(data->base, fd, 0);
|
||||
bufferevent_setcb(bev, http_readcb, http_writecb,
|
||||
http_errorcb, data->base);
|
||||
out = bufferevent_get_output(bev);
|
||||
body = evbuffer_new();
|
||||
|
||||
for (i = 0; i < 10000; ++i)
|
||||
evbuffer_add_printf(body, "this is the body that HEAD should not have");
|
||||
|
||||
evbuffer_add_printf(out,
|
||||
http_run_bev_request(data->base, port,
|
||||
"HEAD /timeout HTTP/1.1\r\n"
|
||||
"Host: somehost\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-Length: %i\r\n"
|
||||
"\r\n",
|
||||
(int)evbuffer_get_length(body)
|
||||
"\r\n%s",
|
||||
(int)evbuffer_get_length(body),
|
||||
evbuffer_pullup(body, -1)
|
||||
);
|
||||
evbuffer_add_buffer(out, body);
|
||||
|
||||
event_base_dispatch(data->base);
|
||||
tt_assert(test_ok == -2);
|
||||
|
||||
http_run_bev_request(data->base, port,
|
||||
"HEAD /__gencb__ HTTP/1.1\r\n"
|
||||
"Host: somehost\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-Length: %i\r\n"
|
||||
"\r\n%s",
|
||||
(int)evbuffer_get_length(body),
|
||||
evbuffer_pullup(body, -1)
|
||||
);
|
||||
tt_assert(test_ok == -2);
|
||||
|
||||
end:
|
||||
|
Loading…
x
Reference in New Issue
Block a user