Improving response header fields processing.
Fields are filtered one by one before being added to fields list. This avoids adding and then skipping connection-specific fields.
This commit is contained in:
parent
caea9d3c07
commit
29911538ea
3 changed files with 46 additions and 27 deletions
|
@ -1110,7 +1110,7 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp)
|
|||
}
|
||||
|
||||
|
||||
static const nxt_lvlhsh_proto_t nxt_http_fields_hash_proto nxt_aligned(64) = {
|
||||
const nxt_lvlhsh_proto_t nxt_http_fields_hash_proto nxt_aligned(64) = {
|
||||
NXT_LVLHSH_BUCKET_SIZE(64),
|
||||
{ NXT_HTTP_FIELD_LVLHSH_SHIFT, 0, 0, 0, 0, 0, 0, 0 },
|
||||
nxt_http_field_hash_test,
|
||||
|
@ -1240,27 +1240,12 @@ nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
|
|||
nxt_int_t
|
||||
nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash, void *ctx)
|
||||
{
|
||||
nxt_int_t ret;
|
||||
nxt_http_field_t *field;
|
||||
nxt_lvlhsh_query_t lhq;
|
||||
nxt_http_field_proc_t *proc;
|
||||
|
||||
lhq.proto = &nxt_http_fields_hash_proto;
|
||||
nxt_int_t ret;
|
||||
nxt_http_field_t *field;
|
||||
|
||||
nxt_list_each(field, fields) {
|
||||
|
||||
lhq.key_hash = field->hash;
|
||||
lhq.key.length = field->name_length;
|
||||
lhq.key.start = field->name;
|
||||
|
||||
if (nxt_lvlhsh_find(hash, &lhq) != NXT_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
proc = lhq.value;
|
||||
|
||||
ret = proc->handler(ctx, field, proc->data);
|
||||
|
||||
ret = nxt_http_field_process(field, hash, ctx);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -113,4 +113,28 @@ nxt_int_t nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash,
|
|||
void *ctx);
|
||||
|
||||
|
||||
const nxt_lvlhsh_proto_t nxt_http_fields_hash_proto;
|
||||
|
||||
nxt_inline nxt_int_t
|
||||
nxt_http_field_process(nxt_http_field_t *field, nxt_lvlhsh_t *hash, void *ctx)
|
||||
{
|
||||
nxt_lvlhsh_query_t lhq;
|
||||
nxt_http_field_proc_t *proc;
|
||||
|
||||
lhq.proto = &nxt_http_fields_hash_proto;
|
||||
|
||||
lhq.key_hash = field->hash;
|
||||
lhq.key.length = field->name_length;
|
||||
lhq.key.start = field->name;
|
||||
|
||||
if (nxt_lvlhsh_find(hash, &lhq) != NXT_OK) {
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
proc = lhq.value;
|
||||
|
||||
return proc->handler(ctx, field, proc->data);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _NXT_HTTP_PARSER_H_INCLUDED_ */
|
||||
|
|
|
@ -3483,7 +3483,13 @@ nxt_router_response_ready_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
field = NULL;
|
||||
|
||||
for (f = resp->fields; f < resp->fields + resp->fields_count; f++) {
|
||||
if (f->skip) {
|
||||
continue;
|
||||
}
|
||||
|
||||
field = nxt_list_add(r->resp.fields);
|
||||
|
||||
if (nxt_slow_path(field == NULL)) {
|
||||
|
@ -3491,26 +3497,30 @@ nxt_router_response_ready_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg,
|
|||
}
|
||||
|
||||
field->hash = f->hash;
|
||||
field->skip = f->skip;
|
||||
field->skip = 0;
|
||||
|
||||
field->name_length = f->name_length;
|
||||
field->value_length = f->value_length;
|
||||
field->name = nxt_unit_sptr_get(&f->name);
|
||||
field->value = nxt_unit_sptr_get(&f->value);
|
||||
|
||||
nxt_debug(task, "header: %*s: %*s",
|
||||
ret = nxt_http_field_process(field, &nxt_response_fields_hash, r);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
nxt_debug(task, "header%s: %*s: %*s",
|
||||
(field->skip ? " skipped" : ""),
|
||||
(size_t) field->name_length, field->name,
|
||||
(size_t) field->value_length, field->value);
|
||||
|
||||
if (field->skip) {
|
||||
r->resp.fields->last->nelts--;
|
||||
}
|
||||
}
|
||||
|
||||
r->status = resp->status;
|
||||
|
||||
ret = nxt_http_fields_process(r->resp.fields,
|
||||
&nxt_response_fields_hash, r);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (resp->piggyback_content_length != 0) {
|
||||
b->mem.pos = nxt_unit_sptr_get(&resp->piggyback_content);
|
||||
b->mem.free = b->mem.pos + resp->piggyback_content_length;
|
||||
|
|
Loading…
Reference in a new issue