allow uwsgi_param to override client headers using HTTP_ parameters
This commit is contained in:
parent
e6ae3f1444
commit
206160c263
1 changed files with 105 additions and 7 deletions
|
@ -19,6 +19,9 @@ typedef struct {
|
||||||
ngx_array_t *params;
|
ngx_array_t *params;
|
||||||
ngx_array_t *params_source;
|
ngx_array_t *params_source;
|
||||||
|
|
||||||
|
ngx_hash_t headers_hash;
|
||||||
|
ngx_uint_t header_params;
|
||||||
|
|
||||||
ngx_array_t *uwsgi_lengths;
|
ngx_array_t *uwsgi_lengths;
|
||||||
ngx_array_t *uwsgi_values;
|
ngx_array_t *uwsgi_values;
|
||||||
|
|
||||||
|
@ -433,19 +436,21 @@ ngx_http_uwsgi_eval(ngx_http_request_t *r, ngx_http_uwsgi_loc_conf_t * uwcf)
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
u_char ch;
|
u_char ch, *lowcase_key;
|
||||||
size_t key_len, val_len, len;
|
size_t key_len, val_len, len, allocated;
|
||||||
ngx_uint_t i, n;
|
ngx_uint_t i, n, hash, header_params;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
ngx_chain_t *cl, *body;
|
ngx_chain_t *cl, *body;
|
||||||
ngx_list_part_t *part;
|
ngx_list_part_t *part;
|
||||||
ngx_table_elt_t *header;
|
ngx_table_elt_t *header, **ignored;
|
||||||
ngx_http_script_code_pt code;
|
ngx_http_script_code_pt code;
|
||||||
ngx_http_script_engine_t e, le;
|
ngx_http_script_engine_t e, le;
|
||||||
ngx_http_uwsgi_loc_conf_t *uwcf;
|
ngx_http_uwsgi_loc_conf_t *uwcf;
|
||||||
ngx_http_script_len_code_pt lcode;
|
ngx_http_script_len_code_pt lcode;
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
|
header_params = 0;
|
||||||
|
ignored = NULL;
|
||||||
|
|
||||||
uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
|
uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
|
||||||
|
|
||||||
|
@ -474,6 +479,16 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||||
|
|
||||||
if (uwcf->upstream.pass_request_headers) {
|
if (uwcf->upstream.pass_request_headers) {
|
||||||
|
|
||||||
|
allocated = 0;
|
||||||
|
lowcase_key = NULL;
|
||||||
|
|
||||||
|
if (uwcf->header_params) {
|
||||||
|
ignored = ngx_palloc(r->pool, uwcf->header_params * sizeof(void *));
|
||||||
|
if (ignored == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
part = &r->headers_in.headers.part;
|
part = &r->headers_in.headers.part;
|
||||||
header = part->elts;
|
header = part->elts;
|
||||||
|
|
||||||
|
@ -489,7 +504,39 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
len += 2 + 5 + header[i].key.len + 2 + header[i].value.len;
|
if (uwcf->header_params) {
|
||||||
|
if (allocated < header[i].key.len) {
|
||||||
|
allocated = header[i].key.len + 16;
|
||||||
|
lowcase_key = ngx_pnalloc(r->pool, allocated);
|
||||||
|
if (lowcase_key == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hash = 0;
|
||||||
|
|
||||||
|
for (n = 0; n < header[i].key.len; n++) {
|
||||||
|
ch = header[i].key.data[n];
|
||||||
|
|
||||||
|
if (ch >= 'A' && ch <= 'Z') {
|
||||||
|
ch |= 0x20;
|
||||||
|
|
||||||
|
} else if (ch == '-') {
|
||||||
|
ch = '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
hash = ngx_hash(hash, ch);
|
||||||
|
lowcase_key[n] = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_hash_find(&uwcf->headers_hash, hash, lowcase_key, n)) {
|
||||||
|
ignored[header_params++] = &header[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len += 2 + sizeof("HTTP_") - 1 + header[i].key.len
|
||||||
|
+ 2 + header[i].value.len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,11 +630,17 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
key_len = 5 + header[i].key.len;
|
for (n = 0; n < header_params; n++) {
|
||||||
|
if (&header[i] == ignored[n]) {
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key_len = sizeof("HTTP_") - 1 + header[i].key.len;
|
||||||
*b->last++ = (u_char) (key_len & 0xff);
|
*b->last++ = (u_char) (key_len & 0xff);
|
||||||
*b->last++ = (u_char) ((key_len >> 8) & 0xff);
|
*b->last++ = (u_char) ((key_len >> 8) & 0xff);
|
||||||
|
|
||||||
b->last = ngx_cpymem(b->last, "HTTP_", 5);
|
b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1);
|
||||||
for (n = 0; n < header[i].key.len; n++) {
|
for (n = 0; n < header[i].key.len; n++) {
|
||||||
ch = header[i].key.data[n];
|
ch = header[i].key.data[n];
|
||||||
|
|
||||||
|
@ -610,6 +663,9 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||||
"uwsgi param: \"%*s: %*s\"",
|
"uwsgi param: \"%*s: %*s\"",
|
||||||
key_len, b->last - (key_len + 2 + val_len),
|
key_len, b->last - (key_len + 2 + val_len),
|
||||||
val_len, b->last - val_len);
|
val_len, b->last - val_len);
|
||||||
|
next:
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1130,7 +1186,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
size_t size;
|
size_t size;
|
||||||
uintptr_t *code;
|
uintptr_t *code;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
|
ngx_array_t headers_names;
|
||||||
ngx_keyval_t *src;
|
ngx_keyval_t *src;
|
||||||
|
ngx_hash_key_t *hk;
|
||||||
ngx_hash_init_t hash;
|
ngx_hash_init_t hash;
|
||||||
ngx_http_script_compile_t sc;
|
ngx_http_script_compile_t sc;
|
||||||
ngx_http_script_copy_code_t *copy;
|
ngx_http_script_copy_code_t *copy;
|
||||||
|
@ -1324,6 +1382,7 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
conf->params_len = prev->params_len;
|
conf->params_len = prev->params_len;
|
||||||
conf->params = prev->params;
|
conf->params = prev->params;
|
||||||
conf->params_source = prev->params_source;
|
conf->params_source = prev->params_source;
|
||||||
|
conf->headers_hash = prev->headers_hash;
|
||||||
|
|
||||||
if (conf->params_source == NULL) {
|
if (conf->params_source == NULL) {
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
|
@ -1340,9 +1399,33 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
|
||||||
|
!= NGX_OK)
|
||||||
|
{
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
src = conf->params_source->elts;
|
src = conf->params_source->elts;
|
||||||
for (i = 0; i < conf->params_source->nelts; i++) {
|
for (i = 0; i < conf->params_source->nelts; i++) {
|
||||||
|
|
||||||
|
if (src[i].key.len > sizeof("HTTP_") - 1
|
||||||
|
&& ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
|
||||||
|
{
|
||||||
|
hk = ngx_array_push(&headers_names);
|
||||||
|
if (hk == NULL) {
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
hk->key.len = src[i].key.len - 5;
|
||||||
|
hk->key.data = src[i].key.data + 5;
|
||||||
|
hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len);
|
||||||
|
hk->value = (void *) 1;
|
||||||
|
|
||||||
|
if (src[i].value.len == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
copy = ngx_array_push_n(conf->params_len,
|
copy = ngx_array_push_n(conf->params_len,
|
||||||
sizeof(ngx_http_script_copy_code_t));
|
sizeof(ngx_http_script_copy_code_t));
|
||||||
if (copy == NULL) {
|
if (copy == NULL) {
|
||||||
|
@ -1404,6 +1487,21 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
|
|
||||||
*code = (uintptr_t) NULL;
|
*code = (uintptr_t) NULL;
|
||||||
|
|
||||||
|
conf->header_params = headers_names.nelts;
|
||||||
|
|
||||||
|
hash.hash = &conf->headers_hash;
|
||||||
|
hash.key = ngx_hash_key_lc;
|
||||||
|
hash.max_size = 512;
|
||||||
|
hash.bucket_size = 64;
|
||||||
|
hash.name = "uwsgi_params_hash";
|
||||||
|
hash.pool = cf->pool;
|
||||||
|
hash.temp_pool = NULL;
|
||||||
|
|
||||||
|
if (ngx_hash_init(&hash, headers_names.elts, headers_names.nelts) != NGX_OK)
|
||||||
|
{
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue