~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/http/ngx_http_core_module.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 #include <ngx_http.h>
 10 
 11 
 12 typedef struct {
 13     u_char    *name;
 14     uint32_t   method;
 15 } ngx_http_method_name_t;
 16 
 17 
 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
 21 
 22 
 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);
 26 
 27 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
 28 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
 29 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
 30 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
 31 static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
 32     void *parent, void *child);
 33 static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf);
 34 static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
 35     void *parent, void *child);
 36 
 37 static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
 38     void *dummy);
 39 static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
 40     void *dummy);
 41 static ngx_int_t ngx_http_core_regex_location(ngx_conf_t *cf,
 42     ngx_http_core_loc_conf_t *clcf, ngx_str_t *regex, ngx_uint_t caseless);
 43 
 44 static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
 45     void *conf);
 46 static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy,
 47     void *conf);
 48 
 49 static char *ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
 50     void *conf);
 51 static char *ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
 52     void *conf);
 53 static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 54 static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
 55     void *conf);
 56 static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd,
 57     void *conf);
 58 static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
 59     void *conf);
 60 static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
 61     void *conf);
 62 static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
 63     void *conf);
 64 static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
 65     void *conf);
 66 static char *ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
 67     void *conf);
 68 static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
 69     void *conf);
 70 static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
 71     void *conf);
 72 #if (NGX_HTTP_GZIP)
 73 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
 74     void *conf);
 75 #endif
 76 
 77 static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
 78 static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data);
 79 
 80 static ngx_conf_post_t  ngx_http_core_lowat_post =
 81     { ngx_http_core_lowat_check };
 82 
 83 static ngx_conf_post_handler_pt  ngx_http_core_pool_size_p =
 84     ngx_http_core_pool_size;
 85 
 86 static ngx_conf_deprecated_t  ngx_conf_deprecated_optimize_server_names = {
 87     ngx_conf_deprecated, "optimize_server_names", "server_name_in_redirect"
 88 };
 89 
 90 static ngx_conf_deprecated_t  ngx_conf_deprecated_open_file_cache_retest = {
 91     ngx_conf_deprecated, "open_file_cache_retest", "open_file_cache_valid"
 92 };
 93 
 94 static ngx_conf_deprecated_t  ngx_conf_deprecated_satisfy_any = {
 95     ngx_conf_deprecated, "satisfy_any", "satisfy"
 96 };
 97 
 98 
 99 static ngx_conf_enum_t  ngx_http_core_request_body_in_file[] = {
100     { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF },
101     { ngx_string("on"), NGX_HTTP_REQUEST_BODY_FILE_ON },
102     { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN },
103     { ngx_null_string, 0 }
104 };
105 
106 
107 #if (NGX_HAVE_FILE_AIO)
108 
109 static ngx_conf_enum_t  ngx_http_core_aio[] = {
110     { ngx_string("off"), NGX_HTTP_AIO_OFF  },
111     { ngx_string("on"), NGX_HTTP_AIO_ON },
112 #if (NGX_HAVE_AIO_SENDFILE)
113     { ngx_string("sendfile"), NGX_HTTP_AIO_SENDFILE },
114 #endif
115     { ngx_null_string, 0 }
116 };
117 
118 #endif
119 
120 
121 static ngx_conf_enum_t  ngx_http_core_satisfy[] = {
122     { ngx_string("all"), NGX_HTTP_SATISFY_ALL },
123     { ngx_string("any"), NGX_HTTP_SATISFY_ANY },
124     { ngx_null_string, 0 }
125 };
126 
127 
128 static ngx_conf_enum_t  ngx_http_core_if_modified_since[] = {
129     { ngx_string("off"), NGX_HTTP_IMS_OFF },
130     { ngx_string("exact"), NGX_HTTP_IMS_EXACT },
131     { ngx_string("before"), NGX_HTTP_IMS_BEFORE },
132     { ngx_null_string, 0 }
133 };
134 
135 
136 static ngx_path_init_t  ngx_http_client_temp_path = {
137     ngx_string(NGX_HTTP_CLIENT_TEMP_PATH), { 0, 0, 0 }
138 };
139 
140 
141 #if (NGX_HTTP_GZIP)
142 
143 static ngx_conf_enum_t  ngx_http_gzip_http_version[] = {
144     { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
145     { ngx_string("1.1"), NGX_HTTP_VERSION_11 },
146     { ngx_null_string, 0 }
147 };
148 
149 
150 static ngx_conf_bitmask_t  ngx_http_gzip_proxied_mask[] = {
151     { ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF },
152     { ngx_string("expired"), NGX_HTTP_GZIP_PROXIED_EXPIRED },
153     { ngx_string("no-cache"), NGX_HTTP_GZIP_PROXIED_NO_CACHE },
154     { ngx_string("no-store"), NGX_HTTP_GZIP_PROXIED_NO_STORE },
155     { ngx_string("private"), NGX_HTTP_GZIP_PROXIED_PRIVATE },
156     { ngx_string("no_last_modified"), NGX_HTTP_GZIP_PROXIED_NO_LM },
157     { ngx_string("no_etag"), NGX_HTTP_GZIP_PROXIED_NO_ETAG },
158     { ngx_string("auth"), NGX_HTTP_GZIP_PROXIED_AUTH },
159     { ngx_string("any"), NGX_HTTP_GZIP_PROXIED_ANY },
160     { ngx_null_string, 0 }
161 };
162 
163 
164 static ngx_str_t  ngx_http_gzip_no_cache = ngx_string("no-cache");
165 static ngx_str_t  ngx_http_gzip_no_store = ngx_string("no-store");
166 static ngx_str_t  ngx_http_gzip_private = ngx_string("private");
167 
168 #endif
169 
170 
171 static ngx_command_t  ngx_http_core_commands[] = {
172 
173     { ngx_string("variables_hash_max_size"),
174       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
175       ngx_conf_set_num_slot,
176       NGX_HTTP_MAIN_CONF_OFFSET,
177       offsetof(ngx_http_core_main_conf_t, variables_hash_max_size),
178       NULL },
179 
180     { ngx_string("variables_hash_bucket_size"),
181       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
182       ngx_conf_set_num_slot,
183       NGX_HTTP_MAIN_CONF_OFFSET,
184       offsetof(ngx_http_core_main_conf_t, variables_hash_bucket_size),
185       NULL },
186 
187     { ngx_string("server_names_hash_max_size"),
188       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
189       ngx_conf_set_num_slot,
190       NGX_HTTP_MAIN_CONF_OFFSET,
191       offsetof(ngx_http_core_main_conf_t, server_names_hash_max_size),
192       NULL },
193 
194     { ngx_string("server_names_hash_bucket_size"),
195       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
196       ngx_conf_set_num_slot,
197       NGX_HTTP_MAIN_CONF_OFFSET,
198       offsetof(ngx_http_core_main_conf_t, server_names_hash_bucket_size),
199       NULL },
200 
201     { ngx_string("server"),
202       NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_MULTI|NGX_CONF_NOARGS,
203       ngx_http_core_server,
204       0,
205       0,
206       NULL },
207 
208     { ngx_string("connection_pool_size"),
209       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
210       ngx_conf_set_size_slot,
211       NGX_HTTP_SRV_CONF_OFFSET,
212       offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
213       &ngx_http_core_pool_size_p },
214 
215     { ngx_string("request_pool_size"),
216       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
217       ngx_conf_set_size_slot,
218       NGX_HTTP_SRV_CONF_OFFSET,
219       offsetof(ngx_http_core_srv_conf_t, request_pool_size),
220       &ngx_http_core_pool_size_p },
221 
222     { ngx_string("client_header_timeout"),
223       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
224       ngx_conf_set_msec_slot,
225       NGX_HTTP_SRV_CONF_OFFSET,
226       offsetof(ngx_http_core_srv_conf_t, client_header_timeout),
227       NULL },
228 
229     { ngx_string("client_header_buffer_size"),
230       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
231       ngx_conf_set_size_slot,
232       NGX_HTTP_SRV_CONF_OFFSET,
233       offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
234       NULL },
235 
236     { ngx_string("large_client_header_buffers"),
237       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
238       ngx_conf_set_bufs_slot,
239       NGX_HTTP_SRV_CONF_OFFSET,
240       offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
241       NULL },
242 
243     { ngx_string("optimize_server_names"),
244       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
245       ngx_conf_set_flag_slot,
246       NGX_HTTP_LOC_CONF_OFFSET,
247       offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect),
248       &ngx_conf_deprecated_optimize_server_names },
249 
250     { ngx_string("ignore_invalid_headers"),
251       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
252       ngx_conf_set_flag_slot,
253       NGX_HTTP_SRV_CONF_OFFSET,
254       offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
255       NULL },
256 
257     { ngx_string("merge_slashes"),
258       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
259       ngx_conf_set_flag_slot,
260       NGX_HTTP_SRV_CONF_OFFSET,
261       offsetof(ngx_http_core_srv_conf_t, merge_slashes),
262       NULL },
263 
264     { ngx_string("underscores_in_headers"),
265       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
266       ngx_conf_set_flag_slot,
267       NGX_HTTP_SRV_CONF_OFFSET,
268       offsetof(ngx_http_core_srv_conf_t, underscores_in_headers),
269       NULL },
270 
271     { ngx_string("location"),
272       NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
273       ngx_http_core_location,
274       NGX_HTTP_SRV_CONF_OFFSET,
275       0,
276       NULL },
277 
278     { ngx_string("listen"),
279       NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
280       ngx_http_core_listen,
281       NGX_HTTP_SRV_CONF_OFFSET,
282       0,
283       NULL },
284 
285     { ngx_string("server_name"),
286       NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
287       ngx_http_core_server_name,
288       NGX_HTTP_SRV_CONF_OFFSET,
289       0,
290       NULL },
291 
292     { ngx_string("types_hash_max_size"),
293       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
294       ngx_conf_set_num_slot,
295       NGX_HTTP_LOC_CONF_OFFSET,
296       offsetof(ngx_http_core_loc_conf_t, types_hash_max_size),
297       NULL },
298 
299     { ngx_string("types_hash_bucket_size"),
300       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
301       ngx_conf_set_num_slot,
302       NGX_HTTP_LOC_CONF_OFFSET,
303       offsetof(ngx_http_core_loc_conf_t, types_hash_bucket_size),
304       NULL },
305 
306     { ngx_string("types"),
307       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
308                                           |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
309       ngx_http_core_types,
310       NGX_HTTP_LOC_CONF_OFFSET,
311       0,
312       NULL },
313 
314     { ngx_string("default_type"),
315       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
316       ngx_conf_set_str_slot,
317       NGX_HTTP_LOC_CONF_OFFSET,
318       offsetof(ngx_http_core_loc_conf_t, default_type),
319       NULL },
320 
321     { ngx_string("root"),
322       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
323                         |NGX_CONF_TAKE1,
324       ngx_http_core_root,
325       NGX_HTTP_LOC_CONF_OFFSET,
326       0,
327       NULL },
328 
329     { ngx_string("alias"),
330       NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
331       ngx_http_core_root,
332       NGX_HTTP_LOC_CONF_OFFSET,
333       0,
334       NULL },
335 
336     { ngx_string("limit_except"),
337       NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE,
338       ngx_http_core_limit_except,
339       NGX_HTTP_LOC_CONF_OFFSET,
340       0,
341       NULL },
342 
343     { ngx_string("client_max_body_size"),
344       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
345       ngx_conf_set_off_slot,
346       NGX_HTTP_LOC_CONF_OFFSET,
347       offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
348       NULL },
349 
350     { ngx_string("client_body_buffer_size"),
351       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
352       ngx_conf_set_size_slot,
353       NGX_HTTP_LOC_CONF_OFFSET,
354       offsetof(ngx_http_core_loc_conf_t, client_body_buffer_size),
355       NULL },
356 
357     { ngx_string("client_body_timeout"),
358       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
359       ngx_conf_set_msec_slot,
360       NGX_HTTP_LOC_CONF_OFFSET,
361       offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
362       NULL },
363 
364     { ngx_string("client_body_temp_path"),
365       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
366       ngx_conf_set_path_slot,
367       NGX_HTTP_LOC_CONF_OFFSET,
368       offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
369       NULL },
370 
371     { ngx_string("client_body_in_file_only"),
372       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
373       ngx_conf_set_enum_slot,
374       NGX_HTTP_LOC_CONF_OFFSET,
375       offsetof(ngx_http_core_loc_conf_t, client_body_in_file_only),
376       &ngx_http_core_request_body_in_file },
377 
378     { ngx_string("client_body_in_single_buffer"),
379       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
380       ngx_conf_set_flag_slot,
381       NGX_HTTP_LOC_CONF_OFFSET,
382       offsetof(ngx_http_core_loc_conf_t, client_body_in_single_buffer),
383       NULL },
384 
385     { ngx_string("sendfile"),
386       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
387                         |NGX_CONF_TAKE1,
388       ngx_conf_set_flag_slot,
389       NGX_HTTP_LOC_CONF_OFFSET,
390       offsetof(ngx_http_core_loc_conf_t, sendfile),
391       NULL },
392 
393     { ngx_string("sendfile_max_chunk"),
394       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
395       ngx_conf_set_size_slot,
396       NGX_HTTP_LOC_CONF_OFFSET,
397       offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
398       NULL },
399 
400 #if (NGX_HAVE_FILE_AIO)
401 
402     { ngx_string("aio"),
403       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
404       ngx_conf_set_enum_slot,
405       NGX_HTTP_LOC_CONF_OFFSET,
406       offsetof(ngx_http_core_loc_conf_t, aio),
407       &ngx_http_core_aio },
408 
409 #endif
410 
411     { ngx_string("read_ahead"),
412       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
413       ngx_conf_set_size_slot,
414       NGX_HTTP_LOC_CONF_OFFSET,
415       offsetof(ngx_http_core_loc_conf_t, read_ahead),
416       NULL },
417 
418     { ngx_string("directio"),
419       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
420       ngx_http_core_directio,
421       NGX_HTTP_LOC_CONF_OFFSET,
422       0,
423       NULL },
424 
425     { ngx_string("directio_alignment"),
426       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
427       ngx_conf_set_off_slot,
428       NGX_HTTP_LOC_CONF_OFFSET,
429       offsetof(ngx_http_core_loc_conf_t, directio_alignment),
430       NULL },
431 
432     { ngx_string("tcp_nopush"),
433       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
434       ngx_conf_set_flag_slot,
435       NGX_HTTP_LOC_CONF_OFFSET,
436       offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
437       NULL },
438 
439     { ngx_string("tcp_nodelay"),
440       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
441       ngx_conf_set_flag_slot,
442       NGX_HTTP_LOC_CONF_OFFSET,
443       offsetof(ngx_http_core_loc_conf_t, tcp_nodelay),
444       NULL },
445 
446     { ngx_string("send_timeout"),
447       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
448       ngx_conf_set_msec_slot,
449       NGX_HTTP_LOC_CONF_OFFSET,
450       offsetof(ngx_http_core_loc_conf_t, send_timeout),
451       NULL },
452 
453     { ngx_string("send_lowat"),
454       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
455       ngx_conf_set_size_slot,
456       NGX_HTTP_LOC_CONF_OFFSET,
457       offsetof(ngx_http_core_loc_conf_t, send_lowat),
458       &ngx_http_core_lowat_post },
459 
460     { ngx_string("postpone_output"),
461       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
462       ngx_conf_set_size_slot,
463       NGX_HTTP_LOC_CONF_OFFSET,
464       offsetof(ngx_http_core_loc_conf_t, postpone_output),
465       NULL },
466 
467     { ngx_string("limit_rate"),
468       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
469                         |NGX_CONF_TAKE1,
470       ngx_conf_set_size_slot,
471       NGX_HTTP_LOC_CONF_OFFSET,
472       offsetof(ngx_http_core_loc_conf_t, limit_rate),
473       NULL },
474 
475     { ngx_string("limit_rate_after"),
476       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
477                         |NGX_CONF_TAKE1,
478       ngx_conf_set_size_slot,
479       NGX_HTTP_LOC_CONF_OFFSET,
480       offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
481       NULL },
482 
483     { ngx_string("keepalive_timeout"),
484       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
485       ngx_http_core_keepalive,
486       NGX_HTTP_LOC_CONF_OFFSET,
487       0,
488       NULL },
489 
490     { ngx_string("keepalive_requests"),
491       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
492       ngx_conf_set_num_slot,
493       NGX_HTTP_LOC_CONF_OFFSET,
494       offsetof(ngx_http_core_loc_conf_t, keepalive_requests),
495       NULL },
496 
497     { ngx_string("satisfy"),
498       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
499       ngx_conf_set_enum_slot,
500       NGX_HTTP_LOC_CONF_OFFSET,
501       offsetof(ngx_http_core_loc_conf_t, satisfy),
502       &ngx_http_core_satisfy },
503 
504     { ngx_string("satisfy_any"),
505       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
506       ngx_conf_set_flag_slot,
507       NGX_HTTP_LOC_CONF_OFFSET,
508       offsetof(ngx_http_core_loc_conf_t, satisfy),
509       &ngx_conf_deprecated_satisfy_any },
510 
511     { ngx_string("internal"),
512       NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
513       ngx_http_core_internal,
514       NGX_HTTP_LOC_CONF_OFFSET,
515       0,
516       NULL },
517 
518     { ngx_string("lingering_time"),
519       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
520       ngx_conf_set_msec_slot,
521       NGX_HTTP_LOC_CONF_OFFSET,
522       offsetof(ngx_http_core_loc_conf_t, lingering_time),
523       NULL },
524 
525     { ngx_string("lingering_timeout"),
526       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
527       ngx_conf_set_msec_slot,
528       NGX_HTTP_LOC_CONF_OFFSET,
529       offsetof(ngx_http_core_loc_conf_t, lingering_timeout),
530       NULL },
531 
532     { ngx_string("reset_timedout_connection"),
533       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
534       ngx_conf_set_flag_slot,
535       NGX_HTTP_LOC_CONF_OFFSET,
536       offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection),
537       NULL },
538 
539     { ngx_string("server_name_in_redirect"),
540       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
541       ngx_conf_set_flag_slot,
542       NGX_HTTP_LOC_CONF_OFFSET,
543       offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect),
544       NULL },
545 
546     { ngx_string("port_in_redirect"),
547       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
548       ngx_conf_set_flag_slot,
549       NGX_HTTP_LOC_CONF_OFFSET,
550       offsetof(ngx_http_core_loc_conf_t, port_in_redirect),
551       NULL },
552 
553     { ngx_string("msie_padding"),
554       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
555       ngx_conf_set_flag_slot,
556       NGX_HTTP_LOC_CONF_OFFSET,
557       offsetof(ngx_http_core_loc_conf_t, msie_padding),
558       NULL },
559 
560     { ngx_string("msie_refresh"),
561       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
562       ngx_conf_set_flag_slot,
563       NGX_HTTP_LOC_CONF_OFFSET,
564       offsetof(ngx_http_core_loc_conf_t, msie_refresh),
565       NULL },
566 
567     { ngx_string("log_not_found"),
568       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
569       ngx_conf_set_flag_slot,
570       NGX_HTTP_LOC_CONF_OFFSET,
571       offsetof(ngx_http_core_loc_conf_t, log_not_found),
572       NULL },
573 
574     { ngx_string("log_subrequest"),
575       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
576       ngx_conf_set_flag_slot,
577       NGX_HTTP_LOC_CONF_OFFSET,
578       offsetof(ngx_http_core_loc_conf_t, log_subrequest),
579       NULL },
580 
581     { ngx_string("recursive_error_pages"),
582       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
583       ngx_conf_set_flag_slot,
584       NGX_HTTP_LOC_CONF_OFFSET,
585       offsetof(ngx_http_core_loc_conf_t, recursive_error_pages),
586       NULL },
587 
588     { ngx_string("server_tokens"),
589       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
590       ngx_conf_set_flag_slot,
591       NGX_HTTP_LOC_CONF_OFFSET,
592       offsetof(ngx_http_core_loc_conf_t, server_tokens),
593       NULL },
594 
595     { ngx_string("if_modified_since"),
596       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
597       ngx_conf_set_enum_slot,
598       NGX_HTTP_LOC_CONF_OFFSET,
599       offsetof(ngx_http_core_loc_conf_t, if_modified_since),
600       &ngx_http_core_if_modified_since },
601 
602     { ngx_string("error_page"),
603       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
604                         |NGX_CONF_2MORE,
605       ngx_http_core_error_page,
606       NGX_HTTP_LOC_CONF_OFFSET,
607       0,
608       NULL },
609 
610     { ngx_string("try_files"),
611       NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
612       ngx_http_core_try_files,
613       NGX_HTTP_LOC_CONF_OFFSET,
614       0,
615       NULL },
616 
617     { ngx_string("post_action"),
618       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
619                         |NGX_CONF_TAKE1,
620       ngx_conf_set_str_slot,
621       NGX_HTTP_LOC_CONF_OFFSET,
622       offsetof(ngx_http_core_loc_conf_t, post_action),
623       NULL },
624 
625     { ngx_string("error_log"),
626       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
627       ngx_http_core_error_log,
628       NGX_HTTP_LOC_CONF_OFFSET,
629       0,
630       NULL },
631 
632     { ngx_string("open_file_cache"),
633       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
634       ngx_http_core_open_file_cache,
635       NGX_HTTP_LOC_CONF_OFFSET,
636       offsetof(ngx_http_core_loc_conf_t, open_file_cache),
637       NULL },
638 
639     { ngx_string("open_file_cache_valid"),
640       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
641       ngx_conf_set_sec_slot,
642       NGX_HTTP_LOC_CONF_OFFSET,
643       offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
644       NULL },
645 
646     { ngx_string("open_file_cache_retest"),
647       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
648       ngx_conf_set_sec_slot,
649       NGX_HTTP_LOC_CONF_OFFSET,
650       offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
651       &ngx_conf_deprecated_open_file_cache_retest },
652 
653     { ngx_string("open_file_cache_min_uses"),
654       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
655       ngx_conf_set_num_slot,
656       NGX_HTTP_LOC_CONF_OFFSET,
657       offsetof(ngx_http_core_loc_conf_t, open_file_cache_min_uses),
658       NULL },
659 
660     { ngx_string("open_file_cache_errors"),
661       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
662       ngx_conf_set_flag_slot,
663       NGX_HTTP_LOC_CONF_OFFSET,
664       offsetof(ngx_http_core_loc_conf_t, open_file_cache_errors),
665       NULL },
666 
667     { ngx_string("open_file_cache_events"),
668       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
669       ngx_conf_set_flag_slot,
670       NGX_HTTP_LOC_CONF_OFFSET,
671       offsetof(ngx_http_core_loc_conf_t, open_file_cache_events),
672       NULL },
673 
674     { ngx_string("resolver"),
675       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
676       ngx_http_core_resolver,
677       NGX_HTTP_LOC_CONF_OFFSET,
678       0,
679       NULL },
680 
681     { ngx_string("resolver_timeout"),
682       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
683       ngx_conf_set_msec_slot,
684       NGX_HTTP_LOC_CONF_OFFSET,
685       offsetof(ngx_http_core_loc_conf_t, resolver_timeout),
686       NULL },
687 
688 #if (NGX_HTTP_GZIP)
689 
690     { ngx_string("gzip_vary"),
691       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
692       ngx_conf_set_flag_slot,
693       NGX_HTTP_LOC_CONF_OFFSET,
694       offsetof(ngx_http_core_loc_conf_t, gzip_vary),
695       NULL },
696 
697     { ngx_string("gzip_http_version"),
698       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
699       ngx_conf_set_enum_slot,
700       NGX_HTTP_LOC_CONF_OFFSET,
701       offsetof(ngx_http_core_loc_conf_t, gzip_http_version),
702       &ngx_http_gzip_http_version },
703 
704     { ngx_string("gzip_proxied"),
705       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
706       ngx_conf_set_bitmask_slot,
707       NGX_HTTP_LOC_CONF_OFFSET,
708       offsetof(ngx_http_core_loc_conf_t, gzip_proxied),
709       &ngx_http_gzip_proxied_mask },
710 
711     { ngx_string("gzip_disable"),
712       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
713       ngx_http_gzip_disable,
714       NGX_HTTP_LOC_CONF_OFFSET,
715       0,
716       NULL },
717 
718 #endif
719 
720       ngx_null_command
721 };
722 
723 
724 static ngx_http_module_t  ngx_http_core_module_ctx = {
725     ngx_http_core_preconfiguration,        /* preconfiguration */
726     NULL,                                  /* postconfiguration */
727 
728     ngx_http_core_create_main_conf,        /* create main configuration */
729     ngx_http_core_init_main_conf,          /* init main configuration */
730 
731     ngx_http_core_create_srv_conf,         /* create server configuration */
732     ngx_http_core_merge_srv_conf,          /* merge server configuration */
733 
734     ngx_http_core_create_loc_conf,         /* create location configuration */
735     ngx_http_core_merge_loc_conf           /* merge location configuration */
736 };
737 
738 
739 ngx_module_t  ngx_http_core_module = {
740     NGX_MODULE_V1,
741     &ngx_http_core_module_ctx,             /* module context */
742     ngx_http_core_commands,                /* module directives */
743     NGX_HTTP_MODULE,                       /* module type */
744     NULL,                                  /* init master */
745     NULL,                                  /* init module */
746     NULL,                                  /* init process */
747     NULL,                                  /* init thread */
748     NULL,                                  /* exit thread */
749     NULL,                                  /* exit process */
750     NULL,                                  /* exit master */
751     NGX_MODULE_V1_PADDING
752 };
753 
754 
755 ngx_str_t  ngx_http_core_get_method = { 3, (u_char *) "GET " };
756 
757 
758 void
759 ngx_http_handler(ngx_http_request_t *r)
760 {
761     ngx_http_core_main_conf_t  *cmcf;
762 
763     r->connection->log->action = NULL;
764 
765     r->connection->unexpected_eof = 0;
766 
767     if (!r->internal) {
768         switch (r->headers_in.connection_type) {
769         case 0:
770             if (r->http_version > NGX_HTTP_VERSION_10) {
771                 r->keepalive = 1;
772             } else {
773                 r->keepalive = 0;
774             }
775             break;
776 
777         case NGX_HTTP_CONNECTION_CLOSE:
778             r->keepalive = 0;
779             break;
780 
781         case NGX_HTTP_CONNECTION_KEEP_ALIVE:
782             r->keepalive = 1;
783             break;
784         }
785 
786         if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) {
787 
788             /*
789              * MSIE may wait for some time if an response for
790              * a POST request was sent over a keepalive connection
791              */
792 
793             r->keepalive = 0;
794         }
795 
796         if (r->headers_in.content_length_n > 0) {
797             r->lingering_close = 1;
798 
799         } else {
800             r->lingering_close = 0;
801         }
802 
803         r->phase_handler = 0;
804 
805     } else {
806         cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
807         r->phase_handler = cmcf->phase_engine.server_rewrite_index;
808     }
809 
810     if (r->unparsed_uri.len) {
811         r->valid_unparsed_uri = 1;
812     }
813 
814     r->valid_location = 1;
815     r->gzip = 0;
816 
817     r->write_event_handler = ngx_http_core_run_phases;
818     ngx_http_core_run_phases(r);
819 }
820 
821 
822 void
823 ngx_http_core_run_phases(ngx_http_request_t *r)
824 {
825     ngx_int_t                   rc;
826     ngx_http_phase_handler_t   *ph;
827     ngx_http_core_main_conf_t  *cmcf;
828 
829     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
830 
831     ph = cmcf->phase_engine.handlers;
832 
833     while (ph[r->phase_handler].checker) {
834 
835         rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
836 
837         if (rc == NGX_OK) {
838             return;
839         }
840     }
841 }
842 
843 
844 ngx_int_t
845 ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
846 {
847     ngx_int_t  rc;
848 
849     /*
850      * generic phase checker,
851      * used by the post read, server rewrite, rewrite, and pre-access phases
852      */
853 
854     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
855                    "generic phase: %ui", r->phase_handler);
856 
857     rc = ph->handler(r);
858 
859     if (rc == NGX_OK) {
860         r->phase_handler = ph->next;
861         return NGX_AGAIN;
862     }
863 
864     if (rc == NGX_DECLINED) {
865         r->phase_handler++;
866         return NGX_AGAIN;
867     }
868 
869     if (rc == NGX_AGAIN || rc == NGX_DONE) {
870         return NGX_OK;
871     }
872 
873     /* rc == NGX_ERROR || rc == NGX_HTTP_...  */
874 
875     ngx_http_finalize_request(r, rc);
876 
877     return NGX_OK;
878 }
879 
880 
881 ngx_int_t
882 ngx_http_core_find_config_phase(ngx_http_request_t *r,
883     ngx_http_phase_handler_t *ph)
884 {
885     u_char                    *p;
886     size_t                     len;
887     ngx_int_t                  rc;
888     ngx_http_core_loc_conf_t  *clcf;
889 
890     r->content_handler = NULL;
891     r->uri_changed = 0;
892 
893     rc = ngx_http_core_find_location(r);
894 
895     if (rc == NGX_ERROR) {
896         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
897         return NGX_OK;
898     }
899 
900     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
901 
902     if (!r->internal && clcf->internal) {
903         ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
904         return NGX_OK;
905     }
906 
907     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
908                    "using configuration \"%s%V\"",
909                    (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
910                    &clcf->name);
911 
912     ngx_http_update_location_config(r);
913 
914     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
915                    "http cl:%O max:%O",
916                    r->headers_in.content_length_n, clcf->client_max_body_size);
917 
918     if (r->headers_in.content_length_n != -1
919         && !r->discard_body
920         && clcf->client_max_body_size
921         && clcf->client_max_body_size < r->headers_in.content_length_n)
922     {
923         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
924                       "client intended to send too large body: %O bytes",
925                       r->headers_in.content_length_n);
926 
927         (void) ngx_http_discard_request_body(r);
928         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
929         return NGX_OK;
930     }
931 
932     if (rc == NGX_DONE) {
933         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
934         if (r->headers_out.location == NULL) {
935             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
936             return NGX_OK;
937         }
938 
939         /*
940          * we do not need to set the r->headers_out.location->hash and
941          * r->headers_out.location->key fields
942          */
943 
944         if (r->args.len == 0) {
945             r->headers_out.location->value = clcf->name;
946 
947         } else {
948             len = clcf->name.len + 1 + r->args.len;
949             p = ngx_pnalloc(r->pool, len);
950 
951             if (p == NULL) {
952                 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
953                 return NGX_OK;
954             }
955 
956             r->headers_out.location->value.len = len;
957             r->headers_out.location->value.data = p;
958 
959             p = ngx_cpymem(p, clcf->name.data, clcf->name.len);
960             *p++ = '?';
961             ngx_memcpy(p, r->args.data, r->args.len);
962         }
963 
964         ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
965         return NGX_OK;
966     }
967 
968     r->phase_handler++;
969     return NGX_AGAIN;
970 }
971 
972 
973 ngx_int_t
974 ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
975     ngx_http_phase_handler_t *ph)
976 {
977     ngx_http_core_srv_conf_t  *cscf;
978 
979     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
980                    "post rewrite phase: %ui", r->phase_handler);
981 
982     if (!r->uri_changed) {
983         r->phase_handler++;
984         return NGX_AGAIN;
985     }
986 
987     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
988                    "uri changes: %d", r->uri_changes);
989 
990     /*
991      * gcc before 3.3 compiles the broken code for
992      *     if (r->uri_changes-- == 0)
993      * if the r->uri_changes is defined as
994      *     unsigned  uri_changes:4
995      */
996 
997     r->uri_changes--;
998 
999     if (r->uri_changes == 0) {
1000         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1001                       "rewrite or internal redirection cycle "
1002                       "while processing \"%V\"", &r->uri);
1003 
1004         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1005         return NGX_OK;
1006     }
1007 
1008     r->phase_handler = ph->next;
1009 
1010     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1011     r->loc_conf = cscf->ctx->loc_conf;
1012 
1013     return NGX_AGAIN;
1014 }
1015 
1016 
1017 ngx_int_t
1018 ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
1019 {
1020     ngx_int_t                  rc;
1021     ngx_http_core_loc_conf_t  *clcf;
1022 
1023     if (r != r->main) {
1024         r->phase_handler = ph->next;
1025         return NGX_AGAIN;
1026     }
1027 
1028     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1029                    "access phase: %ui", r->phase_handler);
1030 
1031     rc = ph->handler(r);
1032 
1033     if (rc == NGX_DECLINED) {
1034         r->phase_handler++;
1035         return NGX_AGAIN;
1036     }
1037 
1038     if (rc == NGX_AGAIN || rc == NGX_DONE) {
1039         return NGX_OK;
1040     }
1041 
1042     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1043 
1044     if (clcf->satisfy == NGX_HTTP_SATISFY_ALL) {
1045 
1046         if (rc == NGX_OK) {
1047             r->phase_handler++;
1048             return NGX_AGAIN;
1049         }
1050 
1051     } else {
1052         if (rc == NGX_OK) {
1053             r->access_code = 0;
1054 
1055             if (r->headers_out.www_authenticate) {
1056                 r->headers_out.www_authenticate->hash = 0;
1057             }
1058 
1059             r->phase_handler = ph->next;
1060             return NGX_AGAIN;
1061         }
1062 
1063         if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) {
1064             r->access_code = rc;
1065 
1066             r->phase_handler++;
1067             return NGX_AGAIN;
1068         }
1069     }
1070 
1071     /* rc == NGX_ERROR || rc == NGX_HTTP_...  */
1072 
1073     ngx_http_finalize_request(r, rc);
1074     return NGX_OK;
1075 }
1076 
1077 
1078 ngx_int_t
1079 ngx_http_core_post_access_phase(ngx_http_request_t *r,
1080     ngx_http_phase_handler_t *ph)
1081 {
1082     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1083                    "post access phase: %ui", r->phase_handler);
1084 
1085     if (r->access_code) {
1086 
1087         if (r->access_code == NGX_HTTP_FORBIDDEN) {
1088             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1089                           "access forbidden by rule");
1090         }
1091 
1092         ngx_http_finalize_request(r, r->access_code);
1093         return NGX_OK;
1094     }
1095 
1096     r->phase_handler++;
1097     return NGX_AGAIN;
1098 }
1099 
1100 
1101 ngx_int_t
1102 ngx_http_core_try_files_phase(ngx_http_request_t *r,
1103     ngx_http_phase_handler_t *ph)
1104 {
1105     size_t                        len, root, alias, reserve, allocated;
1106     u_char                       *p, *name;
1107     ngx_str_t                     path, args;
1108     ngx_uint_t                    test_dir;
1109     ngx_http_try_file_t          *tf;
1110     ngx_open_file_info_t          of;
1111     ngx_http_script_code_pt       code;
1112     ngx_http_script_engine_t      e;
1113     ngx_http_core_loc_conf_t     *clcf;
1114     ngx_http_script_len_code_pt   lcode;
1115 
1116     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1117                    "try files phase: %ui", r->phase_handler);
1118 
1119     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1120 
1121     if (clcf->try_files == NULL) {
1122         r->phase_handler++;
1123         return NGX_AGAIN;
1124     }
1125 
1126     allocated = 0;
1127     root = 0;
1128     name = NULL;
1129     /* suppress MSVC warning */
1130     path.data = NULL;
1131 
1132     tf = clcf->try_files;
1133 
1134     alias = clcf->alias ? clcf->name.len : 0;
1135 
1136     for ( ;; ) {
1137 
1138         if (tf->lengths) {
1139             ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
1140 
1141             e.ip = tf->lengths->elts;
1142             e.request = r;
1143 
1144             /* 1 is for terminating '\0' as in static names */
1145             len = 1;
1146 
1147             while (*(uintptr_t *) e.ip) {
1148                 lcode = *(ngx_http_script_len_code_pt *) e.ip;
1149                 len += lcode(&e);
1150             }
1151 
1152         } else {
1153             len = tf->name.len;
1154         }
1155 
1156         /* 16 bytes are preallocation */
1157         reserve = ngx_abs((ssize_t) (len - r->uri.len)) + alias + 16;
1158 
1159         if (reserve > allocated) {
1160 
1161             /* we just need to allocate path and to copy a root */
1162 
1163             if (ngx_http_map_uri_to_path(r, &path, &root, reserve) == NULL) {
1164                 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1165                 return NGX_OK;
1166             }
1167 
1168             name = path.data + root;
1169             allocated = path.len - root - (r->uri.len - alias);
1170          }
1171 
1172         if (tf->values == NULL) {
1173 
1174             /* tf->name.len includes the terminating '\0' */
1175 
1176             ngx_memcpy(name, tf->name.data, tf->name.len);
1177 
1178             path.len = (name + tf->name.len - 1) - path.data;
1179 
1180         } else {
1181             e.ip = tf->values->elts;
1182             e.pos = name;
1183             e.flushed = 1;
1184 
1185             while (*(uintptr_t *) e.ip) {
1186                 code = *(ngx_http_script_code_pt *) e.ip;
1187                 code((ngx_http_script_engine_t *) &e);
1188             }
1189 
1190             path.len = e.pos - path.data;
1191 
1192             *e.pos = '\0';
1193 
1194             if (alias && ngx_strncmp(name, clcf->name.data, alias) == 0) {
1195                 ngx_memcpy(name, name + alias, len - alias);
1196                 path.len -= alias;
1197             }
1198         }
1199 
1200         test_dir = tf->test_dir;
1201 
1202         tf++;
1203 
1204         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1205                        "try to use file: \"%s\" \"%s\"", name, path.data);
1206 
1207         if (tf->lengths == NULL && tf->name.len == 0) {
1208 
1209             if (tf->code) {
1210                 ngx_http_finalize_request(r, tf->code);
1211                 return NGX_OK;
1212             }
1213 
1214             path.len -= root;
1215             path.data += root;
1216 
1217             if (path.data[0] == '@') {
1218                 (void) ngx_http_named_location(r, &path);
1219 
1220             } else {
1221                 ngx_http_split_args(r, &path, &args);
1222 
1223                 (void) ngx_http_internal_redirect(r, &path, &args);
1224             }
1225 
1226             ngx_http_finalize_request(r, NGX_DONE);
1227             return NGX_OK;
1228         }
1229 
1230         ngx_memzero(&of, sizeof(ngx_open_file_info_t));
1231 
1232         of.directio = clcf->directio;
1233         of.valid = clcf->open_file_cache_valid;
1234         of.min_uses = clcf->open_file_cache_min_uses;
1235         of.test_only = 1;
1236         of.errors = clcf->open_file_cache_errors;
1237         of.events = clcf->open_file_cache_events;
1238 
1239         if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
1240             != NGX_OK)
1241         {
1242             if (of.err != NGX_ENOENT
1243                 && of.err != NGX_ENOTDIR
1244                 && of.err != NGX_ENAMETOOLONG)
1245             {
1246                 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
1247                               "%s \"%s\" failed", of.failed, path.data);
1248             }
1249 
1250             continue;
1251         }
1252 
1253         if (of.is_dir && !test_dir) {
1254             continue;
1255         }
1256 
1257         path.len -= root;
1258         path.data += root;
1259 
1260         if (!alias) {
1261             r->uri = path;
1262 
1263         } else {
1264             r->uri.len = alias + path.len;
1265             r->uri.data = ngx_pnalloc(r->pool, r->uri.len);
1266             if (r->uri.data == NULL) {
1267                 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1268                 return NGX_OK;
1269             }
1270 
1271             p = ngx_copy(r->uri.data, clcf->name.data, alias);
1272             ngx_memcpy(p, name, path.len);
1273         }
1274 
1275         ngx_http_set_exten(r);
1276 
1277         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1278                        "try file uri: \"%V\"", &r->uri);
1279 
1280         r->phase_handler++;
1281         return NGX_AGAIN;
1282     }
1283 
1284     /* not reached */
1285 }
1286 
1287 
1288 ngx_int_t
1289 ngx_http_core_content_phase(ngx_http_request_t *r,
1290     ngx_http_phase_handler_t *ph)
1291 {
1292     size_t     root;
1293     ngx_int_t  rc;
1294     ngx_str_t  path;
1295 
1296     if (r->content_handler) {
1297         r->write_event_handler = ngx_http_request_empty_handler;
1298         ngx_http_finalize_request(r, r->content_handler(r));
1299         return NGX_OK;
1300     }
1301 
1302     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1303                    "content phase: %ui", r->phase_handler);
1304 
1305     rc = ph->handler(r);
1306 
1307     if (rc != NGX_DECLINED) {
1308         ngx_http_finalize_request(r, rc);
1309         return NGX_OK;
1310     }
1311 
1312     /* rc == NGX_DECLINED */
1313 
1314     ph++;
1315 
1316     if (ph->checker) {
1317         r->phase_handler++;
1318         return NGX_AGAIN;
1319     }
1320 
1321     /* no content handler was found */
1322 
1323     if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) {
1324 
1325         if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
1326             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1327                           "directory index of \"%s\" is forbidden", path.data);
1328         }
1329 
1330         ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
1331         return NGX_OK;
1332     }
1333 
1334     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found");
1335 
1336     ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
1337     return NGX_OK;
1338 }
1339 
1340 
1341 void
1342 ngx_http_update_location_config(ngx_http_request_t *r)
1343 {
1344     ngx_http_core_loc_conf_t  *clcf;
1345 
1346     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1347 
1348     if (r->method & clcf->limit_except) {
1349         r->loc_conf = clcf->limit_except_loc_conf;
1350         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1351     }
1352 
1353     if (r == r->main) {
1354         r->connection->log->file = clcf->error_log->file;
1355 
1356         if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
1357             r->connection->log->log_level = clcf->error_log->log_level;
1358         }
1359     }
1360 
1361     if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
1362         r->connection->sendfile = 1;
1363 
1364     } else {
1365         r->connection->sendfile = 0;
1366     }
1367 
1368     if (clcf->client_body_in_file_only) {
1369         r->request_body_in_file_only = 1;
1370         r->request_body_in_persistent_file = 1;
1371         r->request_body_in_clean_file =
1372             clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;
1373         r->request_body_file_log_level = NGX_LOG_NOTICE;
1374 
1375     } else {
1376         r->request_body_file_log_level = NGX_LOG_WARN;
1377     }
1378 
1379     r->request_body_in_single_buf = clcf->client_body_in_single_buffer;
1380 
1381     if (r->keepalive) {
1382         if (clcf->keepalive_timeout == 0) {
1383             r->keepalive = 0;
1384 
1385         } else if (r->connection->requests >= clcf->keepalive_requests) {
1386             r->keepalive = 0;
1387         }
1388     }
1389 
1390     if (!clcf->tcp_nopush) {
1391         /* disable TCP_NOPUSH/TCP_CORK use */
1392         r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
1393     }
1394 
1395     if (r->limit_rate == 0) {
1396         r->limit_rate = clcf->limit_rate;
1397     }
1398 
1399     if (clcf->handler) {
1400         r->content_handler = clcf->handler;
1401     }
1402 }
1403 
1404 
1405 /*
1406  * NGX_OK       - exact or regex match
1407  * NGX_DONE     - auto redirect
1408  * NGX_AGAIN    - inclusive match
1409  * NGX_ERROR    - regex error
1410  * NGX_DECLINED - no match
1411  */
1412 
1413 static ngx_int_t
1414 ngx_http_core_find_location(ngx_http_request_t *r)
1415 {
1416     ngx_int_t                  rc;
1417     ngx_http_core_loc_conf_t  *pclcf;
1418 #if (NGX_PCRE)
1419     ngx_int_t                  n, len;
1420     ngx_uint_t                 noregex;
1421     ngx_http_core_loc_conf_t  *clcf, **clcfp;
1422 
1423     noregex = 0;
1424 #endif
1425 
1426     pclcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1427 
1428     rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
1429 
1430     if (rc == NGX_AGAIN) {
1431 
1432 #if (NGX_PCRE)
1433         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1434 
1435         noregex = clcf->noregex;
1436 #endif
1437 
1438         /* look up nested locations */
1439 
1440         rc = ngx_http_core_find_location(r);
1441     }
1442 
1443     if (rc == NGX_OK || rc == NGX_DONE) {
1444         return rc;
1445     }
1446 
1447     /* rc == NGX_DECLINED or rc == NGX_AGAIN in nested location */
1448 
1449 #if (NGX_PCRE)
1450 
1451     if (noregex == 0 && pclcf->regex_locations) {
1452 
1453         len = 0;
1454 
1455         for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) {
1456 
1457             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1458                            "test location: ~ \"%V\"", &(*clcfp)->name);
1459 
1460             if ((*clcfp)->captures) {
1461 
1462                 len = (NGX_HTTP_MAX_CAPTURES + 1) * 3;
1463 
1464                 if (r->captures == NULL) {
1465                     r->captures = ngx_palloc(r->pool, len * sizeof(int));
1466                     if (r->captures == NULL) {
1467                         return NGX_ERROR;
1468                     }
1469                 }
1470             }
1471 
1472             n = ngx_regex_exec((*clcfp)->regex, &r->uri, r->captures, len);
1473 
1474             if (n == NGX_REGEX_NO_MATCHED) {
1475                 continue;
1476             }
1477 
1478             if (n < 0) {
1479                 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1480                               ngx_regex_exec_n
1481                               " failed: %d on \"%V\" using \"%V\"",
1482                               n, &r->uri, &(*clcfp)->name);
1483                 return NGX_ERROR;
1484             }
1485 
1486             /* match */
1487 
1488             r->loc_conf = (*clcfp)->loc_conf;
1489 
1490             r->ncaptures = len;
1491             r->captures_data = r->uri.data;
1492 
1493             /* look up nested locations */
1494 
1495             rc = ngx_http_core_find_location(r);
1496 
1497             return (rc == NGX_ERROR) ? rc : NGX_OK;
1498         }
1499     }
1500 #endif
1501 
1502     return rc;
1503 }
1504 
1505 
1506 /*
1507  * NGX_OK       - exact match
1508  * NGX_DONE     - auto redirect
1509  * NGX_AGAIN    - inclusive match
1510  * NGX_DECLINED - no match
1511  */
1512 
1513 static ngx_int_t
1514 ngx_http_core_find_static_location(ngx_http_request_t *r,
1515     ngx_http_location_tree_node_t *node)
1516 {
1517     u_char     *uri;
1518     size_t      len, n;
1519     ngx_int_t   rc, rv;
1520 
1521     len = r->uri.len;
1522     uri = r->uri.data;
1523 
1524     rv = NGX_DECLINED;
1525 
1526     for ( ;; ) {
1527 
1528         if (node == NULL) {
1529             return rv;
1530         }
1531 
1532         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1533                        "test location: \"%*s\"", node->len, node->name);
1534 
1535         n = (len <= (size_t) node->len) ? len : node->len;
1536 
1537         rc = ngx_filename_cmp(uri, node->name, n);
1538 
1539         if (rc != 0) {
1540             node = (rc < 0) ? node->left : node->right;
1541 
1542             continue;
1543         }
1544 
1545         if (len > (size_t) node->len) {
1546 
1547             if (node->inclusive) {
1548 
1549                 r->loc_conf = node->inclusive->loc_conf;
1550                 rv = NGX_AGAIN;
1551 
1552                 node = node->tree;
1553                 uri += n;
1554                 len -= n;
1555 
1556                 continue;
1557             }
1558 
1559             /* exact only */
1560 
1561             node = node->right;
1562 
1563             continue;
1564         }
1565 
1566         if (len == (size_t) node->len) {
1567 
1568             r->loc_conf = (node->exact) ? node->exact->loc_conf:
1569                                           node->inclusive->loc_conf;
1570             return NGX_OK;
1571         }
1572 
1573         /* len < node->len */
1574 
1575         if (len + 1 == (size_t) node->len && node->auto_redirect) {
1576 
1577             r->loc_conf = (node->exact) ? node->exact->loc_conf:
1578                                           node->inclusive->loc_conf;
1579             rv = NGX_DONE;
1580         }
1581 
1582         node = node->left;
1583     }
1584 }
1585 
1586 
1587 void *
1588 ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash)
1589 {
1590     u_char      c, *lowcase;
1591     size_t      len;
1592     ngx_uint_t  i, hash;
1593 
1594     if (r->headers_out.content_type.len == 0) {
1595         return NULL;
1596     }
1597 
1598     len = r->headers_out.content_type_len;
1599 
1600     if (r->headers_out.content_type_lowcase == NULL) {
1601 
1602         lowcase = ngx_pnalloc(r->pool, len);
1603         if (lowcase == NULL) {
1604             return NULL;
1605         }
1606 
1607         r->headers_out.content_type_lowcase = lowcase;
1608 
1609         hash = 0;
1610 
1611         for (i = 0; i < len; i++) {
1612             c = ngx_tolower(r->headers_out.content_type.data[i]);
1613             hash = ngx_hash(hash, c);
1614             lowcase[i] = c;
1615         }
1616 
1617         r->headers_out.content_type_hash = hash;
1618     }
1619 
1620     return ngx_hash_find(types_hash, r->headers_out.content_type_hash,
1621                          r->headers_out.content_type_lowcase, len);
1622 }
1623 
1624 
1625 ngx_int_t
1626 ngx_http_set_content_type(ngx_http_request_t *r)
1627 {
1628     u_char                     c, *exten;
1629     ngx_str_t                 *type;
1630     ngx_uint_t                 i, hash;
1631     ngx_http_core_loc_conf_t  *clcf;
1632 
1633     if (r->headers_out.content_type.len) {
1634         return NGX_OK;
1635     }
1636 
1637     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1638 
1639     if (r->exten.len) {
1640 
1641         hash = 0;
1642 
1643         for (i = 0; i < r->exten.len; i++) {
1644             c = r->exten.data[i];
1645 
1646             if (c >= 'A' && c <= 'Z') {
1647 
1648                 exten = ngx_pnalloc(r->pool, r->exten.len);
1649                 if (exten == NULL) {
1650                     return NGX_ERROR;
1651                 }
1652 
1653                 hash = ngx_hash_strlow(exten, r->exten.data, r->exten.len);
1654 
1655                 r->exten.data = exten;
1656 
1657                 break;
1658             }
1659 
1660             hash = ngx_hash(hash, c);
1661         }
1662 
1663         type = ngx_hash_find(&clcf->types_hash, hash,
1664                              r->exten.data, r->exten.len);
1665 
1666         if (type) {
1667             r->headers_out.content_type_len = type->len;
1668             r->headers_out.content_type = *type;
1669 
1670             return NGX_OK;
1671         }
1672     }
1673 
1674     r->headers_out.content_type_len = clcf->default_type.len;
1675     r->headers_out.content_type = clcf->default_type;
1676 
1677     return NGX_OK;
1678 }
1679 
1680 
1681 void
1682 ngx_http_set_exten(ngx_http_request_t *r)
1683 {
1684     ngx_int_t  i;
1685 
1686     r->exten.len = 0;
1687     r->exten.data = NULL;
1688 
1689     for (i = r->uri.len - 1; i > 1; i--) {
1690         if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') {
1691 
1692             r->exten.len = r->uri.len - i - 1;
1693             r->exten.data = &r->uri.data[i + 1];
1694 
1695             return;
1696 
1697         } else if (r->uri.data[i] == '/') {
1698             return;
1699         }
1700     }
1701 
1702     return;
1703 }
1704 
1705 
1706 ngx_int_t
1707 ngx_http_send_header(ngx_http_request_t *r)
1708 {
1709     if (r->err_status) {
1710         r->headers_out.status = r->err_status;
1711         r->headers_out.status_line.len = 0;
1712     }
1713 
1714     return ngx_http_top_header_filter(r);
1715 }
1716 
1717 
1718 ngx_int_t
1719 ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
1720 {
1721     ngx_int_t          rc;
1722     ngx_connection_t  *c;
1723 
1724     c = r->connection;
1725 
1726     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
1727                    "http output filter \"%V?%V\"", &r->uri, &r->args);
1728 
1729     rc = ngx_http_top_body_filter(r, in);
1730 
1731     if (rc == NGX_ERROR) {
1732         /* NGX_ERROR may be returned by any filter */
1733         c->error = 1;
1734     }
1735 
1736     return rc;
1737 }
1738 
1739 
1740 u_char *
1741 ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
1742     size_t *root_length, size_t reserved)
1743 {
1744     u_char                    *last;
1745     size_t                     alias;
1746     ngx_http_core_loc_conf_t  *clcf;
1747 
1748     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1749 
1750     alias = clcf->alias ? clcf->name.len : 0;
1751 
1752     if (alias && !r->valid_location) {
1753         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1754                       "\"alias\" could not be used in location \"%V\" "
1755                       "where URI was rewritten", &clcf->name);
1756         return NULL;
1757     }
1758 
1759     if (clcf->root_lengths == NULL) {
1760 
1761         *root_length = clcf->root.len;
1762 
1763         path->len = clcf->root.len + reserved + r->uri.len - alias + 1;
1764 
1765         path->data = ngx_pnalloc(r->pool, path->len);
1766         if (path->data == NULL) {
1767             return NULL;
1768         }
1769 
1770         last = ngx_copy(path->data, clcf->root.data, clcf->root.len);
1771 
1772     } else {
1773 
1774 #if (NGX_PCRE)
1775         ngx_uint_t  captures;
1776 
1777         captures = alias && clcf->captures;
1778         reserved += captures ? 1 : r->uri.len - alias + 1;
1779 #else
1780         reserved += r->uri.len - alias + 1;
1781 #endif
1782 
1783         if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
1784                                 clcf->root_values->elts)
1785             == NULL)
1786         {
1787             return NULL;
1788         }
1789 
1790         if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0) != NGX_OK) {
1791             return NULL;
1792         }
1793 
1794         *root_length = path->len - reserved;
1795         last = path->data + *root_length;
1796 
1797 #if (NGX_PCRE)
1798         if (captures) {
1799             *last = '\0';
1800             return last;
1801         }
1802 #endif
1803     }
1804 
1805     last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);
1806 
1807     return last;
1808 }
1809 
1810 
1811 ngx_int_t
1812 ngx_http_auth_basic_user(ngx_http_request_t *r)
1813 {
1814     ngx_str_t   auth, encoded;
1815     ngx_uint_t  len;
1816 
1817     if (r->headers_in.user.len == 0 && r->headers_in.user.data != NULL) {
1818         return NGX_DECLINED;
1819     }
1820 
1821     if (r->headers_in.authorization == NULL) {
1822         r->headers_in.user.data = (u_char *) "";
1823         return NGX_DECLINED;
1824     }
1825 
1826     encoded = r->headers_in.authorization->value;
1827 
1828     if (encoded.len < sizeof("Basic ") - 1
1829         || ngx_strncasecmp(encoded.data, (u_char *) "Basic ",
1830                            sizeof("Basic ") - 1)
1831            != 0)
1832     {
1833         r->headers_in.user.data = (u_char *) "";
1834         return NGX_DECLINED;
1835     }
1836 
1837     encoded.len -= sizeof("Basic ") - 1;
1838     encoded.data += sizeof("Basic ") - 1;
1839 
1840     while (encoded.len && encoded.data[0] == ' ') {
1841         encoded.len--;
1842         encoded.data++;
1843     }
1844 
1845     if (encoded.len == 0) {
1846         r->headers_in.user.data = (u_char *) "";
1847         return NGX_DECLINED;
1848     }
1849 
1850     auth.len = ngx_base64_decoded_length(encoded.len);
1851     auth.data = ngx_pnalloc(r->pool, auth.len + 1);
1852     if (auth.data == NULL) {
1853         return NGX_ERROR;
1854     }
1855 
1856     if (ngx_decode_base64(&auth, &encoded) != NGX_OK) {
1857         r->headers_in.user.data = (u_char *) "";
1858         return NGX_DECLINED;
1859     }
1860 
1861     auth.data[auth.len] = '\0';
1862 
1863     for (len = 0; len < auth.len; len++) {
1864         if (auth.data[len] == ':') {
1865             break;
1866         }
1867     }
1868 
1869     if (len == 0 || len == auth.len) {
1870         r->headers_in.user.data = (u_char *) "";
1871         return NGX_DECLINED;
1872     }
1873 
1874     r->headers_in.user.len = len;
1875     r->headers_in.user.data = auth.data;
1876     r->headers_in.passwd.len = auth.len - len - 1;
1877     r->headers_in.passwd.data = &auth.data[len + 1];
1878 
1879     return NGX_OK;
1880 }
1881 
1882 
1883 #if (NGX_HTTP_GZIP)
1884 
1885 ngx_int_t
1886 ngx_http_gzip_ok(ngx_http_request_t *r)
1887 {
1888     time_t                     date, expires;
1889     ngx_uint_t                 p;
1890     ngx_array_t               *cc;
1891     ngx_table_elt_t           *e, *d;
1892     ngx_http_core_loc_conf_t  *clcf;
1893 
1894     if (r->gzip == 1) {
1895         return NGX_OK;
1896     }
1897 
1898     if (r->gzip == 2) {
1899         return NGX_DECLINED;
1900     }
1901 
1902     r->gzip = 2;
1903 
1904     if (r != r->main
1905         || r->headers_in.accept_encoding == NULL
1906         || ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
1907                            "gzip", 4 - 1)
1908            == NULL
1909 
1910         /*
1911          * if the URL (without the "http://" prefix) is longer than 253 bytes,
1912          * then MSIE 4.x can not handle the compressed stream - it waits
1913          * too long, hangs up or crashes
1914          */
1915 
1916         || (r->headers_in.msie4 && r->unparsed_uri.len > 200))
1917     {
1918         return NGX_DECLINED;
1919     }
1920 
1921     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1922 
1923     if (r->headers_in.msie6 && clcf->gzip_disable_msie6) {
1924         return NGX_DECLINED;
1925     }
1926 
1927     if (r->http_version < clcf->gzip_http_version) {
1928         return NGX_DECLINED;
1929     }
1930 
1931     if (r->headers_in.via == NULL) {
1932         goto ok;
1933     }
1934 
1935     p = clcf->gzip_proxied;
1936 
1937     if (p & NGX_HTTP_GZIP_PROXIED_OFF) {
1938         return NGX_DECLINED;
1939     }
1940 
1941     if (p & NGX_HTTP_GZIP_PROXIED_ANY) {
1942         goto ok;
1943     }
1944 
1945     if (r->headers_in.authorization && (p & NGX_HTTP_GZIP_PROXIED_AUTH)) {
1946         goto ok;
1947     }
1948 
1949     e = r->headers_out.expires;
1950 
1951     if (e) {
1952 
1953         if (!(p & NGX_HTTP_GZIP_PROXIED_EXPIRED)) {
1954             return NGX_DECLINED;
1955         }
1956 
1957         expires = ngx_http_parse_time(e->value.data, e->value.len);
1958         if (expires == NGX_ERROR) {
1959             return NGX_DECLINED;
1960         }
1961 
1962         d = r->headers_out.date;
1963 
1964         if (d) {
1965             date = ngx_http_parse_time(d->value.data, d->value.len);
1966             if (date == NGX_ERROR) {
1967                 return NGX_DECLINED;
1968             }
1969 
1970         } else {
1971             date = ngx_time();
1972         }
1973 
1974         if (expires < date) {
1975             goto ok;
1976         }
1977 
1978         return NGX_DECLINED;
1979     }
1980 
1981     cc = &r->headers_out.cache_control;
1982 
1983     if (cc->elts) {
1984 
1985         if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
1986             && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_cache,
1987                                                  NULL)
1988                >= 0)
1989         {
1990             goto ok;
1991         }
1992 
1993         if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE)
1994             && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_store,
1995                                                  NULL)
1996                >= 0)
1997         {
1998             goto ok;
1999         }
2000 
2001         if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE)
2002             && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_private,
2003                                                  NULL)
2004                >= 0)
2005         {
2006             goto ok;
2007         }
2008 
2009         return NGX_DECLINED;
2010     }
2011 
2012     if ((p & NGX_HTTP_GZIP_PROXIED_NO_LM) && r->headers_out.last_modified) {
2013         return NGX_DECLINED;
2014     }
2015 
2016     if ((p & NGX_HTTP_GZIP_PROXIED_NO_ETAG) && r->headers_out.etag) {
2017         return NGX_DECLINED;
2018     }
2019 
2020 ok:
2021 
2022 #if (NGX_PCRE)
2023 
2024     if (clcf->gzip_disable && r->headers_in.user_agent) {
2025 
2026         if (ngx_regex_exec_array(clcf->gzip_disable,
2027                                  &r->headers_in.user_agent->value,
2028                                  r->connection->log)
2029             != NGX_DECLINED)
2030         {
2031             return NGX_DECLINED;
2032         }
2033     }
2034 
2035 #endif
2036 
2037     r->gzip = 1;
2038 
2039     return NGX_OK;
2040 }
2041 
2042 #endif
2043 
2044 
2045 ngx_int_t
2046 ngx_http_subrequest(ngx_http_request_t *r,
2047     ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
2048     ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
2049 {
2050     ngx_connection_t              *c;
2051     ngx_http_request_t            *sr;
2052     ngx_http_core_srv_conf_t      *cscf;
2053     ngx_http_postponed_request_t  *pr, *p;
2054 
2055     r->main->subrequests--;
2056 
2057     if (r->main->subrequests == 0) {
2058         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2059                       "subrequests cycle while processing \"%V\"", uri);
2060         r->main->subrequests = 1;
2061         return NGX_ERROR;
2062     }
2063 
2064     sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
2065     if (sr == NULL) {
2066         return NGX_ERROR;
2067     }
2068 
2069     sr->signature = NGX_HTTP_MODULE;
2070 
2071     c = r->connection;
2072     sr->connection = c;
2073 
2074     sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
2075     if (sr->ctx == NULL) {
2076         return NGX_ERROR;
2077     }
2078 
2079     if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
2080                       sizeof(ngx_table_elt_t))
2081         != NGX_OK)
2082     {
2083         return NGX_ERROR;
2084     }
2085 
2086     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2087     sr->main_conf = cscf->ctx->main_conf;
2088     sr->srv_conf = cscf->ctx->srv_conf;
2089     sr->loc_conf = cscf->ctx->loc_conf;
2090 
2091     sr->pool = r->pool;
2092 
2093     sr->headers_in = r->headers_in;
2094 
2095     ngx_http_clear_content_length(sr);
2096     ngx_http_clear_accept_ranges(sr);
2097     ngx_http_clear_last_modified(sr);
2098 
2099     sr->request_body = r->request_body;
2100 
2101     sr->method = NGX_HTTP_GET;
2102     sr->http_version = r->http_version;
2103 
2104     sr->request_line = r->request_line;
2105     sr->uri = *uri;
2106 
2107     if (args) {
2108         sr->args = *args;
2109     }
2110 
2111     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
2112                    "http subrequest \"%V?%V\"", uri, &sr->args);
2113 
2114     sr->zero_in_uri = (flags & NGX_HTTP_ZERO_IN_URI) != 0;
2115     sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
2116     sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
2117 
2118     sr->unparsed_uri = r->unparsed_uri;
2119     sr->method_name = ngx_http_core_get_method;
2120     sr->http_protocol = r->http_protocol;
2121 
2122     ngx_http_set_exten(sr);
2123 
2124     sr->main = r->main;
2125     sr->parent = r;
2126     sr->post_subrequest = ps;
2127     sr->read_event_handler = ngx_http_request_empty_handler;
2128     sr->write_event_handler = ngx_http_handler;
2129 
2130     if (c->data == r && r->postponed == NULL) {
2131         c->data = sr;
2132     }
2133 
2134     sr->variables = r->variables;
2135 
2136     sr->log_handler = r->log_handler;
2137 
2138     pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
2139     if (pr == NULL) {
2140         return NGX_ERROR;
2141     }
2142 
2143     pr->request = sr;
2144     pr->out = NULL;
2145     pr->next = NULL;
2146 
2147     if (r->postponed) {
2148         for (p = r->postponed; p->next; p = p->next) { /* void */ }
2149         p->next = pr;
2150 
2151     } else {
2152         r->postponed = pr;
2153     }
2154 
2155     sr->internal = 1;
2156 
2157     sr->discard_body = r->discard_body;
2158     sr->expect_tested = 1;
2159     sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
2160 
2161     sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
2162 
2163     r->main->subrequests++;
2164     r->main->count++;
2165 
2166     *psr = sr;
2167 
2168     return ngx_http_post_request(sr, NULL);
2169 }
2170 
2171 
2172 ngx_int_t
2173 ngx_http_internal_redirect(ngx_http_request_t *r,
2174     ngx_str_t *uri, ngx_str_t *args)
2175 {
2176     ngx_http_core_srv_conf_t  *cscf;
2177 
2178     r->uri_changes--;
2179 
2180     if (r->uri_changes == 0) {
2181         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2182                       "rewrite or internal redirection cycle "
2183                       "while internal redirect to \"%V\"", uri);
2184 
2185         r->main->count++;
2186         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
2187         return NGX_DONE;
2188     }
2189 
2190     r->uri = *uri;
2191 
2192     if (args) {
2193         r->args = *args;
2194 
2195     } else {
2196         r->args.len = 0;
2197         r->args.data = NULL;
2198     }
2199 
2200     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2201                    "internal redirect: \"%V?%V\"", uri, &r->args);
2202 
2203     ngx_http_set_exten(r);
2204 
2205     /* clear the modules contexts */
2206     ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
2207 
2208     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2209     r->loc_conf = cscf->ctx->loc_conf;
2210 
2211     ngx_http_update_location_config(r);
2212 
2213 #if (NGX_HTTP_CACHE)
2214     r->cache = NULL;
2215 #endif
2216 
2217     r->internal = 1;
2218     r->main->count++;
2219 
2220     ngx_http_handler(r);
2221 
2222     return NGX_DONE;
2223 }
2224 
2225 
2226 ngx_int_t
2227 ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
2228 {
2229     ngx_http_core_srv_conf_t    *cscf;
2230     ngx_http_core_loc_conf_t   **clcfp;
2231     ngx_http_core_main_conf_t   *cmcf;
2232 
2233     r->main->count++;
2234 
2235     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2236 
2237     if (cscf->named_locations) {
2238 
2239         for (clcfp = cscf->named_locations; *clcfp; clcfp++) {
2240 
2241             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2242                            "test location: \"%V\"", &(*clcfp)->name);
2243 
2244             if (name->len != (*clcfp)->name.len
2245                 || ngx_strncmp(name->data, (*clcfp)->name.data, name->len) != 0)
2246             {
2247                 continue;
2248             }
2249 
2250             ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2251                            "using location: %V \"%V?%V\"",
2252                            name, &r->uri, &r->args);
2253 
2254             r->internal = 1;
2255             r->content_handler = NULL;
2256             r->loc_conf = (*clcfp)->loc_conf;
2257 
2258             ngx_http_update_location_config(r);
2259 
2260             cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
2261 
2262             r->phase_handler = cmcf->phase_engine.location_rewrite_index;
2263 
2264             ngx_http_core_run_phases(r);
2265 
2266             return NGX_DONE;
2267         }
2268     }
2269 
2270     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2271                   "could not find named location \"%V\"", name);
2272 
2273     ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
2274 
2275     return NGX_DONE;
2276 }
2277 
2278 
2279 ngx_http_cleanup_t *
2280 ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
2281 {
2282     ngx_http_cleanup_t  *cln;
2283 
2284     r = r->main;
2285 
2286     cln = ngx_palloc(r->pool, sizeof(ngx_http_cleanup_t));
2287     if (cln == NULL) {
2288         return NULL;
2289     }
2290 
2291     if (size) {
2292         cln->data = ngx_palloc(r->pool, size);
2293         if (cln->data == NULL) {
2294             return NULL;
2295         }
2296 
2297     } else {
2298         cln->data = NULL;
2299     }
2300 
2301     cln->handler = NULL;
2302     cln->next = r->cleanup;
2303 
2304     r->cleanup = cln;
2305 
2306     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2307                    "http cleanup add: %p", cln);
2308 
2309     return cln;
2310 }
2311 
2312 
2313 static char *
2314 ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
2315 {
2316     char                        *rv;
2317     void                        *mconf;
2318     ngx_uint_t                   i;
2319     ngx_conf_t                   pcf;
2320     ngx_http_module_t           *module;
2321     ngx_http_conf_ctx_t         *ctx, *http_ctx;
2322     ngx_http_core_srv_conf_t    *cscf, **cscfp;
2323     ngx_http_core_main_conf_t   *cmcf;
2324 
2325     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
2326     if (ctx == NULL) {
2327         return NGX_CONF_ERROR;
2328     }
2329 
2330     http_ctx = cf->ctx;
2331     ctx->main_conf = http_ctx->main_conf;
2332 
2333     /* the server{}'s srv_conf */
2334 
2335     ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
2336     if (ctx->srv_conf == NULL) {
2337         return NGX_CONF_ERROR;
2338     }
2339 
2340     /* the server{}'s loc_conf */
2341 
2342     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
2343     if (ctx->loc_conf == NULL) {
2344         return NGX_CONF_ERROR;
2345     }
2346 
2347     for (i = 0; ngx_modules[i]; i++) {
2348         if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
2349             continue;
2350         }
2351 
2352         module = ngx_modules[i]->ctx;
2353 
2354         if (module->create_srv_conf) {
2355             mconf = module->create_srv_conf(cf);
2356             if (mconf == NULL) {
2357                 return NGX_CONF_ERROR;
2358             }
2359 
2360             ctx->srv_conf[ngx_modules[i]->ctx_index] = mconf;
2361         }
2362 
2363         if (module->create_loc_conf) {
2364             mconf = module->create_loc_conf(cf);
2365             if (mconf == NULL) {
2366                 return NGX_CONF_ERROR;
2367             }
2368 
2369             ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
2370         }
2371     }
2372 
2373 
2374     /* the server configuration context */
2375 
2376     cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
2377     cscf->ctx = ctx;
2378 
2379 
2380     cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
2381 
2382     cscfp = ngx_array_push(&cmcf->servers);
2383     if (cscfp == NULL) {
2384         return NGX_CONF_ERROR;
2385     }
2386 
2387     *cscfp = cscf;
2388 
2389 
2390     /* parse inside server{} */
2391 
2392     pcf = *cf;
2393     cf->ctx = ctx;
2394     cf->cmd_type = NGX_HTTP_SRV_CONF;
2395 
2396     rv = ngx_conf_parse(cf, NULL);
2397 
2398     *cf = pcf;
2399 
2400     return rv;
2401 }
2402 
2403 
2404 static char *
2405 ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
2406 {
2407     char                      *rv;
2408     u_char                    *mod;
2409     size_t                     len;
2410     ngx_str_t                 *value, *name;
2411     ngx_uint_t                 i;
2412     ngx_conf_t                 save;
2413     ngx_http_module_t         *module;
2414     ngx_http_conf_ctx_t       *ctx, *pctx;
2415     ngx_http_core_loc_conf_t  *clcf, *pclcf;
2416 
2417     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
2418     if (ctx == NULL) {
2419         return NGX_CONF_ERROR;
2420     }
2421 
2422     pctx = cf->ctx;
2423     ctx->main_conf = pctx->main_conf;
2424     ctx->srv_conf = pctx->srv_conf;
2425 
2426     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
2427     if (ctx->loc_conf == NULL) {
2428         return NGX_CONF_ERROR;
2429     }
2430 
2431     for (i = 0; ngx_modules[i]; i++) {
2432         if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
2433             continue;
2434         }
2435 
2436         module = ngx_modules[i]->ctx;
2437 
2438         if (module->create_loc_conf) {
2439             ctx->loc_conf[ngx_modules[i]->ctx_index] =
2440                                                    module->create_loc_conf(cf);
2441             if (ctx->loc_conf[ngx_modules[i]->ctx_index] == NULL) {
2442                  return NGX_CONF_ERROR;
2443             }
2444         }
2445     }
2446 
2447     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
2448     clcf->loc_conf = ctx->loc_conf;
2449 
2450     value = cf->args->elts;
2451 
2452     if (cf->args->nelts == 3) {
2453 
2454         len = value[1].len;
2455         mod = value[1].data;
2456         name = &value[2];
2457 
2458         if (len == 1 && mod[0] == '=') {
2459 
2460             clcf->name = *name;
2461             clcf->exact_match = 1;
2462 
2463         } else if (len == 2 && mod[0] == '^' && mod[1] == '~') {
2464 
2465             clcf->name = *name;
2466             clcf->noregex = 1;
2467 
2468         } else if (len == 1 && mod[0] == '~') {
2469 
2470             if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
2471                 return NGX_CONF_ERROR;
2472             }
2473 
2474         } else if (len == 2 && mod[0] == '~' && mod[1] == '*') {
2475 
2476             if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
2477                 return NGX_CONF_ERROR;
2478             }
2479 
2480         } else {
2481             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2482                                "invalid location modifier \"%V\"", &value[1]);
2483             return NGX_CONF_ERROR;
2484         }
2485 
2486     } else {
2487 
2488         name = &value[1];
2489 
2490         if (name->data[0] == '=') {
2491 
2492             clcf->name.len = name->len - 1;
2493             clcf->name.data = name->data + 1;
2494             clcf->exact_match = 1;
2495 
2496         } else if (name->data[0] == '^' && name->data[1] == '~') {
2497 
2498             clcf->name.len = name->len - 2;
2499             clcf->name.data = name->data + 2;
2500             clcf->noregex = 1;
2501 
2502         } else if (name->data[0] == '~') {
2503 
2504             name->len--;
2505             name->data++;
2506 
2507             if (name->data[0] == '*') {
2508 
2509                 name->len--;
2510                 name->data++;
2511 
2512                 if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
2513                     return NGX_CONF_ERROR;
2514                 }
2515 
2516             } else {
2517                 if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
2518                     return NGX_CONF_ERROR;
2519                 }
2520             }
2521 
2522         } else {
2523 
2524             clcf->name = *name;
2525 
2526             if (name->data[0] == '@') {
2527                 clcf->named = 1;
2528             }
2529         }
2530     }
2531 
2532     pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
2533 
2534     if (pclcf->name.len) {
2535 
2536         /* nested location */
2537 
2538 #if 0
2539         clcf->prev_location = pclcf;
2540 #endif
2541 
2542         if (pclcf->exact_match) {
2543             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2544                                "location \"%V\" could not be inside "
2545                                "the exact location \"%V\"",
2546                                &clcf->name, &pclcf->name);
2547             return NGX_CONF_ERROR;
2548         }
2549 
2550         if (pclcf->named) {
2551             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2552                                "location \"%V\" could not be inside "
2553                                "the named location \"%V\"",
2554                                &clcf->name, &pclcf->name);
2555             return NGX_CONF_ERROR;
2556         }
2557 
2558         if (clcf->named) {
2559             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2560                                "named location \"%V\" must be "
2561                                "on server level only",
2562                                &clcf->name);
2563             return NGX_CONF_ERROR;
2564         }
2565 
2566         len = pclcf->name.len;
2567 
2568 #if (NGX_PCRE)
2569         if (clcf->regex == NULL
2570             && ngx_strncmp(clcf->name.data, pclcf->name.data, len) != 0)
2571 #else
2572         if (ngx_strncmp(clcf->name.data, pclcf->name.data, len) != 0)
2573 #endif
2574         {
2575             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2576                                "location \"%V\" is outside location \"%V\"",
2577                                &clcf->name, &pclcf->name);
2578             return NGX_CONF_ERROR;
2579         }
2580     }
2581 
2582     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
2583         return NGX_CONF_ERROR;
2584     }
2585 
2586     save = *cf;
2587     cf->ctx = ctx;
2588     cf->cmd_type = NGX_HTTP_LOC_CONF;
2589 
2590     rv = ngx_conf_parse(cf, NULL);
2591 
2592     *cf = save;
2593 
2594     return rv;
2595 }
2596 
2597 
2598 static ngx_int_t
2599 ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
2600     ngx_str_t *regex, ngx_uint_t caseless)
2601 {
2602 #if (NGX_PCRE)
2603     ngx_str_t  err;
2604     u_char     errstr[NGX_MAX_CONF_ERRSTR];
2605 
2606     err.len = NGX_MAX_CONF_ERRSTR;
2607     err.data = errstr;
2608 
2609 #if (NGX_HAVE_CASELESS_FILESYSTEM)
2610     caseless = 1;
2611 #endif
2612 
2613     clcf->regex = ngx_regex_compile(regex, caseless ? NGX_REGEX_CASELESS: 0,
2614                                     cf->pool, &err);
2615 
2616     if (clcf->regex == NULL) {
2617         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
2618         return NGX_ERROR;
2619     }
2620 
2621     clcf->name = *regex;
2622     clcf->captures = (ngx_regex_capture_count(clcf->regex) > 0);
2623 
2624     return NGX_OK;
2625 
2626 #else
2627 
2628     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2629                        "the using of the regex \"%V\" requires PCRE library",
2630                        regex);
2631     return NGX_ERROR;
2632 
2633 #endif
2634 }
2635 
2636 
2637 static char *
2638 ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2639 {
2640     ngx_http_core_loc_conf_t *lcf = conf;
2641 
2642     char        *rv;
2643     ngx_conf_t   save;
2644 
2645     if (lcf->types == NULL) {
2646         lcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
2647         if (lcf->types == NULL) {
2648             return NGX_CONF_ERROR;
2649         }
2650     }
2651 
2652     save = *cf;
2653     cf->handler = ngx_http_core_type;
2654     cf->handler_conf = conf;
2655 
2656     rv = ngx_conf_parse(cf, NULL);
2657 
2658     *cf = save;
2659 
2660     return rv;
2661 }
2662 
2663 
2664 static char *
2665 ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
2666 {
2667     ngx_http_core_loc_conf_t *lcf = conf;
2668 
2669     ngx_str_t       *value, *content_type, *old, file;
2670     ngx_uint_t       i, n, hash;
2671     ngx_hash_key_t  *type;
2672 
2673     value = cf->args->elts;
2674 
2675     if (ngx_strcmp(value[0].data, "include") == 0) {
2676         file = value[1];
2677 
2678         if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
2679             return NGX_CONF_ERROR;
2680         }
2681 
2682         ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
2683 
2684         return ngx_conf_parse(cf, &file);
2685     }
2686 
2687     content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));
2688     if (content_type == NULL) {
2689         return NGX_CONF_ERROR;
2690     }
2691 
2692     *content_type = value[0];
2693 
2694     for (i = 1; i < cf->args->nelts; i++) {
2695 
2696         hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
2697 
2698         type = lcf->types->elts;
2699         for (n = 0; n < lcf->types->nelts; n++) {
2700             if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
2701                 old = type[n].value;
2702                 type[n].value = content_type;
2703 
2704                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
2705                                    "duplicate extention \"%V\", "
2706                                    "content type: \"%V\", "
2707                                    "old content type: \"%V\"",
2708                                    &value[i], content_type, old);
2709                 continue;
2710             }
2711         }
2712 
2713 
2714         type = ngx_array_push(lcf->types);
2715         if (type == NULL) {
2716             return NGX_CONF_ERROR;
2717         }
2718 
2719         type->key = value[i];
2720         type->key_hash = hash;
2721         type->value = content_type;
2722     }
2723 
2724     return NGX_CONF_OK;
2725 }
2726 
2727 
2728 static ngx_int_t
2729 ngx_http_core_preconfiguration(ngx_conf_t *cf)
2730 {
2731     return ngx_http_variables_add_core_vars(cf);
2732 }
2733 
2734 
2735 static void *
2736 ngx_http_core_create_main_conf(ngx_conf_t *cf)
2737 {
2738     ngx_http_core_main_conf_t  *cmcf;
2739 
2740     cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
2741     if (cmcf == NULL) {
2742         return NULL;
2743     }
2744 
2745     if (ngx_array_init(&cmcf->servers, cf->pool, 4,
2746                        sizeof(ngx_http_core_srv_conf_t *))
2747         != NGX_OK)
2748     {
2749         return NULL;
2750     }
2751 
2752     cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
2753     cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;
2754 
2755     cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
2756     cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;
2757 
2758     return cmcf;
2759 }
2760 
2761 
2762 static char *
2763 ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
2764 {
2765     ngx_http_core_main_conf_t *cmcf = conf;
2766 
2767     if (cmcf->server_names_hash_max_size == NGX_CONF_UNSET_UINT) {
2768         cmcf->server_names_hash_max_size = 512;
2769     }
2770 
2771     if (cmcf->server_names_hash_bucket_size == NGX_CONF_UNSET_UINT) {
2772         cmcf->server_names_hash_bucket_size = ngx_cacheline_size;
2773     }
2774 
2775     cmcf->server_names_hash_bucket_size =
2776             ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);
2777 
2778 
2779     if (cmcf->variables_hash_max_size == NGX_CONF_UNSET_UINT) {
2780         cmcf->variables_hash_max_size = 512;
2781     }
2782 
2783     if (cmcf->variables_hash_bucket_size == NGX_CONF_UNSET_UINT) {
2784         cmcf->variables_hash_bucket_size = 64;
2785     }
2786 
2787     cmcf->variables_hash_bucket_size =
2788                ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);
2789 
2790     return NGX_CONF_OK;
2791 }
2792 
2793 
2794 static void *
2795 ngx_http_core_create_srv_conf(ngx_conf_t *cf)
2796 {
2797     ngx_http_core_srv_conf_t  *cscf;
2798 
2799     cscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t));
2800     if (cscf == NULL) {
2801         return NULL;
2802     }
2803 
2804     /*
2805      * set by ngx_pcalloc():
2806      *
2807      *     conf->client_large_buffers.num = 0;
2808      */
2809 
2810     if (ngx_array_init(&cscf->listen, cf->temp_pool, 4,
2811                        sizeof(ngx_http_listen_t))
2812         != NGX_OK)
2813     {
2814         return NULL;
2815     }
2816 
2817     if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
2818                        sizeof(ngx_http_server_name_t))
2819         != NGX_OK)
2820     {
2821         return NULL;
2822     }
2823 
2824     cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
2825     cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
2826     cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
2827     cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
2828     cscf->ignore_invalid_headers = NGX_CONF_UNSET;
2829     cscf->merge_slashes = NGX_CONF_UNSET;
2830     cscf->underscores_in_headers = NGX_CONF_UNSET;
2831 
2832     return cscf;
2833 }
2834 
2835 
2836 static char *
2837 ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
2838 {
2839     ngx_http_core_srv_conf_t *prev = parent;
2840     ngx_http_core_srv_conf_t *conf = child;
2841 
2842     ngx_http_listen_t       *ls;
2843     struct sockaddr_in      *sin;
2844     ngx_http_server_name_t  *sn;
2845 
2846     /* TODO: it does not merge, it inits only */
2847 
2848     if (conf->listen.nelts == 0) {
2849         ls = ngx_array_push(&conf->listen);
2850         if (ls == NULL) {
2851             return NGX_CONF_ERROR;
2852         }
2853 
2854         ngx_memzero(ls, sizeof(ngx_http_listen_t));
2855 
2856         sin = (struct sockaddr_in *) &ls->sockaddr;
2857 
2858         sin->sin_family = AF_INET;
2859 #if (NGX_WIN32)
2860         sin->sin_port = htons(80);
2861 #else
2862         sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
2863 #endif
2864         sin->sin_addr.s_addr = INADDR_ANY;
2865 
2866         ls->socklen = sizeof(struct sockaddr_in);
2867 
2868         ls->conf.backlog = NGX_LISTEN_BACKLOG;
2869         ls->conf.rcvbuf = -1;
2870         ls->conf.sndbuf = -1;
2871         ls->conf.wildcard = 1;
2872 
2873         (void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr,
2874                              NGX_SOCKADDR_STRLEN, 1);
2875     }
2876 
2877     if (conf->server_name.data == NULL) {
2878         conf->server_name = cf->cycle->hostname;
2879 
2880         sn = ngx_array_push(&conf->server_names);
2881         if (sn == NULL) {
2882             return NGX_CONF_ERROR;
2883         }
2884 
2885 #if (NGX_PCRE)
2886         sn->regex = NULL;
2887         sn->captures = 0;
2888 #endif
2889         sn->core_srv_conf = conf;
2890         sn->name.len = conf->server_name.len;
2891         sn->name.data = conf->server_name.data;
2892     }
2893 
2894     ngx_conf_merge_size_value(conf->connection_pool_size,
2895                               prev->connection_pool_size, 256);
2896     ngx_conf_merge_size_value(conf->request_pool_size,
2897                               prev->request_pool_size, 4096);
2898     ngx_conf_merge_msec_value(conf->client_header_timeout,
2899                               prev->client_header_timeout, 60000);
2900     ngx_conf_merge_size_value(conf->client_header_buffer_size,
2901                               prev->client_header_buffer_size, 1024);
2902     ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
2903                               prev->large_client_header_buffers,
2904                               4, ngx_pagesize);
2905 
2906     if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
2907         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2908                            "the \"large_client_header_buffers\" size must be "
2909                            "equal to or bigger than \"connection_pool_size\"");
2910         return NGX_CONF_ERROR;
2911     }
2912 
2913     ngx_conf_merge_value(conf->ignore_invalid_headers,
2914                               prev->ignore_invalid_headers, 1);
2915 
2916     ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);
2917 
2918     ngx_conf_merge_value(conf->underscores_in_headers,
2919                               prev->underscores_in_headers, 0);
2920 
2921     return NGX_CONF_OK;
2922 }
2923 
2924 
2925 static void *
2926 ngx_http_core_create_loc_conf(ngx_conf_t *cf)
2927 {
2928     ngx_http_core_loc_conf_t  *lcf;
2929 
2930     lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
2931     if (lcf == NULL) {
2932         return NULL;
2933     }
2934 
2935     /*
2936      * set by ngx_pcalloc():
2937      *
2938      *     lcf->root = { 0, NULL };
2939      *     lcf->limit_except = 0;
2940      *     lcf->post_action = { 0, NULL };
2941      *     lcf->types = NULL;
2942      *     lcf->default_type = { 0, NULL };
2943      *     lcf->error_log = NULL;
2944      *     lcf->error_pages = NULL;
2945      *     lcf->try_files = NULL;
2946      *     lcf->client_body_path = NULL;
2947      *     lcf->regex = NULL;
2948      *     lcf->exact_match = 0;
2949      *     lcf->auto_redirect = 0;
2950      *     lcf->alias = 0;
2951      *     lcf->gzip_proxied = 0;
2952      */
2953 
2954     lcf->client_max_body_size = NGX_CONF_UNSET;
2955     lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
2956     lcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
2957     lcf->satisfy = NGX_CONF_UNSET_UINT;
2958     lcf->if_modified_since = NGX_CONF_UNSET_UINT;
2959     lcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
2960     lcf->client_body_in_single_buffer = NGX_CONF_UNSET;
2961     lcf->internal = NGX_CONF_UNSET;
2962     lcf->sendfile = NGX_CONF_UNSET;
2963     lcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
2964 #if (NGX_HAVE_FILE_AIO)
2965     lcf->aio = NGX_CONF_UNSET;
2966 #endif
2967     lcf->read_ahead = NGX_CONF_UNSET_SIZE;
2968     lcf->directio = NGX_CONF_UNSET;
2969     lcf->directio_alignment = NGX_CONF_UNSET;
2970     lcf->tcp_nopush = NGX_CONF_UNSET;
2971     lcf->tcp_nodelay = NGX_CONF_UNSET;
2972     lcf->send_timeout = NGX_CONF_UNSET_MSEC;
2973     lcf->send_lowat = NGX_CONF_UNSET_SIZE;
2974     lcf->postpone_output = NGX_CONF_UNSET_SIZE;
2975     lcf->limit_rate = NGX_CONF_UNSET_SIZE;
2976     lcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
2977     lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
2978     lcf->keepalive_header = NGX_CONF_UNSET;
2979     lcf->keepalive_requests = NGX_CONF_UNSET_UINT;
2980     lcf->lingering_time = NGX_CONF_UNSET_MSEC;
2981     lcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
2982     lcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
2983     lcf->reset_timedout_connection = NGX_CONF_UNSET;
2984     lcf->server_name_in_redirect = NGX_CONF_UNSET;
2985     lcf->port_in_redirect = NGX_CONF_UNSET;
2986     lcf->msie_padding = NGX_CONF_UNSET;
2987     lcf->msie_refresh = NGX_CONF_UNSET;
2988     lcf->log_not_found = NGX_CONF_UNSET;
2989     lcf->log_subrequest = NGX_CONF_UNSET;
2990     lcf->recursive_error_pages = NGX_CONF_UNSET;
2991     lcf->server_tokens = NGX_CONF_UNSET;
2992     lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
2993     lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
2994 
2995     lcf->open_file_cache = NGX_CONF_UNSET_PTR;
2996     lcf->open_file_cache_valid = NGX_CONF_UNSET;
2997     lcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
2998     lcf->open_file_cache_errors = NGX_CONF_UNSET;
2999     lcf->open_file_cache_events = NGX_CONF_UNSET;
3000 
3001 #if (NGX_HTTP_GZIP)
3002     lcf->gzip_vary = NGX_CONF_UNSET;
3003     lcf->gzip_http_version = NGX_CONF_UNSET_UINT;
3004 #if (NGX_PCRE)
3005     lcf->gzip_disable = NGX_CONF_UNSET_PTR;
3006     lcf->gzip_disable_msie6 = 3;
3007 #endif
3008 #endif
3009 
3010     return lcf;
3011 }
3012 
3013 
3014 static ngx_str_t  ngx_http_core_text_html_type = ngx_string("text/html");
3015 static ngx_str_t  ngx_http_core_image_gif_type = ngx_string("image/gif");
3016 static ngx_str_t  ngx_http_core_image_jpeg_type = ngx_string("image/jpeg");
3017 
3018 static ngx_hash_key_t  ngx_http_core_default_types[] = {
3019     { ngx_string("html"), 0, &ngx_http_core_text_html_type },
3020     { ngx_string("gif"), 0, &ngx_http_core_image_gif_type },
3021     { ngx_string("jpg"), 0, &ngx_http_core_image_jpeg_type },
3022     { ngx_null_string, 0, NULL }
3023 };
3024 
3025 
3026 static char *
3027 ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
3028 {
3029     ngx_http_core_loc_conf_t *prev = parent;
3030     ngx_http_core_loc_conf_t *conf = child;
3031 
3032     ngx_uint_t        i;
3033     ngx_hash_key_t   *type;
3034     ngx_hash_init_t   types_hash;
3035 
3036     if (conf->root.data == NULL) {
3037 
3038         conf->alias = prev->alias;
3039         conf->root = prev->root;
3040         conf->root_lengths = prev->root_lengths;
3041         conf->root_values = prev->root_values;
3042 
3043         if (prev->root.data == NULL) {
3044             conf->root.len = sizeof("html") - 1;
3045             conf->root.data = (u_char *) "html";
3046 
3047             if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) {
3048                 return NGX_CONF_ERROR;
3049             }
3050         }
3051     }
3052 
3053     if (conf->post_action.data == NULL) {
3054         conf->post_action = prev->post_action;
3055     }
3056 
3057     ngx_conf_merge_uint_value(conf->types_hash_max_size,
3058                               prev->types_hash_max_size, 1024);
3059 
3060     ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
3061                               prev->types_hash_bucket_size,
3062                               ngx_cacheline_size);
3063 
3064     conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
3065                                              ngx_cacheline_size);
3066 
3067     /*
3068      * the special handling the "types" directive in the "http" section
3069      * to inherit the http's conf->types_hash to all servers
3070      */
3071 
3072     if (prev->types && prev->types_hash.buckets == NULL) {
3073 
3074         types_hash.hash = &prev->types_hash;
3075         types_hash.key = ngx_hash_key_lc;
3076         types_hash.max_size = conf->types_hash_max_size;
3077         types_hash.bucket_size = conf->types_hash_bucket_size;
3078         types_hash.name = "types_hash";
3079         types_hash.pool = cf->pool;
3080         types_hash.temp_pool = NULL;
3081 
3082         if (ngx_hash_init(&types_hash, prev->types->elts, prev->types->nelts)
3083             != NGX_OK)
3084         {
3085             return NGX_CONF_ERROR;
3086         }
3087     }
3088 
3089     if (conf->types == NULL) {
3090         conf->types = prev->types;
3091         conf->types_hash = prev->types_hash;
3092     }
3093 
3094     if (conf->types == NULL) {
3095         conf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t));
3096         if (conf->types == NULL) {
3097             return NGX_CONF_ERROR;
3098         }
3099 
3100         for (i = 0; ngx_http_core_default_types[i].key.len; i++) {
3101             type = ngx_array_push(conf->types);
3102             if (type == NULL) {
3103                 return NGX_CONF_ERROR;
3104             }
3105 
3106             type->key = ngx_http_core_default_types[i].key;
3107             type->key_hash =
3108                        ngx_hash_key_lc(ngx_http_core_default_types[i].key.data,
3109                                        ngx_http_core_default_types[i].key.len);
3110             type->value = ngx_http_core_default_types[i].value;
3111         }
3112     }
3113 
3114     if (conf->types_hash.buckets == NULL) {
3115 
3116         types_hash.hash = &conf->types_hash;
3117         types_hash.key = ngx_hash_key_lc;
3118         types_hash.max_size = conf->types_hash_max_size;
3119         types_hash.bucket_size = conf->types_hash_bucket_size;
3120         types_hash.name = "mime_types_hash";
3121         types_hash.pool = cf->pool;
3122         types_hash.temp_pool = NULL;
3123 
3124         if (ngx_hash_init(&types_hash, conf->types->elts, conf->types->nelts)
3125             != NGX_OK)
3126         {
3127             return NGX_CONF_ERROR;
3128         }
3129     }
3130 
3131     if (conf->error_log == NULL) {
3132         if (prev->error_log) {
3133             conf->error_log = prev->error_log;
3134         } else {
3135             conf->error_log = &cf->cycle->new_log;
3136         }
3137     }
3138 
3139     if (conf->error_pages == NULL && prev->error_pages) {
3140         conf->error_pages = prev->error_pages;
3141     }
3142 
3143     ngx_conf_merge_str_value(conf->default_type,
3144                               prev->default_type, "text/plain");
3145 
3146     ngx_conf_merge_off_value(conf->client_max_body_size,
3147                               prev->client_max_body_size, 1 * 1024 * 1024);
3148     ngx_conf_merge_size_value(conf->client_body_buffer_size,
3149                               prev->client_body_buffer_size,
3150                               (size_t) 2 * ngx_pagesize);
3151     ngx_conf_merge_msec_value(conf->client_body_timeout,
3152                               prev->client_body_timeout, 60000);
3153 
3154     ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
3155                               NGX_HTTP_SATISFY_ALL);
3156     ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
3157                               NGX_HTTP_IMS_EXACT);
3158     ngx_conf_merge_uint_value(conf->client_body_in_file_only,
3159                               prev->client_body_in_file_only, 0);
3160     ngx_conf_merge_value(conf->client_body_in_single_buffer,
3161                               prev->client_body_in_single_buffer, 0);
3162     ngx_conf_merge_value(conf->internal, prev->internal, 0);
3163     ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
3164     ngx_conf_merge_size_value(conf->sendfile_max_chunk,
3165                               prev->sendfile_max_chunk, 0);
3166 #if (NGX_HAVE_FILE_AIO)
3167     ngx_conf_merge_value(conf->aio, prev->aio, 0);
3168 #endif
3169     ngx_conf_merge_size_value(conf->read_ahead, prev->read_ahead, 0);
3170     ngx_conf_merge_off_value(conf->directio, prev->directio,
3171                               NGX_MAX_OFF_T_VALUE);
3172     ngx_conf_merge_off_value(conf->directio_alignment, prev->directio_alignment,
3173                               512);
3174     ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
3175     ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);
3176 
3177     ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
3178     ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
3179     ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
3180                               1460);
3181     ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
3182     ngx_conf_merge_size_value(conf->limit_rate_after, prev->limit_rate_after,
3183                               0);
3184     ngx_conf_merge_msec_value(conf->keepalive_timeout,
3185                               prev->keepalive_timeout, 75000);
3186     ngx_conf_merge_sec_value(conf->keepalive_header,
3187                               prev->keepalive_header, 0);
3188     ngx_conf_merge_uint_value(conf->keepalive_requests,
3189                               prev->keepalive_requests, 100);
3190     ngx_conf_merge_msec_value(conf->lingering_time,
3191                               prev->lingering_time, 30000);
3192     ngx_conf_merge_msec_value(conf->lingering_timeout,
3193                               prev->lingering_timeout, 5000);
3194     ngx_conf_merge_msec_value(conf->resolver_timeout,
3195                               prev->resolver_timeout, 30000);
3196 
3197     if (conf->resolver == NULL) {
3198 
3199         if (prev->resolver == NULL) {
3200 
3201             /*
3202              * create dummy resolver in http {} context
3203              * to inherit it in all servers
3204              */
3205 
3206             prev->resolver = ngx_resolver_create(cf, NULL);
3207             if (prev->resolver == NULL) {
3208                 return NGX_CONF_ERROR;
3209             }
3210         }
3211 
3212         conf->resolver = prev->resolver;
3213     }
3214 
3215     if (ngx_conf_merge_path_value(cf, &conf->client_body_temp_path,
3216                               prev->client_body_temp_path,
3217                               &ngx_http_client_temp_path)
3218         != NGX_OK)
3219     {
3220         return NGX_CONF_ERROR;
3221     }
3222 
3223     ngx_conf_merge_value(conf->reset_timedout_connection,
3224                               prev->reset_timedout_connection, 0);
3225     ngx_conf_merge_value(conf->server_name_in_redirect,
3226                               prev->server_name_in_redirect, 1);
3227     ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
3228     ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
3229     ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
3230     ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
3231     ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0);
3232     ngx_conf_merge_value(conf->recursive_error_pages,
3233                               prev->recursive_error_pages, 0);
3234     ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
3235 
3236     ngx_conf_merge_ptr_value(conf->open_file_cache,
3237                               prev->open_file_cache, NULL);
3238 
3239     ngx_conf_merge_sec_value(conf->open_file_cache_valid,
3240                               prev->open_file_cache_valid, 60);
3241 
3242     ngx_conf_merge_uint_value(conf->open_file_cache_min_uses,
3243                               prev->open_file_cache_min_uses, 1);
3244 
3245     ngx_conf_merge_sec_value(conf->open_file_cache_errors,
3246                               prev->open_file_cache_errors, 0);
3247 
3248     ngx_conf_merge_sec_value(conf->open_file_cache_events,
3249                               prev->open_file_cache_events, 0);
3250 #if (NGX_HTTP_GZIP)
3251 
3252     ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
3253     ngx_conf_merge_uint_value(conf->gzip_http_version, prev->gzip_http_version,
3254                               NGX_HTTP_VERSION_11);
3255     ngx_conf_merge_bitmask_value(conf->gzip_proxied, prev->gzip_proxied,
3256                               (NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));
3257 
3258 #if (NGX_PCRE)
3259     ngx_conf_merge_ptr_value(conf->gzip_disable, prev->gzip_disable, NULL);
3260 #endif
3261 
3262     if (conf->gzip_disable_msie6 == 3) {
3263         conf->gzip_disable_msie6 =
3264             (prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6;
3265     }
3266 
3267 #endif
3268 
3269     return NGX_CONF_OK;
3270 }
3271 
3272 
3273 static char *
3274 ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3275 {
3276     ngx_http_core_srv_conf_t *scf = conf;
3277 
3278     ngx_str_t          *value, size;
3279     ngx_url_t           u;
3280     ngx_uint_t          n;
3281     ngx_http_listen_t  *ls;
3282 
3283     /*
3284      * TODO: check duplicate 'listen' directives,
3285      *       add resolved name to server names ???
3286      */
3287 
3288     value = cf->args->elts;
3289 
3290     ngx_memzero(&u, sizeof(ngx_url_t));
3291 
3292     u.url = value[1];
3293     u.listen = 1;
3294     u.default_port = 80;
3295 
3296     if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
3297         if (u.err) {
3298             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3299                                "%s in \"%V\" of the \"listen\" directive",
3300                                u.err, &u.url);
3301         }
3302 
3303         return NGX_CONF_ERROR;
3304     }
3305 
3306     ls = ngx_array_push(&scf->listen);
3307     if (ls == NULL) {
3308         return NGX_CONF_ERROR;
3309     }
3310 
3311     ngx_memzero(ls, sizeof(ngx_http_listen_t));
3312 
3313     ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen);
3314 
3315     ls->socklen = u.socklen;
3316     ls->file_name = cf->conf_file->file.name.data;
3317     ls->line = cf->conf_file->line;
3318     ls->conf.backlog = NGX_LISTEN_BACKLOG;
3319     ls->conf.rcvbuf = -1;
3320     ls->conf.sndbuf = -1;
3321     ls->conf.wildcard = u.wildcard;
3322 
3323     (void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr,
3324                          NGX_SOCKADDR_STRLEN, 1);
3325 
3326     if (cf->args->nelts == 2) {
3327         return NGX_CONF_OK;
3328     }
3329 
3330     if (ngx_strcmp(value[2].data, "default") == 0) {
3331         ls->conf.default_server = 1;
3332         n = 3;
3333 
3334     } else {
3335         n = 2;
3336     }
3337 
3338     for ( /* void */ ; n < cf->args->nelts; n++) {
3339 
3340         if (ls->conf.default_server == 0) {
3341             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3342                                "\"%V\" parameter can be specified for "
3343                                "the default \"listen\" directive only",
3344                                &value[n]);
3345             return NGX_CONF_ERROR;
3346         }
3347 
3348         if (ngx_strcmp(value[n].data, "bind") == 0) {
3349             ls->conf.bind = 1;
3350             continue;
3351         }
3352 
3353         if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
3354             ls->conf.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
3355             ls->conf.bind = 1;
3356 
3357             if (ls->conf.backlog == NGX_ERROR || ls->conf.backlog == 0) {
3358                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3359                                    "invalid backlog \"%V\"", &value[n]);
3360                 return NGX_CONF_ERROR;
3361             }
3362 
3363             continue;
3364         }
3365 
3366         if (ngx_strncmp(value[n].data, "rcvbuf=", 7) == 0) {
3367             size.len = value[n].len - 7;
3368             size.data = value[n].data + 7;
3369 
3370             ls->conf.rcvbuf = ngx_parse_size(&size);
3371             ls->conf.bind = 1;
3372 
3373             if (ls->conf.rcvbuf == NGX_ERROR) {
3374                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3375                                    "invalid rcvbuf \"%V\"", &value[n]);
3376                 return NGX_CONF_ERROR;
3377             }
3378 
3379             continue;
3380         }
3381 
3382         if (ngx_strncmp(value[n].data, "sndbuf=", 7) == 0) {
3383             size.len = value[n].len - 7;
3384             size.data = value[n].data + 7;
3385 
3386             ls->conf.sndbuf = ngx_parse_size(&size);
3387             ls->conf.bind = 1;
3388 
3389             if (ls->conf.sndbuf == NGX_ERROR) {
3390                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3391                                    "invalid sndbuf \"%V\"", &value[n]);
3392                 return NGX_CONF_ERROR;
3393             }
3394 
3395             continue;
3396         }
3397 
3398         if (ngx_strncmp(value[n].data, "accept_filter=", 14) == 0) {
3399 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
3400             ls->conf.accept_filter = (char *) &value[n].data[14];
3401             ls->conf.bind = 1;
3402 #else
3403             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3404                                "accept filters \"%V\" are not supported "
3405                                "on this platform, ignored",
3406                                &value[n]);
3407 #endif
3408             continue;
3409         }
3410 
3411         if (ngx_strcmp(value[n].data, "deferred") == 0) {
3412 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
3413             ls->conf.deferred_accept = 1;
3414             ls->conf.bind = 1;
3415 #else
3416             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3417                                "the deferred accept is not supported "
3418                                "on this platform, ignored");
3419 #endif
3420             continue;
3421         }
3422 
3423         if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
3424 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
3425             struct sockaddr  *sa;
3426 
3427             sa = (struct sockaddr *) ls->sockaddr;
3428 
3429             if (sa->sa_family == AF_INET6) {
3430 
3431                 if (ngx_strcmp(&value[n].data[10], "n") == 0) {
3432                     ls->conf.ipv6only = 1;
3433 
3434                 } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
3435                     ls->conf.ipv6only = 2;
3436 
3437                 } else {
3438                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3439                                        "invalid ipv6only flags \"%s\"",
3440                                        &value[n].data[9]);
3441                     return NGX_CONF_ERROR;
3442                 }
3443 
3444                 ls->conf.bind = 1;
3445 
3446             } else {
3447                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3448                                    "ipv6only is not supported "
3449                                    "on addr \"%s\", ignored",
3450                                    ls->conf.addr);
3451             }
3452 
3453             continue;
3454 #else
3455             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3456                                "bind ipv6only is not supported "
3457                                "on this platform");
3458             return NGX_CONF_ERROR;
3459 #endif
3460         }
3461 
3462         if (ngx_strcmp(value[n].data, "ssl") == 0) {
3463 #if (NGX_HTTP_SSL)
3464             ls->conf.ssl = 1;
3465             continue;
3466 #else
3467             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3468                                "the \"ssl\" parameter requires "
3469                                "ngx_http_ssl_module");
3470             return NGX_CONF_ERROR;
3471 #endif
3472         }
3473 
3474         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3475                            "the invalid \"%V\" parameter", &value[n]);
3476         return NGX_CONF_ERROR;
3477     }
3478 
3479     return NGX_CONF_OK;
3480 }
3481 
3482 
3483 static char *
3484 ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3485 {
3486     ngx_http_core_srv_conf_t *cscf = conf;
3487 
3488     u_char                   ch;
3489     ngx_str_t               *value, name;
3490     ngx_uint_t               i;
3491     ngx_http_server_name_t  *sn;
3492 
3493     value = cf->args->elts;
3494 
3495     ch = value[1].data[0];
3496 
3497     if (cscf->server_name.data == NULL) {
3498         if (value[1].len) {
3499             name = value[1];
3500 
3501             if (ch == '.') {
3502                 name.len--;
3503                 name.data++;
3504             }
3505 
3506             cscf->server_name.len = name.len;
3507             cscf->server_name.data = ngx_pstrdup(cf->pool, &name);
3508             if (cscf->server_name.data == NULL) {
3509                 return NGX_CONF_ERROR;
3510             }
3511 
3512         } else {
3513             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3514                                "the first server name must not be empty");
3515             return NGX_CONF_ERROR;
3516         }
3517     }
3518 
3519     for (i = 1; i < cf->args->nelts; i++) {
3520 
3521         ch = value[i].data[0];
3522 
3523         if ((ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
3524             || (ch == '.' && value[i].len < 2))
3525         {
3526             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3527                                "server name \"%V\" is invalid", &value[i]);
3528             return NGX_CONF_ERROR;
3529         }
3530 
3531         if (ngx_strchr(value[i].data, '/')) {
3532             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
3533                                "server name \"%V\" has strange symbols",
3534                                &value[i]);
3535         }
3536 
3537         if (value[i].len == 1 && ch == '*') {
3538             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3539                                "\"server_name *\" is unsupported, use "
3540                                "\"server_name_in_redirect off\" instead");
3541             return NGX_CONF_ERROR;
3542         }
3543 
3544         sn = ngx_array_push(&cscf->server_names);
3545         if (sn == NULL) {
3546             return NGX_CONF_ERROR;
3547         }
3548 
3549 #if (NGX_PCRE)
3550         sn->regex = NULL;
3551         sn->captures = 0;
3552 #endif
3553         sn->core_srv_conf = cscf;
3554         sn->name = value[i];
3555 
3556         if (value[i].data[0] != '~') {
3557             continue;
3558         }
3559 
3560 #if (NGX_PCRE)
3561         {
3562         ngx_str_t  err;
3563         u_char     errstr[NGX_MAX_CONF_ERRSTR];
3564 
3565         if (value[i].len == 1) {
3566             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3567                                "empty regex in server name \"%V\"", &value[i]);
3568             return NGX_CONF_ERROR;
3569         }
3570 
3571         err.len = NGX_MAX_CONF_ERRSTR;
3572         err.data = errstr;
3573 
3574         value[i].len--;
3575         value[i].data++;
3576 
3577         sn->regex = ngx_regex_compile(&value[i], 0, cf->pool, &err);
3578 
3579         if (sn->regex == NULL) {
3580             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
3581             return NGX_CONF_ERROR;
3582         }
3583 
3584         sn->captures = (ngx_regex_capture_count(sn->regex) > 0);
3585         sn->name = value[i];
3586         }
3587 #else
3588         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3589                            "the using of the regex \"%V\" "
3590                            "requires PCRE library", &value[i]);
3591 
3592         return NGX_CONF_ERROR;
3593 #endif
3594     }
3595 
3596     return NGX_CONF_OK;
3597 }
3598 
3599 
3600 static char *
3601 ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3602 {
3603     ngx_http_core_loc_conf_t *lcf = conf;
3604 
3605     ngx_str_t                  *value;
3606     ngx_uint_t                  alias, n;
3607     ngx_http_script_compile_t   sc;
3608 
3609     alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;
3610 
3611     if (lcf->root.data) {
3612 
3613         /* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */
3614 
3615         if ((ngx_uint_t) lcf->alias == alias) {
3616             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3617                                "\"%V\" directive is duplicate",
3618                                &cmd->name);
3619         } else {
3620             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3621                                "\"%V\" directive is duplicate, "
3622                                "\"%s\" directive is specified before",
3623                                &cmd->name, lcf->alias ? "alias" : "root");
3624         }
3625 
3626         return NGX_CONF_ERROR;
3627     }
3628 
3629     if (lcf->named && alias) {
3630         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3631                            "the \"alias\" directive may not be used "
3632                            "inside named location");
3633 
3634         return NGX_CONF_ERROR;
3635     }
3636 
3637     value = cf->args->elts;
3638 
3639     if (ngx_strstr(value[1].data, "$document_root")
3640         || ngx_strstr(value[1].data, "${document_root}"))
3641     {
3642         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3643                            "the $document_root variable may not be used "
3644                            "in the \"%V\" directive",
3645                            &cmd->name);
3646 
3647         return NGX_CONF_ERROR;
3648     }
3649 
3650     if (ngx_strstr(value[1].data, "$realpath_root")
3651         || ngx_strstr(value[1].data, "${realpath_root}"))
3652     {
3653         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3654                            "the $realpath_root variable may not be used "
3655                            "in the \"%V\" directive",
3656                            &cmd->name);
3657 
3658         return NGX_CONF_ERROR;
3659     }
3660 
3661     lcf->alias = alias;
3662     lcf->root = value[1];
3663 
3664     if (!alias && lcf->root.data[lcf->root.len - 1] == '/') {
3665         lcf->root.len--;
3666     }
3667 
3668     if (lcf->root.data[0] != '$') {
3669         if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) != NGX_OK) {
3670             return NGX_CONF_ERROR;
3671         }
3672     }
3673 
3674     n = ngx_http_script_variables_count(&lcf->root);
3675 
3676     ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
3677 
3678     if (n) {
3679         sc.cf = cf;
3680         sc.source = &lcf->root;
3681         sc.lengths = &lcf->root_lengths;
3682         sc.values = &lcf->root_values;
3683         sc.variables = n;
3684         sc.complete_lengths = 1;
3685         sc.complete_values = 1;
3686 
3687         if (ngx_http_script_compile(&sc) != NGX_OK) {
3688             return NGX_CONF_ERROR;
3689         }
3690     }
3691 
3692 #if (NGX_PCRE)
3693 
3694     if (alias && lcf->regex
3695         && (ngx_regex_capture_count(lcf->regex) <= 0 || sc.ncaptures == 0))
3696     {
3697         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3698                            "the \"alias\" directive must use captures "
3699                            "inside location given by regular expression");
3700 
3701         return NGX_CONF_ERROR;
3702     }
3703 
3704 #endif
3705 
3706     return NGX_CONF_OK;
3707 }
3708 
3709 
3710 static ngx_http_method_name_t  ngx_methods_names[] = {
3711    { (u_char *) "GET",       (uint32_t) ~NGX_HTTP_GET },
3712    { (u_char *) "HEAD",      (uint32_t) ~NGX_HTTP_HEAD },
3713    { (u_char *) "POST",      (uint32_t) ~NGX_HTTP_POST },
3714    { (u_char *) "PUT",       (uint32_t) ~NGX_HTTP_PUT },
3715    { (u_char *) "DELETE",    (uint32_t) ~NGX_HTTP_DELETE },
3716    { (u_char *) "MKCOL",     (uint32_t) ~NGX_HTTP_MKCOL },
3717    { (u_char *) "COPY",      (uint32_t) ~NGX_HTTP_COPY },
3718    { (u_char *) "MOVE",      (uint32_t) ~NGX_HTTP_MOVE },
3719    { (u_char *) "OPTIONS",   (uint32_t) ~NGX_HTTP_OPTIONS },
3720    { (u_char *) "PROPFIND" , (uint32_t) ~NGX_HTTP_PROPFIND },
3721    { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH },
3722    { (u_char *) "LOCK",      (uint32_t) ~NGX_HTTP_LOCK },
3723    { (u_char *) "UNLOCK",    (uint32_t) ~NGX_HTTP_UNLOCK },
3724    { NULL, 0 }
3725 };
3726 
3727 
3728 static char *
3729 ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3730 {
3731     ngx_http_core_loc_conf_t *pclcf = conf;
3732 
3733     char                      *rv;
3734     void                      *mconf;
3735     ngx_str_t                 *value;
3736     ngx_uint_t                 i;
3737     ngx_conf_t                 save;
3738     ngx_http_module_t         *module;
3739     ngx_http_conf_ctx_t       *ctx, *pctx;
3740     ngx_http_method_name_t    *name;
3741     ngx_http_core_loc_conf_t  *clcf;
3742 
3743     if (pclcf->limit_except) {
3744         return "duplicate";
3745     }
3746 
3747     pclcf->limit_except = 0xffffffff;
3748 
3749     value = cf->args->elts;
3750 
3751     for (i = 1; i < cf->args->nelts; i++) {
3752         for (name = ngx_methods_names; name->name; name++) {
3753 
3754             if (ngx_strcasecmp(value[i].data, name->name) == 0) {
3755                 pclcf->limit_except &= name->method;
3756                 goto next;
3757             }
3758         }
3759 
3760         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3761                            "invalid method \"%V\"", &value[i]);
3762         return NGX_CONF_ERROR;
3763 
3764     next:
3765         continue;
3766     }
3767 
3768     if (!(pclcf->limit_except & NGX_HTTP_GET)) {
3769         pclcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
3770     }
3771 
3772     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
3773     if (ctx == NULL) {
3774         return NGX_CONF_ERROR;
3775     }
3776 
3777     pctx = cf->ctx;
3778     ctx->main_conf = pctx->main_conf;
3779     ctx->srv_conf = pctx->srv_conf;
3780 
3781     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
3782     if (ctx->loc_conf == NULL) {
3783         return NGX_CONF_ERROR;
3784     }
3785 
3786     for (i = 0; ngx_modules[i]; i++) {
3787         if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
3788             continue;
3789         }
3790 
3791         module = ngx_modules[i]->ctx;
3792 
3793         if (module->create_loc_conf) {
3794 
3795             mconf = module->create_loc_conf(cf);
3796             if (mconf == NULL) {
3797                  return NGX_CONF_ERROR;
3798             }
3799 
3800             ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
3801         }
3802     }
3803 
3804 
3805     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
3806     pclcf->limit_except_loc_conf = ctx->loc_conf;
3807     clcf->loc_conf = ctx->loc_conf;
3808     clcf->name = pclcf->name;
3809     clcf->noname = 1;
3810 
3811     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
3812         return NGX_CONF_ERROR;
3813     }
3814 
3815     save = *cf;
3816     cf->ctx = ctx;
3817     cf->cmd_type = NGX_HTTP_LMT_CONF;
3818 
3819     rv = ngx_conf_parse(cf, NULL);
3820 
3821     *cf = save;
3822 
3823     return rv;
3824 }
3825 
3826 
3827 static char *
3828 ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3829 {
3830     ngx_http_core_loc_conf_t *clcf = conf;
3831 
3832     ngx_str_t  *value;
3833 
3834     if (clcf->directio != NGX_CONF_UNSET) {
3835         return "is duplicate";
3836     }
3837 
3838     value = cf->args->elts;
3839 
3840     if (ngx_strcmp(value[1].data, "off") == 0) {
3841         clcf->directio = NGX_OPEN_FILE_DIRECTIO_OFF;
3842         return NGX_CONF_OK;
3843     }
3844 
3845     clcf->directio = ngx_parse_offset(&value[1]);
3846     if (clcf->directio == (off_t) NGX_ERROR) {
3847         return "invalid value";
3848     }
3849 
3850     return NGX_CONF_OK;
3851 }
3852 
3853 
3854 static char *
3855 ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3856 {
3857     ngx_http_core_loc_conf_t *lcf = conf;
3858 
3859     u_char                            *p;
3860     ngx_int_t                          overwrite;
3861     ngx_str_t                         *value, uri, args;
3862     ngx_uint_t                         i, n;
3863     ngx_http_err_page_t               *err;
3864     ngx_http_complex_value_t           cv;
3865     ngx_http_compile_complex_value_t   ccv;
3866 
3867     if (lcf->error_pages == NULL) {
3868         lcf->error_pages = ngx_array_create(cf->pool, 4,
3869                                             sizeof(ngx_http_err_page_t));
3870         if (lcf->error_pages == NULL) {
3871             return NGX_CONF_ERROR;
3872         }
3873     }
3874 
3875     value = cf->args->elts;
3876 
3877     i = cf->args->nelts - 2;
3878 
3879     if (value[i].data[0] == '=') {
3880         if (i == 1) {
3881             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3882                                "invalid value \"%V\"", &value[i]);
3883             return NGX_CONF_ERROR;
3884         }
3885 
3886         if (value[i].len > 1) {
3887             overwrite = ngx_atoi(&value[i].data[1], value[i].len - 1);
3888 
3889             if (overwrite == NGX_ERROR) {
3890                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3891                                    "invalid value \"%V\"", &value[i]);
3892                 return NGX_CONF_ERROR;
3893             }
3894 
3895         } else {
3896             overwrite = 0;
3897         }
3898 
3899         n = 2;
3900 
3901     } else {
3902         overwrite = -1;
3903         n = 1;
3904     }
3905 
3906     uri = value[cf->args->nelts - 1];
3907 
3908     ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
3909 
3910     ccv.cf = cf;
3911     ccv.value = &uri;
3912     ccv.complex_value = &cv;
3913 
3914     if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
3915         return NGX_CONF_ERROR;
3916     }
3917 
3918     args.len = 0;
3919     args.data = NULL;
3920 
3921     if (cv.lengths == NULL && uri.data[0] == '/') {
3922         p = (u_char *) ngx_strchr(uri.data, '?');
3923 
3924         if (p) {
3925             cv.value.len = p - uri.data;
3926             cv.value.data = uri.data;
3927             p++;
3928             args.len = (uri.data + uri.len) - p;
3929             args.data = p;
3930         }
3931     }
3932 
3933     for (i = 1; i < cf->args->nelts - n; i++) {
3934         err = ngx_array_push(lcf->error_pages);
3935         if (err == NULL) {
3936             return NGX_CONF_ERROR;
3937         }
3938 
3939         err->status = ngx_atoi(value[i].data, value[i].len);
3940 
3941         if (err->status == NGX_ERROR || err->status == 499) {
3942             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3943                                "invalid value \"%V\"", &value[i]);
3944             return NGX_CONF_ERROR;
3945         }
3946 
3947         if (err->status < 400 || err->status > 599) {
3948             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3949                                "value \"%V\" must be between 400 and 599",
3950                                &value[i]);
3951             return NGX_CONF_ERROR;
3952         }
3953 
3954         if (overwrite >= 0) {
3955             err->overwrite = overwrite;
3956 
3957         } else {
3958             switch (err->status) {
3959                 case NGX_HTTP_TO_HTTPS:
3960                 case NGX_HTTPS_CERT_ERROR:
3961                 case NGX_HTTPS_NO_CERT:
3962                     err->overwrite = NGX_HTTP_BAD_REQUEST;
3963                     break;
3964 
3965                 default:
3966                     err->overwrite = err->status;
3967                     break;
3968             }
3969         }
3970 
3971         err->value = cv;
3972         err->args = args;
3973     }
3974 
3975     return NGX_CONF_OK;
3976 }
3977 
3978 
3979 static char *
3980 ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3981 {
3982     ngx_http_core_loc_conf_t *clcf = conf;
3983 
3984     ngx_str_t                  *value;
3985     ngx_int_t                   code;
3986     ngx_uint_t                  i, n;
3987     ngx_http_try_file_t        *tf;
3988     ngx_http_script_compile_t   sc;
3989     ngx_http_core_main_conf_t  *cmcf;
3990 
3991     if (clcf->try_files) {
3992         return "is duplicate";
3993     }
3994 
3995     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
3996 
3997     cmcf->try_files = 1;
3998 
3999     tf = ngx_pcalloc(cf->pool, cf->args->nelts * sizeof(ngx_http_try_file_t));
4000     if (tf == NULL) {
4001         return NGX_CONF_ERROR;
4002     }
4003 
4004     clcf->try_files = tf;
4005 
4006     value = cf->args->elts;
4007 
4008     for (i = 0; i < cf->args->nelts - 1; i++) {
4009 
4010         tf[i].name = value[i + 1];
4011 
4012         if (tf[i].name.data[tf[i].name.len - 1] == '/') {
4013             tf[i].test_dir = 1;
4014             tf[i].name.len--;
4015             tf[i].name.data[tf[i].name.len] = '\0';
4016         }
4017 
4018         n = ngx_http_script_variables_count(&tf[i].name);
4019 
4020         if (n) {
4021             ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
4022 
4023             sc.cf = cf;
4024             sc.source = &tf[i].name;
4025             sc.lengths = &tf[i].lengths;
4026             sc.values = &tf[i].values;
4027             sc.variables = n;
4028             sc.complete_lengths = 1;
4029             sc.complete_values = 1;
4030 
4031             if (ngx_http_script_compile(&sc) != NGX_OK) {
4032                 return NGX_CONF_ERROR;
4033             }
4034 
4035         } else {
4036             /* add trailing '\0' to length */
4037             tf[i].name.len++;
4038         }
4039     }
4040 
4041     if (tf[i - 1].name.data[0] == '=') {
4042 
4043         code = ngx_atoi(tf[i - 1].name.data + 1, tf[i - 1].name.len - 2);
4044 
4045         if (code == NGX_ERROR) {
4046             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4047                                "invalid code \"%*s\"",
4048                                tf[i - 1].name.len - 1, tf[i - 1].name.data);
4049             return NGX_CONF_ERROR;
4050         }
4051 
4052         tf[i].code = code;
4053     }
4054 
4055     return NGX_CONF_OK;
4056 }
4057 
4058 
4059 static char *
4060 ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4061 {
4062     ngx_http_core_loc_conf_t *lcf = conf;
4063 
4064     time_t       inactive;
4065     ngx_str_t   *value, s;
4066     ngx_int_t    max;
4067     ngx_uint_t   i;
4068 
4069     if (lcf->open_file_cache != NGX_CONF_UNSET_PTR) {
4070         return "is duplicate";
4071     }
4072 
4073     value = cf->args->elts;
4074 
4075     max = 0;
4076     inactive = 60;
4077 
4078     for (i = 1; i < cf->args->nelts; i++) {
4079 
4080         if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
4081 
4082             max = ngx_atoi(value[i].data + 4, value[i].len - 4);
4083             if (max == NGX_ERROR) {
4084                 goto failed;
4085             }
4086 
4087             continue;
4088         }
4089 
4090         if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
4091 
4092             s.len = value[i].len - 9;
4093             s.data = value[i].data + 9;
4094 
4095             inactive = ngx_parse_time(&s, 1);
4096             if (inactive < 0) {
4097                 goto failed;
4098             }
4099 
4100             continue;
4101         }
4102 
4103         if (ngx_strcmp(value[i].data, "off") == 0) {
4104 
4105             lcf->open_file_cache = NULL;
4106 
4107             continue;
4108         }
4109 
4110     failed:
4111 
4112         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4113                            "invalid \"open_file_cache\" parameter \"%V\"",
4114                            &value[i]);
4115         return NGX_CONF_ERROR;
4116     }
4117 
4118     if (lcf->open_file_cache == NULL) {
4119         return NGX_CONF_OK;
4120     }
4121 
4122     if (max == 0) {
4123         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4124                            "\"open_file_cache\" must have \"max\" parameter");
4125         return NGX_CONF_ERROR;
4126     }
4127 
4128     lcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
4129     if (lcf->open_file_cache) {
4130         return NGX_CONF_OK;
4131     }
4132 
4133     return NGX_CONF_ERROR;
4134 }
4135 
4136 
4137 static char *
4138 ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4139 {
4140     ngx_http_core_loc_conf_t *lcf = conf;
4141 
4142     ngx_str_t  *value;
4143 
4144     if (lcf->error_log) {
4145         return "is duplicate";
4146     }
4147 
4148     value = cf->args->elts;
4149 
4150     lcf->error_log = ngx_log_create(cf->cycle, &value[1]);
4151     if (lcf->error_log == NULL) {
4152         return NGX_CONF_ERROR;
4153     }
4154 
4155     if (cf->args->nelts == 2) {
4156         lcf->error_log->log_level = NGX_LOG_ERR;
4157         return NGX_CONF_OK;
4158     }
4159 
4160     return ngx_log_set_levels(cf, lcf->error_log);
4161 }
4162 
4163 
4164 static char *
4165 ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4166 {
4167     ngx_http_core_loc_conf_t *lcf = conf;
4168 
4169     ngx_str_t  *value;
4170 
4171     if (lcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
4172         return "is duplicate";
4173     }
4174 
4175     value = cf->args->elts;
4176 
4177     lcf->keepalive_timeout = ngx_parse_time(&value[1], 0);
4178 
4179     if (lcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
4180         return "invalid value";
4181     }
4182 
4183     if (lcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) {
4184         return "value must be less than 597 hours";
4185     }
4186 
4187     if (cf->args->nelts == 2) {
4188         return NGX_CONF_OK;
4189     }
4190 
4191     lcf->keepalive_header = ngx_parse_time(&value[2], 1);
4192 
4193     if (lcf->keepalive_header == NGX_ERROR) {
4194         return "invalid value";
4195     }
4196 
4197     if (lcf->keepalive_header == NGX_PARSE_LARGE_TIME) {
4198         return "value must be less than 68 years";
4199     }
4200 
4201     return NGX_CONF_OK;
4202 }
4203 
4204 
4205 static char *
4206 ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4207 {
4208     ngx_http_core_loc_conf_t *lcf = conf;
4209 
4210     if (lcf->internal != NGX_CONF_UNSET) {
4211         return "is duplicate";
4212     }
4213 
4214     lcf->internal = 1;
4215 
4216     return NGX_CONF_OK;
4217 }
4218 
4219 
4220 static char *
4221 ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4222 {
4223     ngx_http_core_loc_conf_t  *clcf = conf;
4224 
4225     ngx_url_t   u;
4226     ngx_str_t  *value;
4227 
4228     if (clcf->resolver) {
4229         return "is duplicate";
4230     }
4231 
4232     value = cf->args->elts;
4233 
4234     ngx_memzero(&u, sizeof(ngx_url_t));
4235 
4236     u.host = value[1];
4237     u.port = 53;
4238 
4239     if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
4240         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err);
4241         return NGX_CONF_ERROR;
4242     }
4243 
4244     clcf->resolver = ngx_resolver_create(cf, &u.addrs[0]);
4245     if (clcf->resolver == NULL) {
4246         return NGX_OK;
4247     }
4248 
4249     return NGX_CONF_OK;
4250 }
4251 
4252 
4253 #if (NGX_HTTP_GZIP)
4254 
4255 static char *
4256 ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4257 {
4258     ngx_http_core_loc_conf_t  *clcf = conf;
4259 
4260 #if (NGX_PCRE)
4261 
4262     ngx_str_t         err, *value;
4263     ngx_uint_t        i;
4264     ngx_regex_elt_t  *re;
4265     u_char            errstr[NGX_MAX_CONF_ERRSTR];
4266 
4267     if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
4268         clcf->gzip_disable = ngx_array_create(cf->pool, 2,
4269                                               sizeof(ngx_regex_elt_t));
4270         if (clcf->gzip_disable == NULL) {
4271             return NGX_CONF_ERROR;
4272         }
4273     }
4274 
4275     value = cf->args->elts;
4276 
4277     err.len = NGX_MAX_CONF_ERRSTR;
4278     err.data = errstr;
4279 
4280     for (i = 1; i < cf->args->nelts; i++) {
4281 
4282         if (ngx_strcmp(value[1].data, "msie6") == 0) {
4283             clcf->gzip_disable_msie6 = 1;
4284             continue;
4285         }
4286 
4287         re = ngx_array_push(clcf->gzip_disable);
4288         if (re == NULL) {
4289             return NGX_CONF_ERROR;
4290         }
4291 
4292         re->regex = ngx_regex_compile(&value[i], NGX_REGEX_CASELESS, cf->pool,
4293                                       &err);
4294 
4295         if (re->regex == NULL) {
4296             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
4297             return NGX_CONF_ERROR;
4298         }
4299 
4300         re->name = value[i].data;
4301     }
4302 
4303     return NGX_CONF_OK;
4304 
4305 #else
4306     ngx_str_t  *value;
4307 
4308     value = cf->args->elts;
4309 
4310     if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "msie6") == 0) {
4311         clcf->gzip_disable_msie6 = 1;
4312         return NGX_CONF_OK;
4313     }
4314 
4315     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4316                        "without PCRE library \"gzip_disable\" supports "
4317                        "builtin \"msie6\" mask only");
4318 
4319     return NGX_CONF_ERROR;
4320 #endif
4321 }
4322 
4323 #endif
4324 
4325 
4326 static char *
4327 ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
4328 {
4329 #if (NGX_FREEBSD)
4330     ssize_t *np = data;
4331 
4332     if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
4333         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4334                            "\"send_lowat\" must be less than %d "
4335                            "(sysctl net.inet.tcp.sendspace)",
4336                            ngx_freebsd_net_inet_tcp_sendspace);
4337 
4338         return NGX_CONF_ERROR;
4339     }
4340 
4341 #elif !(NGX_HAVE_SO_SNDLOWAT)
4342     ssize_t *np = data;
4343 
4344     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
4345                        "\"send_lowat\" is not supported, ignored");
4346 
4347     *np = 0;
4348 
4349 #endif
4350 
4351     return NGX_CONF_OK;
4352 }
4353 
4354 
4355 static char *
4356 ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data)
4357 {
4358     size_t *sp = data;
4359 
4360     if (*sp < NGX_MIN_POOL_SIZE) {
4361         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4362                            "pool must be no less than %uz", NGX_MIN_POOL_SIZE);
4363 
4364         return NGX_CONF_ERROR;
4365     }
4366 
4367     return NGX_CONF_OK;
4368 }
4369 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.