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塊構成。