Nginx Learing - ngx_http_request_t 结构体

Nginx学习-ngx_http_request_t 结构体

// http处理的核心数据结构
// 保存有所有http模块的配置、ctx数据、请求头、请求体
// 读写事件的处理函数
struct ngx_http_request_s {
    // 结构体的“签名”,C程序里的常用手段,用特殊字符来标记结构体
    uint32_t                          signature;         /* "HTTP" */

    // 请求对应的连接对象,里面有log用于记录日志
    // 里面还有读写事件read/write
    // 使用它来与客户端通信收发数据
    ngx_connection_t                 *connection;

    // 保存有所有http模块的配置、ctx数据
    // 使用ngx_http_get_module_ctx获取ctx
    // 是一个数组,里面存储的是void*
    void                            **ctx;

    // 使用ngx_http_get_module_main_conf访问
    // 都是一维数组,里面存储的是void*
    void                            **main_conf;
    void                            **srv_conf;
    void                            **loc_conf;

    // 读事件的处理函数
    // 随着处理的阶段不同会变化
    // ngx_http_discarded_request_body_handler:丢弃请求体
    // ngx_http_block_reading:忽略读事件,即不读取数据
    ngx_http_event_handler_pt         read_event_handler;

    // 写事件的处理函数
    // 写最开始是ngx_http_empty_handler
    // 然后是ngx_http_core_run_phases
    // 当进入content阶段调用location handler后变成ngx_http_request_empty_handler
    // 最后是ngx_http_set_write_handler
    ngx_http_event_handler_pt         write_event_handler;

#if (NGX_HTTP_CACHE)
    ngx_http_cache_t                 *cache;
#endif

    // 连接后端upstream的数据结构
    ngx_http_upstream_t              *upstream;
    ngx_array_t                      *upstream_states;
                                         /* of ngx_http_upstream_state_t */

    // 请求的内存池,请求结束时会回收
    ngx_pool_t                       *pool;

    // 缓冲区,用于读取请求头
    // 如果有请求体数据,也会都读到这里
    ngx_buf_t                        *header_in;

    // 请求头结构体
    // 里面用链表存储了所有的头,也可以用指针快速访问常用头
    ngx_http_headers_in_t             headers_in;

    // 响应头结构体
    // 里面有状态码/状态行和响应头链表
    ngx_http_headers_out_t            headers_out;

    // 读取并存储请求体
    // 指针的形式只有在需要的时候才分配内存
    // 相关函数ngx_http_discard_request_body/ngx_http_read_client_request_body
    ngx_http_request_body_t          *request_body;

    // 延迟关闭的时间点,用于ngx_http_discarded_request_body_handler
    // 可以在这之前接收数据
    time_t                            lingering_time;

    // 请求开始的时间,可用于限速
    time_t                            start_sec;
    ngx_msec_t                        start_msec;

    // 从请求头解析出来的方法
    // r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD)
    ngx_uint_t                        method;

    // http协议版本号,通常不需要关心
    ngx_uint_t                        http_version;

    // 请求行字符串
    ngx_str_t                         request_line;

    // uri地址,不含参数,即$uri
    ngx_str_t                         uri;

    // uri后的参数,不含问号,即$args
    ngx_str_t                         args;

    // uri里文件的扩展名
    ngx_str_t                         exten;

    // 原始请求uri,未解码,即$request_uri
    ngx_str_t                         unparsed_uri;

    // 请求的方法名字符串,例如GET/POST/DELETE
    // 因为字符串比较慢,所以应该尽量用method来判断方法
    ngx_str_t                         method_name;

    // http协议字符串,通常不需要关注
    ngx_str_t                         http_protocol;

    // 发送的数据链表
    // 所有的header、body数据都会存在这里
    ngx_chain_t                      *out;

    // 指向主请求,即由客户端发起的请求
    // 如果没有子请求,那么r == main
    ngx_http_request_t               *main;

    // 父请求,如果是子请求,那么指向产生它的父请求
    // 如果是主请求,指针是空
    ngx_http_request_t               *parent;

    // 子请求处理相关的数据结构
    ngx_http_postponed_request_t     *postponed;
    ngx_http_post_subrequest_t       *post_subrequest;
    ngx_http_posted_request_t        *posted_requests;

    // 执行ngx_http_core_run_phases时的重要参数,标记在引擎数组里的位置
    // 可以理解为一个执行的“游标”
    ngx_int_t                         phase_handler;

    // 重要!!
    // 本location专门的内容处理函数,产生响应内容
    // 在ngx_http_update_location_config里设置
    ngx_http_handler_pt               content_handler;

    // access阶段里设置的是否允许访问
    ngx_uint_t                        access_code;

    // 变量值数组,每个请求都不同
    // 1.11.10增加了prefix_variables
    ngx_http_variable_value_t        *variables;

#if (NGX_PCRE)
    ngx_uint_t                        ncaptures;
    int                              *captures;
    u_char                           *captures_data;
#endif

    // 限速用
    // 可以用$limit_rate来随时改变
    size_t                            limit_rate;

    // 多少字节之后开始限速
    // 未提供$limit_rate,但可以参考$limit_rate添加
    // 在ngx_http_variables.c
    size_t                            limit_rate_after;

    // 用处不大,仅用于计算body_bytes_sent变量
    // sent = r->connection->sent - r->header_size;
    /* used to learn the Apache compatible response length without a header */
    size_t                            header_size;

    // 收到的请求数据总长度,即header+body
    off_t                             request_length;

    // 出错的状态码,如果设置了会代替headers_out.status
    // 见ngx_http_send_header()
    ngx_uint_t                        err_status;

    ngx_http_connection_t            *http_connection;
    ngx_http_v2_stream_t             *stream;

    // 记录错误日志时可以调用的函数
    // 在ngx_http_log_error里调用
    ngx_http_log_handler_pt           log_handler;

    // 清理结构体链表,结束时会逐个调用
    // 与内存池的清理调用时机不同
    ngx_http_cleanup_t               *cleanup;


    // 引用计数,丢弃/读取请求体/发起子请求都会增加
    // 表示当前请求有其他关联的操作,不能随意关闭
    // 在http_close里会检查count,如果大于1只减少,不会真正关闭
    // 1.8里是8位,1.10改为16位
    unsigned                          count:16;

    // 子请求数量,最多不能超过50个
    unsigned                          subrequests:8;

    // 请求的阻塞数量,用于线程池
    // 当发起一个多线程task时需要增加
    // task结束时需要减少
    unsigned                          blocked:8;

    unsigned                          aio:1;

    unsigned                          http_state:4;

    /* URI with "/." and on Win32 with "//" */
    unsigned                          complex_uri:1;

    /* URI with "%" */
    unsigned                          quoted_uri:1;

    /* URI with "+" */
    unsigned                          plus_in_uri:1;

    /* URI with " " */
    unsigned                          space_in_uri:1;

    unsigned                          invalid_header:1;

    unsigned                          add_uri_to_alias:1;
    unsigned                          valid_location:1;
    unsigned                          valid_unparsed_uri:1;

    // uri是否被改写的标志位
    // 在ngx_http_core_post_rewrite_phase里检查
    unsigned                          uri_changed:1;

    // uri改写的次数
    // 在ngx_http_core_post_rewrite_phase里检查
    unsigned                          uri_changes:4;

    unsigned                          request_body_in_single_buf:1;

    // 是否把请求体数据存入文件,与request_body_no_buffering相反
    unsigned                          request_body_in_file_only:1;

    unsigned                          request_body_in_persistent_file:1;
    unsigned                          request_body_in_clean_file:1;
    unsigned                          request_body_file_group_access:1;
    unsigned                          request_body_file_log_level:3;

    // 0-缓存请求体数据
    // 1-不缓存请求体数据
    unsigned                          request_body_no_buffering:1;

    // 要求upstream的数据都在内存里,方便处理
    unsigned                          subrequest_in_memory:1;

    unsigned                          waited:1;

#if (NGX_HTTP_CACHE)
    unsigned                          cached:1;
    unsigned                          cache_updater:1;
#endif

#if (NGX_HTTP_GZIP)
    unsigned                          gzip_tested:1;
    unsigned                          gzip_ok:1;
    unsigned                          gzip_vary:1;
#endif

    unsigned                          proxy:1;
    unsigned                          bypass_cache:1;
    unsigned                          no_cache:1;

    /*
     * instead of using the request context data in
     * ngx_http_limit_conn_module and ngx_http_limit_req_module
     * we use the single bits in the request structure
     */
    unsigned                          limit_conn_set:1;
    unsigned                          limit_req_set:1;

#if 0
    unsigned                          cacheable:1;
#endif

    unsigned                          pipeline:1;

    // 两种含义,如果请求头有chunked那么置1,表示请求体长度不确定
    // 如果响应头无content_length_n,那么表示响应体长度不确定,是chunked
    unsigned                          chunked:1;

    // 只有头的标志位
    // ngx_http_header_filter_module里检查,如果方法是head则置1
    unsigned                          header_only:1;

    // 是否keep alive
    unsigned                          keepalive:1;

    // 延后关闭标志
    unsigned                          lingering_close:1;

    // 丢弃请求体的标志,在ngx_http_discard_request_body里设置
    unsigned                          discard_body:1;

    // 正在读取请求体,在ngx_http_read_client_request_body里设置
    unsigned                          reading_body:1;

    // 是否是内部请求,即子请求
    unsigned                          internal:1;

    unsigned                          error_page:1;
    unsigned                          filter_finalize:1;
    unsigned                          post_action:1;
    unsigned                          request_complete:1;
    unsigned                          request_output:1;

    // 是否已经发送了头,如果已经发送则不能再次设置或发送头
    unsigned                          header_sent:1;

    unsigned                          expect_tested:1;
    unsigned                          root_tested:1;
    unsigned                          done:1;
    unsigned                          logged:1;

    // 发送数据是否已经被缓冲,即没有完全发送完
    unsigned                          buffered:4;

    unsigned                          main_filter_need_in_memory:1;
    unsigned                          filter_need_in_memory:1;
    unsigned                          filter_need_temporary:1;
    unsigned                          allow_ranges:1;
    unsigned                          subrequest_ranges:1;
    unsigned                          single_range:1;
    unsigned                          disable_not_modified:1;
    unsigned                          stat_reading:1;
    unsigned                          stat_writing:1;
    unsigned                          stat_processing:1;

    unsigned                          health_check:1;

    /* used to parse HTTP headers */

    ngx_uint_t                        state;

    ngx_uint_t                        header_hash;
    ngx_uint_t                        lowcase_index;
    u_char                            lowcase_header[NGX_HTTP_LC_HEADER_LEN];

    u_char                           *header_name_start;
    u_char                           *header_name_end;
    u_char                           *header_start;
    u_char                           *header_end;

    /*
     * a memory that can be reused after parsing a request line
     * via ngx_http_ephemeral_t
     */

    u_char                           *uri_start;
    u_char                           *uri_end;
    u_char                           *uri_ext;
    u_char                           *args_start;
    u_char                           *request_start;
    u_char                           *request_end;
    u_char                           *method_end;
    u_char                           *schema_start;
    u_char                           *schema_end;
    u_char                           *host_start;
    u_char                           *host_end;
    u_char                           *port_start;
    u_char                           *port_end;

    // http的主次版本号
    unsigned                          http_minor:16;
    unsigned                          http_major:16;
};

参考:
https://github.com/chronolaw/annotated_nginx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值