Fix work keepalive and rewrite to named location
[nginx-catap.git] / src / http / ngx_http_core_module.c
bloba2e90ad809f96bc8ac765911488e12472e22528b
2 /*
3 * Copyright (C) Igor Sysoev
4 */
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_http.h>
12 typedef struct {
13 u_char *name;
14 uint32_t method;
15 } ngx_http_method_name_t;
18 #define NGX_HTTP_REQUEST_BODY_FILE_OFF 0
19 #define NGX_HTTP_REQUEST_BODY_FILE_ON 1
20 #define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2
23 static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r);
24 static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r,
25 ngx_http_location_tree_node_t *node);
27 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
28 static ngx_int_t ngx_http_core_postconfiguration(ngx_conf_t *cf);
29 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
30 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
31 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
32 static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
33 void *parent, void *child);
34 static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf);
35 static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
36 void *parent, void *child);
38 static ngx_int_t ngx_http_core_read_request_body(ngx_http_request_t *r);
41 static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
42 void *dummy);
43 static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
44 void *dummy);
45 static ngx_int_t ngx_http_core_regex_location(ngx_conf_t *cf,
46 ngx_http_core_loc_conf_t *clcf, ngx_str_t *regex, ngx_uint_t caseless);
48 static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
49 void *conf);
50 static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy,
51 void *conf);
53 static char *ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
54 void *conf);
55 static char *ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
56 void *conf);
57 static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
58 static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
59 void *conf);
60 static char *ngx_http_core_directio(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_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
65 void *conf);
66 static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
67 void *conf);
68 static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
69 void *conf);
70 static char *ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
71 void *conf);
72 static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
73 void *conf);
74 static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
75 void *conf);
76 #if (NGX_HTTP_GZIP)
77 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
78 void *conf);
79 #endif
80 #if (NGX_STATUS)
81 static char *ngx_http_status_capture(ngx_conf_t *cf,
82 ngx_command_t *cmd, void *conf);
83 #endif
85 static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
86 static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data);
88 static ngx_conf_post_t ngx_http_core_lowat_post =
89 { ngx_http_core_lowat_check };
91 static ngx_conf_post_handler_pt ngx_http_core_pool_size_p =
92 ngx_http_core_pool_size;
94 static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_server_names = {
95 ngx_conf_deprecated, "optimize_server_names", "server_name_in_redirect"
98 static ngx_conf_deprecated_t ngx_conf_deprecated_open_file_cache_retest = {
99 ngx_conf_deprecated, "open_file_cache_retest", "open_file_cache_valid"
102 static ngx_conf_deprecated_t ngx_conf_deprecated_satisfy_any = {
103 ngx_conf_deprecated, "satisfy_any", "satisfy"
107 static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = {
108 { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF },
109 { ngx_string("on"), NGX_HTTP_REQUEST_BODY_FILE_ON },
110 { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN },
111 { ngx_null_string, 0 }
115 #if (NGX_HAVE_FILE_AIO)
117 static ngx_conf_enum_t ngx_http_core_aio[] = {
118 { ngx_string("off"), NGX_HTTP_AIO_OFF },
119 { ngx_string("on"), NGX_HTTP_AIO_ON },
120 #if (NGX_HAVE_AIO_SENDFILE)
121 { ngx_string("sendfile"), NGX_HTTP_AIO_SENDFILE },
122 #endif
123 { ngx_null_string, 0 }
126 #endif
129 static ngx_conf_enum_t ngx_http_core_satisfy[] = {
130 { ngx_string("all"), NGX_HTTP_SATISFY_ALL },
131 { ngx_string("any"), NGX_HTTP_SATISFY_ANY },
132 { ngx_null_string, 0 }
136 static ngx_conf_enum_t ngx_http_core_if_modified_since[] = {
137 { ngx_string("off"), NGX_HTTP_IMS_OFF },
138 { ngx_string("exact"), NGX_HTTP_IMS_EXACT },
139 { ngx_string("before"), NGX_HTTP_IMS_BEFORE },
140 { ngx_null_string, 0 }
144 static ngx_path_init_t ngx_http_client_temp_path = {
145 ngx_string(NGX_HTTP_CLIENT_TEMP_PATH), { 0, 0, 0 }
149 #if (NGX_HTTP_GZIP)
151 static ngx_conf_enum_t ngx_http_gzip_http_version[] = {
152 { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
153 { ngx_string("1.1"), NGX_HTTP_VERSION_11 },
154 { ngx_null_string, 0 }
158 static ngx_conf_bitmask_t ngx_http_gzip_proxied_mask[] = {
159 { ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF },
160 { ngx_string("expired"), NGX_HTTP_GZIP_PROXIED_EXPIRED },
161 { ngx_string("no-cache"), NGX_HTTP_GZIP_PROXIED_NO_CACHE },
162 { ngx_string("no-store"), NGX_HTTP_GZIP_PROXIED_NO_STORE },
163 { ngx_string("private"), NGX_HTTP_GZIP_PROXIED_PRIVATE },
164 { ngx_string("no_last_modified"), NGX_HTTP_GZIP_PROXIED_NO_LM },
165 { ngx_string("no_etag"), NGX_HTTP_GZIP_PROXIED_NO_ETAG },
166 { ngx_string("auth"), NGX_HTTP_GZIP_PROXIED_AUTH },
167 { ngx_string("any"), NGX_HTTP_GZIP_PROXIED_ANY },
168 { ngx_null_string, 0 }
172 static ngx_str_t ngx_http_gzip_no_cache = ngx_string("no-cache");
173 static ngx_str_t ngx_http_gzip_no_store = ngx_string("no-store");
174 static ngx_str_t ngx_http_gzip_private = ngx_string("private");
176 #endif
178 static ngx_conf_enum_t ngx_http_use_args_from_post[] = {
179 { ngx_string("off"), NGX_HTTP_USE_ARGS_FROM_POST_OFF },
180 { ngx_string("on"), NGX_HTTP_USE_ARGS_FROM_POST_LAST },
181 { ngx_string("first"), NGX_HTTP_USE_ARGS_FROM_POST_FIRST },
182 { ngx_string("last"), NGX_HTTP_USE_ARGS_FROM_POST_LAST },
183 { ngx_null_string, 0 }
188 static ngx_command_t ngx_http_core_commands[] = {
190 { ngx_string("variables_hash_max_size"),
191 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
192 ngx_conf_set_num_slot,
193 NGX_HTTP_MAIN_CONF_OFFSET,
194 offsetof(ngx_http_core_main_conf_t, variables_hash_max_size),
195 NULL },
197 { ngx_string("variables_hash_bucket_size"),
198 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
199 ngx_conf_set_num_slot,
200 NGX_HTTP_MAIN_CONF_OFFSET,
201 offsetof(ngx_http_core_main_conf_t, variables_hash_bucket_size),
202 NULL },
204 { ngx_string("server_names_hash_max_size"),
205 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
206 ngx_conf_set_num_slot,
207 NGX_HTTP_MAIN_CONF_OFFSET,
208 offsetof(ngx_http_core_main_conf_t, server_names_hash_max_size),
209 NULL },
211 { ngx_string("server_names_hash_bucket_size"),
212 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
213 ngx_conf_set_num_slot,
214 NGX_HTTP_MAIN_CONF_OFFSET,
215 offsetof(ngx_http_core_main_conf_t, server_names_hash_bucket_size),
216 NULL },
218 { ngx_string("server"),
219 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_MULTI|NGX_CONF_NOARGS,
220 ngx_http_core_server,
223 NULL },
225 { ngx_string("connection_pool_size"),
226 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
227 ngx_conf_set_size_slot,
228 NGX_HTTP_SRV_CONF_OFFSET,
229 offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
230 &ngx_http_core_pool_size_p },
232 { ngx_string("request_pool_size"),
233 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
234 ngx_conf_set_size_slot,
235 NGX_HTTP_SRV_CONF_OFFSET,
236 offsetof(ngx_http_core_srv_conf_t, request_pool_size),
237 &ngx_http_core_pool_size_p },
239 { ngx_string("client_header_timeout"),
240 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
241 ngx_conf_set_msec_slot,
242 NGX_HTTP_SRV_CONF_OFFSET,
243 offsetof(ngx_http_core_srv_conf_t, client_header_timeout),
244 NULL },
246 { ngx_string("client_header_buffer_size"),
247 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
248 ngx_conf_set_size_slot,
249 NGX_HTTP_SRV_CONF_OFFSET,
250 offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
251 NULL },
253 { ngx_string("large_client_header_buffers"),
254 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
255 ngx_conf_set_bufs_slot,
256 NGX_HTTP_SRV_CONF_OFFSET,
257 offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
258 NULL },
260 { ngx_string("optimize_server_names"),
261 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
262 ngx_conf_set_flag_slot,
263 NGX_HTTP_LOC_CONF_OFFSET,
264 offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect),
265 &ngx_conf_deprecated_optimize_server_names },
267 { ngx_string("ignore_invalid_headers"),
268 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
269 ngx_conf_set_flag_slot,
270 NGX_HTTP_SRV_CONF_OFFSET,
271 offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
272 NULL },
274 { ngx_string("merge_slashes"),
275 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
276 ngx_conf_set_flag_slot,
277 NGX_HTTP_SRV_CONF_OFFSET,
278 offsetof(ngx_http_core_srv_conf_t, merge_slashes),
279 NULL },
281 { ngx_string("underscores_in_headers"),
282 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
283 ngx_conf_set_flag_slot,
284 NGX_HTTP_SRV_CONF_OFFSET,
285 offsetof(ngx_http_core_srv_conf_t, underscores_in_headers),
286 NULL },
288 { ngx_string("location"),
289 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
290 ngx_http_core_location,
291 NGX_HTTP_SRV_CONF_OFFSET,
293 NULL },
295 { ngx_string("listen"),
296 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
297 ngx_http_core_listen,
298 NGX_HTTP_SRV_CONF_OFFSET,
300 NULL },
302 { ngx_string("server_name"),
303 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
304 ngx_http_core_server_name,
305 NGX_HTTP_SRV_CONF_OFFSET,
307 NULL },
309 { ngx_string("types_hash_max_size"),
310 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
311 ngx_conf_set_num_slot,
312 NGX_HTTP_LOC_CONF_OFFSET,
313 offsetof(ngx_http_core_loc_conf_t, types_hash_max_size),
314 NULL },
316 { ngx_string("types_hash_bucket_size"),
317 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
318 ngx_conf_set_num_slot,
319 NGX_HTTP_LOC_CONF_OFFSET,
320 offsetof(ngx_http_core_loc_conf_t, types_hash_bucket_size),
321 NULL },
323 { ngx_string("types"),
324 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
325 |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
326 ngx_http_core_types,
327 NGX_HTTP_LOC_CONF_OFFSET,
329 NULL },
331 { ngx_string("default_type"),
332 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
333 ngx_conf_set_str_slot,
334 NGX_HTTP_LOC_CONF_OFFSET,
335 offsetof(ngx_http_core_loc_conf_t, default_type),
336 NULL },
338 { ngx_string("root"),
339 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
340 |NGX_CONF_TAKE1,
341 ngx_http_core_root,
342 NGX_HTTP_LOC_CONF_OFFSET,
344 NULL },
346 { ngx_string("alias"),
347 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
348 ngx_http_core_root,
349 NGX_HTTP_LOC_CONF_OFFSET,
351 NULL },
353 { ngx_string("limit_except"),
354 NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE,
355 ngx_http_core_limit_except,
356 NGX_HTTP_LOC_CONF_OFFSET,
358 NULL },
360 { ngx_string("client_max_body_size"),
361 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
362 ngx_conf_set_off_slot,
363 NGX_HTTP_LOC_CONF_OFFSET,
364 offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
365 NULL },
367 { ngx_string("client_body_buffer_size"),
368 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
369 ngx_conf_set_size_slot,
370 NGX_HTTP_LOC_CONF_OFFSET,
371 offsetof(ngx_http_core_loc_conf_t, client_body_buffer_size),
372 NULL },
374 { ngx_string("client_body_timeout"),
375 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
376 ngx_conf_set_msec_slot,
377 NGX_HTTP_LOC_CONF_OFFSET,
378 offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
379 NULL },
381 { ngx_string("client_body_temp_path"),
382 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
383 ngx_conf_set_path_slot,
384 NGX_HTTP_LOC_CONF_OFFSET,
385 offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
386 NULL },
388 { ngx_string("client_body_in_file_only"),
389 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
390 ngx_conf_set_enum_slot,
391 NGX_HTTP_LOC_CONF_OFFSET,
392 offsetof(ngx_http_core_loc_conf_t, client_body_in_file_only),
393 &ngx_http_core_request_body_in_file },
395 { ngx_string("client_body_in_single_buffer"),
396 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
397 ngx_conf_set_flag_slot,
398 NGX_HTTP_LOC_CONF_OFFSET,
399 offsetof(ngx_http_core_loc_conf_t, client_body_in_single_buffer),
400 NULL },
402 { ngx_string("sendfile"),
403 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
404 |NGX_CONF_TAKE1,
405 ngx_conf_set_flag_slot,
406 NGX_HTTP_LOC_CONF_OFFSET,
407 offsetof(ngx_http_core_loc_conf_t, sendfile),
408 NULL },
410 { ngx_string("sendfile_max_chunk"),
411 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
412 ngx_conf_set_size_slot,
413 NGX_HTTP_LOC_CONF_OFFSET,
414 offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
415 NULL },
417 #if (NGX_HAVE_FILE_AIO)
419 { ngx_string("aio"),
420 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
421 ngx_conf_set_enum_slot,
422 NGX_HTTP_LOC_CONF_OFFSET,
423 offsetof(ngx_http_core_loc_conf_t, aio),
424 &ngx_http_core_aio },
426 #endif
428 { ngx_string("read_ahead"),
429 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
430 ngx_conf_set_size_slot,
431 NGX_HTTP_LOC_CONF_OFFSET,
432 offsetof(ngx_http_core_loc_conf_t, read_ahead),
433 NULL },
435 { ngx_string("directio"),
436 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
437 ngx_http_core_directio,
438 NGX_HTTP_LOC_CONF_OFFSET,
440 NULL },
442 { ngx_string("directio_alignment"),
443 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
444 ngx_conf_set_off_slot,
445 NGX_HTTP_LOC_CONF_OFFSET,
446 offsetof(ngx_http_core_loc_conf_t, directio_alignment),
447 NULL },
449 { ngx_string("tcp_nopush"),
450 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
451 ngx_conf_set_flag_slot,
452 NGX_HTTP_LOC_CONF_OFFSET,
453 offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
454 NULL },
456 { ngx_string("tcp_nodelay"),
457 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
458 ngx_conf_set_flag_slot,
459 NGX_HTTP_LOC_CONF_OFFSET,
460 offsetof(ngx_http_core_loc_conf_t, tcp_nodelay),
461 NULL },
463 { ngx_string("send_timeout"),
464 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
465 ngx_conf_set_msec_slot,
466 NGX_HTTP_LOC_CONF_OFFSET,
467 offsetof(ngx_http_core_loc_conf_t, send_timeout),
468 NULL },
470 { ngx_string("send_lowat"),
471 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
472 ngx_conf_set_size_slot,
473 NGX_HTTP_LOC_CONF_OFFSET,
474 offsetof(ngx_http_core_loc_conf_t, send_lowat),
475 &ngx_http_core_lowat_post },
477 { ngx_string("postpone_output"),
478 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
479 ngx_conf_set_size_slot,
480 NGX_HTTP_LOC_CONF_OFFSET,
481 offsetof(ngx_http_core_loc_conf_t, postpone_output),
482 NULL },
484 { ngx_string("limit_rate"),
485 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
486 |NGX_CONF_TAKE1,
487 ngx_conf_set_size_slot,
488 NGX_HTTP_LOC_CONF_OFFSET,
489 offsetof(ngx_http_core_loc_conf_t, limit_rate),
490 NULL },
492 { ngx_string("limit_rate_after"),
493 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
494 |NGX_CONF_TAKE1,
495 ngx_conf_set_size_slot,
496 NGX_HTTP_LOC_CONF_OFFSET,
497 offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
498 NULL },
500 { ngx_string("keepalive_timeout"),
501 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
502 ngx_http_core_keepalive,
503 NGX_HTTP_LOC_CONF_OFFSET,
505 NULL },
507 { ngx_string("keepalive_requests"),
508 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
509 ngx_conf_set_num_slot,
510 NGX_HTTP_LOC_CONF_OFFSET,
511 offsetof(ngx_http_core_loc_conf_t, keepalive_requests),
512 NULL },
514 { ngx_string("satisfy"),
515 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
516 ngx_conf_set_enum_slot,
517 NGX_HTTP_LOC_CONF_OFFSET,
518 offsetof(ngx_http_core_loc_conf_t, satisfy),
519 &ngx_http_core_satisfy },
521 { ngx_string("satisfy_any"),
522 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
523 ngx_conf_set_flag_slot,
524 NGX_HTTP_LOC_CONF_OFFSET,
525 offsetof(ngx_http_core_loc_conf_t, satisfy),
526 &ngx_conf_deprecated_satisfy_any },
528 { ngx_string("internal"),
529 NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
530 ngx_http_core_internal,
531 NGX_HTTP_LOC_CONF_OFFSET,
533 NULL },
535 { ngx_string("lingering_time"),
536 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
537 ngx_conf_set_msec_slot,
538 NGX_HTTP_LOC_CONF_OFFSET,
539 offsetof(ngx_http_core_loc_conf_t, lingering_time),
540 NULL },
542 { ngx_string("lingering_timeout"),
543 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
544 ngx_conf_set_msec_slot,
545 NGX_HTTP_LOC_CONF_OFFSET,
546 offsetof(ngx_http_core_loc_conf_t, lingering_timeout),
547 NULL },
549 { ngx_string("reset_timedout_connection"),
550 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
551 ngx_conf_set_flag_slot,
552 NGX_HTTP_LOC_CONF_OFFSET,
553 offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection),
554 NULL },
556 { ngx_string("server_name_in_redirect"),
557 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
558 ngx_conf_set_flag_slot,
559 NGX_HTTP_LOC_CONF_OFFSET,
560 offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect),
561 NULL },
563 { ngx_string("port_in_redirect"),
564 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
565 ngx_conf_set_flag_slot,
566 NGX_HTTP_LOC_CONF_OFFSET,
567 offsetof(ngx_http_core_loc_conf_t, port_in_redirect),
568 NULL },
570 { ngx_string("msie_padding"),
571 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
572 ngx_conf_set_flag_slot,
573 NGX_HTTP_LOC_CONF_OFFSET,
574 offsetof(ngx_http_core_loc_conf_t, msie_padding),
575 NULL },
577 { ngx_string("msie_refresh"),
578 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
579 ngx_conf_set_flag_slot,
580 NGX_HTTP_LOC_CONF_OFFSET,
581 offsetof(ngx_http_core_loc_conf_t, msie_refresh),
582 NULL },
584 { ngx_string("log_not_found"),
585 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
586 ngx_conf_set_flag_slot,
587 NGX_HTTP_LOC_CONF_OFFSET,
588 offsetof(ngx_http_core_loc_conf_t, log_not_found),
589 NULL },
591 { ngx_string("log_subrequest"),
592 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
593 ngx_conf_set_flag_slot,
594 NGX_HTTP_LOC_CONF_OFFSET,
595 offsetof(ngx_http_core_loc_conf_t, log_subrequest),
596 NULL },
598 { ngx_string("recursive_error_pages"),
599 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
600 ngx_conf_set_flag_slot,
601 NGX_HTTP_LOC_CONF_OFFSET,
602 offsetof(ngx_http_core_loc_conf_t, recursive_error_pages),
603 NULL },
605 { ngx_string("server_tokens"),
606 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
607 ngx_conf_set_flag_slot,
608 NGX_HTTP_LOC_CONF_OFFSET,
609 offsetof(ngx_http_core_loc_conf_t, server_tokens),
610 NULL },
612 { ngx_string("if_modified_since"),
613 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
614 ngx_conf_set_enum_slot,
615 NGX_HTTP_LOC_CONF_OFFSET,
616 offsetof(ngx_http_core_loc_conf_t, if_modified_since),
617 &ngx_http_core_if_modified_since },
619 { ngx_string("chunked_transfer_encoding"),
620 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
621 ngx_conf_set_flag_slot,
622 NGX_HTTP_LOC_CONF_OFFSET,
623 offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding),
624 NULL },
626 { ngx_string("error_page"),
627 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
628 |NGX_CONF_2MORE,
629 ngx_http_core_error_page,
630 NGX_HTTP_LOC_CONF_OFFSET,
632 NULL },
634 { ngx_string("try_files"),
635 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
636 ngx_http_core_try_files,
637 NGX_HTTP_LOC_CONF_OFFSET,
639 NULL },
641 { ngx_string("post_action"),
642 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
643 |NGX_CONF_TAKE1,
644 ngx_conf_set_str_slot,
645 NGX_HTTP_LOC_CONF_OFFSET,
646 offsetof(ngx_http_core_loc_conf_t, post_action),
647 NULL },
649 { ngx_string("error_log"),
650 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
651 ngx_http_core_error_log,
652 NGX_HTTP_LOC_CONF_OFFSET,
654 NULL },
656 { ngx_string("open_file_cache"),
657 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
658 ngx_http_core_open_file_cache,
659 NGX_HTTP_LOC_CONF_OFFSET,
660 offsetof(ngx_http_core_loc_conf_t, open_file_cache),
661 NULL },
663 { ngx_string("open_file_cache_valid"),
664 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
665 ngx_conf_set_sec_slot,
666 NGX_HTTP_LOC_CONF_OFFSET,
667 offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
668 NULL },
670 { ngx_string("open_file_cache_retest"),
671 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
672 ngx_conf_set_sec_slot,
673 NGX_HTTP_LOC_CONF_OFFSET,
674 offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
675 &ngx_conf_deprecated_open_file_cache_retest },
677 { ngx_string("open_file_cache_min_uses"),
678 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
679 ngx_conf_set_num_slot,
680 NGX_HTTP_LOC_CONF_OFFSET,
681 offsetof(ngx_http_core_loc_conf_t, open_file_cache_min_uses),
682 NULL },
684 { ngx_string("open_file_cache_errors"),
685 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
686 ngx_conf_set_flag_slot,
687 NGX_HTTP_LOC_CONF_OFFSET,
688 offsetof(ngx_http_core_loc_conf_t, open_file_cache_errors),
689 NULL },
691 { ngx_string("open_file_cache_events"),
692 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
693 ngx_conf_set_flag_slot,
694 NGX_HTTP_LOC_CONF_OFFSET,
695 offsetof(ngx_http_core_loc_conf_t, open_file_cache_events),
696 NULL },
698 { ngx_string("resolver"),
699 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
700 ngx_http_core_resolver,
701 NGX_HTTP_LOC_CONF_OFFSET,
703 NULL },
705 { ngx_string("resolver_timeout"),
706 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
707 ngx_conf_set_msec_slot,
708 NGX_HTTP_LOC_CONF_OFFSET,
709 offsetof(ngx_http_core_loc_conf_t, resolver_timeout),
710 NULL },
712 { ngx_string("use_args_from_post"),
713 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
714 ngx_conf_set_enum_slot,
715 NGX_HTTP_LOC_CONF_OFFSET,
716 offsetof(ngx_http_core_loc_conf_t, use_args_from_post),
717 &ngx_http_use_args_from_post },
720 #if (NGX_HTTP_GZIP)
722 { ngx_string("gzip_vary"),
723 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
724 ngx_conf_set_flag_slot,
725 NGX_HTTP_LOC_CONF_OFFSET,
726 offsetof(ngx_http_core_loc_conf_t, gzip_vary),
727 NULL },
729 { ngx_string("gzip_http_version"),
730 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
731 ngx_conf_set_enum_slot,
732 NGX_HTTP_LOC_CONF_OFFSET,
733 offsetof(ngx_http_core_loc_conf_t, gzip_http_version),
734 &ngx_http_gzip_http_version },
736 { ngx_string("gzip_proxied"),
737 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
738 ngx_conf_set_bitmask_slot,
739 NGX_HTTP_LOC_CONF_OFFSET,
740 offsetof(ngx_http_core_loc_conf_t, gzip_proxied),
741 &ngx_http_gzip_proxied_mask },
743 { ngx_string("gzip_disable"),
744 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
745 ngx_http_gzip_disable,
746 NGX_HTTP_LOC_CONF_OFFSET,
748 NULL },
750 #endif
752 #if (NGX_STATUS)
754 { ngx_string("status_capture"),
755 NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
756 ngx_http_status_capture,
757 NGX_HTTP_LOC_CONF_OFFSET,
759 NULL },
761 #endif
763 ngx_null_command
767 static ngx_http_module_t ngx_http_core_module_ctx = {
768 ngx_http_core_preconfiguration, /* preconfiguration */
769 ngx_http_core_postconfiguration, /* postconfiguration */
771 ngx_http_core_create_main_conf, /* create main configuration */
772 ngx_http_core_init_main_conf, /* init main configuration */
774 ngx_http_core_create_srv_conf, /* create server configuration */
775 ngx_http_core_merge_srv_conf, /* merge server configuration */
777 ngx_http_core_create_loc_conf, /* create location configuration */
778 ngx_http_core_merge_loc_conf /* merge location configuration */
782 ngx_module_t ngx_http_core_module = {
783 NGX_MODULE_V1,
784 &ngx_http_core_module_ctx, /* module context */
785 ngx_http_core_commands, /* module directives */
786 NGX_HTTP_MODULE, /* module type */
787 NULL, /* init master */
788 NULL, /* init module */
789 NULL, /* init process */
790 NULL, /* init thread */
791 NULL, /* exit thread */
792 NULL, /* exit process */
793 NULL, /* exit master */
794 NGX_MODULE_V1_PADDING
798 ngx_str_t ngx_http_core_get_method = { 3, (u_char *) "GET " };
801 void
802 ngx_http_handler(ngx_http_request_t *r)
804 ngx_http_core_main_conf_t *cmcf;
806 r->connection->log->action = NULL;
808 r->connection->unexpected_eof = 0;
810 if (!r->internal) {
811 switch (r->headers_in.connection_type) {
812 case 0:
813 if (r->http_version > NGX_HTTP_VERSION_10) {
814 r->keepalive = 1;
815 } else {
816 r->keepalive = 0;
818 break;
820 case NGX_HTTP_CONNECTION_CLOSE:
821 r->keepalive = 0;
822 break;
824 case NGX_HTTP_CONNECTION_KEEP_ALIVE:
825 r->keepalive = 1;
826 break;
829 if (r->keepalive) {
831 if (r->headers_in.msie6) {
832 if (r->method == NGX_HTTP_POST) {
834 * MSIE may wait for some time if an response for
835 * a POST request was sent over a keepalive connection
837 r->keepalive = 0;
840 } else if (r->headers_in.safari) {
842 * Safari may send a POST request to a closed keepalive
843 * connection and stalls for some time
845 r->keepalive = 0;
849 if (r->headers_in.content_length_n > 0) {
850 r->lingering_close = 1;
852 } else {
853 r->lingering_close = 0;
856 r->phase_handler = 0;
858 } else {
859 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
860 r->phase_handler = cmcf->phase_engine.server_rewrite_index;
863 r->valid_location = 1;
864 #if (NGX_HTTP_GZIP)
865 r->gzip_tested = 0;
866 r->gzip_ok = 0;
867 r->gzip_vary = 0;
868 #endif
870 r->write_event_handler = ngx_http_core_run_phases;
871 ngx_http_core_run_phases(r);
875 void
876 ngx_http_core_run_phases(ngx_http_request_t *r)
878 ngx_int_t rc;
879 ngx_http_phase_handler_t *ph;
880 ngx_http_core_main_conf_t *cmcf;
882 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
884 ph = cmcf->phase_engine.handlers;
886 while (ph[r->phase_handler].checker) {
888 rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
890 if (rc == NGX_OK) {
891 return;
897 ngx_int_t
898 ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
900 ngx_int_t rc;
903 * generic phase checker,
904 * used by the post read, server rewrite, rewrite, and pre-access phases
907 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
908 "generic phase: %ui", r->phase_handler);
910 rc = ph->handler(r);
912 if (rc == NGX_OK) {
913 r->phase_handler = ph->next;
914 return NGX_AGAIN;
917 if (rc == NGX_DECLINED) {
918 r->phase_handler++;
919 return NGX_AGAIN;
922 if (rc == NGX_AGAIN || rc == NGX_DONE) {
923 return NGX_OK;
926 /* rc == NGX_ERROR || rc == NGX_HTTP_... */
928 ngx_http_finalize_request(r, rc);
930 return NGX_OK;
934 ngx_int_t
935 ngx_http_core_find_config_phase(ngx_http_request_t *r,
936 ngx_http_phase_handler_t *ph)
938 u_char *p;
939 size_t len;
940 ngx_int_t rc;
941 ngx_http_core_loc_conf_t *clcf;
943 r->content_handler = NULL;
944 r->uri_changed = 0;
946 rc = ngx_http_core_find_location(r);
948 if (rc == NGX_ERROR) {
949 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
950 return NGX_OK;
953 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
955 if (!clcf->regex_locations) {
956 r->uri_remainder.len = r->uri.len - clcf->name.len;
957 r->uri_remainder.data = r->uri.data + clcf->name.len;
958 } else {
959 r->uri_remainder.len = 0;
960 r->uri_remainder.data = NULL;
963 #if (NGX_STATUS)
964 if (clcf->request_counter) {
965 ngx_status_fetch_add(clcf->request_counter);
967 #endif
969 if (!r->internal && clcf->internal) {
970 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
971 return NGX_OK;
974 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
975 "using configuration \"%s%V\"",
976 (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
977 &clcf->name);
979 ngx_http_update_location_config(r);
981 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
982 "http cl:%O max:%O",
983 r->headers_in.content_length_n, clcf->client_max_body_size);
985 if (r->headers_in.content_length_n != -1
986 && !r->discard_body
987 && clcf->client_max_body_size
988 && clcf->client_max_body_size < r->headers_in.content_length_n)
990 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
991 "client intended to send too large body: %O bytes",
992 r->headers_in.content_length_n);
994 (void) ngx_http_discard_request_body(r);
995 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
996 return NGX_OK;
999 if (rc == NGX_DONE) {
1000 r->headers_out.location = ngx_list_push(&r->headers_out.headers);
1001 if (r->headers_out.location == NULL) {
1002 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1003 return NGX_OK;
1007 * we do not need to set the r->headers_out.location->hash and
1008 * r->headers_out.location->key fields
1011 if (r->args.len == 0) {
1012 r->headers_out.location->value = clcf->name;
1014 } else {
1015 len = clcf->name.len + 1 + r->args.len;
1016 p = ngx_pnalloc(r->pool, len);
1018 if (p == NULL) {
1019 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1020 return NGX_OK;
1023 r->headers_out.location->value.len = len;
1024 r->headers_out.location->value.data = p;
1026 p = ngx_cpymem(p, clcf->name.data, clcf->name.len);
1027 *p++ = '?';
1028 ngx_memcpy(p, r->args.data, r->args.len);
1031 ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
1032 return NGX_OK;
1035 r->phase_handler++;
1036 return NGX_AGAIN;
1040 ngx_int_t
1041 ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
1042 ngx_http_phase_handler_t *ph)
1044 ngx_http_core_srv_conf_t *cscf;
1046 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1047 "post rewrite phase: %ui", r->phase_handler);
1049 if (!r->uri_changed) {
1050 r->phase_handler++;
1051 return NGX_AGAIN;
1054 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1055 "uri changes: %d", r->uri_changes);
1058 * gcc before 3.3 compiles the broken code for
1059 * if (r->uri_changes-- == 0)
1060 * if the r->uri_changes is defined as
1061 * unsigned uri_changes:4
1064 r->uri_changes--;
1066 if (r->uri_changes == 0) {
1067 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1068 "rewrite or internal redirection cycle "
1069 "while processing \"%V\"", &r->uri);
1071 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1072 return NGX_OK;
1075 r->phase_handler = ph->next;
1077 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1078 r->loc_conf = cscf->ctx->loc_conf;
1080 return NGX_AGAIN;
1084 ngx_int_t
1085 ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
1087 ngx_int_t rc;
1088 ngx_http_core_loc_conf_t *clcf;
1090 if (r != r->main) {
1091 r->phase_handler = ph->next;
1092 return NGX_AGAIN;
1095 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1096 "access phase: %ui", r->phase_handler);
1098 rc = ph->handler(r);
1100 if (rc == NGX_DECLINED) {
1101 r->phase_handler++;
1102 return NGX_AGAIN;
1105 if (rc == NGX_AGAIN || rc == NGX_DONE) {
1106 return NGX_OK;
1109 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1111 if (clcf->satisfy == NGX_HTTP_SATISFY_ALL) {
1113 if (rc == NGX_OK) {
1114 r->phase_handler++;
1115 return NGX_AGAIN;
1118 } else {
1119 if (rc == NGX_OK) {
1120 r->access_code = 0;
1122 if (r->headers_out.www_authenticate) {
1123 r->headers_out.www_authenticate->hash = 0;
1126 r->phase_handler = ph->next;
1127 return NGX_AGAIN;
1130 if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) {
1131 r->access_code = rc;
1133 r->phase_handler++;
1134 return NGX_AGAIN;
1138 /* rc == NGX_ERROR || rc == NGX_HTTP_... */
1140 ngx_http_finalize_request(r, rc);
1141 return NGX_OK;
1145 ngx_int_t
1146 ngx_http_core_post_access_phase(ngx_http_request_t *r,
1147 ngx_http_phase_handler_t *ph)
1149 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1150 "post access phase: %ui", r->phase_handler);
1152 if (r->access_code) {
1154 if (r->access_code == NGX_HTTP_FORBIDDEN) {
1155 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1156 "access forbidden by rule");
1159 ngx_http_finalize_request(r, r->access_code);
1160 return NGX_OK;
1163 r->phase_handler++;
1164 return NGX_AGAIN;
1168 ngx_int_t
1169 ngx_http_core_try_files_phase(ngx_http_request_t *r,
1170 ngx_http_phase_handler_t *ph)
1172 size_t len, root, alias, reserve, allocated;
1173 u_char *p, *name;
1174 ngx_str_t path, args;
1175 ngx_uint_t test_dir;
1176 ngx_http_try_file_t *tf;
1177 ngx_open_file_info_t of;
1178 ngx_http_script_code_pt code;
1179 ngx_http_script_engine_t e;
1180 ngx_http_core_loc_conf_t *clcf;
1181 ngx_http_script_len_code_pt lcode;
1183 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1184 "try files phase: %ui", r->phase_handler);
1186 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1188 if (clcf->try_files == NULL) {
1189 r->phase_handler++;
1190 return NGX_AGAIN;
1193 allocated = 0;
1194 root = 0;
1195 name = NULL;
1196 /* suppress MSVC warning */
1197 path.data = NULL;
1199 tf = clcf->try_files;
1201 alias = clcf->alias;
1203 for ( ;; ) {
1205 if (tf->lengths) {
1206 ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
1208 e.ip = tf->lengths->elts;
1209 e.request = r;
1211 /* 1 is for terminating '\0' as in static names */
1212 len = 1;
1214 while (*(uintptr_t *) e.ip) {
1215 lcode = *(ngx_http_script_len_code_pt *) e.ip;
1216 len += lcode(&e);
1219 } else {
1220 len = tf->name.len;
1223 /* 16 bytes are preallocation */
1224 reserve = ngx_abs((ssize_t) (len - r->uri.len)) + alias + 16;
1226 if (reserve > allocated) {
1228 /* we just need to allocate path and to copy a root */
1230 if (ngx_http_map_uri_to_path(r, &path, &root, reserve) == NULL) {
1231 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1232 return NGX_OK;
1235 name = path.data + root;
1236 allocated = path.len - root - (r->uri.len - alias);
1239 if (tf->values == NULL) {
1241 /* tf->name.len includes the terminating '\0' */
1243 ngx_memcpy(name, tf->name.data, tf->name.len);
1245 path.len = (name + tf->name.len - 1) - path.data;
1247 } else {
1248 e.ip = tf->values->elts;
1249 e.pos = name;
1250 e.flushed = 1;
1252 while (*(uintptr_t *) e.ip) {
1253 code = *(ngx_http_script_code_pt *) e.ip;
1254 code((ngx_http_script_engine_t *) &e);
1257 path.len = e.pos - path.data;
1259 *e.pos = '\0';
1261 if (alias && ngx_strncmp(name, clcf->name.data, alias) == 0) {
1262 ngx_memcpy(name, name + alias, len - alias);
1263 path.len -= alias;
1267 test_dir = tf->test_dir;
1269 tf++;
1271 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1272 "try to use %s: \"%s\" \"%s\"",
1273 test_dir ? "dir" : "file", name, path.data);
1275 if (tf->lengths == NULL && tf->name.len == 0) {
1277 if (tf->code) {
1278 ngx_http_finalize_request(r, tf->code);
1279 return NGX_OK;
1282 path.len -= root;
1283 path.data += root;
1285 if (path.data[0] == '@') {
1286 (void) ngx_http_named_location(r, &path);
1288 } else {
1289 ngx_http_split_args(r, &path, &args);
1291 (void) ngx_http_internal_redirect(r, &path, &args);
1294 ngx_http_finalize_request(r, NGX_DONE);
1295 return NGX_OK;
1298 ngx_memzero(&of, sizeof(ngx_open_file_info_t));
1300 of.directio = clcf->directio;
1301 of.valid = clcf->open_file_cache_valid;
1302 of.min_uses = clcf->open_file_cache_min_uses;
1303 of.test_only = 1;
1304 of.errors = clcf->open_file_cache_errors;
1305 of.events = clcf->open_file_cache_events;
1307 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
1308 != NGX_OK)
1310 if (of.err != NGX_ENOENT
1311 && of.err != NGX_ENOTDIR
1312 && of.err != NGX_ENAMETOOLONG)
1314 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
1315 "%s \"%s\" failed", of.failed, path.data);
1318 continue;
1321 if (of.is_dir && !test_dir) {
1322 continue;
1325 path.len -= root;
1326 path.data += root;
1328 if (!alias) {
1329 r->uri = path;
1331 #if (NGX_PCRE)
1332 } else if (clcf->regex) {
1333 if (!test_dir) {
1334 r->uri = path;
1335 r->add_uri_to_alias = 1;
1337 #endif
1338 } else {
1339 r->uri.len = alias + path.len;
1340 r->uri.data = ngx_pnalloc(r->pool, r->uri.len);
1341 if (r->uri.data == NULL) {
1342 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1343 return NGX_OK;
1346 p = ngx_copy(r->uri.data, clcf->name.data, alias);
1347 ngx_memcpy(p, name, path.len);
1350 ngx_http_set_exten(r);
1352 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1353 "try file uri: \"%V\"", &r->uri);
1355 r->phase_handler++;
1356 return NGX_AGAIN;
1359 /* not reached */
1363 ngx_int_t
1364 ngx_http_core_content_phase(ngx_http_request_t *r,
1365 ngx_http_phase_handler_t *ph)
1367 size_t root;
1368 ngx_int_t rc;
1369 ngx_str_t path;
1371 if (r->content_handler) {
1372 r->write_event_handler = ngx_http_request_empty_handler;
1373 ngx_http_finalize_request(r, r->content_handler(r));
1374 return NGX_OK;
1377 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1378 "content phase: %ui", r->phase_handler);
1380 rc = ph->handler(r);
1382 if (rc != NGX_DECLINED) {
1383 ngx_http_finalize_request(r, rc);
1384 return NGX_OK;
1387 /* rc == NGX_DECLINED */
1389 ph++;
1391 if (ph->checker) {
1392 r->phase_handler++;
1393 return NGX_AGAIN;
1396 /* no content handler was found */
1398 if (r->uri.data[r->uri.len - 1] == '/') {
1400 if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
1401 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1402 "directory index of \"%s\" is forbidden", path.data);
1405 ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
1406 return NGX_OK;
1409 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found");
1411 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
1412 return NGX_OK;
1416 void
1417 ngx_http_update_location_config(ngx_http_request_t *r)
1419 ngx_http_core_loc_conf_t *clcf;
1421 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1423 if (r->method & clcf->limit_except) {
1424 r->loc_conf = clcf->limit_except_loc_conf;
1425 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1428 if (r == r->main) {
1429 r->connection->log->file = clcf->error_log->file;
1431 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
1432 r->connection->log->log_level = clcf->error_log->log_level;
1436 if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
1437 r->connection->sendfile = 1;
1439 } else {
1440 r->connection->sendfile = 0;
1443 if (clcf->client_body_in_file_only) {
1444 r->request_body_in_file_only = 1;
1445 r->request_body_in_persistent_file = 1;
1446 r->request_body_in_clean_file =
1447 clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;
1448 r->request_body_file_log_level = NGX_LOG_NOTICE;
1450 } else {
1451 r->request_body_file_log_level = NGX_LOG_WARN;
1454 r->request_body_in_single_buf = clcf->client_body_in_single_buffer;
1456 if (r->keepalive) {
1457 if (clcf->keepalive_timeout == 0) {
1458 r->keepalive = 0;
1460 } else if (r->connection->requests >= clcf->keepalive_requests) {
1461 r->keepalive = 0;
1465 if (!clcf->tcp_nopush) {
1466 /* disable TCP_NOPUSH/TCP_CORK use */
1467 r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
1470 if (r->limit_rate == 0) {
1471 r->limit_rate = clcf->limit_rate;
1474 if (clcf->handler) {
1475 r->content_handler = clcf->handler;
1481 * NGX_OK - exact or regex match
1482 * NGX_DONE - auto redirect
1483 * NGX_AGAIN - inclusive match
1484 * NGX_ERROR - regex error
1485 * NGX_DECLINED - no match
1488 static ngx_int_t
1489 ngx_http_core_find_location(ngx_http_request_t *r)
1491 ngx_int_t rc;
1492 ngx_http_core_loc_conf_t *pclcf;
1493 #if (NGX_PCRE)
1494 ngx_int_t n;
1495 ngx_uint_t noregex;
1496 ngx_http_core_loc_conf_t *clcf, **clcfp;
1498 noregex = 0;
1499 #endif
1501 pclcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1503 rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
1505 if (rc == NGX_AGAIN) {
1507 #if (NGX_PCRE)
1508 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1510 noregex = clcf->noregex;
1511 #endif
1513 /* look up nested locations */
1515 rc = ngx_http_core_find_location(r);
1518 if (rc == NGX_OK || rc == NGX_DONE) {
1519 return rc;
1522 /* rc == NGX_DECLINED or rc == NGX_AGAIN in nested location */
1524 #if (NGX_PCRE)
1526 if (noregex == 0 && pclcf->regex_locations) {
1528 for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) {
1530 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1531 "test location: ~ \"%V\"", &(*clcfp)->name);
1533 n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);
1535 if (n == NGX_OK) {
1536 r->loc_conf = (*clcfp)->loc_conf;
1538 /* look up nested locations */
1540 rc = ngx_http_core_find_location(r);
1542 return (rc == NGX_ERROR) ? rc : NGX_OK;
1545 if (n == NGX_DECLINED) {
1546 continue;
1549 return NGX_ERROR;
1552 #endif
1554 return rc;
1559 * NGX_OK - exact match
1560 * NGX_DONE - auto redirect
1561 * NGX_AGAIN - inclusive match
1562 * NGX_DECLINED - no match
1565 static ngx_int_t
1566 ngx_http_core_find_static_location(ngx_http_request_t *r,
1567 ngx_http_location_tree_node_t *node)
1569 u_char *uri;
1570 size_t len, n;
1571 ngx_int_t rc, rv;
1573 len = r->uri.len;
1574 uri = r->uri.data;
1576 rv = NGX_DECLINED;
1578 for ( ;; ) {
1580 if (node == NULL) {
1581 return rv;
1584 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1585 "test location: \"%*s\"", node->len, node->name);
1587 n = (len <= (size_t) node->len) ? len : node->len;
1589 rc = ngx_filename_cmp(uri, node->name, n);
1591 if (rc != 0) {
1592 node = (rc < 0) ? node->left : node->right;
1594 continue;
1597 if (len > (size_t) node->len) {
1599 if (node->inclusive) {
1601 r->loc_conf = node->inclusive->loc_conf;
1602 rv = NGX_AGAIN;
1604 node = node->tree;
1605 uri += n;
1606 len -= n;
1608 continue;
1611 /* exact only */
1613 node = node->right;
1615 continue;
1618 if (len == (size_t) node->len) {
1620 r->loc_conf = (node->exact) ? node->exact->loc_conf:
1621 node->inclusive->loc_conf;
1622 return NGX_OK;
1625 /* len < node->len */
1627 if (len + 1 == (size_t) node->len && node->auto_redirect) {
1629 r->loc_conf = (node->exact) ? node->exact->loc_conf:
1630 node->inclusive->loc_conf;
1631 rv = NGX_DONE;
1634 node = node->left;
1639 void *
1640 ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash)
1642 u_char c, *lowcase;
1643 size_t len;
1644 ngx_uint_t i, hash;
1646 if (types_hash->size == 0) {
1647 return (void *) 4;
1650 if (r->headers_out.content_type.len == 0) {
1651 return NULL;
1654 len = r->headers_out.content_type_len;
1656 if (r->headers_out.content_type_lowcase == NULL) {
1658 lowcase = ngx_pnalloc(r->pool, len);
1659 if (lowcase == NULL) {
1660 return NULL;
1663 r->headers_out.content_type_lowcase = lowcase;
1665 hash = 0;
1667 for (i = 0; i < len; i++) {
1668 c = ngx_tolower(r->headers_out.content_type.data[i]);
1669 hash = ngx_hash(hash, c);
1670 lowcase[i] = c;
1673 r->headers_out.content_type_hash = hash;
1676 return ngx_hash_find(types_hash, r->headers_out.content_type_hash,
1677 r->headers_out.content_type_lowcase, len);
1681 ngx_int_t
1682 ngx_http_set_content_type(ngx_http_request_t *r)
1684 u_char c, *exten;
1685 ngx_str_t *type;
1686 ngx_uint_t i, hash;
1687 ngx_http_core_loc_conf_t *clcf;
1689 if (r->headers_out.content_type.len) {
1690 return NGX_OK;
1693 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1695 if (r->exten.len) {
1697 hash = 0;
1699 for (i = 0; i < r->exten.len; i++) {
1700 c = r->exten.data[i];
1702 if (c >= 'A' && c <= 'Z') {
1704 exten = ngx_pnalloc(r->pool, r->exten.len);
1705 if (exten == NULL) {
1706 return NGX_ERROR;
1709 hash = ngx_hash_strlow(exten, r->exten.data, r->exten.len);
1711 r->exten.data = exten;
1713 break;
1716 hash = ngx_hash(hash, c);
1719 type = ngx_hash_find(&clcf->types_hash, hash,
1720 r->exten.data, r->exten.len);
1722 if (type) {
1723 r->headers_out.content_type_len = type->len;
1724 r->headers_out.content_type = *type;
1726 return NGX_OK;
1730 r->headers_out.content_type_len = clcf->default_type.len;
1731 r->headers_out.content_type = clcf->default_type;
1733 return NGX_OK;
1737 void
1738 ngx_http_set_exten(ngx_http_request_t *r)
1740 ngx_int_t i;
1742 ngx_str_null(&r->exten);
1744 for (i = r->uri.len - 1; i > 1; i--) {
1745 if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') {
1747 r->exten.len = r->uri.len - i - 1;
1748 r->exten.data = &r->uri.data[i + 1];
1750 return;
1752 } else if (r->uri.data[i] == '/') {
1753 return;
1757 return;
1761 ngx_int_t
1762 ngx_http_send_header(ngx_http_request_t *r)
1764 if (r->err_status) {
1765 r->headers_out.status = r->err_status;
1766 r->headers_out.status_line.len = 0;
1769 return ngx_http_top_header_filter(r);
1773 ngx_int_t
1774 ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
1776 ngx_int_t rc;
1777 ngx_connection_t *c;
1779 c = r->connection;
1781 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
1782 "http output filter \"%V?%V\"", &r->uri, &r->args);
1784 rc = ngx_http_top_body_filter(r, in);
1786 if (rc == NGX_ERROR) {
1787 /* NGX_ERROR may be returned by any filter */
1788 c->error = 1;
1791 return rc;
1795 u_char *
1796 ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
1797 size_t *root_length, size_t reserved)
1799 u_char *last;
1800 size_t alias;
1801 ngx_http_core_loc_conf_t *clcf;
1803 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1805 alias = clcf->alias;
1807 if (alias && !r->valid_location) {
1808 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1809 "\"alias\" could not be used in location \"%V\" "
1810 "where URI was rewritten", &clcf->name);
1811 return NULL;
1814 if (clcf->root_lengths == NULL) {
1816 *root_length = clcf->root.len;
1818 path->len = clcf->root.len + reserved + r->uri.len - alias + 1;
1820 path->data = ngx_pnalloc(r->pool, path->len);
1821 if (path->data == NULL) {
1822 return NULL;
1825 last = ngx_copy(path->data, clcf->root.data, clcf->root.len);
1827 } else {
1829 #if (NGX_PCRE)
1830 ngx_uint_t captures;
1832 captures = alias && clcf->regex;
1834 reserved += captures ? r->add_uri_to_alias ? r->uri.len + 1 : 1
1835 : r->uri.len - alias + 1;
1836 #else
1837 reserved += r->uri.len - alias + 1;
1838 #endif
1840 if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
1841 clcf->root_values->elts)
1842 == NULL)
1844 return NULL;
1847 if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0) != NGX_OK) {
1848 return NULL;
1851 *root_length = path->len - reserved;
1852 last = path->data + *root_length;
1854 #if (NGX_PCRE)
1855 if (captures) {
1856 if (!r->add_uri_to_alias) {
1857 *last = '\0';
1858 return last;
1861 alias = 0;
1863 #endif
1866 last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);
1868 return last;
1872 ngx_int_t
1873 ngx_http_auth_basic_user(ngx_http_request_t *r)
1875 ngx_str_t auth, encoded;
1876 ngx_uint_t len;
1878 if (r->headers_in.user.len == 0 && r->headers_in.user.data != NULL) {
1879 return NGX_DECLINED;
1882 if (r->headers_in.authorization == NULL) {
1883 r->headers_in.user.data = (u_char *) "";
1884 return NGX_DECLINED;
1887 encoded = r->headers_in.authorization->value;
1889 if (encoded.len < sizeof("Basic ") - 1
1890 || ngx_strncasecmp(encoded.data, (u_char *) "Basic ",
1891 sizeof("Basic ") - 1)
1892 != 0)
1894 r->headers_in.user.data = (u_char *) "";
1895 return NGX_DECLINED;
1898 encoded.len -= sizeof("Basic ") - 1;
1899 encoded.data += sizeof("Basic ") - 1;
1901 while (encoded.len && encoded.data[0] == ' ') {
1902 encoded.len--;
1903 encoded.data++;
1906 if (encoded.len == 0) {
1907 r->headers_in.user.data = (u_char *) "";
1908 return NGX_DECLINED;
1911 auth.len = ngx_base64_decoded_length(encoded.len);
1912 auth.data = ngx_pnalloc(r->pool, auth.len + 1);
1913 if (auth.data == NULL) {
1914 return NGX_ERROR;
1917 if (ngx_decode_base64(&auth, &encoded) != NGX_OK) {
1918 r->headers_in.user.data = (u_char *) "";
1919 return NGX_DECLINED;
1922 auth.data[auth.len] = '\0';
1924 for (len = 0; len < auth.len; len++) {
1925 if (auth.data[len] == ':') {
1926 break;
1930 if (len == 0 || len == auth.len) {
1931 r->headers_in.user.data = (u_char *) "";
1932 return NGX_DECLINED;
1935 r->headers_in.user.len = len;
1936 r->headers_in.user.data = auth.data;
1937 r->headers_in.passwd.len = auth.len - len - 1;
1938 r->headers_in.passwd.data = &auth.data[len + 1];
1940 return NGX_OK;
1944 #if (NGX_HTTP_GZIP)
1946 ngx_int_t
1947 ngx_http_gzip_ok(ngx_http_request_t *r)
1949 time_t date, expires;
1950 ngx_uint_t p;
1951 ngx_array_t *cc;
1952 ngx_table_elt_t *e, *d;
1953 ngx_http_core_loc_conf_t *clcf;
1955 r->gzip_tested = 1;
1957 if (r != r->main
1958 || r->headers_in.accept_encoding == NULL
1959 || ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
1960 "gzip", 4 - 1)
1961 == NULL
1964 * if the URL (without the "http://" prefix) is longer than 253 bytes,
1965 * then MSIE 4.x can not handle the compressed stream - it waits
1966 * too long, hangs up or crashes
1969 || (r->headers_in.msie4 && r->unparsed_uri.len > 200))
1971 return NGX_DECLINED;
1974 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1976 if (r->headers_in.msie6 && clcf->gzip_disable_msie6) {
1977 return NGX_DECLINED;
1980 if (r->http_version < clcf->gzip_http_version) {
1981 return NGX_DECLINED;
1984 if (r->headers_in.via == NULL) {
1985 goto ok;
1988 p = clcf->gzip_proxied;
1990 if (p & NGX_HTTP_GZIP_PROXIED_OFF) {
1991 return NGX_DECLINED;
1994 if (p & NGX_HTTP_GZIP_PROXIED_ANY) {
1995 goto ok;
1998 if (r->headers_in.authorization && (p & NGX_HTTP_GZIP_PROXIED_AUTH)) {
1999 goto ok;
2002 e = r->headers_out.expires;
2004 if (e) {
2006 if (!(p & NGX_HTTP_GZIP_PROXIED_EXPIRED)) {
2007 return NGX_DECLINED;
2010 expires = ngx_http_parse_time(e->value.data, e->value.len);
2011 if (expires == NGX_ERROR) {
2012 return NGX_DECLINED;
2015 d = r->headers_out.date;
2017 if (d) {
2018 date = ngx_http_parse_time(d->value.data, d->value.len);
2019 if (date == NGX_ERROR) {
2020 return NGX_DECLINED;
2023 } else {
2024 date = ngx_time();
2027 if (expires < date) {
2028 goto ok;
2031 return NGX_DECLINED;
2034 cc = &r->headers_out.cache_control;
2036 if (cc->elts) {
2038 if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
2039 && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_cache,
2040 NULL)
2041 >= 0)
2043 goto ok;
2046 if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE)
2047 && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_store,
2048 NULL)
2049 >= 0)
2051 goto ok;
2054 if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE)
2055 && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_private,
2056 NULL)
2057 >= 0)
2059 goto ok;
2062 return NGX_DECLINED;
2065 if ((p & NGX_HTTP_GZIP_PROXIED_NO_LM) && r->headers_out.last_modified) {
2066 return NGX_DECLINED;
2069 if ((p & NGX_HTTP_GZIP_PROXIED_NO_ETAG) && r->headers_out.etag) {
2070 return NGX_DECLINED;
2075 #if (NGX_PCRE)
2077 if (clcf->gzip_disable && r->headers_in.user_agent) {
2079 if (ngx_regex_exec_array(clcf->gzip_disable,
2080 &r->headers_in.user_agent->value,
2081 r->connection->log)
2082 != NGX_DECLINED)
2084 return NGX_DECLINED;
2088 #endif
2090 r->gzip_ok = 1;
2092 return NGX_OK;
2095 #endif
2098 ngx_int_t
2099 ngx_http_subrequest(ngx_http_request_t *r,
2100 ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
2101 ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
2103 ngx_connection_t *c;
2104 ngx_http_request_t *sr;
2105 ngx_http_core_srv_conf_t *cscf;
2106 ngx_http_postponed_request_t *pr, *p;
2108 r->main->subrequests--;
2110 if (r->main->subrequests == 0) {
2111 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2112 "subrequests cycle while processing \"%V\"", uri);
2113 r->main->subrequests = 1;
2114 return NGX_ERROR;
2117 sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
2118 if (sr == NULL) {
2119 return NGX_ERROR;
2122 sr->signature = NGX_HTTP_MODULE;
2124 c = r->connection;
2125 sr->connection = c;
2127 sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
2128 if (sr->ctx == NULL) {
2129 return NGX_ERROR;
2132 if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
2133 sizeof(ngx_table_elt_t))
2134 != NGX_OK)
2136 return NGX_ERROR;
2139 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2140 sr->main_conf = cscf->ctx->main_conf;
2141 sr->srv_conf = cscf->ctx->srv_conf;
2142 sr->loc_conf = cscf->ctx->loc_conf;
2144 sr->pool = r->pool;
2146 sr->headers_in = r->headers_in;
2148 ngx_http_clear_content_length(sr);
2149 ngx_http_clear_accept_ranges(sr);
2150 ngx_http_clear_last_modified(sr);
2151 ngx_http_clear_etag(sr);
2153 sr->request_body = r->request_body;
2155 sr->method = NGX_HTTP_GET;
2156 sr->http_version = r->http_version;
2158 sr->request_line = r->request_line;
2159 sr->uri = *uri;
2161 if (args) {
2162 sr->args = *args;
2165 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
2166 "http subrequest \"%V?%V\"", uri, &sr->args);
2168 sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
2169 sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
2171 sr->unparsed_uri = r->unparsed_uri;
2172 sr->method_name = ngx_http_core_get_method;
2173 sr->http_protocol = r->http_protocol;
2175 ngx_http_set_exten(sr);
2177 sr->main = r->main;
2178 sr->parent = r;
2179 sr->post_subrequest = ps;
2180 sr->read_event_handler = ngx_http_request_empty_handler;
2181 sr->write_event_handler = ngx_http_handler;
2183 if (c->data == r && r->postponed == NULL) {
2184 c->data = sr;
2187 sr->variables = r->variables;
2189 sr->log_handler = r->log_handler;
2191 pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
2192 if (pr == NULL) {
2193 return NGX_ERROR;
2196 pr->request = sr;
2197 pr->out = NULL;
2198 pr->next = NULL;
2200 if (r->postponed) {
2201 for (p = r->postponed; p->next; p = p->next) { /* void */ }
2202 p->next = pr;
2204 } else {
2205 r->postponed = pr;
2208 sr->internal = 1;
2210 sr->discard_body = r->discard_body;
2211 sr->expect_tested = 1;
2212 sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
2214 sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
2216 r->main->subrequests++;
2217 r->main->count++;
2219 *psr = sr;
2221 return ngx_http_post_request(sr, NULL);
2225 ngx_int_t
2226 ngx_http_internal_redirect(ngx_http_request_t *r,
2227 ngx_str_t *uri, ngx_str_t *args)
2229 ngx_http_core_srv_conf_t *cscf;
2231 r->uri_changes--;
2233 if (r->uri_changes == 0) {
2234 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2235 "rewrite or internal redirection cycle "
2236 "while internal redirect to \"%V\"", uri);
2238 r->main->count++;
2239 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
2240 return NGX_DONE;
2243 r->uri = *uri;
2245 if (args) {
2246 r->args = *args;
2248 } else {
2249 ngx_str_null(&r->args);
2252 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2253 "internal redirect: \"%V?%V\"", uri, &r->args);
2255 ngx_http_set_exten(r);
2257 /* clear the modules contexts */
2258 ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
2260 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2261 r->loc_conf = cscf->ctx->loc_conf;
2263 ngx_http_update_location_config(r);
2265 #if (NGX_HTTP_CACHE)
2266 r->cache = NULL;
2267 #endif
2269 r->internal = 1;
2270 r->add_uri_to_alias = 0;
2271 r->main->count++;
2273 ngx_http_handler(r);
2275 return NGX_DONE;
2279 ngx_int_t
2280 ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
2282 ngx_http_core_srv_conf_t *cscf;
2283 ngx_http_core_loc_conf_t **clcfp;
2284 ngx_http_core_main_conf_t *cmcf;
2286 r->main->count++;
2288 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2290 if (cscf->named_locations) {
2292 for (clcfp = cscf->named_locations; *clcfp; clcfp++) {
2294 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2295 "test location: \"%V\"", &(*clcfp)->name);
2297 if (name->len != (*clcfp)->name.len
2298 || ngx_strncmp(name->data, (*clcfp)->name.data, name->len) != 0)
2300 continue;
2303 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2304 "using location: %V \"%V?%V\"",
2305 name, &r->uri, &r->args);
2307 r->internal = 1;
2308 r->content_handler = NULL;
2309 r->loc_conf = (*clcfp)->loc_conf;
2311 ngx_http_update_location_config(r);
2313 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
2315 r->phase_handler = cmcf->phase_engine.location_rewrite_index;
2317 ngx_http_core_run_phases(r);
2319 return NGX_DONE;
2323 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2324 "could not find named location \"%V\"", name);
2326 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
2328 return NGX_DONE;
2332 ngx_http_cleanup_t *
2333 ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
2335 ngx_http_cleanup_t *cln;
2337 r = r->main;
2339 cln = ngx_palloc(r->pool, sizeof(ngx_http_cleanup_t));
2340 if (cln == NULL) {
2341 return NULL;
2344 if (size) {
2345 cln->data = ngx_palloc(r->pool, size);
2346 if (cln->data == NULL) {
2347 return NULL;
2350 } else {
2351 cln->data = NULL;
2354 cln->handler = NULL;
2355 cln->next = r->cleanup;
2357 r->cleanup = cln;
2359 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2360 "http cleanup add: %p", cln);
2362 return cln;
2366 static char *
2367 ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
2369 char *rv;
2370 void *mconf;
2371 ngx_uint_t i;
2372 ngx_conf_t pcf;
2373 ngx_http_module_t *module;
2374 ngx_http_conf_ctx_t *ctx, *http_ctx;
2375 ngx_http_core_srv_conf_t *cscf, **cscfp;
2376 ngx_http_core_main_conf_t *cmcf;
2378 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
2379 if (ctx == NULL) {
2380 return NGX_CONF_ERROR;
2383 http_ctx = cf->ctx;
2384 ctx->main_conf = http_ctx->main_conf;
2386 /* the server{}'s srv_conf */
2388 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
2389 if (ctx->srv_conf == NULL) {
2390 return NGX_CONF_ERROR;
2393 /* the server{}'s loc_conf */
2395 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
2396 if (ctx->loc_conf == NULL) {
2397 return NGX_CONF_ERROR;
2400 for (i = 0; ngx_modules[i]; i++) {
2401 if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
2402 continue;
2405 module = ngx_modules[i]->ctx;
2407 if (module->create_srv_conf) {
2408 mconf = module->create_srv_conf(cf);
2409 if (mconf == NULL) {
2410 return NGX_CONF_ERROR;
2413 ctx->srv_conf[ngx_modules[i]->ctx_index] = mconf;
2416 if (module->create_loc_conf) {
2417 mconf = module->create_loc_conf(cf);
2418 if (mconf == NULL) {
2419 return NGX_CONF_ERROR;
2422 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
2427 /* the server configuration context */
2429 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
2430 cscf->ctx = ctx;
2433 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
2435 cscfp = ngx_array_push(&cmcf->servers);
2436 if (cscfp == NULL) {
2437 return NGX_CONF_ERROR;
2440 *cscfp = cscf;
2442 #if (NGX_STATUS)
2443 cscf->request_counter =
2444 ngx_pcalloc(cf->pool, sizeof(ngx_status_counter_t));
2445 if (cscf->request_counter == NULL) {
2446 return NGX_CONF_ERROR;
2448 #endif
2450 /* parse inside server{} */
2451 pcf = *cf;
2452 cf->ctx = ctx;
2453 cf->cmd_type = NGX_HTTP_SRV_CONF;
2455 rv = ngx_conf_parse(cf, NULL);
2457 *cf = pcf;
2459 #if (NGX_STATUS)
2460 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2461 cscf->request_counter->label_for_childs.len = sizeof("locations info") - 1;
2462 cscf->request_counter->label_for_childs.data = (u_char *)"locations info";
2463 cscf->request_counter->caption.len = sizeof("Request for host ") - 1;
2464 #endif
2466 #if (NGX_STATUS_XML)
2467 cscf->request_counter->tag_for_childs.len = sizeof("locations") - 1;
2468 cscf->request_counter->tag_for_childs.data = (u_char *)"locations";
2469 cscf->request_counter->tag_name.len = sizeof("host") - 1;
2470 cscf->request_counter->tag_name.data = (u_char *)"host";
2471 #endif
2473 if (cscf->server_name.len) {
2475 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2476 cscf->request_counter->caption.len += cscf->server_name.len;
2477 #endif
2479 #if (NGX_STATUS_XML)
2480 cscf->request_counter->tag_value = cscf->server_name;
2481 #endif
2483 } else {
2485 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2486 cscf->request_counter->caption.len += sizeof("default") - 1;
2487 #endif
2489 #if (NGX_STATUS_XML)
2490 cscf->request_counter->tag_value.len = sizeof("default") - 1;
2491 #endif
2495 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2496 cscf->request_counter->caption.len += sizeof(" ()") - 1
2497 + cscf->listen_string.len;
2498 #endif
2500 #if (NGX_STATUS_XML)
2501 cscf->request_counter->tag_value.len += sizeof(" ()") - 1
2502 + cscf->listen_string.len;
2503 #endif
2506 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2507 cscf->request_counter->caption.data =
2508 ngx_palloc(cf->pool, cscf->request_counter->caption.len);
2509 if (cscf->request_counter->caption.data == NULL) {
2510 return NGX_CONF_ERROR;
2512 #endif
2514 #if (NGX_STATUS_XML)
2515 cscf->request_counter->tag_value.data =
2516 ngx_palloc(cf->pool, cscf->request_counter->tag_value.len);
2517 if (cscf->request_counter->tag_value.data == NULL) {
2518 return NGX_CONF_ERROR;
2520 #endif
2522 if (cscf->server_name.len) {
2524 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2525 ngx_sprintf(cscf->request_counter->caption.data,
2526 "Request for host %V (%V)",
2527 &cscf->server_name, &cscf->listen_string);
2528 #endif
2530 #if (NGX_STATUS_XML)
2531 ngx_sprintf(cscf->request_counter->tag_value.data,
2532 "%V (%V)",
2533 &cscf->server_name, &cscf->listen_string);
2534 #endif
2536 } else {
2538 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2539 ngx_sprintf(cscf->request_counter->caption.data,
2540 "Request for host default (%V)", &cscf->listen_string);
2541 #endif
2543 #if (NGX_STATUS_XML)
2544 ngx_sprintf(cscf->request_counter->tag_value.data,
2545 "default (%V)", &cscf->listen_string);
2546 #endif
2550 if (ngx_status_add_counter(cf->cycle, &ngx_http_module,
2551 cscf->request_counter) != NGX_OK) {
2552 return NGX_CONF_ERROR;
2555 #endif
2557 return rv;
2561 static char *
2562 ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
2564 char *rv;
2565 u_char *mod;
2566 size_t len;
2567 ngx_str_t *value, *name;
2568 ngx_uint_t i;
2569 ngx_conf_t save;
2570 ngx_http_module_t *module;
2571 ngx_http_conf_ctx_t *ctx, *pctx;
2572 ngx_http_core_loc_conf_t *clcf, *pclcf;
2573 #if (NGX_STATUS)
2574 ngx_http_core_srv_conf_t *cscf;
2575 u_char *p_caption;
2576 #endif
2578 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
2579 if (ctx == NULL) {
2580 return NGX_CONF_ERROR;
2583 pctx = cf->ctx;
2584 ctx->main_conf = pctx->main_conf;
2585 ctx->srv_conf = pctx->srv_conf;
2587 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
2588 if (ctx->loc_conf == NULL) {
2589 return NGX_CONF_ERROR;
2592 for (i = 0; ngx_modules[i]; i++) {
2593 if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
2594 continue;
2597 module = ngx_modules[i]->ctx;
2599 if (module->create_loc_conf) {
2600 ctx->loc_conf[ngx_modules[i]->ctx_index] =
2601 module->create_loc_conf(cf);
2602 if (ctx->loc_conf[ngx_modules[i]->ctx_index] == NULL) {
2603 return NGX_CONF_ERROR;
2608 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
2609 clcf->loc_conf = ctx->loc_conf;
2611 value = cf->args->elts;
2613 if (cf->args->nelts == 3) {
2615 len = value[1].len;
2616 mod = value[1].data;
2617 name = &value[2];
2619 if (len == 1 && mod[0] == '=') {
2621 clcf->name = *name;
2622 clcf->exact_match = 1;
2624 } else if (len == 2 && mod[0] == '^' && mod[1] == '~') {
2626 clcf->name = *name;
2627 clcf->noregex = 1;
2629 } else if (len == 1 && mod[0] == '~') {
2631 if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
2632 return NGX_CONF_ERROR;
2635 } else if (len == 2 && mod[0] == '~' && mod[1] == '*') {
2637 if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
2638 return NGX_CONF_ERROR;
2641 } else {
2642 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2643 "invalid location modifier \"%V\"", &value[1]);
2644 return NGX_CONF_ERROR;
2647 } else {
2649 name = &value[1];
2651 if (name->data[0] == '=') {
2653 clcf->name.len = name->len - 1;
2654 clcf->name.data = name->data + 1;
2655 clcf->exact_match = 1;
2657 } else if (name->data[0] == '^' && name->data[1] == '~') {
2659 clcf->name.len = name->len - 2;
2660 clcf->name.data = name->data + 2;
2661 clcf->noregex = 1;
2663 } else if (name->data[0] == '~') {
2665 name->len--;
2666 name->data++;
2668 if (name->data[0] == '*') {
2670 name->len--;
2671 name->data++;
2673 if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
2674 return NGX_CONF_ERROR;
2677 } else {
2678 if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
2679 return NGX_CONF_ERROR;
2683 } else {
2685 clcf->name = *name;
2687 if (name->data[0] == '@') {
2688 clcf->named = 1;
2693 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
2695 if (pclcf->name.len) {
2697 /* nested location */
2699 #if 0
2700 clcf->prev_location = pclcf;
2701 #endif
2703 if (pclcf->exact_match) {
2704 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2705 "location \"%V\" could not be inside "
2706 "the exact location \"%V\"",
2707 &clcf->name, &pclcf->name);
2708 return NGX_CONF_ERROR;
2711 if (pclcf->named) {
2712 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2713 "location \"%V\" could not be inside "
2714 "the named location \"%V\"",
2715 &clcf->name, &pclcf->name);
2716 return NGX_CONF_ERROR;
2719 if (clcf->named) {
2720 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2721 "named location \"%V\" must be "
2722 "on server level only",
2723 &clcf->name);
2724 return NGX_CONF_ERROR;
2727 len = pclcf->name.len;
2729 #if (NGX_PCRE)
2730 if (clcf->regex == NULL
2731 && ngx_strncmp(clcf->name.data, pclcf->name.data, len) != 0)
2732 #else
2733 if (ngx_strncmp(clcf->name.data, pclcf->name.data, len) != 0)
2734 #endif
2736 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2737 "location \"%V\" is outside location \"%V\"",
2738 &clcf->name, &pclcf->name);
2739 return NGX_CONF_ERROR;
2743 #if (NGX_STATUS)
2744 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
2746 if (cscf->request_counter) {
2748 clcf->request_counter =
2749 ngx_pcalloc(cf->pool, sizeof(ngx_status_counter_t));
2750 if (clcf->request_counter == NULL) {
2751 return NGX_CONF_ERROR;
2754 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2755 clcf->request_counter->caption.len = sizeof("Location ") - 1 + value[1].len;
2756 clcf->request_counter->label_for_childs.len = sizeof("codes list") - 1;
2757 clcf->request_counter->label_for_childs.data = (u_char *)"codes list";
2758 #endif
2760 #if (NGX_STATUS_XML)
2761 clcf->request_counter->tag_name.len = sizeof("location") - 1;
2762 clcf->request_counter->tag_name.data = (u_char *)"location";
2763 clcf->request_counter->tag_for_childs.len = sizeof("codes") - 1;
2764 clcf->request_counter->tag_for_childs.data = (u_char *)"codes";
2765 clcf->request_counter->tag_value.len = value[1].len;
2766 #endif
2769 if (cf->args->nelts == 3) {
2771 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2772 clcf->request_counter->caption.len += sizeof(" ") - 1 + value[2].len;
2773 #endif
2775 #if (NGX_STATUS_XML)
2776 clcf->request_counter->tag_value.len +=
2777 sizeof(" ") - 1 + value[2].len;
2778 #endif
2782 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2783 clcf->request_counter->caption.data =
2784 ngx_palloc(cf->pool, clcf->request_counter->caption.len);
2785 if (clcf->request_counter->caption.data == NULL) {
2786 return NGX_CONF_ERROR;
2789 p_caption = clcf->request_counter->caption.data;
2791 p_caption = ngx_sprintf(p_caption, "Location ");
2792 #endif
2794 if (cf->args->nelts == 3) {
2796 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2797 p_caption = ngx_sprintf(p_caption, "%V %V", &value[1], &value[2]);
2798 #endif
2800 #if (NGX_STATUS_XML)
2801 clcf->request_counter->tag_value.data =
2802 ngx_palloc(cf->pool, clcf->request_counter->tag_value.len);
2803 if (clcf->request_counter->tag_value.data == NULL) {
2804 return NGX_CONF_ERROR;
2806 ngx_sprintf(clcf->request_counter->tag_value.data,
2807 "%V %V", &value[1], &value[2]);
2808 #endif
2810 } else {
2812 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
2813 p_caption = ngx_sprintf(p_caption, "%V", &value[1]);
2814 #endif
2816 #if (NGX_STATUS_XML)
2817 clcf->request_counter->tag_value = value[1];
2818 #endif
2821 if (ngx_status_add_child(cf->cycle, cscf->request_counter,
2822 clcf->request_counter) != NGX_OK) {
2823 return NGX_CONF_ERROR;
2827 #endif
2829 if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
2830 return NGX_CONF_ERROR;
2833 save = *cf;
2834 cf->ctx = ctx;
2835 cf->cmd_type = NGX_HTTP_LOC_CONF;
2837 rv = ngx_conf_parse(cf, NULL);
2839 *cf = save;
2841 return rv;
2845 static ngx_int_t
2846 ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
2847 ngx_str_t *regex, ngx_uint_t caseless)
2849 #if (NGX_PCRE)
2850 ngx_regex_compile_t rc;
2851 u_char errstr[NGX_MAX_CONF_ERRSTR];
2853 ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
2855 rc.pattern = *regex;
2856 rc.err.len = NGX_MAX_CONF_ERRSTR;
2857 rc.err.data = errstr;
2859 #if (NGX_HAVE_CASELESS_FILESYSTEM)
2860 rc.options = NGX_REGEX_CASELESS;
2861 #else
2862 rc.options = caseless;
2863 #endif
2865 clcf->regex = ngx_http_regex_compile(cf, &rc);
2866 if (clcf->regex == NULL) {
2867 return NGX_ERROR;
2870 clcf->name = *regex;
2872 return NGX_OK;
2874 #else
2876 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2877 "the using of the regex \"%V\" requires PCRE library",
2878 regex);
2879 return NGX_ERROR;
2881 #endif
2885 static char *
2886 ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2888 ngx_http_core_loc_conf_t *clcf = conf;
2890 char *rv;
2891 ngx_conf_t save;
2893 if (clcf->types == NULL) {
2894 clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
2895 if (clcf->types == NULL) {
2896 return NGX_CONF_ERROR;
2900 save = *cf;
2901 cf->handler = ngx_http_core_type;
2902 cf->handler_conf = conf;
2904 rv = ngx_conf_parse(cf, NULL);
2906 *cf = save;
2908 return rv;
2912 static char *
2913 ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
2915 ngx_http_core_loc_conf_t *clcf = conf;
2917 ngx_str_t *value, *content_type, *old, file;
2918 ngx_uint_t i, n, hash;
2919 ngx_hash_key_t *type;
2921 value = cf->args->elts;
2923 if (ngx_strcmp(value[0].data, "include") == 0) {
2924 file = value[1];
2926 if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
2927 return NGX_CONF_ERROR;
2930 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
2932 return ngx_conf_parse(cf, &file);
2935 content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));
2936 if (content_type == NULL) {
2937 return NGX_CONF_ERROR;
2940 *content_type = value[0];
2942 for (i = 1; i < cf->args->nelts; i++) {
2944 hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
2946 type = clcf->types->elts;
2947 for (n = 0; n < clcf->types->nelts; n++) {
2948 if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
2949 old = type[n].value;
2950 type[n].value = content_type;
2952 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
2953 "duplicate extention \"%V\", "
2954 "content type: \"%V\", "
2955 "old content type: \"%V\"",
2956 &value[i], content_type, old);
2957 continue;
2962 type = ngx_array_push(clcf->types);
2963 if (type == NULL) {
2964 return NGX_CONF_ERROR;
2967 type->key = value[i];
2968 type->key_hash = hash;
2969 type->value = content_type;
2972 return NGX_CONF_OK;
2976 static ngx_int_t
2977 ngx_http_core_preconfiguration(ngx_conf_t *cf)
2979 return ngx_http_variables_add_core_vars(cf);
2982 static ngx_int_t
2983 ngx_http_core_postconfiguration(ngx_conf_t *cf)
2985 ngx_http_handler_pt *h;
2986 ngx_http_core_main_conf_t *cmcf;
2988 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
2990 h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers);
2991 if (h == NULL) {
2992 return NGX_ERROR;
2995 *h = ngx_http_core_read_request_body;
2997 return NGX_OK;
3000 static void *
3001 ngx_http_core_create_main_conf(ngx_conf_t *cf)
3003 ngx_http_core_main_conf_t *cmcf;
3005 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
3006 if (cmcf == NULL) {
3007 return NULL;
3010 if (ngx_array_init(&cmcf->servers, cf->pool, 4,
3011 sizeof(ngx_http_core_srv_conf_t *))
3012 != NGX_OK)
3014 return NULL;
3017 cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
3018 cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;
3020 cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
3021 cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;
3023 return cmcf;
3027 static char *
3028 ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
3030 ngx_http_core_main_conf_t *cmcf = conf;
3032 if (cmcf->server_names_hash_max_size == NGX_CONF_UNSET_UINT) {
3033 cmcf->server_names_hash_max_size = 512;
3036 if (cmcf->server_names_hash_bucket_size == NGX_CONF_UNSET_UINT) {
3037 cmcf->server_names_hash_bucket_size = ngx_cacheline_size;
3040 cmcf->server_names_hash_bucket_size =
3041 ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);
3044 if (cmcf->variables_hash_max_size == NGX_CONF_UNSET_UINT) {
3045 cmcf->variables_hash_max_size = 512;
3048 if (cmcf->variables_hash_bucket_size == NGX_CONF_UNSET_UINT) {
3049 cmcf->variables_hash_bucket_size = 64;
3052 cmcf->variables_hash_bucket_size =
3053 ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);
3055 if (cmcf->ncaptures) {
3056 cmcf->ncaptures = (cmcf->ncaptures + 1) * 3;
3059 return NGX_CONF_OK;
3063 static void *
3064 ngx_http_core_create_srv_conf(ngx_conf_t *cf)
3066 ngx_http_core_srv_conf_t *cscf;
3068 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t));
3069 if (cscf == NULL) {
3070 return NULL;
3074 * set by ngx_pcalloc():
3076 * conf->client_large_buffers.num = 0;
3079 if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
3080 sizeof(ngx_http_server_name_t))
3081 != NGX_OK)
3083 return NULL;
3086 cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
3087 cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
3088 cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
3089 cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
3090 cscf->ignore_invalid_headers = NGX_CONF_UNSET;
3091 cscf->merge_slashes = NGX_CONF_UNSET;
3092 cscf->underscores_in_headers = NGX_CONF_UNSET;
3094 return cscf;
3098 static char *
3099 ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
3101 ngx_http_core_srv_conf_t *prev = parent;
3102 ngx_http_core_srv_conf_t *conf = child;
3104 struct sockaddr_in *sin;
3105 ngx_http_listen_opt_t lsopt;
3106 ngx_http_server_name_t *sn;
3108 /* TODO: it does not merge, it inits only */
3110 ngx_conf_merge_size_value(conf->connection_pool_size,
3111 prev->connection_pool_size, 256);
3112 ngx_conf_merge_size_value(conf->request_pool_size,
3113 prev->request_pool_size, 4096);
3114 ngx_conf_merge_msec_value(conf->client_header_timeout,
3115 prev->client_header_timeout, 60000);
3116 ngx_conf_merge_size_value(conf->client_header_buffer_size,
3117 prev->client_header_buffer_size, 1024);
3118 ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
3119 prev->large_client_header_buffers,
3120 4, 8192);
3122 if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
3123 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3124 "the \"large_client_header_buffers\" size must be "
3125 "equal to or bigger than \"connection_pool_size\"");
3126 return NGX_CONF_ERROR;
3129 ngx_conf_merge_value(conf->ignore_invalid_headers,
3130 prev->ignore_invalid_headers, 1);
3132 ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);
3134 ngx_conf_merge_value(conf->underscores_in_headers,
3135 prev->underscores_in_headers, 0);
3137 if (!conf->listen) {
3138 ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));
3140 sin = &lsopt.u.sockaddr_in;
3142 sin->sin_family = AF_INET;
3143 #if (NGX_WIN32)
3144 sin->sin_port = htons(80);
3145 #else
3146 sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
3147 #endif
3148 sin->sin_addr.s_addr = INADDR_ANY;
3150 lsopt.socklen = sizeof(struct sockaddr_in);
3152 lsopt.backlog = NGX_LISTEN_BACKLOG;
3153 lsopt.rcvbuf = -1;
3154 lsopt.sndbuf = -1;
3155 lsopt.wildcard = 1;
3157 (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr,
3158 NGX_SOCKADDR_STRLEN, 1);
3160 if (ngx_http_add_listen(cf, conf, &lsopt) == NGX_OK) {
3161 return NGX_CONF_OK;
3165 if (conf->server_name.data == NULL) {
3166 conf->server_name = cf->cycle->hostname;
3168 sn = ngx_array_push(&conf->server_names);
3169 if (sn == NULL) {
3170 return NGX_CONF_ERROR;
3173 #if (NGX_PCRE)
3174 sn->regex = NULL;
3175 #endif
3176 sn->server = conf;
3177 sn->name.len = conf->server_name.len;
3178 sn->name.data = conf->server_name.data;
3182 return NGX_CONF_OK;
3186 static void *
3187 ngx_http_core_create_loc_conf(ngx_conf_t *cf)
3189 ngx_http_core_loc_conf_t *clcf;
3191 clcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
3192 if (clcf == NULL) {
3193 return NULL;
3197 * set by ngx_pcalloc():
3199 * clcf->root = { 0, NULL };
3200 * clcf->limit_except = 0;
3201 * clcf->post_action = { 0, NULL };
3202 * clcf->types = NULL;
3203 * clcf->default_type = { 0, NULL };
3204 * clcf->error_log = NULL;
3205 * clcf->error_pages = NULL;
3206 * clcf->try_files = NULL;
3207 * clcf->client_body_path = NULL;
3208 * clcf->regex = NULL;
3209 * clcf->exact_match = 0;
3210 * clcf->auto_redirect = 0;
3211 * clcf->alias = 0;
3212 * clcf->gzip_proxied = 0;
3215 clcf->client_max_body_size = NGX_CONF_UNSET;
3216 clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
3217 clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
3218 clcf->satisfy = NGX_CONF_UNSET_UINT;
3219 clcf->if_modified_since = NGX_CONF_UNSET_UINT;
3220 clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
3221 clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
3222 clcf->internal = NGX_CONF_UNSET;
3223 clcf->sendfile = NGX_CONF_UNSET;
3224 clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
3225 #if (NGX_HAVE_FILE_AIO)
3226 clcf->aio = NGX_CONF_UNSET;
3227 #endif
3228 clcf->read_ahead = NGX_CONF_UNSET_SIZE;
3229 clcf->directio = NGX_CONF_UNSET;
3230 clcf->directio_alignment = NGX_CONF_UNSET;
3231 clcf->tcp_nopush = NGX_CONF_UNSET;
3232 clcf->tcp_nodelay = NGX_CONF_UNSET;
3233 clcf->send_timeout = NGX_CONF_UNSET_MSEC;
3234 clcf->send_lowat = NGX_CONF_UNSET_SIZE;
3235 clcf->postpone_output = NGX_CONF_UNSET_SIZE;
3236 clcf->limit_rate = NGX_CONF_UNSET_SIZE;
3237 clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
3238 clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
3239 clcf->keepalive_header = NGX_CONF_UNSET;
3240 clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
3241 clcf->lingering_time = NGX_CONF_UNSET_MSEC;
3242 clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
3243 clcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
3244 clcf->reset_timedout_connection = NGX_CONF_UNSET;
3245 clcf->server_name_in_redirect = NGX_CONF_UNSET;
3246 clcf->port_in_redirect = NGX_CONF_UNSET;
3247 clcf->msie_padding = NGX_CONF_UNSET;
3248 clcf->msie_refresh = NGX_CONF_UNSET;
3249 clcf->log_not_found = NGX_CONF_UNSET;
3250 clcf->log_subrequest = NGX_CONF_UNSET;
3251 clcf->recursive_error_pages = NGX_CONF_UNSET;
3252 clcf->server_tokens = NGX_CONF_UNSET;
3253 clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
3254 clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
3255 clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
3257 clcf->open_file_cache = NGX_CONF_UNSET_PTR;
3258 clcf->open_file_cache_valid = NGX_CONF_UNSET;
3259 clcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
3260 clcf->open_file_cache_errors = NGX_CONF_UNSET;
3261 clcf->open_file_cache_events = NGX_CONF_UNSET;
3263 #if (NGX_HTTP_GZIP)
3264 clcf->gzip_vary = NGX_CONF_UNSET;
3265 clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
3266 #if (NGX_PCRE)
3267 clcf->gzip_disable = NGX_CONF_UNSET_PTR;
3268 clcf->gzip_disable_msie6 = 3;
3269 #endif
3270 #endif
3272 clcf->use_args_from_post = NGX_CONF_UNSET;
3274 return clcf;
3278 static ngx_str_t ngx_http_core_text_html_type = ngx_string("text/html");
3279 static ngx_str_t ngx_http_core_image_gif_type = ngx_string("image/gif");
3280 static ngx_str_t ngx_http_core_image_jpeg_type = ngx_string("image/jpeg");
3282 static ngx_hash_key_t ngx_http_core_default_types[] = {
3283 { ngx_string("html"), 0, &ngx_http_core_text_html_type },
3284 { ngx_string("gif"), 0, &ngx_http_core_image_gif_type },
3285 { ngx_string("jpg"), 0, &ngx_http_core_image_jpeg_type },
3286 { ngx_null_string, 0, NULL }
3290 static char *
3291 ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
3293 ngx_http_core_loc_conf_t *prev = parent;
3294 ngx_http_core_loc_conf_t *conf = child;
3296 ngx_uint_t i;
3297 ngx_hash_key_t *type;
3298 ngx_hash_init_t types_hash;
3300 if (conf->root.data == NULL) {
3302 conf->alias = prev->alias;
3303 conf->root = prev->root;
3304 conf->root_lengths = prev->root_lengths;
3305 conf->root_values = prev->root_values;
3307 if (prev->root.data == NULL) {
3308 ngx_str_set(&conf->root, "html");
3310 if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) {
3311 return NGX_CONF_ERROR;
3316 if (conf->post_action.data == NULL) {
3317 conf->post_action = prev->post_action;
3320 ngx_conf_merge_uint_value(conf->types_hash_max_size,
3321 prev->types_hash_max_size, 1024);
3323 ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
3324 prev->types_hash_bucket_size,
3325 ngx_cacheline_size);
3327 conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
3328 ngx_cacheline_size);
3331 * the special handling the "types" directive in the "http" section
3332 * to inherit the http's conf->types_hash to all servers
3335 if (prev->types && prev->types_hash.buckets == NULL) {
3337 types_hash.hash = &prev->types_hash;
3338 types_hash.key = ngx_hash_key_lc;
3339 types_hash.max_size = conf->types_hash_max_size;
3340 types_hash.bucket_size = conf->types_hash_bucket_size;
3341 types_hash.name = "types_hash";
3342 types_hash.pool = cf->pool;
3343 types_hash.temp_pool = NULL;
3345 if (ngx_hash_init(&types_hash, prev->types->elts, prev->types->nelts)
3346 != NGX_OK)
3348 return NGX_CONF_ERROR;
3352 if (conf->types == NULL) {
3353 conf->types = prev->types;
3354 conf->types_hash = prev->types_hash;
3357 if (conf->types == NULL) {
3358 conf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t));
3359 if (conf->types == NULL) {
3360 return NGX_CONF_ERROR;
3363 for (i = 0; ngx_http_core_default_types[i].key.len; i++) {
3364 type = ngx_array_push(conf->types);
3365 if (type == NULL) {
3366 return NGX_CONF_ERROR;
3369 type->key = ngx_http_core_default_types[i].key;
3370 type->key_hash =
3371 ngx_hash_key_lc(ngx_http_core_default_types[i].key.data,
3372 ngx_http_core_default_types[i].key.len);
3373 type->value = ngx_http_core_default_types[i].value;
3377 if (conf->types_hash.buckets == NULL) {
3379 types_hash.hash = &conf->types_hash;
3380 types_hash.key = ngx_hash_key_lc;
3381 types_hash.max_size = conf->types_hash_max_size;
3382 types_hash.bucket_size = conf->types_hash_bucket_size;
3383 types_hash.name = "mime_types_hash";
3384 types_hash.pool = cf->pool;
3385 types_hash.temp_pool = NULL;
3387 if (ngx_hash_init(&types_hash, conf->types->elts, conf->types->nelts)
3388 != NGX_OK)
3390 return NGX_CONF_ERROR;
3394 if (conf->error_log == NULL) {
3395 if (prev->error_log) {
3396 conf->error_log = prev->error_log;
3397 } else {
3398 conf->error_log = &cf->cycle->new_log;
3402 if (conf->error_pages == NULL && prev->error_pages) {
3403 conf->error_pages = prev->error_pages;
3406 ngx_conf_merge_str_value(conf->default_type,
3407 prev->default_type, "text/plain");
3409 ngx_conf_merge_off_value(conf->client_max_body_size,
3410 prev->client_max_body_size, 1 * 1024 * 1024);
3411 ngx_conf_merge_size_value(conf->client_body_buffer_size,
3412 prev->client_body_buffer_size,
3413 (size_t) 2 * ngx_pagesize);
3414 ngx_conf_merge_msec_value(conf->client_body_timeout,
3415 prev->client_body_timeout, 60000);
3417 ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
3418 NGX_HTTP_SATISFY_ALL);
3419 ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
3420 NGX_HTTP_IMS_EXACT);
3421 ngx_conf_merge_uint_value(conf->client_body_in_file_only,
3422 prev->client_body_in_file_only, 0);
3423 ngx_conf_merge_value(conf->client_body_in_single_buffer,
3424 prev->client_body_in_single_buffer, 0);
3425 ngx_conf_merge_value(conf->internal, prev->internal, 0);
3426 ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
3427 ngx_conf_merge_size_value(conf->sendfile_max_chunk,
3428 prev->sendfile_max_chunk, 0);
3429 #if (NGX_HAVE_FILE_AIO)
3430 ngx_conf_merge_value(conf->aio, prev->aio, 0);
3431 #endif
3432 ngx_conf_merge_size_value(conf->read_ahead, prev->read_ahead, 0);
3433 ngx_conf_merge_off_value(conf->directio, prev->directio,
3434 NGX_MAX_OFF_T_VALUE);
3435 ngx_conf_merge_off_value(conf->directio_alignment, prev->directio_alignment,
3436 512);
3437 ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
3438 ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);
3440 ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
3441 ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
3442 ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
3443 1460);
3444 ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
3445 ngx_conf_merge_size_value(conf->limit_rate_after, prev->limit_rate_after,
3447 ngx_conf_merge_msec_value(conf->keepalive_timeout,
3448 prev->keepalive_timeout, 75000);
3449 ngx_conf_merge_sec_value(conf->keepalive_header,
3450 prev->keepalive_header, 0);
3451 ngx_conf_merge_uint_value(conf->keepalive_requests,
3452 prev->keepalive_requests, 100);
3453 ngx_conf_merge_msec_value(conf->lingering_time,
3454 prev->lingering_time, 30000);
3455 ngx_conf_merge_msec_value(conf->lingering_timeout,
3456 prev->lingering_timeout, 5000);
3457 ngx_conf_merge_msec_value(conf->resolver_timeout,
3458 prev->resolver_timeout, 30000);
3460 if (conf->resolver == NULL) {
3462 if (prev->resolver == NULL) {
3465 * create dummy resolver in http {} context
3466 * to inherit it in all servers
3469 prev->resolver = ngx_resolver_create(cf, NULL);
3470 if (prev->resolver == NULL) {
3471 return NGX_CONF_ERROR;
3475 conf->resolver = prev->resolver;
3478 if (ngx_conf_merge_path_value(cf, &conf->client_body_temp_path,
3479 prev->client_body_temp_path,
3480 &ngx_http_client_temp_path)
3481 != NGX_OK)
3483 return NGX_CONF_ERROR;
3486 ngx_conf_merge_value(conf->reset_timedout_connection,
3487 prev->reset_timedout_connection, 0);
3488 ngx_conf_merge_value(conf->server_name_in_redirect,
3489 prev->server_name_in_redirect, 1);
3490 ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
3491 ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
3492 ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
3493 ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
3494 ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0);
3495 ngx_conf_merge_value(conf->recursive_error_pages,
3496 prev->recursive_error_pages, 0);
3497 ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
3498 ngx_conf_merge_value(conf->chunked_transfer_encoding,
3499 prev->chunked_transfer_encoding, 1);
3501 ngx_conf_merge_ptr_value(conf->open_file_cache,
3502 prev->open_file_cache, NULL);
3504 ngx_conf_merge_sec_value(conf->open_file_cache_valid,
3505 prev->open_file_cache_valid, 60);
3507 ngx_conf_merge_uint_value(conf->open_file_cache_min_uses,
3508 prev->open_file_cache_min_uses, 1);
3510 ngx_conf_merge_sec_value(conf->open_file_cache_errors,
3511 prev->open_file_cache_errors, 0);
3513 ngx_conf_merge_sec_value(conf->open_file_cache_events,
3514 prev->open_file_cache_events, 0);
3516 #if (NGX_HTTP_GZIP)
3518 ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
3519 ngx_conf_merge_uint_value(conf->gzip_http_version, prev->gzip_http_version,
3520 NGX_HTTP_VERSION_11);
3521 ngx_conf_merge_bitmask_value(conf->gzip_proxied, prev->gzip_proxied,
3522 (NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));
3524 #if (NGX_PCRE)
3525 ngx_conf_merge_ptr_value(conf->gzip_disable, prev->gzip_disable, NULL);
3526 #endif
3528 if (conf->gzip_disable_msie6 == 3) {
3529 conf->gzip_disable_msie6 =
3530 (prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6;
3533 #endif
3535 #if (NGX_STATUS)
3536 if (prev->request_counter) {
3538 conf->request_counter = prev->request_counter;
3541 #endif
3543 ngx_conf_merge_uint_value(conf->use_args_from_post, prev->use_args_from_post,
3544 NGX_HTTP_USE_ARGS_FROM_POST_LAST);
3546 return NGX_CONF_OK;
3550 static ngx_int_t
3551 ngx_http_core_read_request_body(ngx_http_request_t *r)
3553 ngx_int_t rc;
3555 ngx_http_core_loc_conf_t *clcf;
3557 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
3559 if (clcf->use_args_from_post == NGX_HTTP_USE_ARGS_FROM_POST_OFF) {
3560 return NGX_DECLINED;
3563 if (r->method != NGX_HTTP_POST) {
3564 return NGX_DECLINED;
3567 if (!r->headers_in.content_length_n || r->request_body) {
3568 return NGX_DECLINED;
3571 r->request_body_in_single_buf = 1;
3573 rc = ngx_http_read_client_request_body(r, ngx_http_core_run_phases);
3575 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
3576 return rc;
3579 return NGX_DONE;
3583 static char *
3584 ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3586 ngx_http_core_srv_conf_t *cscf = conf;
3588 ngx_str_t *value, size;
3589 ngx_url_t u;
3590 ngx_uint_t n;
3591 ngx_http_listen_opt_t lsopt;
3593 cscf->listen = 1;
3595 value = cf->args->elts;
3597 ngx_memzero(&u, sizeof(ngx_url_t));
3599 u.url = value[1];
3600 u.listen = 1;
3601 u.default_port = 80;
3603 #if (NGX_STATUS)
3604 cscf->listen_string = value[1];
3605 #endif
3607 if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
3608 if (u.err) {
3609 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3610 "%s in \"%V\" of the \"listen\" directive",
3611 u.err, &u.url);
3614 return NGX_CONF_ERROR;
3617 ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));
3619 ngx_memcpy(&lsopt.u.sockaddr, u.sockaddr, u.socklen);
3621 lsopt.socklen = u.socklen;
3622 lsopt.backlog = NGX_LISTEN_BACKLOG;
3623 lsopt.rcvbuf = -1;
3624 lsopt.sndbuf = -1;
3625 lsopt.wildcard = u.wildcard;
3627 (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr,
3628 NGX_SOCKADDR_STRLEN, 1);
3630 for (n = 2; n < cf->args->nelts; n++) {
3632 if (ngx_strcmp(value[n].data, "default_server") == 0
3633 || ngx_strcmp(value[n].data, "default") == 0)
3635 lsopt.default_server = 1;
3636 continue;
3639 if (ngx_strcmp(value[n].data, "bind") == 0) {
3640 lsopt.set = 1;
3641 lsopt.bind = 1;
3642 continue;
3645 if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
3646 lsopt.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
3647 lsopt.set = 1;
3648 lsopt.bind = 1;
3650 if (lsopt.backlog == NGX_ERROR || lsopt.backlog == 0) {
3651 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3652 "invalid backlog \"%V\"", &value[n]);
3653 return NGX_CONF_ERROR;
3656 continue;
3659 if (ngx_strncmp(value[n].data, "rcvbuf=", 7) == 0) {
3660 size.len = value[n].len - 7;
3661 size.data = value[n].data + 7;
3663 lsopt.rcvbuf = ngx_parse_size(&size);
3664 lsopt.set = 1;
3665 lsopt.bind = 1;
3667 if (lsopt.rcvbuf == NGX_ERROR) {
3668 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3669 "invalid rcvbuf \"%V\"", &value[n]);
3670 return NGX_CONF_ERROR;
3673 continue;
3676 if (ngx_strncmp(value[n].data, "sndbuf=", 7) == 0) {
3677 size.len = value[n].len - 7;
3678 size.data = value[n].data + 7;
3680 lsopt.sndbuf = ngx_parse_size(&size);
3681 lsopt.set = 1;
3682 lsopt.bind = 1;
3684 if (lsopt.sndbuf == NGX_ERROR) {
3685 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3686 "invalid sndbuf \"%V\"", &value[n]);
3687 return NGX_CONF_ERROR;
3690 continue;
3693 if (ngx_strncmp(value[n].data, "accept_filter=", 14) == 0) {
3694 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
3695 lsopt.accept_filter = (char *) &value[n].data[14];
3696 lsopt.set = 1;
3697 lsopt.bind = 1;
3698 #else
3699 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3700 "accept filters \"%V\" are not supported "
3701 "on this platform, ignored",
3702 &value[n]);
3703 #endif
3704 continue;
3707 if (ngx_strcmp(value[n].data, "deferred") == 0) {
3708 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
3709 lsopt.deferred_accept = 1;
3710 lsopt.set = 1;
3711 lsopt.bind = 1;
3712 #else
3713 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3714 "the deferred accept is not supported "
3715 "on this platform, ignored");
3716 #endif
3717 continue;
3720 if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
3721 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
3722 struct sockaddr *sa;
3724 sa = &lsopt.u.sockaddr;
3726 if (sa->sa_family == AF_INET6) {
3728 if (ngx_strcmp(&value[n].data[10], "n") == 0) {
3729 lsopt.ipv6only = 1;
3731 } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
3732 lsopt.ipv6only = 2;
3734 } else {
3735 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3736 "invalid ipv6only flags \"%s\"",
3737 &value[n].data[9]);
3738 return NGX_CONF_ERROR;
3741 lsopt.set = 1;
3742 lsopt.bind = 1;
3744 } else {
3745 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3746 "ipv6only is not supported "
3747 "on addr \"%s\", ignored", lsopt.addr);
3750 continue;
3751 #else
3752 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3753 "bind ipv6only is not supported "
3754 "on this platform");
3755 return NGX_CONF_ERROR;
3756 #endif
3759 if (ngx_strcmp(value[n].data, "ssl") == 0) {
3760 #if (NGX_HTTP_SSL)
3761 lsopt.set = 1;
3762 lsopt.ssl = 1;
3763 continue;
3764 #else
3765 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3766 "the \"ssl\" parameter requires "
3767 "ngx_http_ssl_module");
3768 return NGX_CONF_ERROR;
3769 #endif
3772 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3773 "the invalid \"%V\" parameter", &value[n]);
3774 return NGX_CONF_ERROR;
3777 if (ngx_http_add_listen(cf, cscf, &lsopt) == NGX_OK) {
3778 return NGX_CONF_OK;
3781 return NGX_CONF_ERROR;
3785 static char *
3786 ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3788 ngx_http_core_srv_conf_t *cscf = conf;
3790 u_char ch;
3791 ngx_str_t *value, name;
3792 ngx_uint_t i;
3793 ngx_http_server_name_t *sn;
3795 value = cf->args->elts;
3797 ch = value[1].data[0];
3799 if (cscf->server_name.data == NULL) {
3800 if (value[1].len) {
3801 name = value[1];
3803 if (ch == '.') {
3804 name.len--;
3805 name.data++;
3808 cscf->server_name.len = name.len;
3809 cscf->server_name.data = ngx_pstrdup(cf->pool, &name);
3810 if (cscf->server_name.data == NULL) {
3811 return NGX_CONF_ERROR;
3814 } else {
3815 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3816 "the first server name must not be empty");
3817 return NGX_CONF_ERROR;
3821 for (i = 1; i < cf->args->nelts; i++) {
3823 ch = value[i].data[0];
3825 if ((ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
3826 || (ch == '.' && value[i].len < 2))
3828 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3829 "server name \"%V\" is invalid", &value[i]);
3830 return NGX_CONF_ERROR;
3833 if (ngx_strchr(value[i].data, '/')) {
3834 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
3835 "server name \"%V\" has strange symbols",
3836 &value[i]);
3839 if (value[i].len == 1 && ch == '*') {
3840 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3841 "\"server_name *\" is unsupported, use "
3842 "\"server_name_in_redirect off\" instead");
3843 return NGX_CONF_ERROR;
3846 sn = ngx_array_push(&cscf->server_names);
3847 if (sn == NULL) {
3848 return NGX_CONF_ERROR;
3851 #if (NGX_PCRE)
3852 sn->regex = NULL;
3853 #endif
3854 sn->server = cscf;
3855 sn->name = value[i];
3857 if (value[i].data[0] != '~') {
3858 ngx_strlow(sn->name.data, sn->name.data, sn->name.len);
3859 continue;
3862 #if (NGX_PCRE)
3864 u_char *p;
3865 ngx_regex_compile_t rc;
3866 u_char errstr[NGX_MAX_CONF_ERRSTR];
3868 if (value[i].len == 1) {
3869 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3870 "empty regex in server name \"%V\"", &value[i]);
3871 return NGX_CONF_ERROR;
3874 value[i].len--;
3875 value[i].data++;
3877 ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
3879 rc.pattern = value[i];
3880 rc.err.len = NGX_MAX_CONF_ERRSTR;
3881 rc.err.data = errstr;
3883 for (p = value[i].data; p < value[i].data + value[i].len; p++) {
3884 if (*p >= 'A' && *p <= 'Z') {
3885 rc.options = NGX_REGEX_CASELESS;
3886 break;
3890 sn->regex = ngx_http_regex_compile(cf, &rc);
3891 if (sn->regex == NULL) {
3892 return NGX_CONF_ERROR;
3895 sn->name = value[i];
3896 cscf->captures = (rc.captures > 0);
3898 #else
3899 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3900 "the using of the regex \"%V\" "
3901 "requires PCRE library", &value[i]);
3903 return NGX_CONF_ERROR;
3904 #endif
3907 return NGX_CONF_OK;
3911 static char *
3912 ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3914 ngx_http_core_loc_conf_t *clcf = conf;
3916 ngx_str_t *value;
3917 ngx_int_t alias;
3918 ngx_uint_t n;
3919 ngx_http_script_compile_t sc;
3921 alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;
3923 if (clcf->root.data) {
3925 if ((clcf->alias != 0) == alias) {
3926 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3927 "\"%V\" directive is duplicate",
3928 &cmd->name);
3929 } else {
3930 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3931 "\"%V\" directive is duplicate, "
3932 "\"%s\" directive is specified before",
3933 &cmd->name, clcf->alias ? "alias" : "root");
3936 return NGX_CONF_ERROR;
3939 if (clcf->named && alias) {
3940 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3941 "the \"alias\" directive may not be used "
3942 "inside named location");
3944 return NGX_CONF_ERROR;
3947 value = cf->args->elts;
3949 if (ngx_strstr(value[1].data, "$document_root")
3950 || ngx_strstr(value[1].data, "${document_root}"))
3952 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3953 "the $document_root variable may not be used "
3954 "in the \"%V\" directive",
3955 &cmd->name);
3957 return NGX_CONF_ERROR;
3960 if (ngx_strstr(value[1].data, "$realpath_root")
3961 || ngx_strstr(value[1].data, "${realpath_root}"))
3963 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3964 "the $realpath_root variable may not be used "
3965 "in the \"%V\" directive",
3966 &cmd->name);
3968 return NGX_CONF_ERROR;
3971 clcf->alias = alias ? clcf->name.len : 0;
3972 clcf->root = value[1];
3974 if (!alias && clcf->root.data[clcf->root.len - 1] == '/') {
3975 clcf->root.len--;
3978 if (clcf->root.data[0] != '$') {
3979 if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) {
3980 return NGX_CONF_ERROR;
3984 n = ngx_http_script_variables_count(&clcf->root);
3986 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
3988 if (n) {
3989 sc.cf = cf;
3990 sc.source = &clcf->root;
3991 sc.lengths = &clcf->root_lengths;
3992 sc.values = &clcf->root_values;
3993 sc.variables = n;
3994 sc.complete_lengths = 1;
3995 sc.complete_values = 1;
3997 if (ngx_http_script_compile(&sc) != NGX_OK) {
3998 return NGX_CONF_ERROR;
4002 return NGX_CONF_OK;
4006 static ngx_http_method_name_t ngx_methods_names[] = {
4007 { (u_char *) "GET", (uint32_t) ~NGX_HTTP_GET },
4008 { (u_char *) "HEAD", (uint32_t) ~NGX_HTTP_HEAD },
4009 { (u_char *) "POST", (uint32_t) ~NGX_HTTP_POST },
4010 { (u_char *) "PUT", (uint32_t) ~NGX_HTTP_PUT },
4011 { (u_char *) "DELETE", (uint32_t) ~NGX_HTTP_DELETE },
4012 { (u_char *) "MKCOL", (uint32_t) ~NGX_HTTP_MKCOL },
4013 { (u_char *) "COPY", (uint32_t) ~NGX_HTTP_COPY },
4014 { (u_char *) "MOVE", (uint32_t) ~NGX_HTTP_MOVE },
4015 { (u_char *) "OPTIONS", (uint32_t) ~NGX_HTTP_OPTIONS },
4016 { (u_char *) "PROPFIND" , (uint32_t) ~NGX_HTTP_PROPFIND },
4017 { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH },
4018 { (u_char *) "LOCK", (uint32_t) ~NGX_HTTP_LOCK },
4019 { (u_char *) "UNLOCK", (uint32_t) ~NGX_HTTP_UNLOCK },
4020 { (u_char *) "PATCH", (uint32_t) ~NGX_HTTP_PATCH },
4021 { NULL, 0 }
4025 static char *
4026 ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4028 ngx_http_core_loc_conf_t *pclcf = conf;
4030 char *rv;
4031 void *mconf;
4032 ngx_str_t *value;
4033 ngx_uint_t i;
4034 ngx_conf_t save;
4035 ngx_http_module_t *module;
4036 ngx_http_conf_ctx_t *ctx, *pctx;
4037 ngx_http_method_name_t *name;
4038 ngx_http_core_loc_conf_t *clcf;
4040 if (pclcf->limit_except) {
4041 return "duplicate";
4044 pclcf->limit_except = 0xffffffff;
4046 value = cf->args->elts;
4048 for (i = 1; i < cf->args->nelts; i++) {
4049 for (name = ngx_methods_names; name->name; name++) {
4051 if (ngx_strcasecmp(value[i].data, name->name) == 0) {
4052 pclcf->limit_except &= name->method;
4053 goto next;
4057 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4058 "invalid method \"%V\"", &value[i]);
4059 return NGX_CONF_ERROR;
4061 next:
4062 continue;
4065 if (!(pclcf->limit_except & NGX_HTTP_GET)) {
4066 pclcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
4069 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
4070 if (ctx == NULL) {
4071 return NGX_CONF_ERROR;
4074 pctx = cf->ctx;
4075 ctx->main_conf = pctx->main_conf;
4076 ctx->srv_conf = pctx->srv_conf;
4078 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
4079 if (ctx->loc_conf == NULL) {
4080 return NGX_CONF_ERROR;
4083 for (i = 0; ngx_modules[i]; i++) {
4084 if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
4085 continue;
4088 module = ngx_modules[i]->ctx;
4090 if (module->create_loc_conf) {
4092 mconf = module->create_loc_conf(cf);
4093 if (mconf == NULL) {
4094 return NGX_CONF_ERROR;
4097 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
4102 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
4103 pclcf->limit_except_loc_conf = ctx->loc_conf;
4104 clcf->loc_conf = ctx->loc_conf;
4105 clcf->name = pclcf->name;
4106 clcf->noname = 1;
4108 if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
4109 return NGX_CONF_ERROR;
4112 save = *cf;
4113 cf->ctx = ctx;
4114 cf->cmd_type = NGX_HTTP_LMT_CONF;
4116 rv = ngx_conf_parse(cf, NULL);
4118 *cf = save;
4120 return rv;
4124 static char *
4125 ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4127 ngx_http_core_loc_conf_t *clcf = conf;
4129 ngx_str_t *value;
4131 if (clcf->directio != NGX_CONF_UNSET) {
4132 return "is duplicate";
4135 value = cf->args->elts;
4137 if (ngx_strcmp(value[1].data, "off") == 0) {
4138 clcf->directio = NGX_OPEN_FILE_DIRECTIO_OFF;
4139 return NGX_CONF_OK;
4142 clcf->directio = ngx_parse_offset(&value[1]);
4143 if (clcf->directio == (off_t) NGX_ERROR) {
4144 return "invalid value";
4147 return NGX_CONF_OK;
4151 static char *
4152 ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4154 ngx_http_core_loc_conf_t *clcf = conf;
4156 u_char *p;
4157 ngx_int_t overwrite;
4158 ngx_str_t *value, uri, args;
4159 ngx_uint_t i, n;
4160 ngx_http_err_page_t *err;
4161 ngx_http_complex_value_t cv;
4162 ngx_http_compile_complex_value_t ccv;
4164 if (clcf->error_pages == NULL) {
4165 clcf->error_pages = ngx_array_create(cf->pool, 4,
4166 sizeof(ngx_http_err_page_t));
4167 if (clcf->error_pages == NULL) {
4168 return NGX_CONF_ERROR;
4172 value = cf->args->elts;
4174 i = cf->args->nelts - 2;
4176 if (value[i].data[0] == '=') {
4177 if (i == 1) {
4178 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4179 "invalid value \"%V\"", &value[i]);
4180 return NGX_CONF_ERROR;
4183 if (value[i].len > 1) {
4184 overwrite = ngx_atoi(&value[i].data[1], value[i].len - 1);
4186 if (overwrite == NGX_ERROR) {
4187 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4188 "invalid value \"%V\"", &value[i]);
4189 return NGX_CONF_ERROR;
4192 } else {
4193 overwrite = 0;
4196 n = 2;
4198 } else {
4199 overwrite = -1;
4200 n = 1;
4203 uri = value[cf->args->nelts - 1];
4205 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
4207 ccv.cf = cf;
4208 ccv.value = &uri;
4209 ccv.complex_value = &cv;
4211 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
4212 return NGX_CONF_ERROR;
4215 ngx_str_null(&args);
4217 if (cv.lengths == NULL && uri.data[0] == '/') {
4218 p = (u_char *) ngx_strchr(uri.data, '?');
4220 if (p) {
4221 cv.value.len = p - uri.data;
4222 cv.value.data = uri.data;
4223 p++;
4224 args.len = (uri.data + uri.len) - p;
4225 args.data = p;
4229 for (i = 1; i < cf->args->nelts - n; i++) {
4230 err = ngx_array_push(clcf->error_pages);
4231 if (err == NULL) {
4232 return NGX_CONF_ERROR;
4235 err->status = ngx_atoi(value[i].data, value[i].len);
4237 if (err->status == NGX_ERROR || err->status == 499) {
4238 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4239 "invalid value \"%V\"", &value[i]);
4240 return NGX_CONF_ERROR;
4243 if (err->status < 300 || err->status > 599) {
4244 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4245 "value \"%V\" must be between 300 and 599",
4246 &value[i]);
4247 return NGX_CONF_ERROR;
4250 if (overwrite >= 0) {
4251 err->overwrite = overwrite;
4253 } else {
4254 switch (err->status) {
4255 case NGX_HTTP_TO_HTTPS:
4256 case NGX_HTTPS_CERT_ERROR:
4257 case NGX_HTTPS_NO_CERT:
4258 err->overwrite = NGX_HTTP_BAD_REQUEST;
4259 break;
4261 default:
4262 err->overwrite = err->status;
4263 break;
4267 err->value = cv;
4268 err->args = args;
4271 return NGX_CONF_OK;
4275 static char *
4276 ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4278 ngx_http_core_loc_conf_t *clcf = conf;
4280 ngx_str_t *value;
4281 ngx_int_t code;
4282 ngx_uint_t i, n;
4283 ngx_http_try_file_t *tf;
4284 ngx_http_script_compile_t sc;
4285 ngx_http_core_main_conf_t *cmcf;
4287 if (clcf->try_files) {
4288 return "is duplicate";
4291 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
4293 cmcf->try_files = 1;
4295 tf = ngx_pcalloc(cf->pool, cf->args->nelts * sizeof(ngx_http_try_file_t));
4296 if (tf == NULL) {
4297 return NGX_CONF_ERROR;
4300 clcf->try_files = tf;
4302 value = cf->args->elts;
4304 for (i = 0; i < cf->args->nelts - 1; i++) {
4306 tf[i].name = value[i + 1];
4308 if (tf[i].name.data[tf[i].name.len - 1] == '/') {
4309 tf[i].test_dir = 1;
4310 tf[i].name.len--;
4311 tf[i].name.data[tf[i].name.len] = '\0';
4314 n = ngx_http_script_variables_count(&tf[i].name);
4316 if (n) {
4317 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
4319 sc.cf = cf;
4320 sc.source = &tf[i].name;
4321 sc.lengths = &tf[i].lengths;
4322 sc.values = &tf[i].values;
4323 sc.variables = n;
4324 sc.complete_lengths = 1;
4325 sc.complete_values = 1;
4327 if (ngx_http_script_compile(&sc) != NGX_OK) {
4328 return NGX_CONF_ERROR;
4331 } else {
4332 /* add trailing '\0' to length */
4333 tf[i].name.len++;
4337 if (tf[i - 1].name.data[0] == '=') {
4339 code = ngx_atoi(tf[i - 1].name.data + 1, tf[i - 1].name.len - 2);
4341 if (code == NGX_ERROR) {
4342 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4343 "invalid code \"%*s\"",
4344 tf[i - 1].name.len - 1, tf[i - 1].name.data);
4345 return NGX_CONF_ERROR;
4348 tf[i].code = code;
4351 return NGX_CONF_OK;
4355 static char *
4356 ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4358 ngx_http_core_loc_conf_t *clcf = conf;
4360 time_t inactive;
4361 ngx_str_t *value, s;
4362 ngx_int_t max;
4363 ngx_uint_t i;
4365 if (clcf->open_file_cache != NGX_CONF_UNSET_PTR) {
4366 return "is duplicate";
4369 value = cf->args->elts;
4371 max = 0;
4372 inactive = 60;
4374 for (i = 1; i < cf->args->nelts; i++) {
4376 if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
4378 max = ngx_atoi(value[i].data + 4, value[i].len - 4);
4379 if (max == NGX_ERROR) {
4380 goto failed;
4383 continue;
4386 if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
4388 s.len = value[i].len - 9;
4389 s.data = value[i].data + 9;
4391 inactive = ngx_parse_time(&s, 1);
4392 if (inactive < 0) {
4393 goto failed;
4396 continue;
4399 if (ngx_strcmp(value[i].data, "off") == 0) {
4401 clcf->open_file_cache = NULL;
4403 continue;
4406 failed:
4408 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4409 "invalid \"open_file_cache\" parameter \"%V\"",
4410 &value[i]);
4411 return NGX_CONF_ERROR;
4414 if (clcf->open_file_cache == NULL) {
4415 return NGX_CONF_OK;
4418 if (max == 0) {
4419 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4420 "\"open_file_cache\" must have \"max\" parameter");
4421 return NGX_CONF_ERROR;
4424 clcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
4425 if (clcf->open_file_cache) {
4426 return NGX_CONF_OK;
4429 return NGX_CONF_ERROR;
4433 static char *
4434 ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4436 ngx_http_core_loc_conf_t *clcf = conf;
4438 ngx_str_t *value;
4440 if (clcf->error_log) {
4441 return "is duplicate";
4444 value = cf->args->elts;
4446 clcf->error_log = ngx_log_create(cf->cycle, &value[1]);
4447 if (clcf->error_log == NULL) {
4448 return NGX_CONF_ERROR;
4451 if (cf->args->nelts == 2) {
4452 clcf->error_log->log_level = NGX_LOG_ERR;
4453 return NGX_CONF_OK;
4456 return ngx_log_set_levels(cf, clcf->error_log);
4460 static char *
4461 ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4463 ngx_http_core_loc_conf_t *clcf = conf;
4465 ngx_str_t *value;
4467 if (clcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
4468 return "is duplicate";
4471 value = cf->args->elts;
4473 clcf->keepalive_timeout = ngx_parse_time(&value[1], 0);
4475 if (clcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
4476 return "invalid value";
4479 if (clcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) {
4480 return "value must be less than 597 hours";
4483 if (cf->args->nelts == 2) {
4484 return NGX_CONF_OK;
4487 clcf->keepalive_header = ngx_parse_time(&value[2], 1);
4489 if (clcf->keepalive_header == NGX_ERROR) {
4490 return "invalid value";
4493 if (clcf->keepalive_header == NGX_PARSE_LARGE_TIME) {
4494 return "value must be less than 68 years";
4497 return NGX_CONF_OK;
4501 static char *
4502 ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4504 ngx_http_core_loc_conf_t *clcf = conf;
4506 if (clcf->internal != NGX_CONF_UNSET) {
4507 return "is duplicate";
4510 clcf->internal = 1;
4512 return NGX_CONF_OK;
4516 static char *
4517 ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4519 ngx_http_core_loc_conf_t *clcf = conf;
4521 ngx_url_t u;
4522 ngx_str_t *value;
4524 if (clcf->resolver) {
4525 return "is duplicate";
4528 value = cf->args->elts;
4530 ngx_memzero(&u, sizeof(ngx_url_t));
4532 u.host = value[1];
4533 u.port = 53;
4535 if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
4536 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err);
4537 return NGX_CONF_ERROR;
4540 clcf->resolver = ngx_resolver_create(cf, &u.addrs[0]);
4541 if (clcf->resolver == NULL) {
4542 return NGX_OK;
4545 return NGX_CONF_OK;
4549 #if (NGX_HTTP_GZIP)
4551 static char *
4552 ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4554 ngx_http_core_loc_conf_t *clcf = conf;
4556 #if (NGX_PCRE)
4558 ngx_str_t *value;
4559 ngx_uint_t i;
4560 ngx_regex_elt_t *re;
4561 ngx_regex_compile_t rc;
4562 u_char errstr[NGX_MAX_CONF_ERRSTR];
4564 if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
4565 clcf->gzip_disable = ngx_array_create(cf->pool, 2,
4566 sizeof(ngx_regex_elt_t));
4567 if (clcf->gzip_disable == NULL) {
4568 return NGX_CONF_ERROR;
4572 value = cf->args->elts;
4574 ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
4576 rc.pool = cf->pool;
4577 rc.err.len = NGX_MAX_CONF_ERRSTR;
4578 rc.err.data = errstr;
4580 for (i = 1; i < cf->args->nelts; i++) {
4582 if (ngx_strcmp(value[1].data, "msie6") == 0) {
4583 clcf->gzip_disable_msie6 = 1;
4584 continue;
4587 re = ngx_array_push(clcf->gzip_disable);
4588 if (re == NULL) {
4589 return NGX_CONF_ERROR;
4592 rc.pattern = value[1];
4593 rc.options = NGX_REGEX_CASELESS;
4595 if (ngx_regex_compile(&rc) != NGX_OK) {
4596 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
4597 return NGX_CONF_ERROR;
4600 re->regex = rc.regex;
4601 re->name = value[i].data;
4604 return NGX_CONF_OK;
4606 #else
4607 ngx_str_t *value;
4609 value = cf->args->elts;
4611 if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "msie6") == 0) {
4612 clcf->gzip_disable_msie6 = 1;
4613 return NGX_CONF_OK;
4616 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4617 "without PCRE library \"gzip_disable\" supports "
4618 "builtin \"msie6\" mask only");
4620 return NGX_CONF_ERROR;
4621 #endif
4624 #endif
4627 #if (NGX_STATUS)
4629 static char *
4630 ngx_http_status_capture(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4632 ngx_int_t n, p;
4633 ngx_str_t *value;
4634 ngx_uint_t i;
4635 ngx_str_t *status_line;
4636 ngx_status_counter_t *counter;
4637 ngx_http_core_loc_conf_t *clcf;
4639 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
4641 value = cf->args->elts;
4643 clcf->status_counters = ngx_pcalloc(cf->pool,
4644 sizeof(ngx_status_counter_t *) * ngx_http_status_len());
4646 if (clcf->status_counters == NULL) {
4647 return NGX_CONF_ERROR;
4650 for (i = 1; i < cf->args->nelts; i++) {
4652 n = ngx_atoi(value[i].data, value[i].len);
4653 if (n == NGX_ERROR) {
4654 return NGX_CONF_ERROR;
4657 status_line = ngx_http_get_status(n);
4659 if (status_line == NULL) {
4660 continue;
4663 p = ngx_http_get_status_position(n);
4665 counter = ngx_pcalloc(cf->pool, sizeof(ngx_status_counter_t));
4666 if (counter == NULL) {
4667 return NGX_CONF_ERROR;
4670 #if (NGX_STATUS_TXT) || (NGX_STATUS_XML)
4671 counter->caption = *status_line;
4672 #endif
4674 #if (NGX_STATUS_XML)
4675 counter->tag_name.len = sizeof("code") - 1;
4676 counter->tag_name.data = (u_char *)"code";
4677 counter->tag_value = value[i];
4678 #endif
4680 if (ngx_status_add_child(cf->cycle, clcf->request_counter,
4681 counter) != NGX_OK) {
4682 return NGX_CONF_ERROR;
4685 clcf->status_counters[p] = counter;
4688 return NGX_CONF_OK;
4691 #endif
4694 static char *
4695 ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
4697 #if (NGX_FREEBSD)
4698 ssize_t *np = data;
4700 if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
4701 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4702 "\"send_lowat\" must be less than %d "
4703 "(sysctl net.inet.tcp.sendspace)",
4704 ngx_freebsd_net_inet_tcp_sendspace);
4706 return NGX_CONF_ERROR;
4709 #elif !(NGX_HAVE_SO_SNDLOWAT)
4710 ssize_t *np = data;
4712 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
4713 "\"send_lowat\" is not supported, ignored");
4715 *np = 0;
4717 #endif
4719 return NGX_CONF_OK;
4723 static char *
4724 ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data)
4726 size_t *sp = data;
4728 if (*sp < NGX_MIN_POOL_SIZE) {
4729 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4730 "the pool size must be no less than %uz",
4731 NGX_MIN_POOL_SIZE);
4732 return NGX_CONF_ERROR;
4735 if (*sp % NGX_POOL_ALIGNMENT) {
4736 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4737 "the pool size must be a multiple of %uz",
4738 NGX_POOL_ALIGNMENT);
4739 return NGX_CONF_ERROR;
4742 return NGX_CONF_OK;