Mercurial > hg > nginx
comparison src/http/modules/ngx_http_proxy_module.c @ 7047:3fef8c5caa75
Proxy: split configured header names and values.
Previously, each configured header was represented in one of two ways,
depending on whether or not its value included any variables.
If the value didn't include any variables, then it would be represented
as as a single script that contained complete header line with HTTP/1.1
delimiters, i.e.:
"Header: value\r\n"
But if the value included any variables, then it would be represented
as a series of three scripts: first contained header name and the ": "
delimiter, second evaluated to header value, and third contained only
"\r\n", i.e.:
"Header: "
"$value"
"\r\n"
This commit changes that, so that each configured header is represented
as a series of two scripts: first contains only header name, and second
contains (or evaluates to) only header value, i.e.:
"Header"
"$value"
or
"Header"
"value"
This not only makes things more consistent, but also allows header name
and value to be accessed separately.
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
author | Piotr Sikora <piotrsikora@google.com> |
---|---|
date | Wed, 15 Mar 2017 15:55:35 -0700 |
parents | 08537eab4f23 |
children | 2a288909abc6 |
comparison
equal
deleted
inserted
replaced
7046:d635505cd29e | 7047:3fef8c5caa75 |
---|---|
1141 | 1141 |
1142 | 1142 |
1143 static ngx_int_t | 1143 static ngx_int_t |
1144 ngx_http_proxy_create_request(ngx_http_request_t *r) | 1144 ngx_http_proxy_create_request(ngx_http_request_t *r) |
1145 { | 1145 { |
1146 size_t len, uri_len, loc_len, body_len; | 1146 size_t len, uri_len, loc_len, body_len, |
1147 key_len, val_len; | |
1147 uintptr_t escape; | 1148 uintptr_t escape; |
1148 ngx_buf_t *b; | 1149 ngx_buf_t *b; |
1149 ngx_str_t method; | 1150 ngx_str_t method; |
1150 ngx_uint_t i, unparsed_uri; | 1151 ngx_uint_t i, unparsed_uri; |
1151 ngx_chain_t *cl, *body; | 1152 ngx_chain_t *cl, *body; |
1256 le.ip = headers->lengths->elts; | 1257 le.ip = headers->lengths->elts; |
1257 le.request = r; | 1258 le.request = r; |
1258 le.flushed = 1; | 1259 le.flushed = 1; |
1259 | 1260 |
1260 while (*(uintptr_t *) le.ip) { | 1261 while (*(uintptr_t *) le.ip) { |
1261 while (*(uintptr_t *) le.ip) { | 1262 |
1263 lcode = *(ngx_http_script_len_code_pt *) le.ip; | |
1264 key_len = lcode(&le); | |
1265 | |
1266 for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) { | |
1262 lcode = *(ngx_http_script_len_code_pt *) le.ip; | 1267 lcode = *(ngx_http_script_len_code_pt *) le.ip; |
1263 len += lcode(&le); | |
1264 } | 1268 } |
1265 le.ip += sizeof(uintptr_t); | 1269 le.ip += sizeof(uintptr_t); |
1270 | |
1271 if (val_len == 0) { | |
1272 continue; | |
1273 } | |
1274 | |
1275 len += key_len + sizeof(": ") - 1 + val_len + sizeof(CRLF) - 1; | |
1266 } | 1276 } |
1267 | 1277 |
1268 | 1278 |
1269 if (plcf->upstream.pass_request_headers) { | 1279 if (plcf->upstream.pass_request_headers) { |
1270 part = &r->headers_in.headers.part; | 1280 part = &r->headers_in.headers.part; |
1360 e.flushed = 1; | 1370 e.flushed = 1; |
1361 | 1371 |
1362 le.ip = headers->lengths->elts; | 1372 le.ip = headers->lengths->elts; |
1363 | 1373 |
1364 while (*(uintptr_t *) le.ip) { | 1374 while (*(uintptr_t *) le.ip) { |
1375 | |
1365 lcode = *(ngx_http_script_len_code_pt *) le.ip; | 1376 lcode = *(ngx_http_script_len_code_pt *) le.ip; |
1366 | |
1367 /* skip the header line name length */ | |
1368 (void) lcode(&le); | 1377 (void) lcode(&le); |
1369 | 1378 |
1370 if (*(ngx_http_script_len_code_pt *) le.ip) { | 1379 for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) { |
1371 | 1380 lcode = *(ngx_http_script_len_code_pt *) le.ip; |
1372 for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) { | 1381 } |
1373 lcode = *(ngx_http_script_len_code_pt *) le.ip; | 1382 le.ip += sizeof(uintptr_t); |
1383 | |
1384 if (val_len == 0) { | |
1385 e.skip = 1; | |
1386 | |
1387 while (*(uintptr_t *) e.ip) { | |
1388 code = *(ngx_http_script_code_pt *) e.ip; | |
1389 code((ngx_http_script_engine_t *) &e); | |
1374 } | 1390 } |
1375 | 1391 e.ip += sizeof(uintptr_t); |
1376 e.skip = (len == sizeof(CRLF) - 1) ? 1 : 0; | 1392 |
1377 | |
1378 } else { | |
1379 e.skip = 0; | 1393 e.skip = 0; |
1380 } | 1394 |
1381 | 1395 continue; |
1382 le.ip += sizeof(uintptr_t); | 1396 } |
1397 | |
1398 code = *(ngx_http_script_code_pt *) e.ip; | |
1399 code((ngx_http_script_engine_t *) &e); | |
1400 | |
1401 *e.pos++ = ':'; *e.pos++ = ' '; | |
1383 | 1402 |
1384 while (*(uintptr_t *) e.ip) { | 1403 while (*(uintptr_t *) e.ip) { |
1385 code = *(ngx_http_script_code_pt *) e.ip; | 1404 code = *(ngx_http_script_code_pt *) e.ip; |
1386 code((ngx_http_script_engine_t *) &e); | 1405 code((ngx_http_script_engine_t *) &e); |
1387 } | 1406 } |
1388 e.ip += sizeof(uintptr_t); | 1407 e.ip += sizeof(uintptr_t); |
1408 | |
1409 *e.pos++ = CR; *e.pos++ = LF; | |
1389 } | 1410 } |
1390 | 1411 |
1391 b->last = e.pos; | 1412 b->last = e.pos; |
1392 | 1413 |
1393 | 1414 |
3496 | 3517 |
3497 if (src[i].value.len == 0) { | 3518 if (src[i].value.len == 0) { |
3498 continue; | 3519 continue; |
3499 } | 3520 } |
3500 | 3521 |
3501 if (ngx_http_script_variables_count(&src[i].value) == 0) { | 3522 copy = ngx_array_push_n(headers->lengths, |
3502 copy = ngx_array_push_n(headers->lengths, | 3523 sizeof(ngx_http_script_copy_code_t)); |
3503 sizeof(ngx_http_script_copy_code_t)); | 3524 if (copy == NULL) { |
3504 if (copy == NULL) { | 3525 return NGX_ERROR; |
3505 return NGX_ERROR; | 3526 } |
3506 } | 3527 |
3507 | 3528 copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; |
3508 copy->code = (ngx_http_script_code_pt) | 3529 copy->len = src[i].key.len; |
3509 ngx_http_script_copy_len_code; | 3530 |
3510 copy->len = src[i].key.len + sizeof(": ") - 1 | 3531 size = (sizeof(ngx_http_script_copy_code_t) |
3511 + src[i].value.len + sizeof(CRLF) - 1; | 3532 + src[i].key.len + sizeof(uintptr_t) - 1) |
3512 | 3533 & ~(sizeof(uintptr_t) - 1); |
3513 | 3534 |
3514 size = (sizeof(ngx_http_script_copy_code_t) | 3535 copy = ngx_array_push_n(headers->values, size); |
3515 + src[i].key.len + sizeof(": ") - 1 | 3536 if (copy == NULL) { |
3516 + src[i].value.len + sizeof(CRLF) - 1 | 3537 return NGX_ERROR; |
3517 + sizeof(uintptr_t) - 1) | 3538 } |
3518 & ~(sizeof(uintptr_t) - 1); | 3539 |
3519 | 3540 copy->code = ngx_http_script_copy_code; |
3520 copy = ngx_array_push_n(headers->values, size); | 3541 copy->len = src[i].key.len; |
3521 if (copy == NULL) { | 3542 |
3522 return NGX_ERROR; | 3543 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); |
3523 } | 3544 ngx_memcpy(p, src[i].key.data, src[i].key.len); |
3524 | 3545 |
3525 copy->code = ngx_http_script_copy_code; | 3546 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
3526 copy->len = src[i].key.len + sizeof(": ") - 1 | 3547 |
3527 + src[i].value.len + sizeof(CRLF) - 1; | 3548 sc.cf = cf; |
3528 | 3549 sc.source = &src[i].value; |
3529 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); | 3550 sc.flushes = &headers->flushes; |
3530 | 3551 sc.lengths = &headers->lengths; |
3531 p = ngx_cpymem(p, src[i].key.data, src[i].key.len); | 3552 sc.values = &headers->values; |
3532 *p++ = ':'; *p++ = ' '; | 3553 |
3533 p = ngx_cpymem(p, src[i].value.data, src[i].value.len); | 3554 if (ngx_http_script_compile(&sc) != NGX_OK) { |
3534 *p++ = CR; *p = LF; | 3555 return NGX_ERROR; |
3535 | |
3536 } else { | |
3537 copy = ngx_array_push_n(headers->lengths, | |
3538 sizeof(ngx_http_script_copy_code_t)); | |
3539 if (copy == NULL) { | |
3540 return NGX_ERROR; | |
3541 } | |
3542 | |
3543 copy->code = (ngx_http_script_code_pt) | |
3544 ngx_http_script_copy_len_code; | |
3545 copy->len = src[i].key.len + sizeof(": ") - 1; | |
3546 | |
3547 | |
3548 size = (sizeof(ngx_http_script_copy_code_t) | |
3549 + src[i].key.len + sizeof(": ") - 1 + sizeof(uintptr_t) - 1) | |
3550 & ~(sizeof(uintptr_t) - 1); | |
3551 | |
3552 copy = ngx_array_push_n(headers->values, size); | |
3553 if (copy == NULL) { | |
3554 return NGX_ERROR; | |
3555 } | |
3556 | |
3557 copy->code = ngx_http_script_copy_code; | |
3558 copy->len = src[i].key.len + sizeof(": ") - 1; | |
3559 | |
3560 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); | |
3561 p = ngx_cpymem(p, src[i].key.data, src[i].key.len); | |
3562 *p++ = ':'; *p = ' '; | |
3563 | |
3564 | |
3565 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
3566 | |
3567 sc.cf = cf; | |
3568 sc.source = &src[i].value; | |
3569 sc.flushes = &headers->flushes; | |
3570 sc.lengths = &headers->lengths; | |
3571 sc.values = &headers->values; | |
3572 | |
3573 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
3574 return NGX_ERROR; | |
3575 } | |
3576 | |
3577 | |
3578 copy = ngx_array_push_n(headers->lengths, | |
3579 sizeof(ngx_http_script_copy_code_t)); | |
3580 if (copy == NULL) { | |
3581 return NGX_ERROR; | |
3582 } | |
3583 | |
3584 copy->code = (ngx_http_script_code_pt) | |
3585 ngx_http_script_copy_len_code; | |
3586 copy->len = sizeof(CRLF) - 1; | |
3587 | |
3588 | |
3589 size = (sizeof(ngx_http_script_copy_code_t) | |
3590 + sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1) | |
3591 & ~(sizeof(uintptr_t) - 1); | |
3592 | |
3593 copy = ngx_array_push_n(headers->values, size); | |
3594 if (copy == NULL) { | |
3595 return NGX_ERROR; | |
3596 } | |
3597 | |
3598 copy->code = ngx_http_script_copy_code; | |
3599 copy->len = sizeof(CRLF) - 1; | |
3600 | |
3601 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); | |
3602 *p++ = CR; *p = LF; | |
3603 } | 3556 } |
3604 | 3557 |
3605 code = ngx_array_push_n(headers->lengths, sizeof(uintptr_t)); | 3558 code = ngx_array_push_n(headers->lengths, sizeof(uintptr_t)); |
3606 if (code == NULL) { | 3559 if (code == NULL) { |
3607 return NGX_ERROR; | 3560 return NGX_ERROR; |