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:
Mark Ellzey 2012-12-06 12:28:28 -05:00
parent 96130f831c
commit 9d8e243235
4 changed files with 30 additions and 38 deletions

15
evhtp.c
View file

@ -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

View file

@ -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];

View file

@ -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);

View file

@ -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);