Removing a request header in an access phase handler

Hi,

I developing a handler for the access phase. In this handler I intend to
remove a certain header.

It seems that this is exceptionally hard to do - the only hint I have is
how it is done in the headers_more module.

However, I wonder, whether there is an easier way, given that it is not
an unusual operation.

If not, I’d greatly benefit from a documentation of the list and
list-part types. Is that available somewhere? Seems hard to figure out
all the bits and pieces that one has to go through to cleanly remove an
element from a list.

Jan

Hello!

On Mon, Jul 08, 2013 at 06:45:33PM +0200, Jan A. wrote:

Hi,

I developing a handler for the access phase. In this handler I
intend to remove a certain header.

It seems that this is exceptionally hard to do - the only hint I
have is how it is done in the headers_more module.

However, I wonder, whether there is an easier way, given that it
is not an unusual operation.

Removing request headers from a request isn’t something supported
by nginx.

What is supported is filtering/modification of headers passed to
upstream servers with proxy_set_header (fastcgi_param, …).

E.g., this is how proxy module provies a way to add
X-Forwarded-For header. It implements the $proxy_add_x_forward_for
variable, which is expected to be used in a config like this:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

If not, I’d greatly benefit from a documentation of the list and
list-part types. Is that available somewhere? Seems hard to
figure out all the bits and pieces that one has to go through to
cleanly remove an element from a list.

Try looking into src/core/ngx_list.[ch] for a documentation in C.
It doesn’t really support elements removal though.


Maxim D.
http://nginx.org/en/donation.html

Hi Maxim,

thanks, question inline:

On 08.07.2013, at 19:59, Maxim D. [email protected] wrote:

have is how it is done in the headers_more module.
E.g., this is how proxy module provies a way to add
Try looking into src/core/ngx_list.[ch] for a documentation in C.
It doesn’t really support elements removal though.

Yes, I could provide a list_remove implementation - problem is, I think
that the request->headers_in convenience fields point to elements of the
.headers list, yes? Given that list elts is an array, re-organizing that
array would invalidate the pointers of headers_in.

Right ow, I think that renaming the header in question and setting the
headers_in field to null is probably the only option.

What do you think?

Jan

Hello!

On Tue, Jul 09, 2013 at 12:13:37AM +0200, Jan A. wrote:

Hi,
Removing request headers from a request isn’t something supported

elements of the .headers list, yes? Given that list elts is an
array, re-organizing that array would invalidate the pointers of
headers_in.

Right ow, I think that renaming the header in question and
setting the headers_in field to null is probably the only
option.

What do you think?

Quoting myself:

: Removing request headers from a request isn’t something
: supported by nginx.

If you are going to remove request headers - first of all, you
should understand that what you are doing is a hack. And asking
me what do I think is a bit pointless - I think it’s a hack. :slight_smile:


Maxim D.
http://nginx.org/en/donation.html

Jan A. wrote in post #1114756:

Hi,

I developing a handler for the access phase. In this handler I intend to
remove a certain header.

It seems that this is exceptionally hard to do - the only hint I have is
how it is done in the headers_more module.

However, I wonder, whether there is an easier way, given that it is not
an unusual operation.

If not, I’d greatly benefit from a documentation of the list and
list-part types. Is that available somewhere? Seems hard to figure out
all the bits and pieces that one has to go through to cleanly remove an
element from a list.

Jan

Yes, it’s really hard.
Headers are made of part list. Those list might have several elements.
You need to remove the part if there is only one element setting the
next pointer of the previous part on the next current part and
decreasing the nelts counter. If there is several elements, you need to
copy next element on the previous for the whole element array from the
removed element position.

Here some code I’ve found:

static ngx_int_t
ngx_list_delete_elt(ngx_list_t *list, ngx_list_part_t *cur, ngx_uint_t
i)
{
u_char *s, *d, *last;

s = (u_char *) cur->elts + i * list->size;
d = s + list->size;
last = (u_char *) cur->elts + cur->nelts * list->size;

while (d < last) {
    *s++ = *d++;
}

cur->nelts--;

return NGX_OK;

}

ngx_int_t
ngx_list_delete(ngx_list_t *list, void *elt)
{
u_char *data;
ngx_uint_t i;
ngx_list_part_t *part, *pre;

part = &list->part;
pre = part;
data = part->elts;

for (i = 0; /* void */; i++) {

    if (i >= part->nelts) {
        if (part->next == NULL) {
            break;
        }

        i = 0;
        pre = part;
        part = part->next;
        data = part->elts;
    }

    if ((data + i * list->size) == (u_char *) elt) {
        if (&list->part != part && part->nelts == 1) {
            pre->next = part->next;
            if (part == list->last) {
                list->last = pre;
            }

            return NGX_OK;
        }

        return ngx_list_delete_elt(list, part, i);
    }
}

return NGX_ERROR;

}