diff --git a/core/routing.c b/core/routing.c index 76eade05..4d4a5292 100644 --- a/core/routing.c +++ b/core/routing.c @@ -311,6 +311,28 @@ static int uwsgi_router_addheader(struct uwsgi_route *ur, char *arg) { return 0; } +// remheader route +static int uwsgi_router_remheader_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_remove_header(wsgi_req, value, value_len); + free(value); + return UWSGI_ROUTE_NEXT; +} + + +static int uwsgi_router_remheader(struct uwsgi_route *ur, char *arg) { + ur->func = uwsgi_router_remheader_func; + ur->data = arg; + ur->data_len = strlen(arg); + return 0; +} + + // signal route static int uwsgi_router_signal_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) { @@ -355,6 +377,8 @@ void uwsgi_register_embedded_routers() { uwsgi_register_router("goto", uwsgi_router_goto); uwsgi_register_router("addvar", uwsgi_router_addvar); uwsgi_register_router("addheader", uwsgi_router_addheader); + uwsgi_register_router("delheader", uwsgi_router_remheader); + uwsgi_register_router("remheader", uwsgi_router_remheader); uwsgi_register_router("signal", uwsgi_router_signal); uwsgi_register_router("send", uwsgi_router_send); uwsgi_register_router("send-crnl", uwsgi_router_send_crnl); diff --git a/core/utils.c b/core/utils.c index 579d521c..f0ec8ab1 100644 --- a/core/utils.c +++ b/core/utils.c @@ -678,6 +678,14 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) { free(ptr->value); free(ptr); } + // free remove headers + ah = wsgi_req->remove_headers; + while (ah) { + struct uwsgi_string_list *ptr = ah; + ah = ah->next; + free(ptr->value); + free(ptr); + } // free websocket engine if (wsgi_req->websocket_buf) { @@ -3937,6 +3945,11 @@ void uwsgi_additional_header_add(struct wsgi_request *wsgi_req, char *hh, uint16 uwsgi_string_new_list(&wsgi_req->additional_headers, header); } +void uwsgi_remove_header(struct wsgi_request *wsgi_req, char *hh, uint16_t hh_len) { + char *header = uwsgi_concat2n(hh, hh_len, "", 0); + uwsgi_string_new_list(&wsgi_req->remove_headers, header); +} + // based on nginx implementation static uint8_t b64_table64[] = { diff --git a/core/uwsgi.c b/core/uwsgi.c index a6af0aa2..0a835662 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -491,6 +491,8 @@ static struct uwsgi_option uwsgi_base_options[] = { {"clocks-list", no_argument, 0, "list enabled clocks", uwsgi_opt_true, &uwsgi.clock_list, 0}, {"add-header", required_argument, 0, "automatically add HTTP headers to response", uwsgi_opt_add_string_list, &uwsgi.additional_headers, 0}, + {"rem-header", required_argument, 0, "automatically remove specified HTTP header from the response", uwsgi_opt_add_string_list, &uwsgi.remove_headers, 0}, + {"del-header", required_argument, 0, "automatically remove specified HTTP header from the response", uwsgi_opt_add_string_list, &uwsgi.remove_headers, 0}, {"check-static", required_argument, 0, "check for static files in the specified directory", uwsgi_opt_check_static, NULL, UWSGI_OPT_MIME}, {"check-static-docroot", no_argument, 0, "check for static files in the requested DOCUMENT_ROOT", uwsgi_opt_true, &uwsgi.check_static_docroot, UWSGI_OPT_MIME}, diff --git a/core/writer.c b/core/writer.c index cf72a29c..ab6783c0 100644 --- a/core/writer.c +++ b/core/writer.c @@ -60,6 +60,21 @@ int uwsgi_response_add_header(struct wsgi_request *wsgi_req, char *key, uint16_t if (wsgi_req->headers_sent || wsgi_req->headers_size || wsgi_req->response_size || wsgi_req->write_errors) return -1; + struct uwsgi_string_list *rh = uwsgi.remove_headers; + while(rh) { + if (!uwsgi_strnicmp(key, key_len, rh->value, rh->len)) { + return 0; + } + rh = rh->next; + } + rh = wsgi_req->remove_headers; + while(rh) { + if (!uwsgi_strnicmp(key, key_len, rh->value, rh->len)) { + return 0; + } + rh = rh->next; + } + if (!wsgi_req->headers) { wsgi_req->headers = uwsgi_buffer_new(uwsgi.page_size); wsgi_req->headers->limit = UMAX16; diff --git a/core/zlib.c b/core/zlib.c new file mode 100644 index 00000000..a1658292 --- /dev/null +++ b/core/zlib.c @@ -0,0 +1,46 @@ +#include +#include + +/* + +z_stream *uwsgi_deflate_init(int + z_stream *z = uwsgi_malloc(sizeof(z_stream)); + z->zalloc = Z_NULL; + z->zfree = Z_NULL; + z->opaque = Z_NULL; + if (deflateInit(z, Z_DEFAULT_COMPRESSION) != Z_OK) { + goto end; + } + if (deflateSetDictionary(&hr->spdy_z_out, (Bytef *) SPDY_dictionary_txt, sizeof(SPDY_dictionary_txt)) != Z_OK) { + return -1; + } + cs->can_keepalive = 1; + hr->spdy_initialized = 1; + + hr->spdy_phase = UWSGI_SPDY_PHASE_HEADER; + hr->spdy_need = 8; + + main_peer->out = uhttp.spdy3_settings; + main_peer->out->pos = uhttp.spdy3_settings_size; + main_peer->out_pos = 0; + cr_write_to_main(main_peer, hr_ssl_write); + return 1; +end: + return NULL +} + + +char *uwsgi_deflate(char *buf, size_t len, size_t *dlen) { + // calculate the amount of bytes needed for output (+30 should be enough) + Bytef *dbuf = uwsgi_malloc(len+30); + z_stream *z = &hr->spdy_z_out; +z->avail_in = h_buf->pos; z->next_in = (Bytef *) h_buf->buf; z->avail_out = h_buf->pos+30; z->next_out = dbuf; + if (deflate(z, Z_SYNC_FLUSH) != Z_OK) { + free(dbuf); + return NULL; + } + + *dlen = z->next_out - dbuf; + return (char *) dbuf; + +*/ diff --git a/uwsgi.h b/uwsgi.h index 1f47ec27..6cdef878 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -1192,6 +1192,7 @@ struct wsgi_request { struct uwsgi_logvar *logvars; struct uwsgi_string_list *additional_headers; + struct uwsgi_string_list *remove_headers; struct uwsgi_buffer *websocket_buf; size_t websocket_need; @@ -1455,6 +1456,7 @@ struct uwsgi_server { char *vassals_stop_hook; struct uwsgi_string_list *additional_headers; + struct uwsgi_string_list *remove_headers; // maximum time to wait after a reload time_t master_mercy; @@ -3713,6 +3715,7 @@ 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_remove_header(struct wsgi_request *, char *, uint16_t); void uwsgi_proto_hooks_setup(void); diff --git a/uwsgiconfig.py b/uwsgiconfig.py index 846efe18..3af2117b 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -82,6 +82,7 @@ report['spooler'] = False report['debug'] = False report['plugin_dir'] = False report['ipv6'] = False +report['zlib'] = False compile_queue = None print_lock = None @@ -594,6 +595,12 @@ class uConf(object): self.libs.append('-lexecinfo') report['execinfo'] = True + if self.has_include('zlib.h'): + self.cflags.append('-DUWSGI_ZLIB') + self.libs.append('-lz') + self.gcc_list.append('core/zlib') + report['zlib'] = True + if uwsgi_os == 'OpenBSD': try: obsd_major = int(uwsgi_os_k.split('.')[0])