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块。
![](https://raw.githubusercontent.com/Vanyoo/macbook-pro-learning/master/CSDN/8-2015/8-3/server.png)
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管理是一样的,无非“更深入了一层”。
![](https://raw.githubusercontent.com/Vanyoo/macbook-pro-learning/master/CSDN/8-2015/8-3/location.png)
如你所见,在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块构成。