nginx对http头部的处理

 

数据结构

 ngx_http_request_t{
    ngx_http_headers_in_t             headers_in; //存放分析后的request headers
    ngx_http_headers_out_t            headers_out; //存放待发送的response headers
    ngx_chain_t                      *out; //response headers序列化后,放在这里
}

typedef struct {
    ngx_list_t                        headers;

    ngx_table_elt_t                  *host;
    ngx_table_elt_t                  *connection;
...
    ngx_table_elt_t                  *user_agent;
    ngx_table_elt_t                  *content_length;
    ngx_table_elt_t                  *content_type;
    ngx_table_elt_t                  *transfer_encoding;
    ngx_table_elt_t                  *upgrade;
    ngx_table_elt_t                  *keep_alive;
...
    ngx_array_t                       x_forwarded_for;

    ngx_array_t                       cookies;
    ngx_str_t                         server;
    off_t                             content_length_n;
    time_t                            keep_alive_n;

    unsigned                          connection_type:2;
    unsigned                          chunked:1;
...
} ngx_http_headers_in_t;


typedef struct {
    ngx_list_t                        headers;
    ngx_list_t                        trailers;

    ngx_uint_t                        status;
    ngx_str_t                         status_line;

    ngx_table_elt_t                  *server;
    ngx_table_elt_t                  *date;
    ngx_table_elt_t                  *content_length;
    ngx_table_elt_t                  *content_encoding;
    ngx_table_elt_t                  *location;
    ngx_table_elt_t                  *last_modified;
    ngx_table_elt_t                  *www_authenticate;
    ngx_table_elt_t                  *expires;
    ngx_table_elt_t                  *etag;

    size_t                            content_type_len;
    ngx_str_t                         content_type;
    ngx_str_t                         charset;
    u_char                           *content_type_lowcase;
    ngx_uint_t                        content_type_hash;

    ngx_array_t                       cache_control;
    ngx_array_t                       link;

    off_t                             content_length_n;
    off_t                             content_offset;
    time_t                            date_time;
    time_t                            last_modified_time;
} ngx_http_headers_out_t;

typedef struct {
    ngx_uint_t        hash;
    ngx_str_t         key;
    ngx_str_t         value;
    u_char           *lowcase_key;
} ngx_table_elt_t;

header filter

逻辑结构

header filter是一个函数调用系列,用来处理response头部,其逻辑上如下:

//filer1()->filter2()->filter3()->filter4()

filter1 {
    ...
    return filter2();
}

filter2() {
   ...
   return filter3();
}

filter3() {
    ...
    return filter4();
}

实现

实现上,在模块初始化时,用全局变量ngx_http_top_header_filter和模块局部变量ngx_http_top_header_filter相互迭代,构建调用链,例子如下:

//ngx_http.c 全局变量 
ngx_http_output_header_filter_pt  ngx_http_top_header_filter;

//filter1.c 
static ngx_http_output_header_filter_pt ngx_http_next_header_filter; //局部变量
filter1() {
    ...
    return ngx_http_next_header_filter();
}

filter1_init(ngx_conf_t *cf) {
    ngx_http_next_header_filter = ngx_http_top_header_filter;
    ngx_http_top_header_filter = filter1; 
}

//filter2.c 
static ngx_http_output_header_filter_pt ngx_http_next_header_filter; //局部变量
filter2() {
    ...
    return ngx_http_next_header_filter();
}

filter2_init(ngx_conf_t *cf) {
    ngx_http_next_header_filter = ngx_http_top_header_filter;
    ngx_http_top_header_filter = filter2;
}

//ngx_http_core_module.c
//调用所有的header filter
ngx_http_send_header() {
    return ngx_http_top_header_filer();
}

ngx_http_top_header_filter是调用链的开始,ngx_http_header_filter_module是结束,该模块把头部汇总到一个buffer中,挂到request->out上。

 

处理request头部

ngx_http_process_request_headers(r)
{
    for(;;) {
        ngx_http_parse_header_line(r)
        h = ngx_list_push(&r->headers_in.headers); //分配一个ngx_table_elt_t
        hh = ngx_hash_find(&cmcf->headers_in_hash,h);// 头部识别,是否注册了
        if (hh && hh->handler(r, h, hh) != NGX_OK) { //合法检查,赋值给r->headers_out.<头部名词>,理解头部意思
            ...
        } 
    }

}

cmcf->headers_in_hash是系统内置的头部hash表。

 

处理response头部

ngx_http_send_header()开始调用header filter,这些filter把header放在r->headers_out中;最后一个filter(ngx_http_header_filter)把这些header写入缓冲区,放到ngx_chain_t结构中,然后赋给r->out。(btw: 后面的流程ngx_http_output_filter()把body数据挂在r->out后面,并发送出去)。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值