nginx 0.5.21
[nginx-catap.git] / src / http / ngx_http_core_module.c
blob2334f6daaafb9823bd9586bd2187f1b6e39763f2
2 /*
3 * Copyright (C) Igor Sysoev
4 */
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_event.h>
10 #include <ngx_http.h>
11 #include <nginx.h>
14 typedef struct {
15 u_char *name;
16 uint32_t method;
17 } ngx_http_method_name_t;
20 #define NGX_HTTP_LOCATION_EXACT 1
21 #define NGX_HTTP_LOCATION_AUTO_REDIRECT 2
22 #define NGX_HTTP_LOCATION_NOREGEX 3
23 #define NGX_HTTP_LOCATION_REGEX 4
26 #define NGX_HTTP_REQUEST_BODY_FILE_OFF 0
27 #define NGX_HTTP_REQUEST_BODY_FILE_ON 1
28 #define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2
31 static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r,
32 ngx_array_t *locations, size_t len);
34 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
35 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
36 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
37 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
38 static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
39 void *parent, void *child);
40 static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf);
41 static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
42 void *parent, void *child);
44 static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
45 void *dummy);
46 static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
47 void *dummy);
48 static int ngx_http_core_cmp_locations(const void *first, const void *second);
50 static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
51 void *conf);
52 static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy,
53 void *conf);
55 static char *ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
56 void *conf);
57 static char *ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
58 void *conf);
59 static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
60 static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
61 void *conf);
62 static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
63 void *conf);
64 static char *ngx_http_core_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);
71 static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
72 static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data);
74 static ngx_conf_post_t ngx_http_core_lowat_post =
75 { ngx_http_core_lowat_check };
77 static ngx_conf_post_handler_pt ngx_http_core_pool_size_p =
78 ngx_http_core_pool_size;
80 static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_host_names = {
81 ngx_conf_deprecated, "optimize_host_names", "optimize_server_names"
85 static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = {
86 { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF },
87 { ngx_string("on"), NGX_HTTP_REQUEST_BODY_FILE_ON },
88 { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN },
89 { ngx_null_string, 0 }
93 static ngx_command_t ngx_http_core_commands[] = {
95 { ngx_string("variables_hash_max_size"),
96 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
97 ngx_conf_set_num_slot,
98 NGX_HTTP_MAIN_CONF_OFFSET,
99 offsetof(ngx_http_core_main_conf_t, variables_hash_max_size),
100 NULL },
102 { ngx_string("variables_hash_bucket_size"),
103 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
104 ngx_conf_set_num_slot,
105 NGX_HTTP_MAIN_CONF_OFFSET,
106 offsetof(ngx_http_core_main_conf_t, variables_hash_bucket_size),
107 NULL },
109 { ngx_string("server_names_hash_max_size"),
110 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
111 ngx_conf_set_num_slot,
112 NGX_HTTP_MAIN_CONF_OFFSET,
113 offsetof(ngx_http_core_main_conf_t, server_names_hash_max_size),
114 NULL },
116 { ngx_string("server_names_hash_bucket_size"),
117 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
118 ngx_conf_set_num_slot,
119 NGX_HTTP_MAIN_CONF_OFFSET,
120 offsetof(ngx_http_core_main_conf_t, server_names_hash_bucket_size),
121 NULL },
123 { ngx_string("server"),
124 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_MULTI|NGX_CONF_NOARGS,
125 ngx_http_core_server,
128 NULL },
130 { ngx_string("connection_pool_size"),
131 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
132 ngx_conf_set_size_slot,
133 NGX_HTTP_SRV_CONF_OFFSET,
134 offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
135 &ngx_http_core_pool_size_p },
137 { ngx_string("request_pool_size"),
138 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
139 ngx_conf_set_size_slot,
140 NGX_HTTP_SRV_CONF_OFFSET,
141 offsetof(ngx_http_core_srv_conf_t, request_pool_size),
142 &ngx_http_core_pool_size_p },
144 { ngx_string("client_header_timeout"),
145 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
146 ngx_conf_set_msec_slot,
147 NGX_HTTP_SRV_CONF_OFFSET,
148 offsetof(ngx_http_core_srv_conf_t, client_header_timeout),
149 NULL },
151 { ngx_string("client_header_buffer_size"),
152 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
153 ngx_conf_set_size_slot,
154 NGX_HTTP_SRV_CONF_OFFSET,
155 offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
156 NULL },
158 { ngx_string("large_client_header_buffers"),
159 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
160 ngx_conf_set_bufs_slot,
161 NGX_HTTP_SRV_CONF_OFFSET,
162 offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
163 NULL },
165 { ngx_string("optimize_server_names"),
166 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
167 ngx_conf_set_flag_slot,
168 NGX_HTTP_SRV_CONF_OFFSET,
169 offsetof(ngx_http_core_srv_conf_t, optimize_server_names),
170 NULL },
172 { ngx_string("optimize_host_names"),
173 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
174 ngx_conf_set_flag_slot,
175 NGX_HTTP_SRV_CONF_OFFSET,
176 offsetof(ngx_http_core_srv_conf_t, optimize_server_names),
177 &ngx_conf_deprecated_optimize_host_names },
179 { ngx_string("ignore_invalid_headers"),
180 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
181 ngx_conf_set_flag_slot,
182 NGX_HTTP_SRV_CONF_OFFSET,
183 offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
184 NULL },
186 { ngx_string("location"),
187 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
188 ngx_http_core_location,
189 NGX_HTTP_SRV_CONF_OFFSET,
191 NULL },
193 { ngx_string("listen"),
194 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
195 ngx_http_core_listen,
196 NGX_HTTP_SRV_CONF_OFFSET,
198 NULL },
200 { ngx_string("server_name"),
201 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
202 ngx_http_core_server_name,
203 NGX_HTTP_SRV_CONF_OFFSET,
205 NULL },
207 { ngx_string("types_hash_max_size"),
208 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
209 ngx_conf_set_num_slot,
210 NGX_HTTP_LOC_CONF_OFFSET,
211 offsetof(ngx_http_core_loc_conf_t, types_hash_max_size),
212 NULL },
214 { ngx_string("types_hash_bucket_size"),
215 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
216 ngx_conf_set_num_slot,
217 NGX_HTTP_LOC_CONF_OFFSET,
218 offsetof(ngx_http_core_loc_conf_t, types_hash_bucket_size),
219 NULL },
221 { ngx_string("types"),
222 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
223 |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
224 ngx_http_core_types,
225 NGX_HTTP_LOC_CONF_OFFSET,
227 NULL },
229 { ngx_string("default_type"),
230 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
231 ngx_conf_set_str_slot,
232 NGX_HTTP_LOC_CONF_OFFSET,
233 offsetof(ngx_http_core_loc_conf_t, default_type),
234 NULL },
236 { ngx_string("root"),
237 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
238 |NGX_CONF_TAKE1,
239 ngx_http_core_root,
240 NGX_HTTP_LOC_CONF_OFFSET,
242 NULL },
244 { ngx_string("alias"),
245 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
246 ngx_http_core_root,
247 NGX_HTTP_LOC_CONF_OFFSET,
249 NULL },
251 { ngx_string("limit_except"),
252 NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE,
253 ngx_http_core_limit_except,
254 NGX_HTTP_LOC_CONF_OFFSET,
256 NULL },
258 { ngx_string("client_max_body_size"),
259 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
260 ngx_conf_set_off_slot,
261 NGX_HTTP_LOC_CONF_OFFSET,
262 offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
263 NULL },
265 { ngx_string("client_body_buffer_size"),
266 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
267 ngx_conf_set_size_slot,
268 NGX_HTTP_LOC_CONF_OFFSET,
269 offsetof(ngx_http_core_loc_conf_t, client_body_buffer_size),
270 NULL },
272 { ngx_string("client_body_timeout"),
273 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
274 ngx_conf_set_msec_slot,
275 NGX_HTTP_LOC_CONF_OFFSET,
276 offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
277 NULL },
279 { ngx_string("client_body_temp_path"),
280 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
281 ngx_conf_set_path_slot,
282 NGX_HTTP_LOC_CONF_OFFSET,
283 offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
284 (void *) ngx_garbage_collector_temp_handler },
286 { ngx_string("client_body_in_file_only"),
287 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
288 ngx_conf_set_enum_slot,
289 NGX_HTTP_LOC_CONF_OFFSET,
290 offsetof(ngx_http_core_loc_conf_t, client_body_in_file_only),
291 &ngx_http_core_request_body_in_file },
293 { ngx_string("sendfile"),
294 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
295 |NGX_CONF_TAKE1,
296 ngx_conf_set_flag_slot,
297 NGX_HTTP_LOC_CONF_OFFSET,
298 offsetof(ngx_http_core_loc_conf_t, sendfile),
299 NULL },
301 { ngx_string("sendfile_max_chunk"),
302 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
303 ngx_conf_set_size_slot,
304 NGX_HTTP_LOC_CONF_OFFSET,
305 offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
306 NULL },
308 { ngx_string("tcp_nopush"),
309 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
310 ngx_conf_set_flag_slot,
311 NGX_HTTP_LOC_CONF_OFFSET,
312 offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
313 NULL },
315 { ngx_string("tcp_nodelay"),
316 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
317 ngx_conf_set_flag_slot,
318 NGX_HTTP_LOC_CONF_OFFSET,
319 offsetof(ngx_http_core_loc_conf_t, tcp_nodelay),
320 NULL },
322 { ngx_string("send_timeout"),
323 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
324 ngx_conf_set_msec_slot,
325 NGX_HTTP_LOC_CONF_OFFSET,
326 offsetof(ngx_http_core_loc_conf_t, send_timeout),
327 NULL },
329 { ngx_string("send_lowat"),
330 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
331 ngx_conf_set_size_slot,
332 NGX_HTTP_LOC_CONF_OFFSET,
333 offsetof(ngx_http_core_loc_conf_t, send_lowat),
334 &ngx_http_core_lowat_post },
336 { ngx_string("postpone_output"),
337 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
338 ngx_conf_set_size_slot,
339 NGX_HTTP_LOC_CONF_OFFSET,
340 offsetof(ngx_http_core_loc_conf_t, postpone_output),
341 NULL },
343 { ngx_string("limit_rate"),
344 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
345 |NGX_CONF_TAKE1,
346 ngx_conf_set_size_slot,
347 NGX_HTTP_LOC_CONF_OFFSET,
348 offsetof(ngx_http_core_loc_conf_t, limit_rate),
349 NULL },
351 { ngx_string("keepalive_timeout"),
352 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
353 ngx_http_core_keepalive,
354 NGX_HTTP_LOC_CONF_OFFSET,
356 NULL },
358 { ngx_string("satisfy_any"),
359 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
360 ngx_conf_set_flag_slot,
361 NGX_HTTP_LOC_CONF_OFFSET,
362 offsetof(ngx_http_core_loc_conf_t, satisfy_any),
363 NULL },
365 { ngx_string("internal"),
366 NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
367 ngx_http_core_internal,
368 NGX_HTTP_LOC_CONF_OFFSET,
370 NULL },
372 { ngx_string("lingering_time"),
373 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
374 ngx_conf_set_msec_slot,
375 NGX_HTTP_LOC_CONF_OFFSET,
376 offsetof(ngx_http_core_loc_conf_t, lingering_time),
377 NULL },
379 { ngx_string("lingering_timeout"),
380 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
381 ngx_conf_set_msec_slot,
382 NGX_HTTP_LOC_CONF_OFFSET,
383 offsetof(ngx_http_core_loc_conf_t, lingering_timeout),
384 NULL },
386 { ngx_string("reset_timedout_connection"),
387 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
388 ngx_conf_set_flag_slot,
389 NGX_HTTP_LOC_CONF_OFFSET,
390 offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection),
391 NULL },
393 { ngx_string("port_in_redirect"),
394 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
395 ngx_conf_set_flag_slot,
396 NGX_HTTP_LOC_CONF_OFFSET,
397 offsetof(ngx_http_core_loc_conf_t, port_in_redirect),
398 NULL },
400 { ngx_string("msie_padding"),
401 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
402 ngx_conf_set_flag_slot,
403 NGX_HTTP_LOC_CONF_OFFSET,
404 offsetof(ngx_http_core_loc_conf_t, msie_padding),
405 NULL },
407 { ngx_string("msie_refresh"),
408 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
409 ngx_conf_set_flag_slot,
410 NGX_HTTP_LOC_CONF_OFFSET,
411 offsetof(ngx_http_core_loc_conf_t, msie_refresh),
412 NULL },
414 { ngx_string("log_not_found"),
415 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
416 ngx_conf_set_flag_slot,
417 NGX_HTTP_LOC_CONF_OFFSET,
418 offsetof(ngx_http_core_loc_conf_t, log_not_found),
419 NULL },
421 { ngx_string("recursive_error_pages"),
422 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
423 ngx_conf_set_flag_slot,
424 NGX_HTTP_LOC_CONF_OFFSET,
425 offsetof(ngx_http_core_loc_conf_t, recursive_error_pages),
426 NULL },
428 { ngx_string("error_page"),
429 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
430 |NGX_CONF_2MORE,
431 ngx_http_core_error_page,
432 NGX_HTTP_LOC_CONF_OFFSET,
434 NULL },
436 { ngx_string("post_action"),
437 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
438 |NGX_CONF_TAKE1,
439 ngx_conf_set_str_slot,
440 NGX_HTTP_LOC_CONF_OFFSET,
441 offsetof(ngx_http_core_loc_conf_t, post_action),
442 NULL },
444 { ngx_string("error_log"),
445 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
446 ngx_http_core_error_log,
447 NGX_HTTP_LOC_CONF_OFFSET,
449 NULL },
451 #if (NGX_HTTP_CACHE)
453 { ngx_string("open_file_cache"),
454 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE4,
455 ngx_http_set_cache_slot,
456 NGX_HTTP_LOC_CONF_OFFSET,
457 offsetof(ngx_http_core_loc_conf_t, open_files),
458 NULL },
460 #endif
462 ngx_null_command
466 static ngx_http_module_t ngx_http_core_module_ctx = {
467 ngx_http_core_preconfiguration, /* preconfiguration */
468 NULL, /* postconfiguration */
470 ngx_http_core_create_main_conf, /* create main configuration */
471 ngx_http_core_init_main_conf, /* init main configuration */
473 ngx_http_core_create_srv_conf, /* create server configuration */
474 ngx_http_core_merge_srv_conf, /* merge server configuration */
476 ngx_http_core_create_loc_conf, /* create location configuration */
477 ngx_http_core_merge_loc_conf /* merge location configuration */
481 ngx_module_t ngx_http_core_module = {
482 NGX_MODULE_V1,
483 &ngx_http_core_module_ctx, /* module context */
484 ngx_http_core_commands, /* module directives */
485 NGX_HTTP_MODULE, /* module type */
486 NULL, /* init master */
487 NULL, /* init module */
488 NULL, /* init process */
489 NULL, /* init thread */
490 NULL, /* exit thread */
491 NULL, /* exit process */
492 NULL, /* exit master */
493 NGX_MODULE_V1_PADDING
497 void
498 ngx_http_handler(ngx_http_request_t *r)
500 ngx_http_core_main_conf_t *cmcf;
502 r->connection->log->action = NULL;
504 r->connection->unexpected_eof = 0;
506 if (!r->internal) {
507 switch (r->headers_in.connection_type) {
508 case 0:
509 if (r->http_version > NGX_HTTP_VERSION_10) {
510 r->keepalive = 1;
511 } else {
512 r->keepalive = 0;
514 break;
516 case NGX_HTTP_CONNECTION_CLOSE:
517 r->keepalive = 0;
518 break;
520 case NGX_HTTP_CONNECTION_KEEP_ALIVE:
521 r->keepalive = 1;
522 break;
525 if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) {
528 * MSIE may wait for some time if an response for
529 * a POST request was sent over a keepalive connection
532 r->keepalive = 0;
535 if (r->headers_in.content_length_n > 0) {
536 r->lingering_close = 1;
538 } else {
539 r->lingering_close = 0;
542 r->phase_handler = 0;
544 } else {
545 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
546 r->phase_handler = cmcf->phase_engine.server_rewrite_index;
549 if (r->unparsed_uri.len) {
550 r->valid_unparsed_uri = 1;
553 r->valid_location = 1;
555 r->write_event_handler = ngx_http_core_run_phases;
556 ngx_http_core_run_phases(r);
560 void
561 ngx_http_core_run_phases(ngx_http_request_t *r)
563 ngx_int_t rc;
564 ngx_http_phase_handler_t *ph;
565 ngx_http_core_main_conf_t *cmcf;
567 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
569 ph = cmcf->phase_engine.handlers;
571 while (ph[r->phase_handler].checker) {
573 rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
575 if (rc == NGX_OK) {
576 return;
582 ngx_int_t
583 ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
585 ngx_int_t rc;
588 * generic phase checker,
589 * used by the post read, server rewrite, rewrite, and pre-access phases
592 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
593 "generic phase: %ui", r->phase_handler);
595 rc = ph->handler(r);
597 if (rc == NGX_OK) {
598 r->phase_handler = ph->next;
599 return NGX_AGAIN;
602 if (rc == NGX_DECLINED) {
603 r->phase_handler++;
604 return NGX_AGAIN;
607 if (rc == NGX_AGAIN || rc == NGX_DONE) {
608 return NGX_OK;
611 /* rc == NGX_ERROR || rc == NGX_HTTP_... */
613 ngx_http_finalize_request(r, rc);
615 return NGX_OK;
619 ngx_int_t
620 ngx_http_core_find_config_phase(ngx_http_request_t *r,
621 ngx_http_phase_handler_t *ph)
623 ngx_int_t rc;
624 ngx_http_core_loc_conf_t *clcf;
625 ngx_http_core_srv_conf_t *cscf;
627 r->content_handler = NULL;
628 r->uri_changed = 0;
630 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
632 rc = ngx_http_core_find_location(r, &cscf->locations, 0);
634 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
635 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
636 return NGX_OK;
639 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
641 if (!r->internal && clcf->internal) {
642 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
643 return NGX_OK;
646 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
647 "using configuration \"%s%V\"",
648 (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
649 &clcf->name);
651 ngx_http_update_location_config(r);
653 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
654 "http cl:%O max:%O",
655 r->headers_in.content_length_n, clcf->client_max_body_size);
657 if (r->headers_in.content_length_n != -1
658 && !r->discard_body
659 && clcf->client_max_body_size
660 && clcf->client_max_body_size < r->headers_in.content_length_n)
662 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
663 "client intented to send too large body: %O bytes",
664 r->headers_in.content_length_n);
666 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
667 return NGX_OK;
671 if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) {
672 r->headers_out.location = ngx_list_push(&r->headers_out.headers);
673 if (r->headers_out.location == NULL) {
674 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
675 return NGX_OK;
679 * we do not need to set the r->headers_out.location->hash and
680 * r->headers_out.location->key fields
683 r->headers_out.location->value = clcf->name;
685 ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
686 return NGX_OK;
689 r->phase_handler++;
690 return NGX_AGAIN;
694 ngx_int_t
695 ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
696 ngx_http_phase_handler_t *ph)
698 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
699 "post rewrite phase: %ui", r->phase_handler);
701 if (!r->uri_changed) {
702 r->phase_handler++;
703 return NGX_AGAIN;
706 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
707 "uri changes: %d", r->uri_changes);
710 * gcc before 3.3 compiles the broken code for
711 * if (r->uri_changes-- == 0)
712 * if the r->uri_changes is defined as
713 * unsigned uri_changes:4
716 r->uri_changes--;
718 if (r->uri_changes == 0) {
719 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
720 "rewrite or internal redirection cycle "
721 "while processing \"%V\"", &r->uri);
723 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
724 return NGX_OK;
727 r->phase_handler = ph->next;
729 return NGX_AGAIN;
733 ngx_int_t
734 ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
736 ngx_int_t rc;
737 ngx_http_core_loc_conf_t *clcf;
739 if (r != r->main) {
740 r->phase_handler = ph->next;
741 return NGX_AGAIN;
744 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
745 "access phase: %ui", r->phase_handler);
747 rc = ph->handler(r);
749 if (rc == NGX_DECLINED) {
750 r->phase_handler++;
751 return NGX_AGAIN;
754 if (rc == NGX_AGAIN || rc == NGX_DONE) {
755 return NGX_OK;
758 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
760 if (clcf->satisfy_any == 0) {
762 if (rc == NGX_OK) {
763 r->phase_handler++;
764 return NGX_AGAIN;
767 } else {
768 if (rc == NGX_OK) {
769 r->access_code = 0;
771 if (r->headers_out.www_authenticate) {
772 r->headers_out.www_authenticate->hash = 0;
775 r->phase_handler = ph->next;
776 return NGX_AGAIN;
779 if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) {
780 r->access_code = rc;
782 r->phase_handler++;
783 return NGX_AGAIN;
787 /* rc == NGX_ERROR || rc == NGX_HTTP_... */
789 ngx_http_finalize_request(r, rc);
790 return NGX_OK;
794 ngx_int_t
795 ngx_http_core_post_access_phase(ngx_http_request_t *r,
796 ngx_http_phase_handler_t *ph)
798 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
799 "post access phase: %ui", r->phase_handler);
801 if (r->access_code) {
803 if (r->access_code == NGX_HTTP_FORBIDDEN) {
804 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
805 "access forbidden by rule");
808 ngx_http_finalize_request(r, r->access_code);
809 return NGX_OK;
812 r->phase_handler++;
813 return NGX_AGAIN;
817 ngx_int_t
818 ngx_http_core_content_phase(ngx_http_request_t *r,
819 ngx_http_phase_handler_t *ph)
821 size_t root;
822 ngx_int_t rc;
823 ngx_str_t path;
825 if (r->content_handler) {
826 r->write_event_handler = ngx_http_request_empty_handler;
827 ngx_http_finalize_request(r, r->content_handler(r));
828 return NGX_OK;
831 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
832 "content phase: %ui", r->phase_handler);
834 rc = ph->handler(r);
836 if (rc == NGX_DONE) {
837 return NGX_OK;
840 if (rc != NGX_DECLINED) {
841 ngx_http_finalize_request(r, rc);
842 return NGX_OK;
845 /* rc == NGX_DECLINED */
847 ph++;
849 if (ph->checker) {
850 r->phase_handler++;
851 return NGX_AGAIN;
854 /* no content handler was found */
856 if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) {
858 if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
859 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
860 "directory index of \"%V\" is forbidden", &path);
863 ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
864 return NGX_OK;
867 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found");
869 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
870 return NGX_OK;
874 void
875 ngx_http_update_location_config(ngx_http_request_t *r)
877 ngx_http_core_loc_conf_t *clcf;
879 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
881 if (r->method & clcf->limit_except) {
882 r->loc_conf = clcf->limit_except_loc_conf;
883 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
886 if (r == r->main) {
887 r->connection->log->file = clcf->err_log->file;
889 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
890 r->connection->log->log_level = clcf->err_log->log_level;
894 if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
895 r->connection->sendfile = 1;
897 } else {
898 r->connection->sendfile = 0;
901 if (clcf->client_body_in_file_only) {
902 r->request_body_in_file_only = 1;
903 r->request_body_in_persistent_file = 1;
904 r->request_body_in_clean_file =
905 clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;
906 r->request_body_file_log_level = NGX_LOG_NOTICE;
908 } else {
909 r->request_body_file_log_level = NGX_LOG_WARN;
912 if (r->keepalive && clcf->keepalive_timeout == 0) {
913 r->keepalive = 0;
916 if (!clcf->tcp_nopush) {
917 /* disable TCP_NOPUSH/TCP_CORK use */
918 r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
921 if (r->limit_rate == 0) {
922 r->limit_rate = clcf->limit_rate;
925 if (clcf->handler) {
926 r->content_handler = clcf->handler;
931 static ngx_int_t
932 ngx_http_core_find_location(ngx_http_request_t *r,
933 ngx_array_t *locations, size_t len)
935 ngx_int_t n, rc;
936 ngx_uint_t i, found, noregex;
937 ngx_http_core_loc_conf_t *clcf, **clcfp;
939 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
940 "find location for \"%V\"", &r->uri);
942 found = 0;
943 noregex = 0;
945 clcfp = locations->elts;
946 for (i = 0; i < locations->nelts; i++) {
948 #if (NGX_PCRE)
949 if (clcfp[i]->regex) {
950 break;
952 #endif
954 if (clcfp[i]->noname) {
955 break;
958 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
959 "find location: %s\"%V\"",
960 clcfp[i]->exact_match ? "= " : "", &clcfp[i]->name);
962 if (clcfp[i]->auto_redirect
963 && r->uri.len == clcfp[i]->name.len - 1
964 && ngx_strncmp(r->uri.data, clcfp[i]->name.data,
965 clcfp[i]->name.len - 1)
966 == 0)
968 /* the locations are lexicographically sorted */
970 r->loc_conf = clcfp[i]->loc_conf;
972 return NGX_HTTP_LOCATION_AUTO_REDIRECT;
975 if (r->uri.len < clcfp[i]->name.len) {
976 continue;
979 n = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len);
981 if (n < 0) {
982 /* the locations are lexicographically sorted */
983 break;
986 if (n == 0) {
987 if (clcfp[i]->exact_match) {
989 if (r->uri.len == clcfp[i]->name.len) {
990 r->loc_conf = clcfp[i]->loc_conf;
991 return NGX_HTTP_LOCATION_EXACT;
994 continue;
997 if (len > clcfp[i]->name.len) {
998 /* the previous match is longer */
999 break;
1002 r->loc_conf = clcfp[i]->loc_conf;
1003 noregex = clcfp[i]->noregex;
1004 found = 1;
1008 if (found) {
1009 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1011 if (clcf->locations.nelts) {
1012 rc = ngx_http_core_find_location(r, &clcf->locations, len);
1014 if (rc != NGX_OK) {
1015 return rc;
1020 #if (NGX_PCRE)
1022 if (noregex) {
1023 return NGX_HTTP_LOCATION_NOREGEX;
1026 /* regex matches */
1028 for (/* void */; i < locations->nelts; i++) {
1030 if (!clcfp[i]->regex) {
1031 continue;
1034 if (clcfp[i]->noname) {
1035 break;
1038 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1039 "find location: ~ \"%V\"", &clcfp[i]->name);
1041 n = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0);
1043 if (n == NGX_REGEX_NO_MATCHED) {
1044 continue;
1047 if (n < 0) {
1048 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1049 ngx_regex_exec_n
1050 " failed: %d on \"%V\" using \"%V\"",
1051 n, &r->uri, &clcfp[i]->name);
1052 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1055 /* match */
1057 r->loc_conf = clcfp[i]->loc_conf;
1059 return NGX_HTTP_LOCATION_REGEX;
1062 #endif /* NGX_PCRE */
1064 return NGX_OK;
1068 ngx_int_t
1069 ngx_http_set_content_type(ngx_http_request_t *r)
1071 u_char c, *p, *exten;
1072 ngx_str_t *type;
1073 ngx_uint_t i, hash;
1074 ngx_http_core_loc_conf_t *clcf;
1076 if (r->headers_out.content_type.len) {
1077 return NGX_OK;
1080 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1082 if (r->exten.len) {
1084 hash = 0;
1086 for (i = 0; i < r->exten.len; i++) {
1087 c = r->exten.data[i];
1089 if (c >= 'A' && c <= 'Z') {
1091 p = ngx_palloc(r->pool, r->exten.len);
1092 if (p == NULL) {
1093 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1096 hash = 0;
1097 exten = p;
1099 for (i = 0; i < r->exten.len; i++) {
1100 c = ngx_tolower(r->exten.data[i]);
1101 hash = ngx_hash(hash, c);
1102 *p++ = c;
1105 r->exten.data = exten;
1107 break;
1110 hash = ngx_hash(hash, c);
1113 type = ngx_hash_find(&clcf->types_hash, hash,
1114 r->exten.data, r->exten.len);
1116 if (type) {
1117 r->headers_out.content_type_len = type->len;
1118 r->headers_out.content_type = *type;
1120 return NGX_OK;
1124 r->headers_out.content_type_len = clcf->default_type.len;
1125 r->headers_out.content_type = clcf->default_type;
1127 return NGX_OK;
1131 ngx_int_t
1132 ngx_http_set_exten(ngx_http_request_t *r)
1134 ngx_int_t i;
1136 r->exten.len = 0;
1137 r->exten.data = NULL;
1139 for (i = r->uri.len - 1; i > 1; i--) {
1140 if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') {
1142 r->exten.len = r->uri.len - i - 1;
1143 r->exten.data = &r->uri.data[i + 1];
1145 break;
1147 } else if (r->uri.data[i] == '/') {
1148 break;
1152 return NGX_OK;
1156 ngx_int_t
1157 ngx_http_send_header(ngx_http_request_t *r)
1159 if (r->err_status) {
1160 r->headers_out.status = r->err_status;
1161 r->headers_out.status_line.len = 0;
1164 return ngx_http_top_header_filter(r);
1168 ngx_int_t
1169 ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
1171 ngx_int_t rc;
1173 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1174 "http output filter \"%V?%V\"", &r->uri, &r->args);
1176 rc = ngx_http_top_body_filter(r, in);
1178 if (rc == NGX_ERROR) {
1179 /* NGX_ERROR may be returned by any filter */
1180 r->connection->error = 1;
1183 return rc;
1187 u_char *
1188 ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
1189 size_t *root_length, size_t reserved)
1191 u_char *last;
1192 size_t alias;
1193 ngx_http_core_loc_conf_t *clcf;
1195 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1197 alias = clcf->alias ? clcf->name.len : 0;
1199 if (alias && !r->valid_location) {
1200 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1201 "\"alias\" could not be used in location \"%V\" "
1202 "where URI was rewritten", &clcf->name);
1203 return NULL;
1206 reserved += r->uri.len - alias + 1;
1208 if (clcf->root_lengths == NULL) {
1210 *root_length = clcf->root.len;
1212 path->len = clcf->root.len + reserved;
1214 path->data = ngx_palloc(r->pool, path->len);
1215 if (path->data == NULL) {
1216 return NULL;
1219 last = ngx_copy(path->data, clcf->root.data, clcf->root.len);
1221 } else {
1222 if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
1223 clcf->root_values->elts)
1224 == NULL)
1226 return NULL;
1229 if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path) == NGX_ERROR) {
1230 return NULL;
1233 *root_length = path->len - reserved;
1234 last = path->data + *root_length;
1237 last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);
1239 return last;
1243 ngx_int_t
1244 ngx_http_auth_basic_user(ngx_http_request_t *r)
1246 ngx_str_t auth, encoded;
1247 ngx_uint_t len;
1249 if (r->headers_in.user.len == 0 && r->headers_in.user.data != NULL) {
1250 return NGX_DECLINED;
1253 if (r->headers_in.authorization == NULL) {
1254 r->headers_in.user.data = (u_char *) "";
1255 return NGX_DECLINED;
1258 encoded = r->headers_in.authorization->value;
1260 if (encoded.len < sizeof("Basic ") - 1
1261 || ngx_strncasecmp(encoded.data, (u_char *) "Basic ",
1262 sizeof("Basic ") - 1)
1263 != 0)
1265 r->headers_in.user.data = (u_char *) "";
1266 return NGX_DECLINED;
1269 encoded.len -= sizeof("Basic ") - 1;
1270 encoded.data += sizeof("Basic ") - 1;
1272 while (encoded.len && encoded.data[0] == ' ') {
1273 encoded.len--;
1274 encoded.data++;
1277 if (encoded.len == 0) {
1278 r->headers_in.user.data = (u_char *) "";
1279 return NGX_DECLINED;
1282 auth.len = ngx_base64_decoded_length(encoded.len);
1283 auth.data = ngx_palloc(r->pool, auth.len + 1);
1284 if (auth.data == NULL) {
1285 return NGX_ERROR;
1288 if (ngx_decode_base64(&auth, &encoded) != NGX_OK) {
1289 r->headers_in.user.data = (u_char *) "";
1290 return NGX_DECLINED;
1293 auth.data[auth.len] = '\0';
1295 for (len = 0; len < auth.len; len++) {
1296 if (auth.data[len] == ':') {
1297 break;
1301 if (len == 0 || len == auth.len) {
1302 r->headers_in.user.data = (u_char *) "";
1303 return NGX_DECLINED;
1306 r->headers_in.user.len = len;
1307 r->headers_in.user.data = auth.data;
1308 r->headers_in.passwd.len = auth.len - len - 1;
1309 r->headers_in.passwd.data = &auth.data[len + 1];
1311 return NGX_OK;
1315 ngx_int_t
1316 ngx_http_subrequest(ngx_http_request_t *r,
1317 ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
1318 ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
1320 ngx_connection_t *c;
1321 ngx_http_request_t *sr;
1322 ngx_http_log_ctx_t *ctx;
1323 ngx_http_core_srv_conf_t *cscf;
1324 ngx_http_postponed_request_t *pr, *p;
1326 r->main->subrequests--;
1328 if (r->main->subrequests == 0) {
1329 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1330 "subrequests cycle while processing \"%V\"", uri);
1331 r->main->subrequests = 1;
1332 return NGX_ERROR;
1335 sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
1336 if (sr == NULL) {
1337 return NGX_ERROR;
1340 sr->signature = NGX_HTTP_MODULE;
1342 c = r->connection;
1343 sr->connection = c;
1345 sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
1346 if (sr->ctx == NULL) {
1347 return NGX_ERROR;
1350 if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
1351 sizeof(ngx_table_elt_t))
1352 == NGX_ERROR)
1354 return NGX_ERROR;
1357 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1358 sr->main_conf = cscf->ctx->main_conf;
1359 sr->srv_conf = cscf->ctx->srv_conf;
1360 sr->loc_conf = cscf->ctx->loc_conf;
1362 sr->pool = r->pool;
1364 sr->headers_in = r->headers_in;
1366 ngx_http_clear_content_length(sr);
1367 ngx_http_clear_accept_ranges(sr);
1368 ngx_http_clear_last_modified(sr);
1370 sr->request_body = r->request_body;
1372 sr->method = NGX_HTTP_GET;
1373 sr->http_version = r->http_version;
1375 sr->request_line = r->request_line;
1376 sr->uri = *uri;
1378 if (args) {
1379 sr->args = *args;
1382 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
1383 "http subrequest \"%V?%V\"", uri, &sr->args);
1385 sr->zero_in_uri = (flags & NGX_HTTP_ZERO_IN_URI) != 0;
1386 sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
1388 sr->unparsed_uri = r->unparsed_uri;
1389 sr->method_name = r->method_name;
1390 sr->http_protocol = r->http_protocol;
1392 if (ngx_http_set_exten(sr) != NGX_OK) {
1393 return NGX_ERROR;
1396 sr->main = r->main;
1397 sr->parent = r;
1398 sr->post_subrequest = ps;
1399 sr->read_event_handler = ngx_http_request_empty_handler;
1400 sr->write_event_handler = ngx_http_request_empty_handler;
1402 if (c->data == r) {
1403 c->data = sr;
1406 sr->in_addr = r->in_addr;
1407 sr->port = r->port;
1408 sr->port_text = r->port_text;
1409 sr->server_name = r->server_name;
1411 sr->variables = r->variables;
1413 sr->log_handler = r->log_handler;
1415 pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
1416 if (pr == NULL) {
1417 return NGX_ERROR;
1420 pr->request = sr;
1421 pr->out = NULL;
1422 pr->next = NULL;
1424 if (r->postponed) {
1425 for (p = r->postponed; p->next; p = p->next) { /* void */ }
1426 p->next = pr;
1428 } else {
1429 r->postponed = pr;
1432 ctx = c->log->data;
1433 ctx->current_request = sr;
1435 sr->internal = 1;
1436 sr->fast_subrequest = 1;
1438 sr->discard_body = r->discard_body;
1439 sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
1441 sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
1443 ngx_http_handler(sr);
1445 if (!c->destroyed) {
1446 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
1447 "http subrequest done \"%V?%V\"", uri, &sr->args);
1449 r->main->subrequests++;
1451 *psr = sr;
1453 if (sr->fast_subrequest) {
1454 sr->fast_subrequest = 0;
1456 if (sr->done) {
1457 return NGX_OK;
1461 return NGX_AGAIN;
1464 return NGX_DONE;
1468 ngx_int_t
1469 ngx_http_internal_redirect(ngx_http_request_t *r,
1470 ngx_str_t *uri, ngx_str_t *args)
1472 ngx_http_core_srv_conf_t *cscf;
1474 r->uri_changes--;
1476 if (r->uri_changes == 0) {
1477 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1478 "rewrite or internal redirection cycle "
1479 "while internal redirect to \"%V\"", uri);
1481 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1482 return NGX_DONE;
1485 r->uri = *uri;
1487 if (args) {
1488 r->args = *args;
1490 } else {
1491 r->args.len = 0;
1492 r->args.data = NULL;
1495 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1496 "internal redirect: \"%V?%V\"", uri, &r->args);
1498 if (ngx_http_set_exten(r) != NGX_OK) {
1499 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1500 return NGX_DONE;
1503 /* clear the modules contexts */
1504 ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
1506 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1507 r->loc_conf = cscf->ctx->loc_conf;
1509 ngx_http_update_location_config(r);
1511 r->internal = 1;
1513 ngx_http_handler(r);
1515 return NGX_DONE;
1519 ngx_http_cleanup_t *
1520 ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
1522 ngx_http_cleanup_t *cln;
1524 r = r->main;
1526 cln = ngx_palloc(r->pool, sizeof(ngx_http_cleanup_t));
1527 if (cln == NULL) {
1528 return NULL;
1531 if (size) {
1532 cln->data = ngx_palloc(r->pool, size);
1533 if (cln->data == NULL) {
1534 return NULL;
1537 } else {
1538 cln->data = NULL;
1541 cln->handler = NULL;
1542 cln->next = r->cleanup;
1544 r->cleanup = cln;
1546 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1547 "http cleanup add: %p", cln);
1549 return cln;
1553 static char *
1554 ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
1556 char *rv;
1557 void *mconf;
1558 ngx_uint_t m;
1559 ngx_conf_t pcf;
1560 ngx_http_module_t *module;
1561 ngx_http_conf_ctx_t *ctx, *http_ctx;
1562 ngx_http_core_srv_conf_t *cscf, **cscfp;
1563 ngx_http_core_main_conf_t *cmcf;
1565 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
1566 if (ctx == NULL) {
1567 return NGX_CONF_ERROR;
1570 http_ctx = cf->ctx;
1571 ctx->main_conf = http_ctx->main_conf;
1573 /* the server{}'s srv_conf */
1575 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
1576 if (ctx->srv_conf == NULL) {
1577 return NGX_CONF_ERROR;
1580 /* the server{}'s loc_conf */
1582 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
1583 if (ctx->loc_conf == NULL) {
1584 return NGX_CONF_ERROR;
1587 for (m = 0; ngx_modules[m]; m++) {
1588 if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
1589 continue;
1592 module = ngx_modules[m]->ctx;
1594 if (module->create_srv_conf) {
1595 mconf = module->create_srv_conf(cf);
1596 if (mconf == NULL) {
1597 return NGX_CONF_ERROR;
1600 ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf;
1603 if (module->create_loc_conf) {
1604 mconf = module->create_loc_conf(cf);
1605 if (mconf == NULL) {
1606 return NGX_CONF_ERROR;
1609 ctx->loc_conf[ngx_modules[m]->ctx_index] = mconf;
1614 /* the server configuration context */
1616 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
1617 cscf->ctx = ctx;
1620 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
1622 cscfp = ngx_array_push(&cmcf->servers);
1623 if (cscfp == NULL) {
1624 return NGX_CONF_ERROR;
1627 *cscfp = cscf;
1630 /* parse inside server{} */
1632 pcf = *cf;
1633 cf->ctx = ctx;
1634 cf->cmd_type = NGX_HTTP_SRV_CONF;
1636 rv = ngx_conf_parse(cf, NULL);
1638 *cf = pcf;
1640 if (rv != NGX_CONF_OK) {
1641 return rv;
1644 ngx_sort(cscf->locations.elts, (size_t) cscf->locations.nelts,
1645 sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
1647 return rv;
1651 static char *
1652 ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
1654 char *rv;
1655 ngx_int_t m;
1656 ngx_str_t *value;
1657 ngx_conf_t save;
1658 ngx_http_module_t *module;
1659 ngx_http_conf_ctx_t *ctx, *pctx;
1660 ngx_http_core_srv_conf_t *cscf;
1661 ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp;
1662 #if (NGX_PCRE)
1663 ngx_str_t err;
1664 u_char errstr[NGX_MAX_CONF_ERRSTR];
1665 #endif
1667 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
1668 if (ctx == NULL) {
1669 return NGX_CONF_ERROR;
1672 pctx = cf->ctx;
1673 ctx->main_conf = pctx->main_conf;
1674 ctx->srv_conf = pctx->srv_conf;
1676 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
1677 if (ctx->loc_conf == NULL) {
1678 return NGX_CONF_ERROR;
1681 for (m = 0; ngx_modules[m]; m++) {
1682 if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
1683 continue;
1686 module = ngx_modules[m]->ctx;
1688 if (module->create_loc_conf) {
1689 ctx->loc_conf[ngx_modules[m]->ctx_index] =
1690 module->create_loc_conf(cf);
1691 if (ctx->loc_conf[ngx_modules[m]->ctx_index] == NULL) {
1692 return NGX_CONF_ERROR;
1697 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
1698 clcf->loc_conf = ctx->loc_conf;
1700 value = cf->args->elts;
1702 if (cf->args->nelts == 3) {
1703 if (value[1].len == 1 && value[1].data[0] == '=') {
1704 clcf->name = value[2];
1705 clcf->exact_match = 1;
1707 } else if (value[1].len == 2
1708 && value[1].data[0] == '^'
1709 && value[1].data[1] == '~')
1711 clcf->name = value[2];
1712 clcf->noregex = 1;
1714 } else if ((value[1].len == 1 && value[1].data[0] == '~')
1715 || (value[1].len == 2
1716 && value[1].data[0] == '~'
1717 && value[1].data[1] == '*'))
1719 #if (NGX_PCRE)
1720 err.len = NGX_MAX_CONF_ERRSTR;
1721 err.data = errstr;
1723 clcf->regex = ngx_regex_compile(&value[2],
1724 value[1].len == 2 ? NGX_REGEX_CASELESS: 0,
1725 cf->pool, &err);
1727 if (clcf->regex == NULL) {
1728 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
1729 return NGX_CONF_ERROR;
1732 clcf->name = value[2];
1733 #else
1734 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1735 "the using of the regex \"%V\" "
1736 "requires PCRE library", &value[2]);
1737 return NGX_CONF_ERROR;
1738 #endif
1740 } else {
1741 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1742 "invalid location modifier \"%V\"", &value[1]);
1743 return NGX_CONF_ERROR;
1746 } else {
1747 clcf->name = value[1];
1750 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
1752 if (pclcf->name.len == 0) {
1753 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
1755 clcfp = ngx_array_push(&cscf->locations);
1756 if (clcfp == NULL) {
1757 return NGX_CONF_ERROR;
1760 } else {
1761 #if 0
1762 clcf->prev_location = pclcf;
1763 #endif
1765 if (pclcf->exact_match) {
1766 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1767 "location \"%V\" could not be inside "
1768 "the exact location \"%V\"",
1769 &clcf->name, &pclcf->name);
1770 return NGX_CONF_ERROR;
1773 #if (NGX_PCRE)
1774 if (clcf->regex == NULL
1775 && ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
1776 != 0)
1777 #else
1778 if (ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
1779 != 0)
1780 #endif
1782 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1783 "location \"%V\" is outside location \"%V\"",
1784 &clcf->name, &pclcf->name);
1785 return NGX_CONF_ERROR;
1788 if (pclcf->locations.elts == NULL) {
1789 if (ngx_array_init(&pclcf->locations, cf->pool, 4, sizeof(void *))
1790 != NGX_OK)
1792 return NGX_CONF_ERROR;
1796 clcfp = ngx_array_push(&pclcf->locations);
1797 if (clcfp == NULL) {
1798 return NGX_CONF_ERROR;
1802 *clcfp = clcf;
1804 save = *cf;
1805 cf->ctx = ctx;
1806 cf->cmd_type = NGX_HTTP_LOC_CONF;
1808 rv = ngx_conf_parse(cf, NULL);
1810 *cf = save;
1812 if (rv != NGX_CONF_OK) {
1813 return rv;
1816 ngx_sort(clcf->locations.elts, (size_t) clcf->locations.nelts,
1817 sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
1819 return rv;
1823 static int
1824 ngx_http_core_cmp_locations(const void *one, const void *two)
1826 ngx_int_t rc;
1827 ngx_http_core_loc_conf_t *first, *second;
1829 first = *(ngx_http_core_loc_conf_t **) one;
1830 second = *(ngx_http_core_loc_conf_t **) two;
1832 if (first->noname && !second->noname) {
1833 /* shift no named locations to the end */
1834 return 1;
1837 if (!first->noname && second->noname) {
1838 /* shift no named locations to the end */
1839 return -1;
1842 if (first->noname || second->noname) {
1843 /* do not sort no named locations */
1844 return 0;
1847 #if (NGX_PCRE)
1849 if (first->regex && !second->regex) {
1850 /* shift the regex matches to the end */
1851 return 1;
1854 if (!first->regex && second->regex) {
1855 /* shift the regex matches to the end */
1856 return -1;
1859 if (first->regex || second->regex) {
1860 /* do not sort the regex matches */
1861 return 0;
1864 #endif
1866 rc = ngx_strcmp(first->name.data, second->name.data);
1868 if (rc == 0 && second->exact_match) {
1869 /* an exact match must be before the same inclusive one */
1870 return 1;
1873 return (int) rc;
1877 static char *
1878 ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1880 ngx_http_core_loc_conf_t *lcf = conf;
1882 char *rv;
1883 ngx_conf_t save;
1885 if (lcf->types == NULL) {
1886 lcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
1887 if (lcf->types == NULL) {
1888 return NGX_CONF_ERROR;
1892 save = *cf;
1893 cf->handler = ngx_http_core_type;
1894 cf->handler_conf = conf;
1896 rv = ngx_conf_parse(cf, NULL);
1898 *cf = save;
1900 return rv;
1904 static char *
1905 ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
1907 ngx_http_core_loc_conf_t *lcf = conf;
1909 ngx_str_t *value, *content_type, *old, file;
1910 ngx_uint_t i, n;
1911 ngx_hash_key_t *type;
1913 value = cf->args->elts;
1915 if (ngx_strcmp(value[0].data, "include") == 0) {
1916 file = value[1];
1918 if (ngx_conf_full_name(cf->cycle, &file) == NGX_ERROR){
1919 return NGX_CONF_ERROR;
1922 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
1924 return ngx_conf_parse(cf, &file);
1927 content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));
1928 if (content_type == NULL) {
1929 return NGX_CONF_ERROR;
1932 *content_type = value[0];
1934 for (i = 1; i < cf->args->nelts; i++) {
1936 for (n = 0; n < value[i].len; n++) {
1937 value[i].data[n] = ngx_tolower(value[i].data[n]);
1940 type = lcf->types->elts;
1941 for (n = 0; n < lcf->types->nelts; n++) {
1942 if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
1943 old = type[n].value;
1944 type[n].value = content_type;
1946 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1947 "duplicate extention \"%V\", "
1948 "content type: \"%V\", "
1949 "old content type: \"%V\"",
1950 &value[i], content_type, old);
1951 continue;
1956 type = ngx_array_push(lcf->types);
1957 if (type == NULL) {
1958 return NGX_CONF_ERROR;
1961 type->key = value[i];
1962 type->key_hash = ngx_hash_key(value[i].data, value[i].len);
1963 type->value = content_type;
1966 return NGX_CONF_OK;
1970 static ngx_int_t
1971 ngx_http_core_preconfiguration(ngx_conf_t *cf)
1973 return ngx_http_variables_add_core_vars(cf);
1977 static void *
1978 ngx_http_core_create_main_conf(ngx_conf_t *cf)
1980 ngx_http_core_main_conf_t *cmcf;
1982 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
1983 if (cmcf == NULL) {
1984 return NGX_CONF_ERROR;
1987 if (ngx_array_init(&cmcf->servers, cf->pool, 4,
1988 sizeof(ngx_http_core_srv_conf_t *))
1989 != NGX_OK)
1991 return NGX_CONF_ERROR;
1994 cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
1995 cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;
1997 cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
1998 cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;
2000 return cmcf;
2004 static char *
2005 ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
2007 ngx_http_core_main_conf_t *cmcf = conf;
2009 if (cmcf->server_names_hash_max_size == NGX_CONF_UNSET_UINT) {
2010 cmcf->server_names_hash_max_size = 512;
2013 if (cmcf->server_names_hash_bucket_size == NGX_CONF_UNSET_UINT) {
2014 cmcf->server_names_hash_bucket_size = ngx_cacheline_size;
2017 cmcf->server_names_hash_bucket_size =
2018 ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);
2021 if (cmcf->variables_hash_max_size == NGX_CONF_UNSET_UINT) {
2022 cmcf->variables_hash_max_size = 512;
2025 if (cmcf->variables_hash_bucket_size == NGX_CONF_UNSET_UINT) {
2026 cmcf->variables_hash_bucket_size = 64;
2029 cmcf->variables_hash_bucket_size =
2030 ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);
2032 return NGX_CONF_OK;
2036 static void *
2037 ngx_http_core_create_srv_conf(ngx_conf_t *cf)
2039 ngx_http_core_srv_conf_t *cscf;
2041 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t));
2042 if (cscf == NULL) {
2043 return NGX_CONF_ERROR;
2047 * set by ngx_pcalloc():
2049 * conf->client_large_buffers.num = 0;
2052 if (ngx_array_init(&cscf->locations, cf->pool, 4, sizeof(void *))
2053 == NGX_ERROR)
2055 return NGX_CONF_ERROR;
2058 if (ngx_array_init(&cscf->listen, cf->pool, 4, sizeof(ngx_http_listen_t))
2059 == NGX_ERROR)
2061 return NGX_CONF_ERROR;
2064 if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
2065 sizeof(ngx_http_server_name_t))
2066 == NGX_ERROR)
2068 return NGX_CONF_ERROR;
2071 cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
2072 cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
2073 cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
2074 cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
2075 cscf->optimize_server_names = NGX_CONF_UNSET;
2076 cscf->ignore_invalid_headers = NGX_CONF_UNSET;
2078 return cscf;
2082 static char *
2083 ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
2085 ngx_http_core_srv_conf_t *prev = parent;
2086 ngx_http_core_srv_conf_t *conf = child;
2088 ngx_http_listen_t *ls;
2089 ngx_http_server_name_t *sn;
2091 /* TODO: it does not merge, it inits only */
2093 if (conf->listen.nelts == 0) {
2094 ls = ngx_array_push(&conf->listen);
2095 if (ls == NULL) {
2096 return NGX_CONF_ERROR;
2099 ngx_memzero(ls, sizeof(ngx_http_listen_t));
2101 ls->addr = INADDR_ANY;
2102 #if (NGX_WIN32)
2103 ls->port = 80;
2104 #else
2105 /* STUB: getuid() should be cached */
2106 ls->port = (getuid() == 0) ? 80 : 8000;
2107 #endif
2108 ls->family = AF_INET;
2110 ls->conf.backlog = -1;
2111 ls->conf.rcvbuf = -1;
2112 ls->conf.sndbuf = -1;
2115 if (conf->server_name.data == NULL) {
2116 conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN);
2117 if (conf->server_name.data == NULL) {
2118 return NGX_CONF_ERROR;
2121 if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN)
2122 == -1)
2124 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
2125 "gethostname() failed");
2126 return NGX_CONF_ERROR;
2129 conf->server_name.len = ngx_strlen(conf->server_name.data);
2131 sn = ngx_array_push(&conf->server_names);
2132 if (sn == NULL) {
2133 return NGX_CONF_ERROR;
2136 sn->name.len = conf->server_name.len;
2137 sn->name.data = conf->server_name.data;
2138 sn->core_srv_conf = conf;
2141 ngx_conf_merge_size_value(conf->connection_pool_size,
2142 prev->connection_pool_size, 256);
2143 ngx_conf_merge_size_value(conf->request_pool_size,
2144 prev->request_pool_size, 4096);
2145 ngx_conf_merge_msec_value(conf->client_header_timeout,
2146 prev->client_header_timeout, 60000);
2147 ngx_conf_merge_size_value(conf->client_header_buffer_size,
2148 prev->client_header_buffer_size, 1024);
2149 ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
2150 prev->large_client_header_buffers,
2151 4, ngx_pagesize);
2153 if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
2154 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2155 "the \"large_client_header_buffers\" size must be "
2156 "equal to or bigger than \"connection_pool_size\"");
2157 return NGX_CONF_ERROR;
2160 ngx_conf_merge_value(conf->optimize_server_names,
2161 prev->optimize_server_names, 1);
2163 ngx_conf_merge_value(conf->ignore_invalid_headers,
2164 prev->ignore_invalid_headers, 1);
2166 return NGX_CONF_OK;
2170 static void *
2171 ngx_http_core_create_loc_conf(ngx_conf_t *cf)
2173 ngx_http_core_loc_conf_t *lcf;
2175 lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
2176 if (lcf == NULL) {
2177 return NGX_CONF_ERROR;
2181 * set by ngx_pcalloc():
2183 * lcf->root = { 0, NULL };
2184 * lcf->limit_except = 0;
2185 * lcf->post_action = { 0, NULL };
2186 * lcf->types = NULL;
2187 * lcf->default_type = { 0, NULL };
2188 * lcf->err_log = NULL;
2189 * lcf->error_pages = NULL;
2190 * lcf->client_body_path = NULL;
2191 * lcf->regex = NULL;
2192 * lcf->exact_match = 0;
2193 * lcf->auto_redirect = 0;
2194 * lcf->alias = 0;
2197 lcf->client_max_body_size = NGX_CONF_UNSET;
2198 lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
2199 lcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
2200 lcf->satisfy_any = NGX_CONF_UNSET;
2201 lcf->internal = NGX_CONF_UNSET;
2202 lcf->client_body_in_file_only = NGX_CONF_UNSET;
2203 lcf->sendfile = NGX_CONF_UNSET;
2204 lcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
2205 lcf->tcp_nopush = NGX_CONF_UNSET;
2206 lcf->tcp_nodelay = NGX_CONF_UNSET;
2207 lcf->send_timeout = NGX_CONF_UNSET_MSEC;
2208 lcf->send_lowat = NGX_CONF_UNSET_SIZE;
2209 lcf->postpone_output = NGX_CONF_UNSET_SIZE;
2210 lcf->limit_rate = NGX_CONF_UNSET_SIZE;
2211 lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
2212 lcf->keepalive_header = NGX_CONF_UNSET;
2213 lcf->lingering_time = NGX_CONF_UNSET_MSEC;
2214 lcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
2215 lcf->reset_timedout_connection = NGX_CONF_UNSET;
2216 lcf->port_in_redirect = NGX_CONF_UNSET;
2217 lcf->msie_padding = NGX_CONF_UNSET;
2218 lcf->msie_refresh = NGX_CONF_UNSET;
2219 lcf->log_not_found = NGX_CONF_UNSET;
2220 lcf->recursive_error_pages = NGX_CONF_UNSET;
2221 lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
2222 lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
2224 return lcf;
2228 static ngx_str_t ngx_http_core_text_html_type = ngx_string("text/html");
2229 static ngx_str_t ngx_http_core_image_gif_type = ngx_string("image/gif");
2230 static ngx_str_t ngx_http_core_image_jpeg_type = ngx_string("image/jpeg");
2232 static ngx_hash_key_t ngx_http_core_default_types[] = {
2233 { ngx_string("html"), 0, &ngx_http_core_text_html_type },
2234 { ngx_string("gif"), 0, &ngx_http_core_image_gif_type },
2235 { ngx_string("jpg"), 0, &ngx_http_core_image_jpeg_type },
2236 { ngx_null_string, 0, NULL }
2240 static char *
2241 ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
2243 ngx_http_core_loc_conf_t *prev = parent;
2244 ngx_http_core_loc_conf_t *conf = child;
2246 ngx_uint_t i;
2247 ngx_hash_key_t *type;
2248 ngx_hash_init_t types_hash;
2250 if (conf->root.data == NULL) {
2252 conf->alias = prev->alias;
2253 conf->root = prev->root;
2254 conf->root_lengths = prev->root_lengths;
2255 conf->root_values = prev->root_values;
2257 if (prev->root.data == NULL) {
2258 conf->root.len = sizeof("html") - 1;
2259 conf->root.data = (u_char *) "html";
2261 if (ngx_conf_full_name(cf->cycle, &conf->root) == NGX_ERROR) {
2262 return NGX_CONF_ERROR;
2267 if (conf->post_action.data == NULL) {
2268 conf->post_action = prev->post_action;
2271 ngx_conf_merge_uint_value(conf->types_hash_max_size,
2272 prev->types_hash_max_size, 1024);
2274 ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
2275 prev->types_hash_bucket_size,
2276 ngx_cacheline_size);
2278 conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
2279 ngx_cacheline_size);
2282 * the special handling the "types" directive in the "http" section
2283 * to inherit the http's conf->types_hash to all servers
2286 if (prev->types && prev->types_hash.buckets == NULL) {
2288 types_hash.hash = &prev->types_hash;
2289 types_hash.key = ngx_hash_key_lc;
2290 types_hash.max_size = conf->types_hash_max_size;
2291 types_hash.bucket_size = conf->types_hash_bucket_size;
2292 types_hash.name = "types_hash";
2293 types_hash.pool = cf->pool;
2294 types_hash.temp_pool = NULL;
2296 if (ngx_hash_init(&types_hash, prev->types->elts, prev->types->nelts)
2297 != NGX_OK)
2299 return NGX_CONF_ERROR;
2303 if (conf->types == NULL) {
2304 conf->types = prev->types;
2305 conf->types_hash = prev->types_hash;
2308 if (conf->types == NULL) {
2309 conf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t));
2310 if (conf->types == NULL) {
2311 return NGX_CONF_ERROR;
2314 for (i = 0; ngx_http_core_default_types[i].key.len; i++) {
2315 type = ngx_array_push(conf->types);
2316 if (type == NULL) {
2317 return NGX_CONF_ERROR;
2320 type->key = ngx_http_core_default_types[i].key;
2321 type->key_hash =
2322 ngx_hash_key_lc(ngx_http_core_default_types[i].key.data,
2323 ngx_http_core_default_types[i].key.len);
2324 type->value = ngx_http_core_default_types[i].value;
2328 if (conf->types_hash.buckets == NULL) {
2330 types_hash.hash = &conf->types_hash;
2331 types_hash.key = ngx_hash_key_lc;
2332 types_hash.max_size = conf->types_hash_max_size;
2333 types_hash.bucket_size = conf->types_hash_bucket_size;
2334 types_hash.name = "mime_types_hash";
2335 types_hash.pool = cf->pool;
2336 types_hash.temp_pool = NULL;
2338 if (ngx_hash_init(&types_hash, conf->types->elts, conf->types->nelts)
2339 != NGX_OK)
2341 return NGX_CONF_ERROR;
2345 if (conf->err_log == NULL) {
2346 if (prev->err_log) {
2347 conf->err_log = prev->err_log;
2348 } else {
2349 conf->err_log = cf->cycle->new_log;
2353 if (conf->error_pages == NULL && prev->error_pages) {
2354 conf->error_pages = prev->error_pages;
2357 ngx_conf_merge_str_value(conf->default_type,
2358 prev->default_type, "text/plain");
2360 ngx_conf_merge_off_value(conf->client_max_body_size,
2361 prev->client_max_body_size, 1 * 1024 * 1024);
2362 ngx_conf_merge_size_value(conf->client_body_buffer_size,
2363 prev->client_body_buffer_size,
2364 (size_t) 2 * ngx_pagesize);
2365 ngx_conf_merge_msec_value(conf->client_body_timeout,
2366 prev->client_body_timeout, 60000);
2368 ngx_conf_merge_value(conf->satisfy_any, prev->satisfy_any, 0);
2369 ngx_conf_merge_value(conf->internal, prev->internal, 0);
2370 ngx_conf_merge_value(conf->client_body_in_file_only,
2371 prev->client_body_in_file_only, 0);
2372 ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
2373 ngx_conf_merge_size_value(conf->sendfile_max_chunk,
2374 prev->sendfile_max_chunk, 0);
2375 ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
2376 ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);
2378 ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
2379 ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
2380 ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
2381 1460);
2382 ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
2383 ngx_conf_merge_msec_value(conf->keepalive_timeout,
2384 prev->keepalive_timeout, 75000);
2385 ngx_conf_merge_sec_value(conf->keepalive_header,
2386 prev->keepalive_header, 0);
2387 ngx_conf_merge_msec_value(conf->lingering_time,
2388 prev->lingering_time, 30000);
2389 ngx_conf_merge_msec_value(conf->lingering_timeout,
2390 prev->lingering_timeout, 5000);
2392 ngx_conf_merge_path_value(conf->client_body_temp_path,
2393 prev->client_body_temp_path,
2394 NGX_HTTP_CLIENT_TEMP_PATH, 0, 0, 0,
2395 ngx_garbage_collector_temp_handler, cf);
2397 ngx_conf_merge_value(conf->reset_timedout_connection,
2398 prev->reset_timedout_connection, 0);
2399 ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
2400 ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
2401 ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
2402 ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
2403 ngx_conf_merge_value(conf->recursive_error_pages,
2404 prev->recursive_error_pages, 0);
2406 if (conf->open_files == NULL) {
2407 conf->open_files = prev->open_files;
2410 return NGX_CONF_OK;
2414 /* AF_INET only */
2416 static char *
2417 ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2419 ngx_http_core_srv_conf_t *scf = conf;
2421 ngx_str_t *value, size;
2422 ngx_url_t u;
2423 ngx_uint_t n;
2424 ngx_http_listen_t *ls;
2427 * TODO: check duplicate 'listen' directives,
2428 * add resolved name to server names ???
2431 value = cf->args->elts;
2433 ngx_memzero(&u, sizeof(ngx_url_t));
2435 u.url = value[1];
2436 u.listen = 1;
2437 u.default_port = 80;
2439 if (ngx_parse_url(cf, &u) != NGX_OK) {
2440 if (u.err) {
2441 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2442 "%s in \"%V\" of the \"listen\" directive",
2443 u.err, &u.url);
2446 return NGX_CONF_ERROR;
2449 ls = ngx_array_push(&scf->listen);
2450 if (ls == NULL) {
2451 return NGX_CONF_ERROR;
2454 ngx_memzero(ls, sizeof(ngx_http_listen_t));
2456 ls->family = AF_INET;
2457 ls->addr = u.addr.in_addr;
2458 ls->port = u.port;
2459 ls->file_name = cf->conf_file->file.name;
2460 ls->line = cf->conf_file->line;
2461 ls->conf.backlog = -1;
2462 ls->conf.rcvbuf = -1;
2463 ls->conf.sndbuf = -1;
2465 n = ngx_inet_ntop(AF_INET, &ls->addr, ls->conf.addr, INET_ADDRSTRLEN + 6);
2466 ngx_sprintf(&ls->conf.addr[n], ":%ui", ls->port);
2468 if (cf->args->nelts == 2) {
2469 return NGX_CONF_OK;
2472 if (ngx_strcmp(value[2].data, "default") == 0) {
2473 ls->conf.default_server = 1;
2474 n = 3;
2476 } else {
2477 n = 2;
2480 for ( /* void */ ; n < cf->args->nelts; n++) {
2482 if (ls->conf.default_server == 0) {
2483 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2484 "\"%V\" parameter can be specified for "
2485 "the default \"listen\" directive only",
2486 &value[n]);
2487 return NGX_CONF_ERROR;
2490 if (ngx_strcmp(value[n].data, "bind") == 0) {
2491 ls->conf.bind = 1;
2492 continue;
2495 if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
2496 ls->conf.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
2497 ls->conf.bind = 1;
2499 if (ls->conf.backlog == NGX_ERROR || ls->conf.backlog == 0) {
2500 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2501 "invalid backlog \"%V\"", &value[n]);
2502 return NGX_CONF_ERROR;
2505 continue;
2508 if (ngx_strncmp(value[n].data, "rcvbuf=", 7) == 0) {
2509 size.len = value[n].len - 7;
2510 size.data = value[n].data + 7;
2512 ls->conf.rcvbuf = ngx_parse_size(&size);
2513 ls->conf.bind = 1;
2515 if (ls->conf.rcvbuf == NGX_ERROR) {
2516 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2517 "invalid rcvbuf \"%V\"", &value[n]);
2518 return NGX_CONF_ERROR;
2521 continue;
2524 if (ngx_strncmp(value[n].data, "sndbuf=", 7) == 0) {
2525 size.len = value[n].len - 7;
2526 size.data = value[n].data + 7;
2528 ls->conf.sndbuf = ngx_parse_size(&size);
2529 ls->conf.bind = 1;
2531 if (ls->conf.sndbuf == NGX_ERROR) {
2532 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2533 "invalid sndbuf \"%V\"", &value[n]);
2534 return NGX_CONF_ERROR;
2537 continue;
2540 if (ngx_strncmp(value[n].data, "accept_filter=", 14) == 0) {
2541 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
2542 ls->conf.accept_filter = (char *) &value[n].data[14];
2543 ls->conf.bind = 1;
2544 #else
2545 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2546 "accept filters \"%V\" are not supported "
2547 "on this platform, ignored",
2548 &value[n]);
2549 #endif
2550 continue;
2553 if (ngx_strcmp(value[n].data, "deferred") == 0) {
2554 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
2555 ls->conf.deferred_accept = 1;
2556 ls->conf.bind = 1;
2557 #else
2558 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2559 "the deferred accept is not supported "
2560 "on this platform, ignored");
2561 #endif
2562 continue;
2565 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2566 "the invalid \"%V\" parameter", &value[n]);
2567 return NGX_CONF_ERROR;
2570 return NGX_CONF_OK;
2574 static char *
2575 ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2577 ngx_http_core_srv_conf_t *cscf = conf;
2579 u_char ch;
2580 ngx_str_t *value, name;
2581 ngx_uint_t i;
2582 ngx_http_server_name_t *sn;
2584 value = cf->args->elts;
2586 ch = value[1].data[0];
2588 if (cscf->server_name.data == NULL && value[1].len) {
2589 if (ch == '*') {
2590 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2591 "first server name \"%V\" must not be wildcard",
2592 &value[1]);
2593 return NGX_CONF_ERROR;
2596 name = value[1];
2598 if (ch == '.') {
2599 name.len--;
2600 name.data++;
2603 cscf->server_name.len = name.len;
2604 cscf->server_name.data = ngx_pstrdup(cf->pool, &name);
2605 if (cscf->server_name.data == NULL) {
2606 return NGX_CONF_ERROR;
2610 for (i = 1; i < cf->args->nelts; i++) {
2612 ch = value[i].data[0];
2614 if (value[i].len == 1 && ch == '*') {
2615 cscf->wildcard = 1;
2616 continue;
2619 if (value[i].len == 0
2620 || (ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
2621 || (ch == '.' && value[i].len < 2))
2623 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2624 "server name \"%V\" is invalid", &value[i]);
2625 return NGX_CONF_ERROR;
2628 if (ngx_strchr(value[i].data, '/')) {
2629 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
2630 "server name \"%V\" has strange symbols",
2631 &value[i]);
2634 sn = ngx_array_push(&cscf->server_names);
2635 if (sn == NULL) {
2636 return NGX_CONF_ERROR;
2639 sn->name.len = value[i].len;
2640 sn->name.data = value[i].data;
2641 sn->core_srv_conf = cscf;
2644 return NGX_CONF_OK;
2648 static char *
2649 ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2651 ngx_http_core_loc_conf_t *lcf = conf;
2653 ngx_str_t *value;
2654 ngx_uint_t alias, n;
2655 ngx_http_script_compile_t sc;
2657 alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;
2659 if (lcf->root.data) {
2661 /* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */
2663 if ((ngx_uint_t) lcf->alias == alias) {
2664 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2665 "\"%V\" directive is duplicate",
2666 &cmd->name);
2667 } else {
2668 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2669 "\"%V\" directive is duplicate, "
2670 "\"%s\" directive is specified before",
2671 &cmd->name, lcf->alias ? "alias" : "root");
2674 return NGX_CONF_ERROR;
2677 value = cf->args->elts;
2679 if (ngx_strstr(value[1].data, "$document_root")
2680 || ngx_strstr(value[1].data, "${document_root}"))
2682 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2683 "the $document_root variable may not be used "
2684 "in the \"%V\" directive",
2685 &cmd->name);
2687 return NGX_CONF_ERROR;
2690 lcf->alias = alias;
2691 lcf->root = value[1];
2693 if (!alias && lcf->root.data[lcf->root.len - 1] == '/') {
2694 lcf->root.len--;
2697 if (lcf->root.data[0] != '$') {
2698 if (ngx_conf_full_name(cf->cycle, &lcf->root) == NGX_ERROR) {
2699 return NGX_CONF_ERROR;
2703 n = ngx_http_script_variables_count(&lcf->root);
2705 if (n == 0) {
2706 return NGX_CONF_OK;
2709 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
2711 sc.cf = cf;
2712 sc.source = &lcf->root;
2713 sc.lengths = &lcf->root_lengths;
2714 sc.values = &lcf->root_values;
2715 sc.variables = n;
2716 sc.complete_lengths = 1;
2717 sc.complete_values = 1;
2719 if (ngx_http_script_compile(&sc) != NGX_OK) {
2720 return NGX_CONF_ERROR;
2723 return NGX_CONF_OK;
2727 static ngx_http_method_name_t ngx_methods_names[] = {
2728 { (u_char *) "GET", (uint32_t) ~NGX_HTTP_GET },
2729 { (u_char *) "HEAD", (uint32_t) ~NGX_HTTP_HEAD },
2730 { (u_char *) "POST", (uint32_t) ~NGX_HTTP_POST },
2731 { (u_char *) "PUT", (uint32_t) ~NGX_HTTP_PUT },
2732 { (u_char *) "DELETE", (uint32_t) ~NGX_HTTP_DELETE },
2733 { (u_char *) "MKCOL", (uint32_t) ~NGX_HTTP_MKCOL },
2734 { (u_char *) "COPY", (uint32_t) ~NGX_HTTP_COPY },
2735 { (u_char *) "MOVE", (uint32_t) ~NGX_HTTP_MOVE },
2736 { (u_char *) "OPTIONS", (uint32_t) ~NGX_HTTP_OPTIONS },
2737 { (u_char *) "PROPFIND" , (uint32_t) ~NGX_HTTP_PROPFIND },
2738 { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH },
2739 { (u_char *) "LOCK", (uint32_t) ~NGX_HTTP_LOCK },
2740 { (u_char *) "UNLOCK", (uint32_t) ~NGX_HTTP_UNLOCK },
2741 { NULL, 0 }
2745 static char *
2746 ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2748 ngx_http_core_loc_conf_t *clcf = conf;
2750 char *rv;
2751 void *mconf;
2752 ngx_str_t *value;
2753 ngx_uint_t i;
2754 ngx_conf_t save;
2755 ngx_http_module_t *module;
2756 ngx_http_conf_ctx_t *ctx, *pctx;
2757 ngx_http_method_name_t *name;
2758 ngx_http_core_loc_conf_t *lcf, **clcfp;
2760 if (clcf->limit_except) {
2761 return "duplicate";
2764 clcf->limit_except = 0xffffffff;
2766 value = cf->args->elts;
2768 for (i = 1; i < cf->args->nelts; i++) {
2769 for (name = ngx_methods_names; name->name; name++) {
2771 if (ngx_strcasecmp(value[i].data, name->name) == 0) {
2772 clcf->limit_except &= name->method;
2773 goto next;
2777 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2778 "invalid method \"%V\"", &value[i]);
2779 return NGX_CONF_ERROR;
2781 next:
2782 continue;
2785 if (!(clcf->limit_except & NGX_HTTP_GET)) {
2786 clcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
2789 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
2790 if (ctx == NULL) {
2791 return NGX_CONF_ERROR;
2794 pctx = cf->ctx;
2795 ctx->main_conf = pctx->main_conf;
2796 ctx->srv_conf = pctx->srv_conf;
2798 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
2799 if (ctx->loc_conf == NULL) {
2800 return NGX_CONF_ERROR;
2803 for (i = 0; ngx_modules[i]; i++) {
2804 if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
2805 continue;
2808 module = ngx_modules[i]->ctx;
2810 if (module->create_loc_conf) {
2812 mconf = module->create_loc_conf(cf);
2813 if (mconf == NULL) {
2814 return NGX_CONF_ERROR;
2817 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
2822 lcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
2823 clcf->limit_except_loc_conf = ctx->loc_conf;
2824 lcf->loc_conf = ctx->loc_conf;
2825 lcf->name = clcf->name;
2826 lcf->noname = 1;
2828 if (clcf->locations.elts == NULL) {
2829 if (ngx_array_init(&clcf->locations, cf->pool, 4, sizeof(void *))
2830 == NGX_ERROR)
2832 return NGX_CONF_ERROR;
2836 clcfp = ngx_array_push(&clcf->locations);
2837 if (clcfp == NULL) {
2838 return NGX_CONF_ERROR;
2841 *clcfp = lcf;
2844 save = *cf;
2845 cf->ctx = ctx;
2846 cf->cmd_type = NGX_HTTP_LMT_CONF;
2848 rv = ngx_conf_parse(cf, NULL);
2850 *cf = save;
2852 return rv;
2856 static char *
2857 ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2859 ngx_http_core_loc_conf_t *lcf = conf;
2861 ngx_int_t overwrite;
2862 ngx_str_t *value, uri;
2863 ngx_uint_t i, n, nvar;
2864 ngx_array_t *uri_lengths, *uri_values;
2865 ngx_http_err_page_t *err;
2866 ngx_http_script_compile_t sc;
2868 if (lcf->error_pages == NULL) {
2869 lcf->error_pages = ngx_array_create(cf->pool, 4,
2870 sizeof(ngx_http_err_page_t));
2871 if (lcf->error_pages == NULL) {
2872 return NGX_CONF_ERROR;
2876 value = cf->args->elts;
2878 i = cf->args->nelts - 2;
2880 if (value[i].data[0] == '=') {
2881 if (i == 1) {
2882 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2883 "invalid value \"%V\"", &value[i]);
2884 return NGX_CONF_ERROR;
2887 if (value[i].len > 1) {
2888 overwrite = ngx_atoi(&value[i].data[1], value[i].len - 1);
2890 if (overwrite == NGX_ERROR) {
2891 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2892 "invalid value \"%V\"", &value[i]);
2893 return NGX_CONF_ERROR;
2896 } else {
2897 overwrite = 0;
2900 n = 2;
2902 } else {
2903 overwrite = -1;
2904 n = 1;
2907 uri = value[cf->args->nelts - 1];
2908 uri_lengths = NULL;
2909 uri_values = NULL;
2911 nvar = ngx_http_script_variables_count(&uri);
2913 if (nvar) {
2914 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
2916 sc.cf = cf;
2917 sc.source = &uri;
2918 sc.lengths = &uri_lengths;
2919 sc.values = &uri_values;
2920 sc.variables = nvar;
2921 sc.complete_lengths = 1;
2922 sc.complete_values = 1;
2924 if (ngx_http_script_compile(&sc) != NGX_OK) {
2925 return NGX_CONF_ERROR;
2929 for (i = 1; i < cf->args->nelts - n; i++) {
2930 err = ngx_array_push(lcf->error_pages);
2931 if (err == NULL) {
2932 return NGX_CONF_ERROR;
2935 err->status = ngx_atoi(value[i].data, value[i].len);
2937 if (err->status == NGX_ERROR || err->status == 499) {
2938 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2939 "invalid value \"%V\"", &value[i]);
2940 return NGX_CONF_ERROR;
2943 if (err->status < 400 || err->status > 599) {
2944 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2945 "value \"%V\" must be between 400 and 599",
2946 &value[i]);
2947 return NGX_CONF_ERROR;
2950 err->overwrite = (overwrite >= 0) ? overwrite : err->status;
2952 err->uri = uri;
2953 err->uri_lengths = uri_lengths;
2954 err->uri_values = uri_values;
2957 return NGX_CONF_OK;
2961 static char *
2962 ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2964 ngx_http_core_loc_conf_t *lcf = conf;
2966 lcf->err_log = ngx_log_create_errlog(cf->cycle, cf->args);
2967 if (lcf->err_log == NULL) {
2968 return NGX_CONF_ERROR;
2971 return ngx_set_error_log_levels(cf, lcf->err_log);
2975 static char *
2976 ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2978 ngx_http_core_loc_conf_t *lcf = conf;
2980 ngx_str_t *value;
2982 if (lcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
2983 return "is duplicate";
2986 value = cf->args->elts;
2988 lcf->keepalive_timeout = ngx_parse_time(&value[1], 0);
2990 if (lcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
2991 return "invalid value";
2994 if (lcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) {
2995 return "value must be less than 597 hours";
2998 if (cf->args->nelts == 2) {
2999 return NGX_CONF_OK;
3002 lcf->keepalive_header = ngx_parse_time(&value[2], 1);
3004 if (lcf->keepalive_header == NGX_ERROR) {
3005 return "invalid value";
3008 if (lcf->keepalive_header == NGX_PARSE_LARGE_TIME) {
3009 return "value must be less than 68 years";
3012 return NGX_CONF_OK;
3016 static char *
3017 ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3019 ngx_http_core_loc_conf_t *lcf = conf;
3021 if (lcf->internal != NGX_CONF_UNSET) {
3022 return "is duplicate";
3025 lcf->internal = 1;
3027 return NGX_CONF_OK;
3031 static char *
3032 ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
3034 #if (NGX_FREEBSD)
3035 ssize_t *np = data;
3037 if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
3038 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3039 "\"send_lowat\" must be less than %d "
3040 "(sysctl net.inet.tcp.sendspace)",
3041 ngx_freebsd_net_inet_tcp_sendspace);
3043 return NGX_CONF_ERROR;
3046 #elif !(NGX_HAVE_SO_SNDLOWAT)
3047 ssize_t *np = data;
3049 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
3050 "\"send_lowat\" is not supported, ignored");
3052 *np = 0;
3054 #endif
3056 return NGX_CONF_OK;
3060 static char *
3061 ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data)
3063 size_t *sp = data;
3065 if (*sp < NGX_MIN_POOL_SIZE) {
3066 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3067 "pool must be no less than %uz", NGX_MIN_POOL_SIZE);
3069 return NGX_CONF_ERROR;
3072 return NGX_CONF_OK;