From 4014bc53bd0dbc1f328a4889c79d1d55de191ffb Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Sun, 21 Oct 2012 11:31:47 +0200 Subject: [PATCH] fixed handling of 'remaining' post data in http router --- core/event.c | 6 ++--- plugins/http/http.c | 55 +++++++++++++++++++++++++++++++++------------ uwsgiconfig.py | 2 +- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/core/event.c b/core/event.c index 58291d4c..e5816110 100644 --- a/core/event.c +++ b/core/event.c @@ -108,7 +108,7 @@ int event_queue_interesting_fd_has_error(void *events, int id) { int event_queue_interesting_fd_is_read(void *events, int id) { port_event_t *pe = (port_event_t *) events; - if (pe[id].portev_events == POLLIN) { + if (pe[id].portev_events = POLLIN) { return 1; } return 0; @@ -427,7 +427,7 @@ int event_queue_interesting_fd_has_error(void *events, int id) { int event_queue_interesting_fd_is_read(void *events, int id) { struct epoll_event *ee = (struct epoll_event *) events; - if (ee[id].events == EPOLLIN) { + if (ee[id].events & EPOLLIN) { return 1; } return 0; @@ -435,7 +435,7 @@ int event_queue_interesting_fd_is_read(void *events, int id) { int event_queue_interesting_fd_is_write(void *events, int id) { struct epoll_event *ee = (struct epoll_event *) events; - if (ee[id].events == EPOLLOUT) { + if (ee[id].events & EPOLLOUT) { return 1; } return 0; diff --git a/plugins/http/http.c b/plugins/http/http.c index b85ee3a7..c86d85b8 100644 --- a/plugins/http/http.c +++ b/plugins/http/http.c @@ -585,6 +585,41 @@ ssize_t hr_instance_read_response(struct corerouter_session * cs) { return len; } +int hr_start_waiting(struct corerouter_session * cs) { + struct http_session *hs = (struct http_session *) cs; + // stop writing to the instance + uwsgi_cr_hook_instance_write(cs, NULL); + // start reading from the instance + uwsgi_cr_hook_instance_read(cs, hr_instance_read_response); + // re-start reading from the client (for body or connection close) + // allocate a buffer for client body (could be delimited or dynamic) + hs->post_buf_max = UMAX16; + if (cs->post_cl > 0) { + hs->post_buf_max = UMIN(UMAX16, cs->post_cl); + } + hs->post_buf = uwsgi_buffer_new(hs->post_buf_max); + if (!hs->post_buf) + return -1; + uwsgi_cr_hook_read(cs, hr_read_body); + return 0; +} + +ssize_t hr_post_remains(struct corerouter_session * cs) { + char *ptr = (cs->buffer->buf + cs->buffer->pos) - cs->post_remains; + ssize_t len = write(cs->instance_fd, ptr + cs->buffer_pos, cs->post_remains - cs->buffer_pos); + if (len < 0) { + cr_try_again; + uwsgi_error("hr_post_remains()"); + return -1; + } + + cs->buffer_pos += len; + if (cs->buffer_pos == (ssize_t) cs->post_remains) { + if (hr_start_waiting(cs)) return -1; + } + + return len; +} ssize_t hr_instance_send_request(struct corerouter_session * cs) { struct http_session *hs = (struct http_session *) cs; @@ -601,20 +636,12 @@ ssize_t hr_instance_send_request(struct corerouter_session * cs) { // for response if (cs->buffer_pos == cs->uh.pktsize) { cs->buffer_pos = 0; - // stop writing to the instance - uwsgi_cr_hook_instance_write(cs, NULL); - // start reading from the instance - uwsgi_cr_hook_instance_read(cs, hr_instance_read_response); - // re-start reading from the client (for body or connection close) - // allocate a buffer for client body (could be delimited or dynamic) - hs->post_buf_max = UMAX16; - if (cs->post_cl > 0) { - hs->post_buf_max = UMIN(UMAX16, cs->post_cl); - } - hs->post_buf = uwsgi_buffer_new(hs->post_buf_max); - if (!hs->post_buf) - return -1; - uwsgi_cr_hook_read(cs, hr_read_body); + // some HTTP body left ? + if (cs->post_remains > 0) { + uwsgi_cr_hook_instance_write(cs, hr_post_remains); + return len; + } + if (hr_start_waiting(cs)) return -1; } return len; diff --git a/uwsgiconfig.py b/uwsgiconfig.py index de9d3ac0..95e74037 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -1,6 +1,6 @@ # uWSGI build system -uwsgi_version = '1.3.1-dev' +uwsgi_version = '1.4-dev' import os import re