httprouter keepalive preliminary support

This commit is contained in:
roberto@precise64
2012-05-13 23:47:32 +02:00
parent 6ec3b05ce5
commit e46077f576
4 changed files with 40 additions and 23 deletions
+13 -12
View File
@@ -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);
+1
View File
@@ -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 *);
+24 -9
View File
@@ -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() {
+2 -2
View File
@@ -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;
}