parser fixes / deal with paused responses better.
- parser: in some cases, the next state was not being set if a user callback returned a non 0. - evhtp: check for a paused request, no matter if the parser failed.
This commit is contained in:
parent
96130f831c
commit
9d8e243235
4 changed files with 30 additions and 38 deletions
15
evhtp.c
15
evhtp.c
|
@ -1452,16 +1452,13 @@ _evhtp_connection_readcb(evbev_t * bev, void * arg) {
|
|||
}
|
||||
}
|
||||
|
||||
if (avail != nread) {
|
||||
if (c->request && c->request->status == EVHTP_RES_PAUSE) {
|
||||
evhtp_request_pause(c->request);
|
||||
} else {
|
||||
evhtp_connection_free(c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
evbuffer_drain(bufferevent_get_input(bev), nread);
|
||||
|
||||
if (c->request && c->request->status == EVHTP_RES_PAUSE) {
|
||||
evhtp_request_pause(c->request);
|
||||
} else if (avail != nread) {
|
||||
evhtp_connection_free(c);
|
||||
}
|
||||
} /* _evhtp_connection_readcb */
|
||||
|
||||
static void
|
||||
|
|
|
@ -1591,15 +1591,15 @@ hdrline_start:
|
|||
|
||||
switch (ch) {
|
||||
case CR:
|
||||
res = hook_hdr_val_run(p, hooks, p->buf, p->buf_idx);
|
||||
res = hook_hdr_val_run(p, hooks, p->buf, p->buf_idx);
|
||||
p->state = s_hdrline_almost_done;
|
||||
|
||||
if (res) {
|
||||
p->error = htparse_error_user;
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
p->state = s_hdrline_almost_done;
|
||||
res = hook_on_hdrs_complete_run(p, hooks);
|
||||
res = hook_on_hdrs_complete_run(p, hooks);
|
||||
|
||||
if (res) {
|
||||
p->error = htparse_error_user;
|
||||
|
@ -1615,21 +1615,22 @@ hdrline_start:
|
|||
case '\t':
|
||||
/* this is a multiline header value, we must go back to
|
||||
* reading as a header value */
|
||||
p->state = s_hdrline_hdr_val;
|
||||
p->state = s_hdrline_hdr_val;
|
||||
break;
|
||||
default:
|
||||
res = hook_hdr_val_run(p, hooks, p->buf, p->buf_idx);
|
||||
res = hook_hdr_val_run(p, hooks, p->buf, p->buf_idx);
|
||||
|
||||
p->buf_idx = 0;
|
||||
p->buf[p->buf_idx++] = ch;
|
||||
p->buf[p->buf_idx] = '\0';
|
||||
|
||||
p->state = s_hdrline_hdr_key;
|
||||
|
||||
if (res) {
|
||||
p->error = htparse_error_user;
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
p->buf_idx = 0;
|
||||
p->buf[p->buf_idx++] = ch;
|
||||
p->buf[p->buf_idx] = '\0';
|
||||
|
||||
p->state = s_hdrline_hdr_key;
|
||||
break;
|
||||
} /* switch */
|
||||
break;
|
||||
|
@ -1675,7 +1676,9 @@ hdrline_start:
|
|||
break;
|
||||
case s_hdrline_done:
|
||||
htparse_log_debug("[%p] s_hdrline_done", p);
|
||||
|
||||
res = 0;
|
||||
|
||||
if (p->flags & parser_flag_trailing) {
|
||||
res = hook_on_msg_complete_run(p, hooks);
|
||||
p->state = s_start;
|
||||
|
@ -1694,8 +1697,8 @@ hdrline_start:
|
|||
p->error = htparse_error_user;
|
||||
return i + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
case s_chunk_size_start:
|
||||
c = unhex[(unsigned char)ch];
|
||||
|
||||
|
|
12
test_basic.c
12
test_basic.c
|
@ -15,13 +15,11 @@ testcb(evhtp_request_t * req, void * a) {
|
|||
|
||||
int
|
||||
main(int argc, char ** argv) {
|
||||
evbase_t * evbase = event_base_new();
|
||||
evhtp_t * htp = evhtp_new(evbase, NULL);
|
||||
evhtp_callback_t * cb_1 = NULL;
|
||||
evhtp_callback_t * cb_2 = NULL;
|
||||
evbase_t * evbase = event_base_new();
|
||||
evhtp_t * htp = evhtp_new(evbase, NULL);
|
||||
|
||||
cb_1 = evhtp_set_cb(htp, "/1/ping", testcb, "one");
|
||||
cb_2 = evhtp_set_cb(htp, "/1/ping.json", testcb, "two");
|
||||
evhtp_set_cb(htp, "/1/ping", testcb, "one");
|
||||
evhtp_set_cb(htp, "/1/ping.json", testcb, "two");
|
||||
#ifndef EVHTP_DISABLE_EVTHR
|
||||
evhtp_use_threads(htp, NULL, 4, NULL);
|
||||
#endif
|
||||
|
@ -30,8 +28,6 @@ main(int argc, char ** argv) {
|
|||
event_base_loop(evbase, 0);
|
||||
|
||||
evhtp_unbind_socket(htp);
|
||||
evhtp_callback_free(cb_2);
|
||||
evhtp_callback_free(cb_1);
|
||||
evhtp_free(htp);
|
||||
event_base_free(evbase);
|
||||
|
||||
|
|
16
test_vhost.c
16
test_vhost.c
|
@ -13,15 +13,13 @@ testcb(evhtp_request_t * req, void * a) {
|
|||
|
||||
int
|
||||
main(int argc, char ** argv) {
|
||||
evbase_t * evbase = event_base_new();
|
||||
evhtp_t * evhtp = evhtp_new(evbase, NULL);
|
||||
evhtp_t * v1 = evhtp_new(evbase, NULL);
|
||||
evhtp_t * v2 = evhtp_new(evbase, NULL);
|
||||
evhtp_callback_t * cb_1 = NULL;
|
||||
evhtp_callback_t * cb_2 = NULL;
|
||||
evbase_t * evbase = event_base_new();
|
||||
evhtp_t * evhtp = evhtp_new(evbase, NULL);
|
||||
evhtp_t * v1 = evhtp_new(evbase, NULL);
|
||||
evhtp_t * v2 = evhtp_new(evbase, NULL);
|
||||
|
||||
cb_1 = evhtp_set_cb(v1, "/host1", NULL, "host1.com");
|
||||
cb_2 = evhtp_set_cb(v2, "/localhost", testcb, "localhost");
|
||||
evhtp_set_cb(v1, "/host1", NULL, "host1.com");
|
||||
evhtp_set_cb(v2, "/localhost", testcb, "localhost");
|
||||
|
||||
evhtp_add_vhost(evhtp, "host1.com", v1);
|
||||
evhtp_add_vhost(evhtp, "localhost", v2);
|
||||
|
@ -46,8 +44,6 @@ main(int argc, char ** argv) {
|
|||
event_base_loop(evbase, 0);
|
||||
|
||||
evhtp_unbind_socket(evhtp);
|
||||
evhtp_callback_free(cb_2);
|
||||
evhtp_callback_free(cb_1);
|
||||
evhtp_free(v2);
|
||||
evhtp_free(v1);
|
||||
evhtp_free(evhtp);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue