《深入理解Nginx》之HTTP模块

Nginx HTTP模块

ngx_http_module

      对于每一个HTTP模块,都必须实现ngx_http_module接口。

typedef struct {
    /* 在解析http{}配置项前的回调函数 */
    ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);

    /* 解析完http{}配置项后的回调函数 */
    ngx_int_t   (*postconfiguration)(ngx_conf_t *cf);

    /* 创建用于HTTP全局配置项的结构体,该结构体中的成员将保存直属于http{}块的配置参数项,它会在解析main配置项前调用 */
    void       *(*create_main_conf)(ngx_conf_t *cf);

    /* 解析完main配置项后调用 */
    char       *(*init_main_conf)(ngx_conf_t *cf, void *conf);

    /* 创建用于存储可同时出现在main、srv级别配置项的结构体,该结构体中的成员与server配置相关联 */
    void       *(*create_srv_conf)(ngx_conf_t *cf);

    /* 用于把出现在main、srv级别中的配置项合并到srv级别配置项中 */
    char       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);

    /* 创建用于存储可同时出现在main、srv、loc级别配置项的结构体,该结构体中的成员与location配置相关联 */
    void       *(*create_loc_conf)(ngx_conf_t *cf);

    /* 用于把出现在main、srv、loc级别中的配置项合并到srv级别配置项中 */
    char       *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t;

ngx_http_conf_ctx_t

      用于存放HTTP的配置项。

typedef struct {
    /* 指向一个指针数组,每个元素都是create_main_conf函数创建的全局结构体,
    解析直属http{}块内的main级别配置参数 */
    void            **main_conf;

    /* 指向一个指针数组,每个元素都是create_srv_conf函数创建的全局结构体,
    解析直属http{}或server{}块内的配置参数 */
    viud            **srv_conf;

    /* 指向一个指针数组,每个元素都是create_loc_conf函数创建的全局结构体,
    解析直属http{}、server{}或location{}块内的配置参数 */
    viud            **loc_conf;
}   ngx_http_conf_ctx_t;

管理main级别下的配置

      ngx_cycle_t成员数组ctx中第七个指针由ngx_http_module模块使用(因为ngx_http_module模块在ngx_modules[]数组中的第七个),至于不同的http模块,相应的三个配置项的下标存放在ctx_index中。
      由ngx_cycle_t核心结构体中找到main级别的结构体所用的宏:

#define ngx_http_cycle_get_module_main_conf(cycle,module)  \
    (cycle->conf_ctx[ngx_http_module.index] ?  \
    ((ngx_http_conf_ctx_t*)
    cycle->conf_ctx[ngx_http_module.index]))->main_conf[module.ctx_index] : NULL)

管理server级别下的配置

      在解析main级别配置项时,遇到server{}块,就会调用ngx_http_core_server函数来解析server块。



ngx_http_core_main_conf_t
typedef struct {
    ngx_array_t                servers;         /* ngx_http_core_srv_conf_t */

    ngx_http_phase_engine_t    phase_engine;

    ngx_hash_t                 headers_in_hash;

    ngx_hash_t                 variables_hash;

    ngx_array_t                variables;       /* ngx_http_variable_t */
    ngx_uint_t                 ncaptures;

    ngx_uint_t                 server_names_hash_max_size;
    ngx_uint_t                 server_names_hash_bucket_size;

    ngx_uint_t                 variables_hash_max_size;
    ngx_uint_t                 variables_hash_bucket_size;

    ngx_hash_keys_arrays_t    *variables_keys;

    ngx_array_t               *ports;

    ngx_uint_t                 try_files;       /* unsigned  try_files:1 */

    ngx_http_phase_t           phases[NGX_HTTP_LOG_PHASE + 1]; 
} ngx_http_core_main_conf_t;

      可以看到,其中有一个成员是动态数组server。这个数组中的每一个元素都是ngx_http_core_srv_conf_t结构体。

ngx_http_core_srv_conf_t
typedef struct {
    /* array of the ngx_http_server_name_t, "server_name" directive */
    ngx_array_t                 server_names;

    /* server ctx */
    ngx_http_conf_ctx_t        *ctx;

    ngx_str_t                   server_name;

    size_t                      connection_pool_size;
    size_t                      request_pool_size;
    size_t                      client_header_buffer_size;

    ngx_bufs_t                  large_client_header_buffers;

    ngx_msec_t                  client_header_timeout;

    ngx_flag_t                  ignore_invalid_headers;
    ngx_flag_t                  merge_slashes;
    ngx_flag_t                  underscores_in_headers;

    unsigned                    listen:1;
#if (NGX_PCRE)
    unsigned                    captures:1;
#endif

    ngx_http_core_loc_conf_t  **named_locations;
} ngx_http_core_srv_conf_t;

      ngx_http_core_srv_conf_t结构体中的ctx成员就指向一个解析完的server级别配置项。

管理location级别下的配置

      这个其实和server管理是一样的,无非“更深入了一层”。



      如你所见,在main中找到server对象,在server中找到location对象。但是这里有一点不一样:ngx_http_core_srv_conf_t中有ngx_http_core_srv_conf_t**变量,其中存放着用来连接server{}块下的location{}块指针数组。

ngx_http_core_loc_conf_t
struct ngx_http_core_loc_conf_s {
    ngx_str_t     name;          /* location name */

#if (NGX_PCRE)
    ngx_http_regex_t  *regex;
#endif

    unsigned      noname:1;   /* "if () {}" block or limit_except */
    unsigned      lmt_excpt:1;
    unsigned      named:1;

    unsigned      exact_match:1;
    unsigned      noregex:1;

    unsigned      auto_redirect:1;
#if (NGX_HTTP_GZIP)
    unsigned      gzip_disable_msie6:2;
#if (NGX_HTTP_DEGRADATION)
    unsigned      gzip_disable_degradation:2;
#endif
#endif

    ngx_http_location_tree_node_t   *static_locations;
#if (NGX_PCRE)
    ngx_http_core_loc_conf_t       **regex_locations;
#endif

    /* pointer to the modules' loc_conf */
    void        **loc_conf;

    uint32_t      limit_except;
    void        **limit_except_loc_conf;

    ngx_http_handler_pt  handler;

    /* location name length for inclusive location with inherited alias */
    size_t        alias;
    ngx_str_t     root;                    /* root, alias */
    ngx_str_t     post_action;

    ngx_array_t  *root_lengths;
    ngx_array_t  *root_values;

    ngx_array_t  *types;
    ngx_hash_t    types_hash;
    ngx_str_t     default_type;

    off_t         client_max_body_size;    /* client_max_body_size */
    off_t         directio;                /* directio */
    off_t         directio_alignment;      /* directio_alignment */

    size_t        client_body_buffer_size; /* client_body_buffer_size */
    size_t        send_lowat;              /* send_lowat */
    size_t        postpone_output;         /* postpone_output */
    size_t        limit_rate;              /* limit_rate */
    size_t        limit_rate_after;        /* limit_rate_after */
    size_t        sendfile_max_chunk;      /* sendfile_max_chunk */
    size_t        read_ahead;              /* read_ahead */

    ngx_msec_t    client_body_timeout;     /* client_body_timeout */
    ngx_msec_t    send_timeout;            /* send_timeout */
    ngx_msec_t    keepalive_timeout;       /* keepalive_timeout */
    ngx_msec_t    lingering_time;          /* lingering_time */
    ngx_msec_t    lingering_timeout;       /* lingering_timeout */
    ngx_msec_t    resolver_timeout;        /* resolver_timeout */

    ngx_resolver_t  *resolver;             /* resolver */

    time_t        keepalive_header;        /* keepalive_timeout */

    ngx_uint_t    keepalive_requests;      /* keepalive_requests */
    ngx_uint_t    keepalive_disable;       /* keepalive_disable */
    ngx_uint_t    satisfy;                 /* satisfy */
    ngx_uint_t    lingering_close;         /* lingering_close */
    ngx_uint_t    if_modified_since;       /* if_modified_since */
    ngx_uint_t    max_ranges;              /* max_ranges */
    ngx_uint_t    client_body_in_file_only; /* client_body_in_file_only */

    ngx_flag_t    client_body_in_single_buffer;
                                           /* client_body_in_singe_buffer */
    ngx_flag_t    internal;                /* internal */
    ngx_flag_t    sendfile;                /* sendfile */
#if (NGX_HAVE_FILE_AIO)
    ngx_flag_t    aio;                     /* aio */
#endif
    ngx_flag_t    tcp_nopush;              /* tcp_nopush */
    ngx_flag_t    tcp_nodelay;             /* tcp_nodelay */
    ngx_flag_t    reset_timedout_connection; /* reset_timedout_connection */
    ngx_flag_t    server_name_in_redirect; /* server_name_in_redirect */
    ngx_flag_t    port_in_redirect;        /* port_in_redirect */
    ngx_flag_t    msie_padding;            /* msie_padding */
    ngx_flag_t    msie_refresh;            /* msie_refresh */
    ngx_flag_t    log_not_found;           /* log_not_found */
    ngx_flag_t    log_subrequest;          /* log_subrequest */
    ngx_flag_t    recursive_error_pages;   /* recursive_error_pages */
    ngx_flag_t    server_tokens;           /* server_tokens */
    ngx_flag_t    chunked_transfer_encoding; /* chunked_transfer_encoding */
    ngx_flag_t    etag;                    /* etag */

#if (NGX_HTTP_GZIP)
    ngx_flag_t    gzip_vary;               /* gzip_vary */

    ngx_uint_t    gzip_http_version;       /* gzip_http_version */
    ngx_uint_t    gzip_proxied;            /* gzip_proxied */

#if (NGX_PCRE)
    ngx_array_t  *gzip_disable;            /* gzip_disable */
#endif
#endif

#if (NGX_HAVE_OPENAT)
    ngx_uint_t    disable_symlinks;        /* disable_symlinks */
    ngx_http_complex_value_t  *disable_symlinks_from;
#endif

    ngx_array_t  *error_pages;             /* error_page */
    ngx_http_try_file_t    *try_files;     /* try_files */

    ngx_path_t   *client_body_temp_path;   /* client_body_temp_path */

    ngx_open_file_cache_t  *open_file_cache;
    time_t        open_file_cache_valid;
    ngx_uint_t    open_file_cache_min_uses;
    ngx_flag_t    open_file_cache_errors;
    ngx_flag_t    open_file_cache_events;

    ngx_log_t    *error_log;

    ngx_uint_t    types_hash_max_size;
    ngx_uint_t    types_hash_bucket_size;

    ngx_queue_t  *locations;

#if 0
    ngx_http_core_loc_conf_t  *prev_location;
#endif
};

typedef struct {
    /* 将同属一个location{}的配置项连接起来 */
    ngx_queue_t                      queue;

    /* 如果location中的字符串能精确匹配,则exact指向对应的ngx_http_core_loc_conf_t结构体,否则为NULL */
    ngx_http_core_loc_conf_t        *exact;

    /* 如果无法精确匹配,则inlcusive指向ngx_http_core_loc_conf_t结构体,否则为NULL */
    ngx_http_core_loc_conf_t        *inclusive;

    /* 块名称 */
    ngx_str_t                       *name;
    u_char                          *file_name;
    ngx_uint_t                       line;
    ngx_queue_t                      list;
} ngx_http_location_queue_t;

      ngx_http_core_loc_conf_t中的locations指向ngx_http_location_queue_t双向队列,这个队列由属于当前块的所有location块构成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值