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;