From 3cd7a1163df8da7591ce29bb8ba7571a6843b25e Mon Sep 17 00:00:00 2001 From: Roberto De Ioris Date: Sat, 5 Jan 2013 09:35:47 +0100 Subject: [PATCH] added addheader routing instruction --- core/routing.c | 24 ++++++++++++++++++++++++ core/static.c | 11 +++++++++++ core/utils.c | 16 ++++++++++++++++ plugins/cgi/cgi_plugin.c | 11 +++++++++++ plugins/php/php_plugin.c | 11 +++++++++++ plugins/psgi/psgi_response.c | 16 ++++++++++++++++ plugins/python/wsgi_headers.c | 17 +++++++++++++++++ plugins/rack/rack_plugin.c | 10 ++++++++++ uwsgi.h | 3 ++- 9 files changed, 118 insertions(+), 1 deletion(-) diff --git a/core/routing.c b/core/routing.c index 6d8b8388..1a6fbd51 100644 --- a/core/routing.c +++ b/core/routing.c @@ -268,6 +268,29 @@ static int uwsgi_router_addvar(struct uwsgi_route *ur, char *arg) { } +// addheader route +static int uwsgi_router_addheader_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { + + char **subject = (char **) (((char *)(wsgi_req))+ur->subject); + uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len); + + char *value = uwsgi_regexp_apply_ovec(*subject, *subject_len, ur->data, ur->data_len, ur->ovector, ur->ovn); + uint16_t value_len = strlen(value); + uwsgi_additional_header_add(wsgi_req, value, value_len); + free(value); + return UWSGI_ROUTE_NEXT; +} + + +static int uwsgi_router_addheader(struct uwsgi_route *ur, char *arg) { + ur->func = uwsgi_router_addheader_func; + ur->data = arg; + ur->data_len = strlen(arg); + return 0; +} + + + // register embedded routers void uwsgi_register_embedded_routers() { uwsgi_register_router("continue", uwsgi_router_continue); @@ -277,6 +300,7 @@ void uwsgi_register_embedded_routers() { uwsgi_register_router("log", uwsgi_router_log); uwsgi_register_router("goto", uwsgi_router_goto); uwsgi_register_router("addvar", uwsgi_router_addvar); + uwsgi_register_router("addheader", uwsgi_router_addheader); } struct uwsgi_router *uwsgi_register_router(char *name, int (*func) (struct uwsgi_route *, char *)) { diff --git a/core/static.c b/core/static.c index b8412adb..7b8e831a 100644 --- a/core/static.c +++ b/core/static.c @@ -408,6 +408,17 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si ah = ah->next; } + ah = wsgi_req->additional_headers; + while (ah) { + headers_vec[0].iov_base = ah->value; + headers_vec[0].iov_len = ah->len; + headers_vec[1].iov_base = "\r\n"; + headers_vec[1].iov_len = 2; + wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 2); + wsgi_req->header_cnt++; + ah = ah->next; + } + wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2); return 0; } diff --git a/core/utils.c b/core/utils.c index bda6fd4e..3c7d428c 100644 --- a/core/utils.c +++ b/core/utils.c @@ -725,6 +725,15 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) { free(ptr); } + // free additional headers + struct uwsgi_string_list *ah = wsgi_req->additional_headers; + while (ah) { + struct uwsgi_string_list *ptr = ah; + ah = ah->next; + free(ptr->value); + free(ptr); + } + // reset request tmp_id = wsgi_req->async_id; @@ -3992,3 +4001,10 @@ int uwsgi_uuid_cmp(char *x, char *y) { } return 0; } + +void uwsgi_additional_header_add(struct wsgi_request *wsgi_req, char *hh, uint16_t hh_len) { + // will be freed on request's end + char *header = uwsgi_concat2n(hh, hh_len, "", 0); + uwsgi_string_new_list(&wsgi_req->additional_headers, header); +} + diff --git a/plugins/cgi/cgi_plugin.c b/plugins/cgi/cgi_plugin.c index 88462b9f..323208a8 100644 --- a/plugins/cgi/cgi_plugin.c +++ b/plugins/cgi/cgi_plugin.c @@ -347,6 +347,17 @@ send_body: ah = ah->next; } + ah = wsgi_req->additional_headers; + while(ah) { + iov[0].iov_base = ah->value; + iov[0].iov_len = ah->len; + iov[1].iov_base = "\r\n"; + iov[1].iov_len = 2; + wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, iov, 2); + wsgi_req->header_cnt++; + ah = ah->next; + } + wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2); if (len-i > 0) { wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, buf+i, len-i); diff --git a/plugins/php/php_plugin.c b/plugins/php/php_plugin.c index 53d62892..32d1ba5c 100644 --- a/plugins/php/php_plugin.c +++ b/plugins/php/php_plugin.c @@ -207,6 +207,17 @@ static int sapi_uwsgi_send_headers(sapi_headers_struct *sapi_headers) ah = ah->next; } + ah = wsgi_req->additional_headers; + while(ah) { + iov[0].iov_base = ah->value; + iov[0].iov_len = ah->len; + iov[1].iov_base = "\r\n"; + iov[1].iov_len = 2; + wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, iov, 2); + wsgi_req->header_cnt++; + ah = ah->next; + } + wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2); diff --git a/plugins/psgi/psgi_response.c b/plugins/psgi/psgi_response.c index 5377475b..f292a256 100644 --- a/plugins/psgi/psgi_response.c +++ b/plugins/psgi/psgi_response.c @@ -148,6 +148,22 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) { ah = ah->next; } + ah = wsgi_req->additional_headers; + while(ah) { + if (wsgi_req->header_cnt+1 > uwsgi.max_vars) { + uwsgi_log("no more space in iovec. consider increasing max-vars...\n"); + break; + } + wsgi_req->header_cnt++; + wsgi_req->hvec[j].iov_base = ah->value; + wsgi_req->hvec[j].iov_len = ah->len; + j++; + wsgi_req->hvec[j].iov_base = "\r\n"; + wsgi_req->hvec[j].iov_len = 2; + j++; + ah = ah->next; + } + wsgi_req->hvec[j].iov_base = "\r\n"; wsgi_req->hvec[j].iov_len = 2; wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, wsgi_req->hvec, j+1); diff --git a/plugins/python/wsgi_headers.c b/plugins/python/wsgi_headers.c index 937197d4..3bfd7ba6 100644 --- a/plugins/python/wsgi_headers.c +++ b/plugins/python/wsgi_headers.c @@ -256,6 +256,23 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) { } } + ah = wsgi_req->additional_headers; + while(ah) { + if (wsgi_req->header_cnt+1 <= uwsgi.max_vars) { + wsgi_req->header_cnt++; + wsgi_req->hvec[j].iov_base = ah->value; + wsgi_req->hvec[j].iov_len = ah->len; + j++; + wsgi_req->hvec[j].iov_base = nl; + wsgi_req->hvec[j].iov_len = NL_SIZE; + j++; + ah = ah->next; + } + else { + uwsgi_log("no more space in iovec. consider increasing max-vars...\n"); + break; + } + } // \r\n wsgi_req->hvec[j].iov_base = nl; diff --git a/plugins/rack/rack_plugin.c b/plugins/rack/rack_plugin.c index 0377cc4f..5d835a0a 100644 --- a/plugins/rack/rack_plugin.c +++ b/plugins/rack/rack_plugin.c @@ -927,6 +927,16 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) { wsgi_req->header_cnt++; ah = ah->next; } + ah = wsgi_req->additional_headers; + while(ah) { + iov[0].iov_base = ah->value; + iov[0].iov_len = ah->len; + iov[1].iov_base = "\r\n"; + iov[1].iov_len = 2; + wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, iov, 2); + wsgi_req->header_cnt++; + ah = ah->next; + } wsgi_req->socket->proto_write(wsgi_req, (char *)"\r\n", 2); diff --git a/uwsgi.h b/uwsgi.h index 3e5a5729..065cc74c 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -1019,7 +1019,6 @@ struct uwsgi_logvar { struct uwsgi_logvar *next; }; - struct wsgi_request { struct uwsgi_header uh; //temporary attr @@ -1187,6 +1186,7 @@ struct wsgi_request { int signal_received; struct uwsgi_logvar *logvars; + struct uwsgi_string_list *additional_headers; uint16_t stream_id; @@ -3653,6 +3653,7 @@ void uwsgi_uuid(char *); int uwsgi_uuid_cmp(char *, char *); int uwsgi_legion_i_am_the_lord(char *); +void uwsgi_additional_header_add(struct wsgi_request *, char *, uint16_t); void uwsgi_subscribe_all(uint8_t, int); #define uwsgi_unsubscribe_all() uwsgi_subscribe_all(1, 1)