1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_event.h>
10 #include <ngx_http.h>
11 #include <nginx.h>
12
13
14 typedef struct {
15 u_char *name;
16 uint32_t method;
17 } ngx_http_method_name_t;
18
19
20 #define NGX_HTTP_LOCATION_EXACT 1
21 #define NGX_HTTP_LOCATION_AUTO_REDIRECT 2
22 #define NGX_HTTP_LOCATION_NOREGEX 3
23 #define NGX_HTTP_LOCATION_REGEX 4
24
25
26 #define NGX_HTTP_REQUEST_BODY_FILE_OFF 0
27 #define NGX_HTTP_REQUEST_BODY_FILE_ON 1
28 #define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2
29
30
31 static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r,
32 ngx_array_t *locations, ngx_uint_t regex_start, size_t len);
33
34 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
35 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
36 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
37 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
38 static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
39 void *parent, void *child);
40 static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf);
41 static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
42 void *parent, void *child);
43
44 static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
45 void *dummy);
46 static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
47 void *dummy);
48 static int ngx_http_core_cmp_locations(const void *first, const void *second);
49
50 static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
51 void *conf);
52 static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy,
53 void *conf);
54
55 static char *ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
56 void *conf);
57 static char *ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
58 void *conf);
59 static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
60 static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
61 void *conf);
62 static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
63 void *conf);
64 static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
65 void *conf);
66 static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
67 void *conf);
68 static char *ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
69 void *conf);
70 static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
71 void *conf);
72 static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
73 void *conf);
74 #if (NGX_HTTP_GZIP)
75 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
76 void *conf);
77 #endif
78
79 static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
80 static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data);
81
82 static ngx_conf_post_t ngx_http_core_lowat_post =
83 { ngx_http_core_lowat_check };
84
85 static ngx_conf_post_handler_pt ngx_http_core_pool_size_p =
86 ngx_http_core_pool_size;
87
88 static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_host_names = {
89 ngx_conf_deprecated, "optimize_host_names", "optimize_server_names"
90 };
91
92 static ngx_conf_deprecated_t ngx_conf_deprecated_open_file_cache_retest = {
93 ngx_conf_deprecated, "open_file_cache_retest", "open_file_cache_valid"
94 };
95
96 static ngx_conf_deprecated_t ngx_conf_deprecated_satisfy_any = {
97 ngx_conf_deprecated, "satisfy_any", "satisfy"
98 };
99
100
101 static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = {
102 { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF },
103 { ngx_string("on"), NGX_HTTP_REQUEST_BODY_FILE_ON },
104 { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN },
105 { ngx_null_string, 0 }
106 };
107
108
109 static ngx_conf_enum_t ngx_http_core_satisfy[] = {
110 { ngx_string("all"), NGX_HTTP_SATISFY_ALL },
111 { ngx_string("any"), NGX_HTTP_SATISFY_ANY },
112 { ngx_null_string, 0 }
113 };
114
115
116 #if (NGX_HTTP_GZIP)
117
118 static ngx_conf_enum_t ngx_http_gzip_http_version[] = {
119 { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
120 { ngx_string("1.1"), NGX_HTTP_VERSION_11 },
121 { ngx_null_string, 0 }
122 };
123
124
125 static ngx_conf_bitmask_t ngx_http_gzip_proxied_mask[] = {
126 { ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF },
127 { ngx_string("expired"), NGX_HTTP_GZIP_PROXIED_EXPIRED },
128 { ngx_string("no-cache"), NGX_HTTP_GZIP_PROXIED_NO_CACHE },
129 { ngx_string("no-store"), NGX_HTTP_GZIP_PROXIED_NO_STORE },
130 { ngx_string("private"), NGX_HTTP_GZIP_PROXIED_PRIVATE },
131 { ngx_string("no_last_modified"), NGX_HTTP_GZIP_PROXIED_NO_LM },
132 { ngx_string("no_etag"), NGX_HTTP_GZIP_PROXIED_NO_ETAG },
133 { ngx_string("auth"), NGX_HTTP_GZIP_PROXIED_AUTH },
134 { ngx_string("any"), NGX_HTTP_GZIP_PROXIED_ANY },
135 { ngx_null_string, 0 }
136 };
137
138
139 static ngx_str_t ngx_http_gzip_no_cache = ngx_string("no-cache");
140 static ngx_str_t ngx_http_gzip_no_store = ngx_string("no-store");
141 static ngx_str_t ngx_http_gzip_private = ngx_string("private");
142
143 #endif
144
145
146 static ngx_command_t ngx_http_core_commands[] = {
147
148 { ngx_string("variables_hash_max_size"),
149 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
150 ngx_conf_set_num_slot,
151 NGX_HTTP_MAIN_CONF_OFFSET,
152 offsetof(ngx_http_core_main_conf_t, variables_hash_max_size),
153 NULL },
154
155 { ngx_string("variables_hash_bucket_size"),
156 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
157 ngx_conf_set_num_slot,
158 NGX_HTTP_MAIN_CONF_OFFSET,
159 offsetof(ngx_http_core_main_conf_t, variables_hash_bucket_size),
160 NULL },
161
162 { ngx_string("server_names_hash_max_size"),
163 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
164 ngx_conf_set_num_slot,
165 NGX_HTTP_MAIN_CONF_OFFSET,
166 offsetof(ngx_http_core_main_conf_t, server_names_hash_max_size),
167 NULL },
168
169 { ngx_string("server_names_hash_bucket_size"),
170 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
171 ngx_conf_set_num_slot,
172 NGX_HTTP_MAIN_CONF_OFFSET,
173 offsetof(ngx_http_core_main_conf_t, server_names_hash_bucket_size),
174 NULL },
175
176 { ngx_string("server"),
177 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_MULTI|NGX_CONF_NOARGS,
178 ngx_http_core_server,
179 0,
180 0,
181 NULL },
182
183 { ngx_string("connection_pool_size"),
184 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
185 ngx_conf_set_size_slot,
186 NGX_HTTP_SRV_CONF_OFFSET,
187 offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
188 &ngx_http_core_pool_size_p },
189
190 { ngx_string("request_pool_size"),
191 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
192 ngx_conf_set_size_slot,
193 NGX_HTTP_SRV_CONF_OFFSET,
194 offsetof(ngx_http_core_srv_conf_t, request_pool_size),
195 &ngx_http_core_pool_size_p },
196
197 { ngx_string("client_header_timeout"),
198 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
199 ngx_conf_set_msec_slot,
200 NGX_HTTP_SRV_CONF_OFFSET,
201 offsetof(ngx_http_core_srv_conf_t, client_header_timeout),
202 NULL },
203
204 { ngx_string("client_header_buffer_size"),
205 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
206 ngx_conf_set_size_slot,
207 NGX_HTTP_SRV_CONF_OFFSET,
208 offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
209 NULL },
210
211 { ngx_string("large_client_header_buffers"),
212 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
213 ngx_conf_set_bufs_slot,
214 NGX_HTTP_SRV_CONF_OFFSET,
215 offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
216 NULL },
217
218 { ngx_string("optimize_server_names"),
219 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
220 ngx_conf_set_flag_slot,
221 NGX_HTTP_SRV_CONF_OFFSET,
222 offsetof(ngx_http_core_srv_conf_t, optimize_server_names),
223 NULL },
224
225 { ngx_string("optimize_host_names"),
226 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
227 ngx_conf_set_flag_slot,
228 NGX_HTTP_SRV_CONF_OFFSET,
229 offsetof(ngx_http_core_srv_conf_t, optimize_server_names),
230 &ngx_conf_deprecated_optimize_host_names },
231
232 { ngx_string("ignore_invalid_headers"),
233 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
234 ngx_conf_set_flag_slot,
235 NGX_HTTP_SRV_CONF_OFFSET,
236 offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
237 NULL },
238
239 { ngx_string("merge_slashes"),
240 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
241 ngx_conf_set_flag_slot,
242 NGX_HTTP_SRV_CONF_OFFSET,
243 offsetof(ngx_http_core_srv_conf_t, merge_slashes),
244 NULL },
245
246 { ngx_string("location"),
247 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
248 ngx_http_core_location,
249 NGX_HTTP_SRV_CONF_OFFSET,
250 0,
251 NULL },
252
253 { ngx_string("listen"),
254 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
255 ngx_http_core_listen,
256 NGX_HTTP_SRV_CONF_OFFSET,
257 0,
258 NULL },
259
260 { ngx_string("server_name"),
261 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
262 ngx_http_core_server_name,
263 NGX_HTTP_SRV_CONF_OFFSET,
264 0,
265 NULL },
266
267 { ngx_string("types_hash_max_size"),
268 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
269 ngx_conf_set_num_slot,
270 NGX_HTTP_LOC_CONF_OFFSET,
271 offsetof(ngx_http_core_loc_conf_t, types_hash_max_size),
272 NULL },
273
274 { ngx_string("types_hash_bucket_size"),
275 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
276 ngx_conf_set_num_slot,
277 NGX_HTTP_LOC_CONF_OFFSET,
278 offsetof(ngx_http_core_loc_conf_t, types_hash_bucket_size),
279 NULL },
280
281 { ngx_string("types"),
282 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
283 |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
284 ngx_http_core_types,
285 NGX_HTTP_LOC_CONF_OFFSET,
286 0,
287 NULL },
288
289 { ngx_string("default_type"),
290 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
291 ngx_conf_set_str_slot,
292 NGX_HTTP_LOC_CONF_OFFSET,
293 offsetof(ngx_http_core_loc_conf_t, default_type),
294 NULL },
295
296 { ngx_string("root"),
297 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
298 |NGX_CONF_TAKE1,
299 ngx_http_core_root,
300 NGX_HTTP_LOC_CONF_OFFSET,
301 0,
302 NULL },
303
304 { ngx_string("alias"),
305 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
306 ngx_http_core_root,
307 NGX_HTTP_LOC_CONF_OFFSET,
308 0,
309 NULL },
310
311 { ngx_string("limit_except"),
312 NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE,
313 ngx_http_core_limit_except,
314 NGX_HTTP_LOC_CONF_OFFSET,
315 0,
316 NULL },
317
318 { ngx_string("client_max_body_size"),
319 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
320 ngx_conf_set_off_slot,
321 NGX_HTTP_LOC_CONF_OFFSET,
322 offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
323 NULL },
324
325 { ngx_string("client_body_buffer_size"),
326 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
327 ngx_conf_set_size_slot,
328 NGX_HTTP_LOC_CONF_OFFSET,
329 offsetof(ngx_http_core_loc_conf_t, client_body_buffer_size),
330 NULL },
331
332 { ngx_string("client_body_timeout"),
333 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
334 ngx_conf_set_msec_slot,
335 NGX_HTTP_LOC_CONF_OFFSET,
336 offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
337 NULL },
338
339 { ngx_string("client_body_temp_path"),
340 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
341 ngx_conf_set_path_slot,
342 NGX_HTTP_LOC_CONF_OFFSET,
343 offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
344 (void *) ngx_garbage_collector_temp_handler },
345
346 { ngx_string("client_body_in_file_only"),
347 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
348 ngx_conf_set_enum_slot,
349 NGX_HTTP_LOC_CONF_OFFSET,
350 offsetof(ngx_http_core_loc_conf_t, client_body_in_file_only),
351 &ngx_http_core_request_body_in_file },
352
353 { ngx_string("sendfile"),
354 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
355 |NGX_CONF_TAKE1,
356 ngx_conf_set_flag_slot,
357 NGX_HTTP_LOC_CONF_OFFSET,
358 offsetof(ngx_http_core_loc_conf_t, sendfile),
359 NULL },
360
361 { ngx_string("sendfile_max_chunk"),
362 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
363 ngx_conf_set_size_slot,
364 NGX_HTTP_LOC_CONF_OFFSET,
365 offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
366 NULL },
367
368 { ngx_string("tcp_nopush"),
369 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
370 ngx_conf_set_flag_slot,
371 NGX_HTTP_LOC_CONF_OFFSET,
372 offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
373 NULL },
374
375 { ngx_string("tcp_nodelay"),
376 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
377 ngx_conf_set_flag_slot,
378 NGX_HTTP_LOC_CONF_OFFSET,
379 offsetof(ngx_http_core_loc_conf_t, tcp_nodelay),
380 NULL },
381
382 { ngx_string("send_timeout"),
383 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
384 ngx_conf_set_msec_slot,
385 NGX_HTTP_LOC_CONF_OFFSET,
386 offsetof(ngx_http_core_loc_conf_t, send_timeout),
387 NULL },
388
389 { ngx_string("send_lowat"),
390 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
391 ngx_conf_set_size_slot,
392 NGX_HTTP_LOC_CONF_OFFSET,
393 offsetof(ngx_http_core_loc_conf_t, send_lowat),
394 &ngx_http_core_lowat_post },
395
396 { ngx_string("postpone_output"),
397 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
398 ngx_conf_set_size_slot,
399 NGX_HTTP_LOC_CONF_OFFSET,
400 offsetof(ngx_http_core_loc_conf_t, postpone_output),
401 NULL },
402
403 { ngx_string("limit_rate"),
404 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
405 |NGX_CONF_TAKE1,
406 ngx_conf_set_size_slot,
407 NGX_HTTP_LOC_CONF_OFFSET,
408 offsetof(ngx_http_core_loc_conf_t, limit_rate),
409 NULL },
410
411 { ngx_string("keepalive_timeout"),
412 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
413 ngx_http_core_keepalive,
414 NGX_HTTP_LOC_CONF_OFFSET,
415 0,
416 NULL },
417
418 { ngx_string("satisfy"),
419 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
420 ngx_conf_set_enum_slot,
421 NGX_HTTP_LOC_CONF_OFFSET,
422 offsetof(ngx_http_core_loc_conf_t, satisfy),
423 &ngx_http_core_satisfy },
424
425 { ngx_string("satisfy_any"),
426 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
427 ngx_conf_set_flag_slot,
428 NGX_HTTP_LOC_CONF_OFFSET,
429 offsetof(ngx_http_core_loc_conf_t, satisfy),
430 &ngx_conf_deprecated_satisfy_any },
431
432 { ngx_string("internal"),
433 NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
434 ngx_http_core_internal,
435 NGX_HTTP_LOC_CONF_OFFSET,
436 0,
437 NULL },
438
439 { ngx_string("lingering_time"),
440 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
441 ngx_conf_set_msec_slot,
442 NGX_HTTP_LOC_CONF_OFFSET,
443 offsetof(ngx_http_core_loc_conf_t, lingering_time),
444 NULL },
445
446 { ngx_string("lingering_timeout"),
447 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
448 ngx_conf_set_msec_slot,
449 NGX_HTTP_LOC_CONF_OFFSET,
450 offsetof(ngx_http_core_loc_conf_t, lingering_timeout),
451 NULL },
452
453 { ngx_string("reset_timedout_connection"),
454 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
455 ngx_conf_set_flag_slot,
456 NGX_HTTP_LOC_CONF_OFFSET,
457 offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection),
458 NULL },
459
460 { ngx_string("server_name_in_redirect"),
461 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
462 ngx_conf_set_flag_slot,
463 NGX_HTTP_LOC_CONF_OFFSET,
464 offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect),
465 NULL },
466
467 { ngx_string("port_in_redirect"),
468 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
469 ngx_conf_set_flag_slot,
470 NGX_HTTP_LOC_CONF_OFFSET,
471 offsetof(ngx_http_core_loc_conf_t, port_in_redirect),
472 NULL },
473
474 { ngx_string("msie_padding"),
475 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
476 ngx_conf_set_flag_slot,
477 NGX_HTTP_LOC_CONF_OFFSET,
478 offsetof(ngx_http_core_loc_conf_t, msie_padding),
479 NULL },
480
481 { ngx_string("msie_refresh"),
482 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
483 ngx_conf_set_flag_slot,
484 NGX_HTTP_LOC_CONF_OFFSET,
485 offsetof(ngx_http_core_loc_conf_t, msie_refresh),
486 NULL },
487
488 { ngx_string("log_not_found"),
489 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
490 ngx_conf_set_flag_slot,
491 NGX_HTTP_LOC_CONF_OFFSET,
492 offsetof(ngx_http_core_loc_conf_t, log_not_found),
493 NULL },
494
495 { ngx_string("recursive_error_pages"),
496 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
497 ngx_conf_set_flag_slot,
498 NGX_HTTP_LOC_CONF_OFFSET,
499 offsetof(ngx_http_core_loc_conf_t, recursive_error_pages),
500 NULL },
501
502 { ngx_string("server_tokens"),
503 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
504 ngx_conf_set_flag_slot,
505 NGX_HTTP_LOC_CONF_OFFSET,
506 offsetof(ngx_http_core_loc_conf_t, server_tokens),
507 NULL },
508
509 { ngx_string("error_page"),
510 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
511 |NGX_CONF_2MORE,
512 ngx_http_core_error_page,
513 NGX_HTTP_LOC_CONF_OFFSET,
514 0,
515 NULL },
516
517 { ngx_string("post_action"),
518 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
519 |NGX_CONF_TAKE1,
520 ngx_conf_set_str_slot,
521 NGX_HTTP_LOC_CONF_OFFSET,
522 offsetof(ngx_http_core_loc_conf_t, post_action),
523 NULL },
524
525 { ngx_string("error_log"),
526 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
527 ngx_http_core_error_log,
528 NGX_HTTP_LOC_CONF_OFFSET,
529 0,
530 NULL },
531
532 { ngx_string("open_file_cache"),
533 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
534 ngx_http_core_open_file_cache,
535 NGX_HTTP_LOC_CONF_OFFSET,
536 offsetof(ngx_http_core_loc_conf_t, open_file_cache),
537 NULL },
538
539 { ngx_string("open_file_cache_valid"),
540 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
541 ngx_conf_set_sec_slot,
542 NGX_HTTP_LOC_CONF_OFFSET,
543 offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
544 NULL },
545
546 { ngx_string("open_file_cache_retest"),
547 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
548 ngx_conf_set_sec_slot,
549 NGX_HTTP_LOC_CONF_OFFSET,
550 offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
551 &ngx_conf_deprecated_open_file_cache_retest },
552
553 { ngx_string("open_file_cache_min_uses"),
554 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
555 ngx_conf_set_num_slot,
556 NGX_HTTP_LOC_CONF_OFFSET,
557 offsetof(ngx_http_core_loc_conf_t, open_file_cache_min_uses),
558 NULL },
559
560 { ngx_string("open_file_cache_errors"),
561 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
562 ngx_conf_set_flag_slot,
563 NGX_HTTP_LOC_CONF_OFFSET,
564 offsetof(ngx_http_core_loc_conf_t, open_file_cache_errors),
565 NULL },
566
567 { ngx_string("open_file_cache_events"),
568 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
569 ngx_conf_set_flag_slot,
570 NGX_HTTP_LOC_CONF_OFFSET,
571 offsetof(ngx_http_core_loc_conf_t, open_file_cache_events),
572 NULL },
573
574 { ngx_string("resolver"),
575 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
576 ngx_http_core_resolver,
577 NGX_HTTP_LOC_CONF_OFFSET,
578 0,
579 NULL },
580
581 { ngx_string("resolver_timeout"),
582 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
583 ngx_conf_set_msec_slot,
584 NGX_HTTP_LOC_CONF_OFFSET,
585 offsetof(ngx_http_core_loc_conf_t, resolver_timeout),
586 NULL },
587
588 #if (NGX_HTTP_GZIP)
589
590 { ngx_string("gzip_vary"),
591 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
592 ngx_conf_set_flag_slot,
593 NGX_HTTP_LOC_CONF_OFFSET,
594 offsetof(ngx_http_core_loc_conf_t, gzip_vary),
595 NULL },
596
597 { ngx_string("gzip_http_version"),
598 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
599 ngx_conf_set_enum_slot,
600 NGX_HTTP_LOC_CONF_OFFSET,
601 offsetof(ngx_http_core_loc_conf_t, gzip_http_version),
602 &ngx_http_gzip_http_version },
603
604 { ngx_string("gzip_proxied"),
605 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
606 ngx_conf_set_bitmask_slot,
607 NGX_HTTP_LOC_CONF_OFFSET,
608 offsetof(ngx_http_core_loc_conf_t, gzip_proxied),
609 &ngx_http_gzip_proxied_mask },
610
611 { ngx_string("gzip_disable"),
612 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
613 ngx_http_gzip_disable,
614 NGX_HTTP_LOC_CONF_OFFSET,
615 0,
616 NULL },
617
618 #endif
619
620 ngx_null_command
621 };
622
623
624 static ngx_http_module_t ngx_http_core_module_ctx = {
625 ngx_http_core_preconfiguration, /* preconfiguration */
626 NULL, /* postconfiguration */
627
628 ngx_http_core_create_main_conf, /* create main configuration */
629 ngx_http_core_init_main_conf, /* init main configuration */
630
631 ngx_http_core_create_srv_conf, /* create server configuration */
632 ngx_http_core_merge_srv_conf, /* merge server configuration */
633
634 ngx_http_core_create_loc_conf, /* create location configuration */
635 ngx_http_core_merge_loc_conf /* merge location configuration */
636 };
637
638
639 ngx_module_t ngx_http_core_module = {
640 NGX_MODULE_V1,
641 &ngx_http_core_module_ctx, /* module context */
642 ngx_http_core_commands, /* module directives */
643 NGX_HTTP_MODULE, /* module type */
644 NULL, /* init master */
645 NULL, /* init module */
646 NULL, /* init process */
647 NULL, /* init thread */
648 NULL, /* exit thread */
649 NULL, /* exit process */
650 NULL, /* exit master */
651 NGX_MODULE_V1_PADDING
652 };
653
654
655 static ngx_str_t ngx_http_core_get_method = { 3, (u_char *) "GET " };
656
657
658 void
659 ngx_http_handler(ngx_http_request_t *r)
660 {
661 ngx_http_core_main_conf_t *cmcf;
662
663 r->connection->log->action = NULL;
664
665 r->connection->unexpected_eof = 0;
666
667 if (!r->internal) {
668 switch (r->headers_in.connection_type) {
669 case 0:
670 if (r->http_version > NGX_HTTP_VERSION_10) {
671 r->keepalive = 1;
672 } else {
673 r->keepalive = 0;
674 }
675 break;
676
677 case NGX_HTTP_CONNECTION_CLOSE:
678 r->keepalive = 0;
679 break;
680
681 case NGX_HTTP_CONNECTION_KEEP_ALIVE:
682 r->keepalive = 1;
683 break;
684 }
685
686 if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) {
687
688 /*
689 * MSIE may wait for some time if an response for
690 * a POST request was sent over a keepalive connection
691 */
692
693 r->keepalive = 0;
694 }
695
696 if (r->headers_in.content_length_n > 0) {
697 r->lingering_close = 1;
698
699 } else {
700 r->lingering_close = 0;
701 }
702
703 r->phase_handler = 0;
704
705 } else {
706 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
707 r->phase_handler = cmcf->phase_engine.server_rewrite_index;
708 }
709
710 if (r->unparsed_uri.len) {
711 r->valid_unparsed_uri = 1;
712 }
713
714 r->valid_location = 1;
715 r->gzip = 0;
716
717 r->write_event_handler = ngx_http_core_run_phases;
718 ngx_http_core_run_phases(r);
719 }
720
721
722 void
723 ngx_http_core_run_phases(ngx_http_request_t *r)
724 {
725 ngx_int_t rc;
726 ngx_http_phase_handler_t *ph;
727 ngx_http_core_main_conf_t *cmcf;
728
729 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
730
731 ph = cmcf->phase_engine.handlers;
732
733 while (ph[r->phase_handler].checker) {
734
735 rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
736
737 if (rc == NGX_OK) {
738 return;
739 }
740 }
741 }
742
743
744 ngx_int_t
745 ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
746 {
747 ngx_int_t rc;
748
749 /*
750 * generic phase checker,
751 * used by the post read, server rewrite, rewrite, and pre-access phases
752 */
753
754 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
755 "generic phase: %ui", r->phase_handler);
756
757 rc = ph->handler(r);
758
759 if (rc == NGX_OK) {
760 r->phase_handler = ph->next;
761 return NGX_AGAIN;
762 }
763
764 if (rc == NGX_DECLINED) {
765 r->phase_handler++;
766 return NGX_AGAIN;
767 }
768
769 if (rc == NGX_AGAIN || rc == NGX_DONE) {
770 return NGX_OK;
771 }
772
773 /* rc == NGX_ERROR || rc == NGX_HTTP_... */
774
775 ngx_http_finalize_request(r, rc);
776
777 return NGX_OK;
778 }
779
780
781 ngx_int_t
782 ngx_http_core_find_config_phase(ngx_http_request_t *r,
783 ngx_http_phase_handler_t *ph)
784 {
785 u_char *p;
786 size_t len;
787 ngx_int_t rc;
788 ngx_http_core_loc_conf_t *clcf;
789 ngx_http_core_srv_conf_t *cscf;
790
791 r->content_handler = NULL;
792 r->uri_changed = 0;
793
794 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
795
796 rc = ngx_http_core_find_location(r, &cscf->locations, cscf->regex_start, 0);
797
798 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
799 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
800 return NGX_OK;
801 }
802
803 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
804
805 if (!r->internal && clcf->internal) {
806 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
807 return NGX_OK;
808 }
809
810 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
811 "using configuration \"%s%V\"",
812 (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
813 &clcf->name);
814
815 ngx_http_update_location_config(r);
816
817 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
818 "http cl:%O max:%O",
819 r->headers_in.content_length_n, clcf->client_max_body_size);
820
821 if (r->headers_in.content_length_n != -1
822 && !r->discard_body
823 && clcf->client_max_body_size
824 && clcf->client_max_body_size < r->headers_in.content_length_n)
825 {
826 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
827 "client intended to send too large body: %O bytes",
828 r->headers_in.content_length_n);
829
830 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
831 return NGX_OK;
832 }
833
834
835 if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) {
836 r->headers_out.location = ngx_list_push(&r->headers_out.headers);
837 if (r->headers_out.location == NULL) {
838 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
839 return NGX_OK;
840 }
841
842 /*
843 * we do not need to set the r->headers_out.location->hash and
844 * r->headers_out.location->key fields
845 */
846
847 if (r->args.len == 0) {
848 r->headers_out.location->value = clcf->name;
849
850 } else {
851 len = clcf->name.len + 1 + r->args.len;
852 p = ngx_palloc(r->pool, len);
853
854 if (p == NULL) {
855 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
856 return NGX_OK;
857 }
858
859 r->headers_out.location->value.len = len;
860 r->headers_out.location->value.data = p;
861
862 p = ngx_cpymem(p, clcf->name.data, clcf->name.len);
863 *p++ = '?';
864 ngx_memcpy(p, r->args.data, r->args.len);
865 }
866
867 ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
868 return NGX_OK;
869 }
870
871 r->phase_handler++;
872 return NGX_AGAIN;
873 }
874
875
876 ngx_int_t
877 ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
878 ngx_http_phase_handler_t *ph)
879 {
880 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
881 "post rewrite phase: %ui", r->phase_handler);
882
883 if (!r->uri_changed) {
884 r->phase_handler++;
885 return NGX_AGAIN;
886 }
887
888 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
889 "uri changes: %d", r->uri_changes);
890
891 /*
892 * gcc before 3.3 compiles the broken code for
893 * if (r->uri_changes-- == 0)
894 * if the r->uri_changes is defined as
895 * unsigned uri_changes:4
896 */
897
898 r->uri_changes--;
899
900 if (r->uri_changes == 0) {
901 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
902 "rewrite or internal redirection cycle "
903 "while processing \"%V\"", &r->uri);
904
905 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
906 return NGX_OK;
907 }
908
909 r->phase_handler = ph->next;
910
911 return NGX_AGAIN;
912 }