diff --git a/core/buffer.c b/core/buffer.c index 03e2f56b..e6145506 100644 --- a/core/buffer.c +++ b/core/buffer.c @@ -114,3 +114,13 @@ int uwsgi_buffer_send(struct uwsgi_buffer *ub, int fd) { return 0; } + +int uwsgi_buffer_num64(struct uwsgi_buffer *ub, int64_t num) { + char buf[sizeof(UMAX64_STR)+1]; + int ret = snprintf(buf, sizeof(UMAX64_STR)+1, "%lld", (long long) num); + if (ret <= 0 || ret > (int) (sizeof(UMAX64_STR)+1)) { + return -1; + } + return uwsgi_buffer_append(ub, buf, ret); +} + diff --git a/core/offload.c b/core/offload.c index bf2d3e76..2bd48294 100644 --- a/core/offload.c +++ b/core/offload.c @@ -331,7 +331,7 @@ static int uwsgi_offload_net_transfer(struct uwsgi_thread *ut, struct uwsgi_offl } } else if (fd == uor->s) { - rlen = read(uor->fd, uor->buf, 4096); + rlen = read(uor->s, uor->buf, 4096); if (rlen > 0) { uor->to_write = rlen; uor->pos = 0; diff --git a/plugins/router_http/router_http.c b/plugins/router_http/router_http.c index 5c5c75c0..eff044b4 100644 --- a/plugins/router_http/router_http.c +++ b/plugins/router_http/router_http.c @@ -12,13 +12,24 @@ int uwsgi_routing_func_http(struct wsgi_request *wsgi_req, struct uwsgi_route *u // get the http address from the route char *addr = ur->data; + char *uri = NULL; + uint16_t uri_len = 0; + if (ur->data3_len) { + uri = uwsgi_regexp_apply_ovec(wsgi_req->uri, wsgi_req->uri_len, ur->data3, ur->data3_len, ur->ovector, ur->ovn); + uri_len = strlen(uri); + } + + // convert the wsgi_request to an http proxy request - struct uwsgi_buffer *ub = uwsgi_to_http(wsgi_req, ur->data2, ur->data2_len); + struct uwsgi_buffer *ub = uwsgi_to_http(wsgi_req, ur->data2, ur->data2_len, uri, uri_len); if (!ub) { + if (uri) free(uri); uwsgi_log("unable to generate http request for %s\n", addr); return UWSGI_ROUTE_NEXT; } + if (uri) free(uri); + // ok now if have offload threads, directly use them if (wsgi_req->socket->can_offload) { if (!uwsgi_offload_request_net_do(wsgi_req, addr, ub)) { @@ -86,6 +97,12 @@ int uwsgi_router_http(struct uwsgi_route *ur, char *args) { *comma = 0; ur->data_len = strlen(ur->data); ur->data2 = comma+1; + comma = strchr(ur->data2, ','); + if (comma) { + *comma = 0; + ur->data3 = comma+1; + ur->data3_len = strlen(ur->data3); + } ur->data2_len = strlen(ur->data2); } return 0; diff --git a/proto/http.c b/proto/http.c index 89bef89b..42d987a4 100644 --- a/proto/http.c +++ b/proto/http.c @@ -393,14 +393,19 @@ void uwsgi_httpize_var(char *buf, size_t len) { } } -struct uwsgi_buffer *uwsgi_to_http(struct wsgi_request *wsgi_req, char *host, uint16_t host_len) { +struct uwsgi_buffer *uwsgi_to_http(struct wsgi_request *wsgi_req, char *host, uint16_t host_len, char *uri, uint16_t uri_len) { struct uwsgi_buffer *ub = uwsgi_buffer_new(4096); if (uwsgi_buffer_append(ub, wsgi_req->method, wsgi_req->method_len)) goto clear; if (uwsgi_buffer_append(ub, " ", 1)) goto clear; - if (uwsgi_buffer_append(ub, wsgi_req->uri, wsgi_req->uri_len)) goto clear; + if (uri_len && uri) { + if (uwsgi_buffer_append(ub, uri, uri_len)) goto clear; + } + else { + if (uwsgi_buffer_append(ub, wsgi_req->uri, wsgi_req->uri_len)) goto clear; + } if (uwsgi_buffer_append(ub, " HTTP/1.0\r\n", 11)) goto clear; @@ -447,11 +452,22 @@ next: if (uwsgi_buffer_append(ub, "\r\n", 2)) goto clear; } + if (wsgi_req->content_type_len > 0) { + if (uwsgi_buffer_append(ub, "Content-Type: ", 14)) goto clear; + if (uwsgi_buffer_append(ub, wsgi_req->content_type, wsgi_req->content_type_len)) goto clear; + if (uwsgi_buffer_append(ub, "\r\n", 2)) goto clear; + } + + if (wsgi_req->post_cl > 0) { + if (uwsgi_buffer_append(ub, "Content-Length: ", 16)) goto clear; + if (uwsgi_buffer_num64(ub, (int64_t) wsgi_req->post_cl)) goto clear; + if (uwsgi_buffer_append(ub, "\r\n", 2)) goto clear; + } + // append required headers if (uwsgi_buffer_append(ub, "Connection: close\r\n", 19)) goto clear; if (uwsgi_buffer_append(ub, "X-Forwarded-For: ", 17)) goto clear; - if (x_forwarded_for_len > 0) { if (uwsgi_buffer_append(ub, x_forwarded_for, x_forwarded_for_len)) goto clear; if (uwsgi_buffer_append(ub, ", ", 2)) goto clear; diff --git a/uwsgi.h b/uwsgi.h index 72799905..4e5b79a8 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -850,6 +850,9 @@ struct uwsgi_route { void *data2; size_t data2_len; + void *data3; + size_t data3_len; + // 64bit value for custom usage uint64_t custom; @@ -3363,9 +3366,10 @@ int uwsgi_buffer_append(struct uwsgi_buffer *, char *, size_t); int uwsgi_buffer_fix(struct uwsgi_buffer *, size_t); int uwsgi_buffer_ensure(struct uwsgi_buffer *, size_t); void uwsgi_buffer_destroy(struct uwsgi_buffer *); +int uwsgi_buffer_num64(struct uwsgi_buffer *, int64_t); void uwsgi_httpize_var(char *, size_t); -struct uwsgi_buffer *uwsgi_to_http(struct wsgi_request *, char *, uint16_t); +struct uwsgi_buffer *uwsgi_to_http(struct wsgi_request *, char *, uint16_t, char *, uint16_t); ssize_t uwsgi_pipe(int, int, int); ssize_t uwsgi_pipe_sized(int, int, size_t, int);