diff --git a/plugins/corerouter/corerouter.c b/plugins/corerouter/corerouter.c index 296370fa..24c6abbd 100644 --- a/plugins/corerouter/corerouter.c +++ b/plugins/corerouter/corerouter.c @@ -340,9 +340,19 @@ static void corerouter_expire_timeouts(struct uwsgi_corerouter *ucr) { } } -struct corerouter_session *corerouter_alloc_session(size_t size) { +struct corerouter_session *corerouter_alloc_session(struct uwsgi_corerouter *ucr, struct uwsgi_gateway_socket *ugs, int new_connection, struct sockaddr *cr_addr, socklen_t cr_addr_len) { - return uwsgi_calloc(size); + ucr->cr_table[new_connection] = uwsgi_calloc(ucr->session_size); + ucr->cr_table[new_connection]->fd = new_connection; + ucr->cr_table[new_connection]->instance_fd = -1; + ucr->cr_table[new_connection]->status = COREROUTER_STATUS_RECV_HDR; + + ucr->cr_table[new_connection]->timeout = cr_add_timeout(ucr, ucr->cr_table[new_connection]); + + ucr->alloc_session(ucr, ugs, ucr->cr_table[new_connection], cr_addr, cr_addr_len); + event_queue_add_fd_read(ucr->queue, new_connection); + + return ucr->cr_table[new_connection]; } void uwsgi_corerouter_loop(int id, void *data) { @@ -530,16 +540,7 @@ void uwsgi_corerouter_loop(int id, void *data) { uwsgi_socket_b(new_connection); #endif - ucr->cr_table[new_connection] = corerouter_alloc_session(ucr->session_size); - ucr->cr_table[new_connection]->fd = new_connection; - ucr->cr_table[new_connection]->instance_fd = -1; - ucr->cr_table[new_connection]->status = COREROUTER_STATUS_RECV_HDR; - - ucr->cr_table[new_connection]->timeout = cr_add_timeout(ucr, ucr->cr_table[new_connection]); - - ucr->alloc_session(ucr, ugs, ucr->cr_table[new_connection], (struct sockaddr *) &cr_addr, cr_addr_len); - - event_queue_add_fd_read(ucr->queue, new_connection); + corerouter_alloc_session(ucr, ugs, new_connection, (struct sockaddr *) &cr_addr, cr_addr_len); } else if (ugs->subscription) { uwsgi_corerouter_manage_subscription(ucr, id, ugs); diff --git a/plugins/corerouter/cr.h b/plugins/corerouter/cr.h index 5f0a9301..3fea890e 100644 --- a/plugins/corerouter/cr.h +++ b/plugins/corerouter/cr.h @@ -165,6 +165,7 @@ void uwsgi_corerouter_setup_sockets(struct uwsgi_corerouter *); int uwsgi_corerouter_init(struct uwsgi_corerouter *); +struct corerouter_session *corerouter_alloc_session(struct uwsgi_corerouter *, struct uwsgi_gateway_socket *, int, struct sockaddr *, socklen_t); void corerouter_close_session(struct uwsgi_corerouter *, struct corerouter_session *); int uwsgi_cr_map_use_void(struct uwsgi_corerouter *, struct corerouter_session *); diff --git a/plugins/http/http.c b/plugins/http/http.c index a5ba302e..d6a446e5 100644 --- a/plugins/http/http.c +++ b/plugins/http/http.c @@ -25,6 +25,7 @@ struct uwsgi_http { uint8_t modifier1; struct uwsgi_string_list *http_vars; int manage_expect; + int keepalive; } uhttp; @@ -46,6 +47,7 @@ struct uwsgi_option http_options[] = { {"http-subscription-use-regexp", no_argument, 0, "enable regexp usage in subscription system", uwsgi_opt_true, &uhttp.cr.subscription_regexp, 0}, {"http-timeout", required_argument, 0, "set internal http socket timeout", uwsgi_opt_set_int, &uhttp.cr.socket_timeout, 0}, {"http-manage-expect", no_argument, 0, "manage the Expect HTTP request header", uwsgi_opt_true, &uhttp.manage_expect, 0}, + {"http-keepalive", no_argument, 0, "support HTTP keepalive requests", uwsgi_opt_true, &uhttp.keepalive, 0}, {"http-use-code-string", required_argument, 0, "use code string as hostname->server mapper for the http router", uwsgi_opt_corerouter_cs, &uhttp, 0}, {"http-use-socket", optional_argument, 0, "forward request to the specified uwsgi socket", uwsgi_opt_corerouter_use_socket, &uhttp, 0}, @@ -83,6 +85,7 @@ struct http_session { size_t received_body; + in_addr_t ip_addr; char ip[INET_ADDRSTRLEN]; @@ -568,6 +571,7 @@ void uwsgi_http_switch_events(struct uwsgi_corerouter *ucr, struct corerouter_se break; } + // update transfer statistics if (cs->un) cs->un->transferred += len; @@ -576,6 +580,20 @@ void uwsgi_http_switch_events(struct uwsgi_corerouter *ucr, struct corerouter_se // body from client else if (interesting_fd == cs->fd) { + // Keep-Alive ? + if (uhttp.keepalive && hs->received_body >= cs->post_cl) { + // duplicate the socket + int new_ka_connection = dup(cs->fd); + if (new_ka_connection >= 0) { + uwsgi_log("keepalive to %d\n", new_ka_connection); + struct http_session *new_hs = (struct http_session *) corerouter_alloc_session(&uhttp.cr, NULL, new_ka_connection, NULL, -1); + new_hs->ip_addr = hs->ip_addr; + new_hs->port = hs->port; + new_hs->port_len = hs->port_len; + } + break; + } + len = recv(cs->fd, bbuf, UMAX16, 0); #ifdef UWSGI_EVENT_USE_PORT event_queue_add_fd_read(uhttp_queue, cs->fd); @@ -588,15 +606,11 @@ void uwsgi_http_switch_events(struct uwsgi_corerouter *ucr, struct corerouter_se } - if (hs->received_body >= cs->post_cl) { - break; - } - if (len + hs->received_body > cs->post_cl) { len = cs->post_cl - hs->received_body; } - len = send(cs->instance_fd, hs->buffer, len, 0); + len = send(cs->instance_fd, bbuf, len, 0); if (len <= 0) { if (len < 0) @@ -612,7 +626,6 @@ void uwsgi_http_switch_events(struct uwsgi_corerouter *ucr, struct corerouter_se break; - // fallback to destroy !!! default: uwsgi_log("unknown event: closing session\n"); @@ -631,11 +644,13 @@ void http_alloc_session(struct uwsgi_corerouter *ucr, struct uwsgi_gateway_socke struct http_session *hs = (struct http_session *) cs; hs->ptr = hs->buffer; cs->modifier1 = uhttp.modifier1; - if (sa->sa_family == AF_INET) { + if (sa && sa->sa_family == AF_INET) { hs->ip_addr = ((struct sockaddr_in *) sa)->sin_addr.s_addr; } - hs->port = ugs->port; - hs->port_len = ugs->port_len; + if (ugs) { + hs->port = ugs->port; + hs->port_len = ugs->port_len; + } } int http_init() { diff --git a/plugins/rack/rack_plugin.c b/plugins/rack/rack_plugin.c index d3bebc45..f5839606 100644 --- a/plugins/rack/rack_plugin.c +++ b/plugins/rack/rack_plugin.c @@ -107,7 +107,7 @@ VALUE rb_uwsgi_io_read(VALUE obj, VALUE args) { struct wsgi_request *wsgi_req; Data_Get_Struct(obj, struct wsgi_request, wsgi_req); VALUE chunk; - int chunk_size; + unsigned int chunk_size; if (!wsgi_req->post_cl || wsgi_req->buf_pos >= wsgi_req->post_cl) { /* @@ -130,7 +130,7 @@ VALUE rb_uwsgi_io_read(VALUE obj, VALUE args) { return chunk; } else if (RARRAY_LEN(args) > 0) { - chunk_size = NUM2INT(RARRAY_PTR(args)[0]); + chunk_size = NUM2UINT(RARRAY_PTR(args)[0]); if (wsgi_req->buf_pos+chunk_size > wsgi_req->post_cl) { chunk_size = wsgi_req->post_cl-wsgi_req->buf_pos; }