《深入理解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塊構成。

發佈了88 篇原創文章 · 獲贊 9 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章