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