主页

索引

模块索引

搜索页面

Nginx数据结构

作者:

新溪-gordon <programfan.info#gmail.com>

时间:

2014-07-29

高级模块说明

ngx_command_t:

 1
 2//
 3struct ngx_command_s {
 4  ngx_str_t   name;   // 配置项名, 无空格
 5  ngx_uint_t  type;   // 配置项type
 6
 7  // 出现了name中制定的配置项后,将会调用set方法处理配置项参数。
 8  // 这个可以使用nginx预设的14个解析配置方法,也可以使用自定义的。
 9  char        *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);   // 指令操作
10
11  // 因为有可能模块同时会有main,srv,loc三种配置结构体,指定这个配置项解析完后要放在哪个结构体内
12  ngx_uint_t  conf;
13
14  // 表示当前配置项在整个存储配置项的结构体中的偏移位置,可以使用offsetof(test_stru, b)来获取
15  ngx_uint_t  offset;
16
17  // 命令处理完后的回调指针,对于set的14种预设的解析配置方法
18  void        *post;
19}
20
21// 说明
22/*
23  type:
24      NGX_HTTP_MAIN_CONF
25      NGX_HTTP_SRV_CONF
26      NGX_HTTP_LOC_CONF
27      NGX_HTTP_UP_CONF
28
29      NGX_CONF_NOARGS
30      NGX_CONF_TAKE1
31      NGX_CONF_TAKE2
32
33      NGX_CONF_FLAG
34      NGX_CONF_1MORE
35
36  set:
37     参数cf: 包含传给指令的参数
38     参数cmd: 指向当前的ngx_command_t结构
39     参数conf: 指向custom configuration struct
40
41      // setting particular types of values in the custom configuration sturct
42      ngx_conf_set_flag_slot
43      ngx_conf_set_str_slot
44      ngx_conf_set_num_slot
45      ngx_conf_set_size_slot
46
47   conf:
48      NGX_HTTP_MAIN_CONF_OFFSET
49      NGX_HTTP_SRV_CONF_OFFSET
50      NGX_HTTP_LOC_CONF_OFFSET
51
52   post:
53      ngx_conf_post_t
54      ngx_conf_enum_t
55      ngx_conf_bitmask_t
56      null
57
58 */

ngx_http_module_t:

 1
 2//HTTP框架在读取,重载配置文件时定义了由ngx_http_module_t接口描述的8个阶段
 3//这8个阶段的调用顺序应该是:
 4/*
 5create_main_conf
 6create_srv_conf
 7create_loc_conf
 8preconfiguration
 9init_main_conf
10merge_srv_conf
11merge_loc_conf
12postconfiguration
13*/
14typedef struct {
15  ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);  //解析配置文件前调用
16  ngx_int_t   (*postconfiguration)(ngx_conf_t *cf); //完成配置文件解析后调用
17
18  void       *(*create_main_conf)(ngx_conf_t *cf);  //当需要创建数据结构用户存储main级别的全局配置项时候调用
19  char       *(*init_main_conf)(ngx_conf_t *cf, void *conf); //初始化main级别配置项
20
21  void       *(*create_srv_conf)(ngx_conf_t *cf); //当需要创建数据结构用户存储srv级别的全局配置项时候调用
22  char       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf); //srv覆盖策略
23
24  void       *(*create_loc_conf)(ngx_conf_t *cf); //当需要创建数据结构用户存储loc级别的全局配置项时候调用
25  char       *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf); //loc覆盖策略
26} ngx_http_module_t;
27
28

ngx_module_t:

 1
 2
 3
 4//参考:
 5//http://blog.csdn.net/livelylittlefish/article/details/6571497
 6#define NGX_MODULE_V1          0, 0, 0, 0, 0, 0, 1      //该宏用来初始化前7个字段  
 7#define NGX_MODULE_V1_PADDING  0, 0, 0, 0, 0, 0, 0, 0   //该宏用来初始化最后8个字段
 8
 9
10//ngx_module_s是模块的定义
11struct ngx_module_s {
12  //对于一类模块(由下面的type成员决定类别)而言,ctx_index标示当前模块在这类模块中的序号。
13  //这个成员常常是由管理这类模块的一个nginx核心模块设置的,对于所有的HTTP模块而言,ctx_index
14  //是由核心模块ngx_http_module设置的。
15  ngx_uint_t            ctx_index;
16
17  //index表示当前模块在ngx_modules数组中的序号。Nginx启动的时候会根据ngx_modules数组设置各个模块的index值
18  ngx_uint_t            index; 
19
20  //spare系列的保留变量,暂未使用
21  ngx_uint_t            spare0;
22  ngx_uint_t            spare1;
23  ngx_uint_t            spare2;
24  ngx_uint_t            spare3;
25
26  //nginx模块版本,目前只有一种,暂定为1
27  //前面这7个参数使用NGX_MODULE_V1赋值
28  ngx_uint_t            version;
29
30
31  //模块上下文,每个模块有不同模块上下文,每个模块都有自己的特性,而ctx会指向特定类型模块的公共接口。
32  //比如,在HTTP模块中,ctx需要指向ngx_http_module_t结构体。
33  void                 *ctx;
34
35  //模块命令集,将处理nginx.conf中的配置项
36  // 如,在http模块中,指向ngx_command_t结构体
37  ngx_command_t        *commands;
38
39
40  //标示该模块的类型,和ctx是紧密相关的。它的取值范围是以下几种:
41  //NGX_HTTP_MODULE,NGX_CORE_MODULE,NGX_CONF_MODULE,
42  //NGX_EVENT_MODULE,NGX_MAIL_MODULE
43  ngx_uint_t            type;
44
45
46  //下面7个函数是nginx在启动,停止过程中的7个执行点
47  ngx_int_t           (*init_master)(ngx_log_t *log);         //初始化master
48  ngx_int_t           (*init_module)(ngx_cycle_t *cycle);     //初始化模块
49  ngx_int_t           (*init_process)(ngx_cycle_t *cycle);    //初始化进程
50  ngx_int_t           (*init_thread)(ngx_cycle_t *cycle);     //初始化线程
51  void                (*exit_thread)(ngx_cycle_t *cycle);     //退出线程
52  void                (*exit_process)(ngx_cycle_t *cycle);    //退出进程
53  void                (*exit_master)(ngx_cycle_t *cycle);     //退出master
54
55
56  //保留字段,无用,可以使用NGX_MODULE_V1_PADDING来替换
57  uintptr_t             spare_hook0;
58  uintptr_t             spare_hook1;
59  uintptr_t             spare_hook2;
60  uintptr_t             spare_hook3;
61  uintptr_t             spare_hook4;
62  uintptr_t             spare_hook5;
63  uintptr_t             spare_hook6;
64  uintptr_t             spare_hook7;
65
66
67}

ngx_http_request_t:

  1
  2//这个结构定义了一个HTTP请求。
  3struct ngx_http_request_s {
  4  uint32_t                          signature;         /* "HTTP" */
  5
  6  // 这个请求对应的客户端连接
  7  ngx_connection_t                 *connection;  //当前request的连接
  8
  9  // 指向存放所有HTTP模块的上下文结构体的指针数组
 10  void                            **ctx;  //上下文
 11
 12  // 指向请求对应的存放main级别配置结构体的指针数组
 13  void                            **main_conf; //main配置
 14
 15  // 指向请求对应的存放srv级别配置结构体的指针数组
 16  void                            **srv_conf;  //srv配置
 17
 18  // 指向请求对应的存放loc级别配置结构体的指针数组
 19  void                            **loc_conf;  //loc配置
 20
 21  /*
 22    在接收完HTTP头部,第一次在业务上处理HTTP请求时,HTTP框架提供的处理方法是ngx_http_process_request。
 23    但如果该方法无法一次处理完该请求的全部业务,在归还控制权到epoll事件模块后,该请求再次被回调时,将通过ngx_http_request_handler方法来处理,
 24    而这个方法中对于可读事件的处理就是调用read_event_handler处理请求。也就是说,HTTP模块希望在底层处理请求的读事件,重新实现read_evet_handler方法。
 25  */
 26  ngx_http_event_handler_pt         read_event_handler;
 27
 28  /*
 29    与read_event_handler回调方法类似,如果ngx_http_request_handler方法判断当前事件是可写事件,则调用write_event_handler处理请求。
 30  */
 31  ngx_http_event_handler_pt         write_event_handler;
 32
 33#if (NGX_HTTP_CACHE)
 34  ngx_http_cache_t                 *cache;
 35#endif
 36
 37  // upstream机制用到的结构体
 38  ngx_http_upstream_t              *upstream;  //load-balance,如果模块是load-balance的话设置这个
 39  ngx_array_t                      *upstream_states;
 40  /* of ngx_http_upstream_state_t */
 41
 42  /*
 43    表示这个请求的内存池,在ngx_http_free_request 方法中销毁。它与ngx_connection_t中的内存池意义不同,当请求释放时,
 44    TCP连接可能并没有关闭,这时请求的内存池会销毁,但ngx_connection_t的内存池不会销毁
 45  */
 46  ngx_pool_t                       *pool;     //连接池
 47
 48  // 用于接收HTTP请求内容的缓冲区,主要用于接收HTTP头部
 49  ngx_buf_t                        *header_in;
 50
 51  /*
 52    ngx_http_prcess_request_headers 方法在接收,解析完HTTP请求的头部后,会把解析完的每个HTTP头部加入到headers_in的headers连表中,
 53    同时会构造headers_in中的其他成员
 54  */
 55  ngx_http_headers_in_t             headers_in; //request的header
 56  /*
 57    HTTP模块会把想要发送到HTTP相应信息放到headers_out中,期望HTTP框架将headers_out中的成员序列化为HTTP相应包发送给用户
 58  */
 59  ngx_http_headers_out_t            headers_out; //response的header,使用ngx_http_send_header发送
 60
 61  // 接收HTTP请求中包体的数据结构
 62  ngx_http_request_body_t          *request_body; //response的body
 63
 64  // 延迟关闭连接的时间
 65  time_t                            lingering_time;
 66
 67  /*
 68    当前请求初始化时的时间。如果这个请求是子请求,则该时间是自请求的生成时间;如果这个请求是用户发来的请求,则是建立起TCP连接后,第一次接收到可读事件时的时间
 69  */
 70  time_t                            start_sec;
 71
 72  // 与start_sec配合使用,表示相对于start_sec秒的毫秒偏移量
 73  ngx_msec_t                        start_msec;
 74
 75  ngx_uint_t                        method;
 76  ngx_uint_t                        http_version; //http的版本
 77
 78  ngx_str_t                         request_line;
 79  ngx_str_t                         uri;  //请求的路径 eg '/query.php'
 80  ngx_str_t                         args; //请求的参数 eg 'name=john'
 81  ngx_str_t                         exten; 
 82  ngx_str_t                         unparsed_uri;
 83
 84  ngx_str_t                         method_name;
 85  ngx_str_t                         http_protocol;
 86
 87  /*
 88    表示需要发送给客户端的HTTP相应。out中保存着由headers_out中序列化后的表示HTTP头部的TCP流。在调用ngx_http_output_filter方法后,
 89    out中还会保存待发送的HTTP包体,它是实现异步发送的HTTP相应的关键
 90  */
 91  ngx_chain_t                      *out; //输出的chain
 92
 93  /*
 94    当前请求既可能是用户发来的请求,也可能是派生出的子请求,而main则标识一系列相关的派生子请求的原始请求,
 95    我们一般可以通过main和当前请求的地址是否相等来判断当前请求是否为用户发来的原始请求。
 96  */
 97  ngx_http_request_t               *main;
 98
 99  // 当前请求的父请求。注意,父请求未必是原始请求
100  ngx_http_request_t               *parent;
101
102  // 与subrequest子请求相关的功能。
103  ngx_http_postponed_request_t     *postponed;
104  ngx_http_post_subrequest_t       *post_subrequest;
105
106  /*
107    所有自请求都是通过posted_requests这个单链表来链接起来的,执行post子请求时调用的ngx_http_run_posted_requests
108    方法就是通过遍历该单链表来执行子请求的。
109  */
110  ngx_http_posted_request_t        *posted_requests;
111
112  ngx_http_virtual_names_t         *virtual_names;
113
114  /*
115    全局的ngx_http_phase_engine_t结构体中定义了一个ngx_http_phase_handler_t 回调方法组成的数组,
116    而phase_handler成员则与该数组配合使用,表示请求下次应当执行以phase_handler作为序号指定的数组中的回调方法。
117    HTTP框架正是以这种方式把各个HTTP模块集成起来处理请求的。
118  */
119  ngx_int_t                         phase_handler;
120
121  /*
122    表示NGX_HTTP_CONTENT_PHASE阶段提供给HTTP模块处理请求的一种方式,content_handler指向HTTP模块实现的请求处理方法。
123  */
124  ngx_http_handler_pt               content_handler;
125
126  /*
127    在NGX_HTTP_ACCESS_PHASE阶段需要判断请求是否具有访问权限时,通过access_code来传递HTTP模块的handler回调方法的返回值,
128    如果access_code为0,则表示请求具备访问权限,反之则说明请求不具备访问权限
129  */ 
130  ngx_uint_t                        access_code;
131
132  ngx_http_variable_value_t        *variables;
133
134#if (NGX_PCRE)
135  ngx_uint_t                        ncaptures;
136  int                              *captures;
137  u_char                           *captures_data;
138#endif
139
140  size_t                            limit_rate;
141
142  /* used to learn the Apache compatible response length without a header */
143  size_t                            header_size;
144
145  // HTTP请求的全部长度,包括HTTP包体
146  off_t                             request_length;
147
148  ngx_uint_t                        err_status;
149
150  ngx_http_connection_t            *http_connection;
151
152  ngx_http_log_handler_pt           log_handler;
153
154  // 在这个请求中,如果打开了某些资源,并需要在请求结束时释放,那么都需要在把定义的释放资源方法添加到cleanup成员中。
155  ngx_http_cleanup_t               *cleanup;
156
157  unsigned                          subrequests:8;
158
159  /*
160    表示当前请求的引用次数。例如,在使用subrequest功能时,依附在这个请求上的自请求数目会返回到count上,每增加一个子请求,
161    count数就要加1。其中任何一个自请求派生出新的子请求时,对应的原始请求(main指针指向的请求)的count值都要加1.又如,
162    当我们接收HTTP包体的时候,由于这也是一个异步调用,所以count上也需要加1,这样在结束请求时,就不会在count引用计数未清零时销毁请求。
163  */
164  unsigned                          count:8;
165
166  // 标志位,目前仅由aio使用
167  unsigned                          blocked:8;
168
169  // 标志位,为1表示当前请求正在使用异步文件IO
170  unsigned                          aio:1;
171
172  unsigned                          http_state:4;
173
174  /* URI with "/." and on Win32 with "//" */
175  unsigned                          complex_uri:1;
176
177  /* URI with "%" */
178  unsigned                          quoted_uri:1;
179
180  /* URI with "+" */
181  unsigned                          plus_in_uri:1;
182
183  /* URI with " " */
184  unsigned                          space_in_uri:1;
185
186  unsigned                          invalid_header:1;
187
188  unsigned                          add_uri_to_alias:1;
189  unsigned                          valid_location:1;
190  unsigned                          valid_unparsed_uri:1;
191
192  // 标志位,为1表示URL发生过rewrite重写
193  unsigned                          uri_changed:1;
194
195  /*
196    表示使用rewrite重写URL的次数。因为目前最多可以更改10次,所以uri_changes初始化为11,而每重写URL一次就把uri_changes减1,
197    一旦uri_changes等于0,则向用户返回失败
198  */
199  unsigned                          uri_changes:4;
200
201  unsigned                          request_body_in_single_buf:1;
202  unsigned                          request_body_in_file_only:1;
203  unsigned                          request_body_in_persistent_file:1;
204  unsigned                          request_body_in_clean_file:1;
205  unsigned                          request_body_file_group_access:1;
206  unsigned                          request_body_file_log_level:3;
207
208  unsigned                          subrequest_in_memory:1;
209  unsigned                          waited:1;
210
211#if (NGX_HTTP_CACHE)
212  unsigned                          cached:1;
213#endif
214
215#if (NGX_HTTP_GZIP)
216  unsigned                          gzip_tested:1;
217  unsigned                          gzip_ok:1;
218  unsigned                          gzip_vary:1;
219#endif
220
221  unsigned                          proxy:1;
222  unsigned                          bypass_cache:1;
223  unsigned                          no_cache:1;
224
225  /*
226   * instead of using the request context data in
227   * ngx_http_limit_zone_module and ngx_http_limit_req_module
228   * we use the single bits in the request structure
229   */
230  unsigned                          limit_zone_set:1;
231  unsigned                          limit_req_set:1;
232
233#if 0
234  unsigned                          cacheable:1;
235#endif
236
237  unsigned                          pipeline:1;
238  unsigned                          plain_http:1;
239  unsigned                          chunked:1;
240  unsigned                          header_only:1;
241
242  // 标志位,为1表示当前请求是keepalive请求
243  unsigned                          keepalive:1;
244
245  // 延迟关闭标志位,为1表示需要延迟关闭。例如在接收完HTTP头部时如果发现包体存在,该标志位会设置1,而放弃接收包体会设为0
246  unsigned                          lingering_close:1;
247
248  // 标志位,为1表示正在丢弃HTTP请求中的包体
249  unsigned                          discard_body:1;
250
251  // 标志位,为1表示请求的当前状态是在做内部跳转
252  unsigned                          internal:1;
253  unsigned                          error_page:1;
254  unsigned                          ignore_content_encoding:1;
255  unsigned                          filter_finalize:1;
256  unsigned                          post_action:1;
257  unsigned                          request_complete:1;
258  unsigned                          request_output:1;
259
260  // 标志位,为1表示发送给客户端的HTTP相应头部已经发送。在调用ngx_http_send_header方法后,若已经成功地启动相应头部发送流程,
261  // 该标志位就会置1,用来防止反复地发送头部。
262  unsigned                          header_sent:1;
263  unsigned                          expect_tested:1;
264  unsigned                          root_tested:1;
265  unsigned                          done:1;
266  unsigned                          logged:1;
267
268  // 表示缓冲中是否有待发送内容的标志位
269  unsigned                          buffered:4;
270
271  unsigned                          main_filter_need_in_memory:1;
272  unsigned                          filter_need_in_memory:1;
273  unsigned                          filter_need_temporary:1;
274  unsigned                          allow_ranges:1;
275
276#if (NGX_STAT_STUB)
277  unsigned                          stat_reading:1;
278  unsigned                          stat_writing:1;
279#endif
280
281  /* used to parse HTTP headers */
282
283  // 状态机解析HTTP时使用stats来表示当前的解析状态。
284  ngx_uint_t                        state;
285
286  ngx_uint_t                        header_hash;
287  ngx_uint_t                        lowcase_index;
288  u_char                            lowcase_header[NGX_HTTP_LC_HEADER_LEN];
289
290  u_char                           *header_name_start;
291  u_char                           *header_name_end;
292  u_char                           *header_start;
293  u_char                           *header_end;
294
295  /*
296   * a memory that can be reused after parsing a request line
297   * via ngx_http_ephemeral_t
298   */
299
300  u_char                           *uri_start;
301  u_char                           *uri_end;
302  u_char                           *uri_ext;
303  u_char                           *args_start;
304  u_char                           *request_start;
305  u_char                           *request_end;
306  u_char                           *method_end;
307  u_char                           *schema_start;
308  u_char                           *schema_end;
309  u_char                           *host_start;
310  u_char                           *host_end;
311  u_char                           *port_start;
312  u_char                           *port_end;
313
314  unsigned                          http_minor:16;
315  unsigned                          http_major:16;
316
317}
318
319
320

主页

索引

模块索引

搜索页面