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_LVLHSH_BUCKET_SIZE(64),
|
||||||
{ NXT_HTTP_FIELD_LVLHSH_SHIFT, 0, 0, 0, 0, 0, 0, 0 },
|
{ NXT_HTTP_FIELD_LVLHSH_SHIFT, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
nxt_http_field_hash_test,
|
nxt_http_field_hash_test,
|
||||||
|
@ -1242,25 +1242,10 @@ nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash, void *ctx)
|
||||||
{
|
{
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
nxt_http_field_t *field;
|
nxt_http_field_t *field;
|
||||||
nxt_lvlhsh_query_t lhq;
|
|
||||||
nxt_http_field_proc_t *proc;
|
|
||||||
|
|
||||||
lhq.proto = &nxt_http_fields_hash_proto;
|
|
||||||
|
|
||||||
nxt_list_each(field, fields) {
|
nxt_list_each(field, fields) {
|
||||||
|
|
||||||
lhq.key_hash = field->hash;
|
ret = nxt_http_field_process(field, hash, ctx);
|
||||||
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);
|
|
||||||
|
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,4 +113,28 @@ nxt_int_t nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash,
|
||||||
void *ctx);
|
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_ */
|
#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;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
field = NULL;
|
||||||
|
|
||||||
for (f = resp->fields; f < resp->fields + resp->fields_count; f++) {
|
for (f = resp->fields; f < resp->fields + resp->fields_count; f++) {
|
||||||
|
if (f->skip) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
field = nxt_list_add(r->resp.fields);
|
field = nxt_list_add(r->resp.fields);
|
||||||
|
|
||||||
if (nxt_slow_path(field == NULL)) {
|
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->hash = f->hash;
|
||||||
field->skip = f->skip;
|
field->skip = 0;
|
||||||
|
|
||||||
field->name_length = f->name_length;
|
field->name_length = f->name_length;
|
||||||
field->value_length = f->value_length;
|
field->value_length = f->value_length;
|
||||||
field->name = nxt_unit_sptr_get(&f->name);
|
field->name = nxt_unit_sptr_get(&f->name);
|
||||||
field->value = nxt_unit_sptr_get(&f->value);
|
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);
|
||||||
(size_t) field->name_length, field->name,
|
|
||||||
(size_t) field->value_length, field->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
r->status = resp->status;
|
|
||||||
|
|
||||||
ret = nxt_http_fields_process(r->resp.fields,
|
|
||||||
&nxt_response_fields_hash, r);
|
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
goto fail;
|
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;
|
||||||
|
|
||||||
if (resp->piggyback_content_length != 0) {
|
if (resp->piggyback_content_length != 0) {
|
||||||
b->mem.pos = nxt_unit_sptr_get(&resp->piggyback_content);
|
b->mem.pos = nxt_unit_sptr_get(&resp->piggyback_content);
|
||||||
b->mem.free = b->mem.pos + resp->piggyback_content_length;
|
b->mem.free = b->mem.pos + resp->piggyback_content_length;
|
||||||
|
|
Loading…
Reference in a new issue