Removing a request header in an access phase handler

David Pesce lists at ruby-forum.com
Thu Mar 6 13:22:13 UTC 2014


Jan Algermissen 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;
}

-- 
Posted via http://www.ruby-forum.com/.



More information about the nginx mailing list