Skip to content

Commit 3aef1d6

Browse files
committed
Reworked multi headers to use linked lists.
Multi headers are now using linked lists instead of arrays. Notably, the following fields were changed: r->headers_in.cookies (renamed to r->headers_in.cookie), r->headers_in.x_forwarded_for, r->headers_out.cache_control, r->headers_out.link, u->headers_in.cache_control u->headers_in.cookies (renamed to u->headers_in.set_cookie). The r->headers_in.cookies and u->headers_in.cookies fields were renamed to r->headers_in.cookie and u->headers_in.set_cookie to match header names. The ngx_http_parse_multi_header_lines() and ngx_http_parse_set_cookie_lines() functions were changed accordingly. With this change, multi headers are now essentially equivalent to normal headers, and following changes will further make them equivalent.
1 parent 7dc6f4e commit 3aef1d6

17 files changed

+175
-245
lines changed

src/http/modules/ngx_http_geo_module.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,15 +327,15 @@ static ngx_int_t
327327
ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
328328
ngx_addr_t *addr)
329329
{
330-
ngx_array_t *xfwd;
330+
ngx_table_elt_t *xfwd;
331331

332332
if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) {
333333
return NGX_ERROR;
334334
}
335335

336-
xfwd = &r->headers_in.x_forwarded_for;
336+
xfwd = r->headers_in.x_forwarded_for;
337337

338-
if (xfwd->nelts > 0 && ctx->proxies != NULL) {
338+
if (xfwd != NULL && ctx->proxies != NULL) {
339339
(void) ngx_http_get_forwarded_addr(r, addr, xfwd, NULL,
340340
ctx->proxies, ctx->proxy_recursive);
341341
}

src/http/modules/ngx_http_geoip_module.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -240,16 +240,16 @@ static u_long
240240
ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
241241
{
242242
ngx_addr_t addr;
243-
ngx_array_t *xfwd;
243+
ngx_table_elt_t *xfwd;
244244
struct sockaddr_in *sin;
245245

246246
addr.sockaddr = r->connection->sockaddr;
247247
addr.socklen = r->connection->socklen;
248248
/* addr.name = r->connection->addr_text; */
249249

250-
xfwd = &r->headers_in.x_forwarded_for;
250+
xfwd = r->headers_in.x_forwarded_for;
251251

252-
if (xfwd->nelts > 0 && gcf->proxies != NULL) {
252+
if (xfwd != NULL && gcf->proxies != NULL) {
253253
(void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
254254
gcf->proxies, gcf->proxy_recursive);
255255
}
@@ -292,7 +292,7 @@ static geoipv6_t
292292
ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
293293
{
294294
ngx_addr_t addr;
295-
ngx_array_t *xfwd;
295+
ngx_table_elt_t *xfwd;
296296
in_addr_t addr4;
297297
struct in6_addr addr6;
298298
struct sockaddr_in *sin;
@@ -302,9 +302,9 @@ ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
302302
addr.socklen = r->connection->socklen;
303303
/* addr.name = r->connection->addr_text; */
304304

305-
xfwd = &r->headers_in.x_forwarded_for;
305+
xfwd = r->headers_in.x_forwarded_for;
306306

307-
if (xfwd->nelts > 0 && gcf->proxies != NULL) {
307+
if (xfwd != NULL && gcf->proxies != NULL) {
308308
(void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
309309
gcf->proxies, gcf->proxy_recursive);
310310
}

src/http/modules/ngx_http_headers_filter_module.c

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
329329
time_t now, expires_time, max_age;
330330
ngx_str_t value;
331331
ngx_int_t rc;
332-
ngx_uint_t i;
333-
ngx_table_elt_t *e, *cc, **ccp;
332+
ngx_table_elt_t *e, *cc;
334333
ngx_http_expires_t expires;
335334

336335
expires = conf->expires;
@@ -371,38 +370,28 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
371370
len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
372371
e->value.len = len - 1;
373372

374-
ccp = r->headers_out.cache_control.elts;
373+
cc = r->headers_out.cache_control;
375374

376-
if (ccp == NULL) {
377-
378-
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
379-
1, sizeof(ngx_table_elt_t *))
380-
!= NGX_OK)
381-
{
382-
return NGX_ERROR;
383-
}
375+
if (cc == NULL) {
384376

385377
cc = ngx_list_push(&r->headers_out.headers);
386378
if (cc == NULL) {
387379
return NGX_ERROR;
388380
}
389381

382+
r->headers_out.cache_control = cc;
383+
cc->next = NULL;
384+
390385
cc->hash = 1;
391386
ngx_str_set(&cc->key, "Cache-Control");
392387

393-
ccp = ngx_array_push(&r->headers_out.cache_control);
394-
if (ccp == NULL) {
395-
return NGX_ERROR;
396-
}
397-
398-
*ccp = cc;
399-
400388
} else {
401-
for (i = 1; i < r->headers_out.cache_control.nelts; i++) {
402-
ccp[i]->hash = 0;
389+
for (cc = cc->next; cc; cc = cc->next) {
390+
cc->hash = 0;
403391
}
404392

405-
cc = ccp[0];
393+
cc = r->headers_out.cache_control;
394+
cc->next = NULL;
406395
}
407396

408397
if (expires == NGX_HTTP_EXPIRES_EPOCH) {
@@ -564,22 +553,12 @@ static ngx_int_t
564553
ngx_http_add_multi_header_lines(ngx_http_request_t *r,
565554
ngx_http_header_val_t *hv, ngx_str_t *value)
566555
{
567-
ngx_array_t *pa;
568556
ngx_table_elt_t *h, **ph;
569557

570558
if (value->len == 0) {
571559
return NGX_OK;
572560
}
573561

574-
pa = (ngx_array_t *) ((char *) &r->headers_out + hv->offset);
575-
576-
if (pa->elts == NULL) {
577-
if (ngx_array_init(pa, r->pool, 1, sizeof(ngx_table_elt_t *)) != NGX_OK)
578-
{
579-
return NGX_ERROR;
580-
}
581-
}
582-
583562
h = ngx_list_push(&r->headers_out.headers);
584563
if (h == NULL) {
585564
return NGX_ERROR;
@@ -589,12 +568,12 @@ ngx_http_add_multi_header_lines(ngx_http_request_t *r,
589568
h->key = hv->key;
590569
h->value = *value;
591570

592-
ph = ngx_array_push(pa);
593-
if (ph == NULL) {
594-
return NGX_ERROR;
595-
}
571+
ph = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
572+
573+
while (*ph) { ph = &(*ph)->next; }
596574

597575
*ph = h;
576+
h->next = NULL;
598577

599578
return NGX_OK;
600579
}

src/http/modules/ngx_http_proxy_module.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2559,22 +2559,20 @@ static ngx_int_t
25592559
ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
25602560
ngx_http_variable_value_t *v, uintptr_t data)
25612561
{
2562-
size_t len;
2563-
u_char *p;
2564-
ngx_uint_t i, n;
2565-
ngx_table_elt_t **h;
2562+
size_t len;
2563+
u_char *p;
2564+
ngx_table_elt_t *h, *xfwd;
25662565

25672566
v->valid = 1;
25682567
v->no_cacheable = 0;
25692568
v->not_found = 0;
25702569

2571-
n = r->headers_in.x_forwarded_for.nelts;
2572-
h = r->headers_in.x_forwarded_for.elts;
2570+
xfwd = r->headers_in.x_forwarded_for;
25732571

25742572
len = 0;
25752573

2576-
for (i = 0; i < n; i++) {
2577-
len += h[i]->value.len + sizeof(", ") - 1;
2574+
for (h = xfwd; h; h = h->next) {
2575+
len += h->value.len + sizeof(", ") - 1;
25782576
}
25792577

25802578
if (len == 0) {
@@ -2593,8 +2591,8 @@ ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
25932591
v->len = len;
25942592
v->data = p;
25952593

2596-
for (i = 0; i < n; i++) {
2597-
p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
2594+
for (h = xfwd; h; h = h->next) {
2595+
p = ngx_copy(p, h->value.data, h->value.len);
25982596
*p++ = ','; *p++ = ' ';
25992597
}
26002598

src/http/modules/ngx_http_realip_module.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,8 @@ ngx_http_realip_handler(ngx_http_request_t *r)
134134
ngx_str_t *value;
135135
ngx_uint_t i, hash;
136136
ngx_addr_t addr;
137-
ngx_array_t *xfwd;
138137
ngx_list_part_t *part;
139-
ngx_table_elt_t *header;
138+
ngx_table_elt_t *header, *xfwd;
140139
ngx_connection_t *c;
141140
ngx_http_realip_ctx_t *ctx;
142141
ngx_http_realip_loc_conf_t *rlcf;
@@ -168,9 +167,9 @@ ngx_http_realip_handler(ngx_http_request_t *r)
168167

169168
case NGX_HTTP_REALIP_XFWD:
170169

171-
xfwd = &r->headers_in.x_forwarded_for;
170+
xfwd = r->headers_in.x_forwarded_for;
172171

173-
if (xfwd->elts == NULL) {
172+
if (xfwd == NULL) {
174173
return NGX_DECLINED;
175174
}
176175

src/http/modules/ngx_http_userid_filter_module.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,9 @@ ngx_http_userid_set_variable(ngx_http_request_t *r,
319319
static ngx_http_userid_ctx_t *
320320
ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf)
321321
{
322-
ngx_int_t n;
323-
ngx_str_t src, dst;
324-
ngx_table_elt_t **cookies;
325-
ngx_http_userid_ctx_t *ctx;
322+
ngx_str_t src, dst;
323+
ngx_table_elt_t *cookie;
324+
ngx_http_userid_ctx_t *ctx;
326325

327326
ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module);
328327

@@ -339,20 +338,19 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf)
339338
ngx_http_set_ctx(r, ctx, ngx_http_userid_filter_module);
340339
}
341340

342-
n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &conf->name,
343-
&ctx->cookie);
344-
if (n == NGX_DECLINED) {
341+
cookie = ngx_http_parse_multi_header_lines(r, r->headers_in.cookie,
342+
&conf->name, &ctx->cookie);
343+
if (cookie == NULL) {
345344
return ctx;
346345
}
347346

348347
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
349348
"uid cookie: \"%V\"", &ctx->cookie);
350349

351350
if (ctx->cookie.len < 22) {
352-
cookies = r->headers_in.cookies.elts;
353351
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
354352
"client sent too short userid cookie \"%V\"",
355-
&cookies[n]->value);
353+
&cookie->value);
356354
return ctx;
357355
}
358356

@@ -370,10 +368,9 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf)
370368
dst.data = (u_char *) ctx->uid_got;
371369

372370
if (ngx_decode_base64(&dst, &src) == NGX_ERROR) {
373-
cookies = r->headers_in.cookies.elts;
374371
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
375372
"client sent invalid userid cookie \"%V\"",
376-
&cookies[n]->value);
373+
&cookie->value);
377374
return ctx;
378375
}
379376

src/http/modules/perl/nginx.xs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ header_in(r, key)
302302

303303
if (hh) {
304304

305-
if (hh->offset == offsetof(ngx_http_headers_in_t, cookies)) {
305+
if (hh->offset == offsetof(ngx_http_headers_in_t, cookie)) {
306306
sep = ';';
307307
goto multi;
308308
}
@@ -327,26 +327,22 @@ header_in(r, key)
327327

328328
/* Cookie, X-Forwarded-For */
329329

330-
a = (ngx_array_t *) ((char *) &r->headers_in + hh->offset);
331-
332-
n = a->nelts;
330+
ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset);
333331

334-
if (n == 0) {
332+
if (*ph == NULL) {
335333
XSRETURN_UNDEF;
336334
}
337335

338-
ph = a->elts;
339-
340-
if (n == 1) {
336+
if ((*ph)->next == NULL) {
341337
ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len);
342338

343339
goto done;
344340
}
345341

346342
size = - (ssize_t) (sizeof("; ") - 1);
347343

348-
for (i = 0; i < n; i++) {
349-
size += ph[i]->value.len + sizeof("; ") - 1;
344+
for (h = *ph; h; h = h->next) {
345+
size += h->value.len + sizeof("; ") - 1;
350346
}
351347

352348
value = ngx_pnalloc(r->pool, size);
@@ -357,10 +353,10 @@ header_in(r, key)
357353

358354
p = value;
359355

360-
for (i = 0; /* void */ ; i++) {
361-
p = ngx_copy(p, ph[i]->value.data, ph[i]->value.len);
356+
for (h = *ph; h; h = h->next) {
357+
p = ngx_copy(p, h->value.data, h->value.len);
362358

363-
if (i == n - 1) {
359+
if (h->next == NULL) {
364360
break;
365361
}
366362

src/http/ngx_http.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ ngx_int_t ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
103103
ngx_str_t *args, ngx_uint_t *flags);
104104
ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
105105
ngx_uint_t allow_underscores);
106-
ngx_int_t ngx_http_parse_multi_header_lines(ngx_array_t *headers,
107-
ngx_str_t *name, ngx_str_t *value);
108-
ngx_int_t ngx_http_parse_set_cookie_lines(ngx_array_t *headers,
109-
ngx_str_t *name, ngx_str_t *value);
106+
ngx_table_elt_t *ngx_http_parse_multi_header_lines(ngx_http_request_t *r,
107+
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value);
108+
ngx_table_elt_t *ngx_http_parse_set_cookie_lines(ngx_http_request_t *r,
109+
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value);
110110
ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len,
111111
ngx_str_t *value);
112112
void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri,

0 commit comments

Comments
 (0)