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