[PATCH 07 of 20] All non-unique input headers are now linked lists

Maxim Dounin mdounin at mdounin.ru
Thu May 12 23:54:21 UTC 2022


Hello!

On Wed, May 11, 2022 at 11:40:48PM +0400, Sergey Kandaurov wrote:

> On Thu, Apr 21, 2022 at 01:18:47AM +0300, Maxim Dounin wrote:
> > # HG changeset patch
> > # User Maxim Dounin <mdounin at mdounin.ru>
> > # Date 1650492324 -10800
> > #      Thu Apr 21 01:05:24 2022 +0300
> > # Node ID 238d1f5f438735432822689605fa37b1b0e01517
> > # Parent  50fe52f516ff9c148aa9e7dfcc1c31cc6a4929ae
> > All non-unique input headers are now linked lists.
> > 
> > The ngx_http_process_multi_header_lines() function is removed, as it is
> > exactly equivalent to ngx_http_process_header_line().  Similarly,
> > ngx_http_variable_header() is used instead of ngx_http_variable_headers().
> > 
> > diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
> > --- a/src/http/ngx_http_request.c
> > +++ b/src/http/ngx_http_request.c
> > @@ -22,8 +22,6 @@ static ngx_int_t ngx_http_process_header
> >      ngx_table_elt_t *h, ngx_uint_t offset);
> >  static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
> >      ngx_table_elt_t *h, ngx_uint_t offset);
> > -static ngx_int_t ngx_http_process_multi_header_lines(ngx_http_request_t *r,
> > -    ngx_table_elt_t *h, ngx_uint_t offset);
> >  static ngx_int_t ngx_http_process_host(ngx_http_request_t *r,
> >      ngx_table_elt_t *h, ngx_uint_t offset);
> >  static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
> > @@ -164,7 +162,7 @@ ngx_http_header_t  ngx_http_headers_in[]
> >  #if (NGX_HTTP_X_FORWARDED_FOR)
> >      { ngx_string("X-Forwarded-For"),
> >                   offsetof(ngx_http_headers_in_t, x_forwarded_for),
> > -                 ngx_http_process_multi_header_lines },
> > +                 ngx_http_process_header_line },
> >  #endif
> >  
> >  #if (NGX_HTTP_REALIP)
> > @@ -197,7 +195,7 @@ ngx_http_header_t  ngx_http_headers_in[]
> >  #endif
> >  
> >      { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookie),
> > -                 ngx_http_process_multi_header_lines },
> > +                 ngx_http_process_header_line },
> >  
> >      { ngx_null_string, 0, NULL }
> >  };
> > @@ -1742,10 +1740,10 @@ ngx_http_process_header_line(ngx_http_re
> >  
> >      ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
> >  
> > -    if (*ph == NULL) {
> > -        *ph = h;
> > -        h->next = NULL;
> > -    }
> > +    while (*ph) { ph = &(*ph)->next; }
> > +
> > +    *ph = h;
> > +    h->next = NULL;
> >  
> >      return NGX_OK;
> >  }
> 
> Essentially, this makes the following headers multi-valuable,
> which are specified (or otherwise implied) to have a single value:
> Referer, Content-Type, Range, Keep-Alive, X-Real-IP,
> also DAV headers (including Date) and User-Agent (as below).
> This makes proxying comma-delimited header values to backend, such as:
>   Date: Wed, 11 May 2022 19:29:54 GMT
>   Date: Wed, 11 May 2022 19:29:55 GMT
> ->
>   HTTP_DATE: Wed, 11 May 2022 19:29:54 GMT, Wed, 11 May 2022 19:29:55 GMT
> 
> Convert them to ngx_http_process_unique_header_line() ?

I don't think this change affects proxying: both previously and 
with the patch all headers were proxied.  The difference is that 
now nginx itself can access all the headers provided if it needs 
to (or reject particular requests if it the particular header 
might be important).

While rejecting requests with such duplicate headers might be 
correct thing to do, it might not be the optimal approach from the 
robustness point of view. 

> 
> > @@ -1851,13 +1849,10 @@ ngx_http_process_user_agent(ngx_http_req
> >  {
> >      u_char  *user_agent, *msie;
> >  
> > -    if (r->headers_in.user_agent) {
> > -        return NGX_OK;
> > +    if (ngx_http_process_header_line(r, h, offset) != NGX_OK) {
> > +        return NGX_ERROR;
> >      }
> >  
> > -    r->headers_in.user_agent = h;
> > -    h->next = NULL;
> > -
> >      /* check some widespread browsers while the header is in CPU cache */
> >  
> >      user_agent = h->value.data;
> > @@ -1919,23 +1914,6 @@ ngx_http_process_user_agent(ngx_http_req
> >  }
> >  
> >  
> > -static ngx_int_t
> > -ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h,
> > -    ngx_uint_t offset)
> > -{
> > -    ngx_table_elt_t  **ph;
> > -
> > -    ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
> > -
> > -    while (*ph) { ph = &(*ph)->next; }
> > -
> > -    *ph = h;
> > -    h->next = NULL;
> > -
> > -    return NGX_OK;
> > -}
> > -
> > -
> >  ngx_int_t
> >  ngx_http_process_request_header(ngx_http_request_t *r)
> >  {
> > diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
> > --- a/src/http/ngx_http_variables.c
> > +++ b/src/http/ngx_http_variables.c
> > @@ -27,8 +27,6 @@ static ngx_int_t ngx_http_variable_heade
> >  
> >  static ngx_int_t ngx_http_variable_cookies(ngx_http_request_t *r,
> >      ngx_http_variable_value_t *v, uintptr_t data);
> > -static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r,
> > -    ngx_http_variable_value_t *v, uintptr_t data);
> >  static ngx_int_t ngx_http_variable_headers_internal(ngx_http_request_t *r,
> >      ngx_http_variable_value_t *v, uintptr_t data, u_char sep);
> >  
> > @@ -178,7 +176,7 @@ static ngx_http_variable_t  ngx_http_cor
> >  #endif
> >  
> >  #if (NGX_HTTP_X_FORWARDED_FOR)
> > -    { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_headers,
> > +    { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header,
> >        offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 },
> >  #endif
> >  
> > @@ -327,10 +325,10 @@ static ngx_http_variable_t  ngx_http_cor
> >      { ngx_string("sent_http_transfer_encoding"), NULL,
> >        ngx_http_variable_sent_transfer_encoding, 0, 0, 0 },
> >  
> > -    { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers,
> > +    { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_header,
> >        offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 },
> >  
> > -    { ngx_string("sent_http_link"), NULL, ngx_http_variable_headers,
> > +    { ngx_string("sent_http_link"), NULL, ngx_http_variable_header,
> >        offsetof(ngx_http_request_t, headers_out.link), 0, 0 },
> >  
> >      { ngx_string("limit_rate"), ngx_http_variable_set_limit_rate,
> > @@ -807,22 +805,7 @@ static ngx_int_t
> >  ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v,
> >      uintptr_t data)
> >  {
> > -    ngx_table_elt_t  *h;
> > -
> > -    h = *(ngx_table_elt_t **) ((char *) r + data);
> > -
> > -    if (h) {
> > -        v->len = h->value.len;
> > -        v->valid = 1;
> > -        v->no_cacheable = 0;
> > -        v->not_found = 0;
> > -        v->data = h->value.data;
> > -
> > -    } else {
> > -        v->not_found = 1;
> > -    }
> > -
> > -    return NGX_OK;
> > +    return ngx_http_variable_headers_internal(r, v, data, ',');
> >  }
> >  
> >  
> > @@ -835,14 +818,6 @@ ngx_http_variable_cookies(ngx_http_reque
> >  
> >  
> >  static ngx_int_t
> > -ngx_http_variable_headers(ngx_http_request_t *r,
> > -    ngx_http_variable_value_t *v, uintptr_t data)
> > -{
> > -    return ngx_http_variable_headers_internal(r, v, data, ',');
> > -}
> > -
> > -
> > -static ngx_int_t
> >  ngx_http_variable_headers_internal(ngx_http_request_t *r,
> >      ngx_http_variable_value_t *v, uintptr_t data, u_char sep)
> >  {
> > 
> _______________________________________________
> nginx-devel mailing list -- nginx-devel at nginx.org
> To unsubscribe send an email to nginx-devel-leave at nginx.org

-- 
Maxim Dounin
http://mdounin.ru/



More information about the nginx-devel mailing list