3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
14 #define NGX_HTTP_LOCATION_EXACT 1
15 #define NGX_HTTP_LOCATION_AUTO_REDIRECT 2
16 #define NGX_HTTP_LOCATION_NOREGEX 3
17 #define NGX_HTTP_LOCATION_REGEX 4
20 static void ngx_http_core_phase_event_handler(ngx_event_t
*rev
);
21 static void ngx_http_core_run_phases(ngx_http_request_t
*r
);
22 static ngx_int_t
ngx_http_core_find_location(ngx_http_request_t
*r
,
23 ngx_array_t
*locations
, size_t len
);
25 static void *ngx_http_core_create_main_conf(ngx_conf_t
*cf
);
26 static char *ngx_http_core_init_main_conf(ngx_conf_t
*cf
, void *conf
);
27 static void *ngx_http_core_create_srv_conf(ngx_conf_t
*cf
);
28 static char *ngx_http_core_merge_srv_conf(ngx_conf_t
*cf
,
29 void *parent
, void *child
);
30 static void *ngx_http_core_create_loc_conf(ngx_conf_t
*cf
);
31 static char *ngx_http_core_merge_loc_conf(ngx_conf_t
*cf
,
32 void *parent
, void *child
);
34 static char *ngx_http_core_server(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
36 static char *ngx_http_core_location(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
38 static int ngx_http_core_cmp_locations(const void *first
, const void *second
);
40 static char *ngx_http_core_types(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
42 static char *ngx_http_core_type(ngx_conf_t
*cf
, ngx_command_t
*dummy
,
45 static char *ngx_http_core_listen(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
47 static char *ngx_http_core_server_name(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
49 static char *ngx_http_core_root(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
);
50 static char *ngx_http_core_error_page(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
52 static char *ngx_http_core_error_log(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
54 static char *ngx_http_core_keepalive(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
57 static char *ngx_http_core_lowat_check(ngx_conf_t
*cf
, void *post
, void *data
);
59 static ngx_conf_post_t ngx_http_core_lowat_post
=
60 { ngx_http_core_lowat_check
};
63 static ngx_conf_enum_t ngx_http_restrict_host_names
[] = {
64 { ngx_string("off"), NGX_HTTP_RESTRICT_HOST_OFF
},
65 { ngx_string("on"), NGX_HTTP_RESTRICT_HOST_ON
},
66 { ngx_string("close"), NGX_HTTP_RESTRICT_HOST_CLOSE
},
67 { ngx_null_string
, 0 }
71 static ngx_command_t ngx_http_core_commands
[] = {
73 { ngx_string("server_names_hash"),
74 NGX_HTTP_MAIN_CONF
|NGX_CONF_TAKE1
,
75 ngx_conf_set_num_slot
,
76 NGX_HTTP_MAIN_CONF_OFFSET
,
77 offsetof(ngx_http_core_main_conf_t
, server_names_hash
),
80 { ngx_string("server_names_hash_threshold"),
81 NGX_HTTP_MAIN_CONF
|NGX_CONF_TAKE1
,
82 ngx_conf_set_num_slot
,
83 NGX_HTTP_MAIN_CONF_OFFSET
,
84 offsetof(ngx_http_core_main_conf_t
, server_names_hash_threshold
),
87 { ngx_string("server"),
88 NGX_HTTP_MAIN_CONF
|NGX_CONF_BLOCK
|NGX_CONF_NOARGS
,
94 { ngx_string("connection_pool_size"),
95 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_CONF_TAKE1
,
96 ngx_conf_set_size_slot
,
97 NGX_HTTP_SRV_CONF_OFFSET
,
98 offsetof(ngx_http_core_srv_conf_t
, connection_pool_size
),
101 { ngx_string("post_accept_timeout"),
102 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_CONF_TAKE1
,
103 ngx_conf_set_msec_slot
,
104 NGX_HTTP_SRV_CONF_OFFSET
,
105 offsetof(ngx_http_core_srv_conf_t
, post_accept_timeout
),
108 { ngx_string("request_pool_size"),
109 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_CONF_TAKE1
,
110 ngx_conf_set_size_slot
,
111 NGX_HTTP_SRV_CONF_OFFSET
,
112 offsetof(ngx_http_core_srv_conf_t
, request_pool_size
),
115 { ngx_string("client_header_timeout"),
116 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_CONF_TAKE1
,
117 ngx_conf_set_msec_slot
,
118 NGX_HTTP_SRV_CONF_OFFSET
,
119 offsetof(ngx_http_core_srv_conf_t
, client_header_timeout
),
122 { ngx_string("client_header_buffer_size"),
123 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_CONF_TAKE1
,
124 ngx_conf_set_size_slot
,
125 NGX_HTTP_SRV_CONF_OFFSET
,
126 offsetof(ngx_http_core_srv_conf_t
, client_header_buffer_size
),
129 { ngx_string("large_client_header_buffers"),
130 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_CONF_TAKE2
,
131 ngx_conf_set_bufs_slot
,
132 NGX_HTTP_SRV_CONF_OFFSET
,
133 offsetof(ngx_http_core_srv_conf_t
, large_client_header_buffers
),
136 { ngx_string("restrict_host_names"),
137 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_CONF_TAKE1
,
138 ngx_conf_set_enum_slot
,
139 NGX_HTTP_SRV_CONF_OFFSET
,
140 offsetof(ngx_http_core_srv_conf_t
, restrict_host_names
),
141 &ngx_http_restrict_host_names
},
143 { ngx_string("location"),
144 NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_BLOCK
|NGX_CONF_TAKE12
,
145 ngx_http_core_location
,
146 NGX_HTTP_SRV_CONF_OFFSET
,
150 { ngx_string("listen"),
152 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_CONF_TAKE1
,
154 NGX_HTTP_SRV_CONF
|NGX_CONF_TAKE12
,
156 ngx_http_core_listen
,
157 NGX_HTTP_SRV_CONF_OFFSET
,
161 { ngx_string("server_name"),
162 NGX_HTTP_SRV_CONF
|NGX_CONF_1MORE
,
163 ngx_http_core_server_name
,
164 NGX_HTTP_SRV_CONF_OFFSET
,
168 { ngx_string("types"),
169 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
170 |NGX_CONF_BLOCK
|NGX_CONF_NOARGS
,
172 NGX_HTTP_LOC_CONF_OFFSET
,
176 { ngx_string("default_type"),
177 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
178 ngx_conf_set_str_slot
,
179 NGX_HTTP_LOC_CONF_OFFSET
,
180 offsetof(ngx_http_core_loc_conf_t
, default_type
),
183 { ngx_string("root"),
184 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
186 NGX_HTTP_LOC_CONF_OFFSET
,
190 { ngx_string("alias"),
191 NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
193 NGX_HTTP_LOC_CONF_OFFSET
,
197 { ngx_string("client_max_body_size"),
198 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
199 ngx_conf_set_size_slot
,
200 NGX_HTTP_LOC_CONF_OFFSET
,
201 offsetof(ngx_http_core_loc_conf_t
, client_max_body_size
),
204 { ngx_string("client_body_buffer_size"),
205 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
206 ngx_conf_set_size_slot
,
207 NGX_HTTP_LOC_CONF_OFFSET
,
208 offsetof(ngx_http_core_loc_conf_t
, client_body_buffer_size
),
211 { ngx_string("client_body_timeout"),
212 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
213 ngx_conf_set_msec_slot
,
214 NGX_HTTP_LOC_CONF_OFFSET
,
215 offsetof(ngx_http_core_loc_conf_t
, client_body_timeout
),
218 { ngx_string("client_body_temp_path"),
219 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1234
,
220 ngx_conf_set_path_slot
,
221 NGX_HTTP_LOC_CONF_OFFSET
,
222 offsetof(ngx_http_core_loc_conf_t
, client_body_temp_path
),
223 (void *) ngx_garbage_collector_temp_handler
},
225 { ngx_string("sendfile"),
226 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_FLAG
,
227 ngx_conf_set_flag_slot
,
228 NGX_HTTP_LOC_CONF_OFFSET
,
229 offsetof(ngx_http_core_loc_conf_t
, sendfile
),
232 { ngx_string("tcp_nopush"),
233 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_FLAG
,
234 ngx_conf_set_flag_slot
,
235 NGX_HTTP_LOC_CONF_OFFSET
,
236 offsetof(ngx_http_core_loc_conf_t
, tcp_nopush
),
239 { ngx_string("tcp_nodelay"),
240 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_FLAG
,
241 ngx_conf_set_flag_slot
,
242 NGX_HTTP_LOC_CONF_OFFSET
,
243 offsetof(ngx_http_core_loc_conf_t
, tcp_nodelay
),
246 { ngx_string("send_timeout"),
247 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
248 ngx_conf_set_msec_slot
,
249 NGX_HTTP_LOC_CONF_OFFSET
,
250 offsetof(ngx_http_core_loc_conf_t
, send_timeout
),
253 { ngx_string("send_lowat"),
254 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
255 ngx_conf_set_size_slot
,
256 NGX_HTTP_LOC_CONF_OFFSET
,
257 offsetof(ngx_http_core_loc_conf_t
, send_lowat
),
258 &ngx_http_core_lowat_post
},
260 { ngx_string("postpone_output"),
261 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
262 ngx_conf_set_size_slot
,
263 NGX_HTTP_LOC_CONF_OFFSET
,
264 offsetof(ngx_http_core_loc_conf_t
, postpone_output
),
267 { ngx_string("limit_rate"),
268 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_HTTP_LIF_CONF
270 ngx_conf_set_size_slot
,
271 NGX_HTTP_LOC_CONF_OFFSET
,
272 offsetof(ngx_http_core_loc_conf_t
, limit_rate
),
275 { ngx_string("keepalive_timeout"),
276 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE12
,
277 ngx_http_core_keepalive
,
278 NGX_HTTP_LOC_CONF_OFFSET
,
282 { ngx_string("lingering_time"),
283 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
284 ngx_conf_set_msec_slot
,
285 NGX_HTTP_LOC_CONF_OFFSET
,
286 offsetof(ngx_http_core_loc_conf_t
, lingering_time
),
289 { ngx_string("lingering_timeout"),
290 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
291 ngx_conf_set_msec_slot
,
292 NGX_HTTP_LOC_CONF_OFFSET
,
293 offsetof(ngx_http_core_loc_conf_t
, lingering_timeout
),
296 { ngx_string("reset_timedout_connection"),
297 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_FLAG
,
298 ngx_conf_set_flag_slot
,
299 NGX_HTTP_LOC_CONF_OFFSET
,
300 offsetof(ngx_http_core_loc_conf_t
, reset_timedout_connection
),
303 { ngx_string("msie_padding"),
304 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_FLAG
,
305 ngx_conf_set_flag_slot
,
306 NGX_HTTP_LOC_CONF_OFFSET
,
307 offsetof(ngx_http_core_loc_conf_t
, msie_padding
),
310 { ngx_string("error_page"),
311 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_2MORE
,
312 ngx_http_core_error_page
,
313 NGX_HTTP_LOC_CONF_OFFSET
,
317 { ngx_string("error_log"),
318 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_1MORE
,
319 ngx_http_core_error_log
,
320 NGX_HTTP_LOC_CONF_OFFSET
,
326 { ngx_string("open_file_cache"),
327 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE4
,
328 ngx_http_set_cache_slot
,
329 NGX_HTTP_LOC_CONF_OFFSET
,
330 offsetof(ngx_http_core_loc_conf_t
, open_files
),
339 ngx_http_module_t ngx_http_core_module_ctx
= {
342 ngx_http_core_create_main_conf
, /* create main configuration */
343 ngx_http_core_init_main_conf
, /* init main configuration */
345 ngx_http_core_create_srv_conf
, /* create server configuration */
346 ngx_http_core_merge_srv_conf
, /* merge server configuration */
348 ngx_http_core_create_loc_conf
, /* create location configuration */
349 ngx_http_core_merge_loc_conf
/* merge location configuration */
353 ngx_module_t ngx_http_core_module
= {
355 &ngx_http_core_module_ctx
, /* module context */
356 ngx_http_core_commands
, /* module directives */
357 NGX_HTTP_MODULE
, /* module type */
358 NULL
, /* init module */
359 NULL
/* init process */
364 ngx_http_handler(ngx_http_request_t
*r
)
366 r
->connection
->log
->action
= NULL
;
368 r
->connection
->unexpected_eof
= 0;
370 switch (r
->headers_in
.connection_type
) {
372 if (r
->http_version
> NGX_HTTP_VERSION_10
) {
379 case NGX_HTTP_CONNECTION_CLOSE
:
383 case NGX_HTTP_CONNECTION_KEEP_ALIVE
:
388 if (r
->keepalive
&& r
->headers_in
.msie
&& r
->method
== NGX_HTTP_POST
) {
391 * MSIE may wait for some time if the response for the POST request
392 * is sent over the keepalive connection
399 /* TEST STUB */ r
->http_version
= NGX_HTTP_VERSION_10
;
400 /* TEST STUB */ r
->keepalive
= 0;
403 if (r
->headers_in
.content_length_n
> 0) {
404 r
->lingering_close
= 1;
407 r
->lingering_close
= 0;
411 /* TEST STUB */ r
->lingering_close
= 1;
414 r
->connection
->write
->event_handler
= ngx_http_core_phase_event_handler
;
418 r
->phase
= NGX_HTTP_REWRITE_PHASE
;
419 r
->phase_handler
= 0;
421 ngx_http_core_run_phases(r
);
426 ngx_http_core_phase_event_handler(ngx_event_t
*ev
)
429 ngx_http_request_t
*r
;
434 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, ev
->log
, 0, "phase event handler");
436 ngx_http_core_run_phases(r
);
441 ngx_http_core_run_phases(ngx_http_request_t
*r
)
444 ngx_http_handler_pt
*h
;
445 ngx_http_core_loc_conf_t
*clcf
;
446 ngx_http_core_main_conf_t
*cmcf
;
448 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
450 for (/* void */; r
->phase
< NGX_HTTP_LAST_PHASE
; r
->phase
++) {
452 if (r
->phase
== NGX_HTTP_REWRITE_PHASE
+ 1 && r
->uri_changed
) {
454 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
455 "uri changes: %d", r
->uri_changes
);
458 * gcc before 3.3 compiles the broken code for
459 * if (r->uri_changes-- == 0)
460 * if the r->uri_changes is defined as
461 * unsigned uri_changes:4
466 if (r
->uri_changes
== 0) {
467 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0,
469 ngx_http_finalize_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
473 r
->phase
= NGX_HTTP_FIND_CONFIG_PHASE
;
476 if (r
->phase
== NGX_HTTP_CONTENT_PHASE
&& r
->content_handler
) {
477 r
->connection
->write
->event_handler
= ngx_http_empty_handler
;
478 ngx_http_finalize_request(r
, r
->content_handler(r
));
482 h
= cmcf
->phases
[r
->phase
].handlers
.elts
;
483 for (r
->phase_handler
= cmcf
->phases
[r
->phase
].handlers
.nelts
- 1;
484 r
->phase_handler
>= 0;
487 rc
= h
[r
->phase_handler
](r
);
489 if (rc
== NGX_DONE
) {
492 * we should never use r here because
493 * it could point to already freed data
499 if (rc
== NGX_DECLINED
) {
503 if (rc
>= NGX_HTTP_SPECIAL_RESPONSE
|| rc
== NGX_ERROR
) {
504 ngx_http_finalize_request(r
, rc
);
508 if (r
->phase
== NGX_HTTP_CONTENT_PHASE
) {
509 ngx_http_finalize_request(r
, rc
);
513 if (rc
== NGX_AGAIN
) {
517 if (rc
== NGX_OK
&& cmcf
->phases
[r
->phase
].type
== NGX_OK
) {
523 /* no content handler was found */
525 if (r
->uri
.data
[r
->uri
.len
- 1] == '/' && !r
->zero_in_uri
) {
527 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
529 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0,
530 "directory index of \"%V%V\" is forbidden",
531 &clcf
->root
, &r
->uri
);
533 ngx_http_finalize_request(r
, NGX_HTTP_FORBIDDEN
);
537 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0, "no handler found");
539 ngx_http_finalize_request(r
, NGX_HTTP_NOT_FOUND
);
544 ngx_http_find_location_config(ngx_http_request_t
*r
)
547 ngx_http_core_loc_conf_t
*clcf
;
548 ngx_http_core_srv_conf_t
*cscf
;
550 r
->content_handler
= NULL
;
553 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
555 rc
= ngx_http_core_find_location(r
, &cscf
->locations
, 0);
557 if (rc
== NGX_HTTP_INTERNAL_SERVER_ERROR
) {
561 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
563 r
->connection
->log
->file
= clcf
->err_log
->file
;
564 if (!(r
->connection
->log
->log_level
& NGX_LOG_DEBUG_CONNECTION
)) {
565 r
->connection
->log
->log_level
= clcf
->err_log
->log_level
;
568 if ((ngx_io
.flags
& NGX_IO_SENDFILE
) && clcf
->sendfile
) {
569 r
->connection
->sendfile
= 1;
572 r
->connection
->sendfile
= 0;
575 if (r
->keepalive
&& clcf
->keepalive_timeout
== 0) {
579 if (!clcf
->tcp_nopush
) {
580 /* disable TCP_NOPUSH/TCP_CORK use */
581 r
->connection
->tcp_nopush
= NGX_TCP_NOPUSH_DISABLED
;
585 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
586 "http cl:%z max:%uz",
587 r
->headers_in
.content_length_n
, clcf
->client_max_body_size
);
589 if (r
->headers_in
.content_length_n
!= -1
590 && clcf
->client_max_body_size
591 && clcf
->client_max_body_size
< (size_t) r
->headers_in
.content_length_n
)
593 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0,
594 "client intented to send too large body: %z bytes",
595 r
->headers_in
.content_length_n
);
597 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE
;
601 if (rc
== NGX_HTTP_LOCATION_AUTO_REDIRECT
) {
602 r
->headers_out
.location
= ngx_list_push(&r
->headers_out
.headers
);
603 if (r
->headers_out
.location
== NULL
) {
604 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
607 r
->headers_out
.location
->value
= clcf
->name
;
609 return NGX_HTTP_MOVED_PERMANENTLY
;
613 r
->content_handler
= clcf
->handler
;
621 ngx_http_core_find_location(ngx_http_request_t
*r
,
622 ngx_array_t
*locations
, size_t len
)
625 ngx_uint_t i
, found
, noregex
;
626 ngx_http_core_loc_conf_t
*clcf
, **clcfp
;
628 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0, "find location");
633 clcfp
= locations
->elts
;
634 for (i
= 0; i
< locations
->nelts
; i
++) {
637 if (clcfp
[i
]->regex
) {
642 if (clcfp
[i
]->noname
) {
646 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
647 "find location: %s\"%V\"",
648 clcfp
[i
]->exact_match
? "= " : "", &clcfp
[i
]->name
);
650 if (clcfp
[i
]->auto_redirect
651 && r
->uri
.len
== clcfp
[i
]->name
.len
- 1
652 && ngx_strncmp(r
->uri
.data
, clcfp
[i
]->name
.data
,
653 clcfp
[i
]->name
.len
- 1) == 0)
655 /* the locations are lexicographically sorted */
657 r
->loc_conf
= clcfp
[i
]->loc_conf
;
659 return NGX_HTTP_LOCATION_AUTO_REDIRECT
;
662 if (r
->uri
.len
< clcfp
[i
]->name
.len
) {
666 n
= ngx_strncmp(r
->uri
.data
, clcfp
[i
]->name
.data
, clcfp
[i
]->name
.len
);
669 /* the locations are lexicographically sorted */
674 if (clcfp
[i
]->exact_match
) {
676 if (r
->uri
.len
== clcfp
[i
]->name
.len
) {
677 r
->loc_conf
= clcfp
[i
]->loc_conf
;
678 return NGX_HTTP_LOCATION_EXACT
;
684 if (len
> clcfp
[i
]->name
.len
) {
685 /* the previous match is longer */
689 r
->loc_conf
= clcfp
[i
]->loc_conf
;
690 noregex
= clcfp
[i
]->noregex
;
696 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
698 if (clcf
->locations
.nelts
) {
699 rc
= ngx_http_core_find_location(r
, &clcf
->locations
, len
);
710 return NGX_HTTP_LOCATION_NOREGEX
;
715 for (/* void */; i
< locations
->nelts
; i
++) {
717 if (!clcfp
[i
]->regex
) {
721 if (clcfp
[i
]->noname
) {
725 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
726 "find location: ~ \"%V\"", &clcfp
[i
]->name
);
728 n
= ngx_regex_exec(clcfp
[i
]->regex
, &r
->uri
, NULL
, 0);
730 if (n
== NGX_REGEX_NO_MATCHED
) {
735 ngx_log_error(NGX_LOG_ALERT
, r
->connection
->log
, 0,
737 " failed: %d on \"%V\" using \"%V\"",
738 n
, &r
->uri
, &clcfp
[i
]->name
);
739 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
744 r
->loc_conf
= clcfp
[i
]->loc_conf
;
746 return NGX_HTTP_LOCATION_REGEX
;
749 #endif /* NGX_PCRE */
756 ngx_http_set_content_type(ngx_http_request_t
*r
)
758 u_char c
, *p
, *exten
;
761 ngx_http_type_t
*type
;
762 ngx_http_core_loc_conf_t
*clcf
;
764 r
->headers_out
.content_type
= ngx_list_push(&r
->headers_out
.headers
);
765 if (r
->headers_out
.content_type
== NULL
) {
766 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
769 r
->headers_out
.content_type
->key
.len
= 0;
770 r
->headers_out
.content_type
->key
.data
= NULL
;
771 r
->headers_out
.content_type
->value
.len
= 0;
772 r
->headers_out
.content_type
->value
.data
= NULL
;
774 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
778 if (!r
->low_case_exten
) {
779 for (i
= 0; i
< r
->exten
.len
; i
++) {
780 c
= r
->exten
.data
[i
];
781 if (c
>= 'A' && c
<= 'Z') {
786 if (i
< r
->exten
.len
) {
787 if (!(p
= ngx_palloc(r
->pool
, r
->exten
.len
))) {
788 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
793 for (i
= 0; i
< r
->exten
.len
; i
++) {
794 c
= r
->exten
.data
[i
];
795 if (c
>= 'A' && c
<= 'Z') {
796 *p
++ = (u_char
) (c
| 0x20);
802 r
->exten
.data
= exten
;
805 r
->low_case_exten
= 1;
809 key
= ngx_crc(r
->exten
.data
, r
->exten
.key
);
811 ngx_http_types_hash_key(key
, r
->exten
);
813 type
= clcf
->types
[key
].elts
;
814 for (i
= 0; i
< clcf
->types
[key
].nelts
; i
++) {
815 if (r
->exten
.len
!= type
[i
].exten
.len
) {
819 if (ngx_memcmp(r
->exten
.data
, type
[i
].exten
.data
, r
->exten
.len
)
822 r
->headers_out
.content_type
->value
= type
[i
].type
;
828 if (r
->headers_out
.content_type
->value
.len
== 0) {
829 r
->headers_out
.content_type
->value
= clcf
->default_type
;
837 ngx_http_send_header(ngx_http_request_t
*r
)
844 r
->headers_out
.status
= r
->err_status
;
845 r
->headers_out
.status_line
.len
= 0;
848 return ngx_http_top_header_filter(r
);
853 ngx_http_output_filter(ngx_http_request_t
*r
, ngx_chain_t
*in
)
857 if (r
->connection
->write
->error
) {
861 rc
= ngx_http_top_body_filter(r
, in
);
863 if (rc
== NGX_ERROR
) {
865 /* NGX_ERROR may be returned by any filter */
867 r
->connection
->write
->error
= 1;
875 ngx_http_redirect(ngx_http_request_t
*r
, int redirect
)
881 ngx_http_close_request(r
, 0);
887 ngx_http_set_exten(ngx_http_request_t
*r
)
892 r
->exten
.data
= NULL
;
894 for (i
= r
->uri
.len
- 1; i
> 1; i
--) {
895 if (r
->uri
.data
[i
] == '.' && r
->uri
.data
[i
- 1] != '/') {
896 r
->exten
.len
= r
->uri
.len
- i
- 1;
898 if (r
->exten
.len
> 0) {
899 if (!(r
->exten
.data
= ngx_palloc(r
->pool
, r
->exten
.len
+ 1))) {
903 ngx_cpystrn(r
->exten
.data
, &r
->uri
.data
[i
+ 1],
909 } else if (r
->uri
.data
[i
] == '/') {
914 r
->low_case_exten
= 0;
921 ngx_http_internal_redirect(ngx_http_request_t
*r
,
922 ngx_str_t
*uri
, ngx_str_t
*args
)
924 ngx_http_core_srv_conf_t
*cscf
;
926 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
927 "internal redirect: \"%V\"", uri
);
935 if (ngx_http_set_exten(r
) != NGX_OK
) {
936 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
941 /* allocate the new module's contexts */
943 r
->ctx
= ngx_pcalloc(r
->pool
, sizeof(void *) * ngx_http_max_module
);
944 if (r
->ctx
== NULL
) {
945 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
950 /* clear the modules contexts */
952 ngx_memzero(r
->ctx
, sizeof(void *) * ngx_http_max_module
);
955 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
956 r
->loc_conf
= cscf
->ctx
->loc_conf
;
964 #if 0 /* STUB: test the delay http handler */
967 ngx_http_delay_handler(ngx_http_request_t
*r
)
972 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
974 ngx_add_timer(r
->connection
->write
, 10000);
978 r
->connection
->write
->timedout
= 0;
979 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
987 ngx_http_variable_t
*
988 ngx_http_add_variable(ngx_conf_t
*cf
)
990 ngx_http_variable_t
*var
;
991 ngx_http_core_main_conf_t
*cmcf
;
993 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
995 if (cmcf
->variables
.elts
== NULL
) {
996 if (ngx_array_init(&cmcf
->variables
, cf
->pool
, 5,
997 sizeof(ngx_http_variable_t
)) == NGX_ERROR
)
1003 if (!(var
= ngx_array_push(&cmcf
->variables
))) {
1007 var
->index
= cmcf
->variables
.nelts
- 1;
1013 ngx_http_variable_value_t
*
1014 ngx_http_get_variable(ngx_http_request_t
*r
, ngx_uint_t index
)
1016 ngx_http_variable_t
*v
;
1017 ngx_http_core_main_conf_t
*cmcf
;
1019 /* TODO: cached variables */
1021 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
1023 if (cmcf
->variables
.elts
== NULL
|| cmcf
->variables
.nelts
<= index
) {
1024 ngx_log_error(NGX_LOG_ALERT
, r
->connection
->log
, 0,
1025 "unknown variable index: %d", index
);
1029 v
= cmcf
->variables
.elts
;
1031 return v
[index
].handler(r
, v
[index
].data
);
1036 ngx_http_core_server(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *dummy
)
1042 ngx_http_module_t
*module
;
1043 ngx_http_conf_ctx_t
*ctx
, *http_ctx
;
1044 ngx_http_core_srv_conf_t
*cscf
, **cscfp
;
1045 ngx_http_core_main_conf_t
*cmcf
;
1047 if (!(ctx
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_conf_ctx_t
)))) {
1048 return NGX_CONF_ERROR
;
1052 ctx
->main_conf
= http_ctx
->main_conf
;
1054 /* the server{}'s srv_conf */
1056 ctx
->srv_conf
= ngx_pcalloc(cf
->pool
, sizeof(void *) * ngx_http_max_module
);
1057 if (ctx
->srv_conf
== NULL
) {
1058 return NGX_CONF_ERROR
;
1061 /* the server{}'s loc_conf */
1063 ctx
->loc_conf
= ngx_pcalloc(cf
->pool
, sizeof(void *) * ngx_http_max_module
);
1064 if (ctx
->loc_conf
== NULL
) {
1065 return NGX_CONF_ERROR
;
1068 for (m
= 0; ngx_modules
[m
]; m
++) {
1069 if (ngx_modules
[m
]->type
!= NGX_HTTP_MODULE
) {
1073 module
= ngx_modules
[m
]->ctx
;
1075 if (module
->create_srv_conf
) {
1076 if (!(mconf
= module
->create_srv_conf(cf
))) {
1077 return NGX_CONF_ERROR
;
1080 ctx
->srv_conf
[ngx_modules
[m
]->ctx_index
] = mconf
;
1083 if (module
->create_loc_conf
) {
1084 if (!(mconf
= module
->create_loc_conf(cf
))) {
1085 return NGX_CONF_ERROR
;
1088 ctx
->loc_conf
[ngx_modules
[m
]->ctx_index
] = mconf
;
1093 /* the server configuration context */
1095 cscf
= ctx
->srv_conf
[ngx_http_core_module
.ctx_index
];
1099 cmcf
= ctx
->main_conf
[ngx_http_core_module
.ctx_index
];
1101 if (!(cscfp
= ngx_array_push(&cmcf
->servers
))) {
1102 return NGX_CONF_ERROR
;
1108 /* parse inside server{} */
1112 cf
->cmd_type
= NGX_HTTP_SRV_CONF
;
1114 rv
= ngx_conf_parse(cf
, NULL
);
1118 if (rv
!= NGX_CONF_OK
) {
1122 ngx_qsort(cscf
->locations
.elts
, (size_t) cscf
->locations
.nelts
,
1123 sizeof(ngx_http_core_loc_conf_t
*), ngx_http_core_cmp_locations
);
1130 ngx_http_core_location(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *dummy
)
1136 ngx_http_module_t
*module
;
1137 ngx_http_conf_ctx_t
*ctx
, *pctx
;
1138 ngx_http_core_srv_conf_t
*cscf
;
1139 ngx_http_core_loc_conf_t
*clcf
, *pclcf
, **clcfp
;
1142 u_char errstr
[NGX_MAX_CONF_ERRSTR
];
1145 if (!(ctx
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_conf_ctx_t
)))) {
1146 return NGX_CONF_ERROR
;
1150 ctx
->main_conf
= pctx
->main_conf
;
1151 ctx
->srv_conf
= pctx
->srv_conf
;
1153 ctx
->loc_conf
= ngx_pcalloc(cf
->pool
, sizeof(void *) * ngx_http_max_module
);
1154 if (ctx
->loc_conf
== NULL
) {
1155 return NGX_CONF_ERROR
;
1158 for (m
= 0; ngx_modules
[m
]; m
++) {
1159 if (ngx_modules
[m
]->type
!= NGX_HTTP_MODULE
) {
1163 module
= ngx_modules
[m
]->ctx
;
1165 if (module
->create_loc_conf
) {
1166 ctx
->loc_conf
[ngx_modules
[m
]->ctx_index
] =
1167 module
->create_loc_conf(cf
);
1168 if (ctx
->loc_conf
[ngx_modules
[m
]->ctx_index
] == NULL
) {
1169 return NGX_CONF_ERROR
;
1174 clcf
= ctx
->loc_conf
[ngx_http_core_module
.ctx_index
];
1175 clcf
->loc_conf
= ctx
->loc_conf
;
1177 value
= cf
->args
->elts
;
1179 if (cf
->args
->nelts
== 3) {
1180 if (value
[1].len
== 1 && value
[1].data
[0] == '=') {
1181 clcf
->name
= value
[2];
1182 clcf
->exact_match
= 1;
1184 } else if (value
[1].len
== 2
1185 && value
[1].data
[0] == '^'
1186 && value
[1].data
[1] == '~')
1188 clcf
->name
= value
[2];
1191 } else if ((value
[1].len
== 1 && value
[1].data
[0] == '~')
1192 || (value
[1].len
== 2
1193 && value
[1].data
[0] == '~'
1194 && value
[1].data
[1] == '*'))
1197 err
.len
= NGX_MAX_CONF_ERRSTR
;
1200 clcf
->regex
= ngx_regex_compile(&value
[2],
1201 value
[1].len
== 2 ? NGX_REGEX_CASELESS
: 0,
1204 if (clcf
->regex
== NULL
) {
1205 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0, "%s", err
.data
);
1206 return NGX_CONF_ERROR
;
1209 clcf
->name
= value
[2];
1211 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1212 "the using of the regex \"%V\" "
1213 "requires PCRE library", &value
[2]);
1214 return NGX_CONF_ERROR
;
1218 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1219 "invalid location modifier \"%V\"", &value
[1]);
1220 return NGX_CONF_ERROR
;
1224 clcf
->name
= value
[1];
1227 pclcf
= pctx
->loc_conf
[ngx_http_core_module
.ctx_index
];
1229 if (pclcf
->name
.len
== 0) {
1230 cscf
= ctx
->srv_conf
[ngx_http_core_module
.ctx_index
];
1231 if (!(clcfp
= ngx_array_push(&cscf
->locations
))) {
1232 return NGX_CONF_ERROR
;
1237 clcf
->prev_location
= pclcf
;
1240 if (pclcf
->exact_match
) {
1241 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1242 "location \"%V\" could not be inside "
1243 "the exact location \"%V\"",
1244 &clcf
->name
, &pclcf
->name
);
1245 return NGX_CONF_ERROR
;
1249 if (clcf
->regex
== NULL
1250 && ngx_strncmp(clcf
->name
.data
, pclcf
->name
.data
, pclcf
->name
.len
)
1253 if (ngx_strncmp(clcf
->name
.data
, pclcf
->name
.data
, pclcf
->name
.len
)
1257 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1258 "location \"%V\" is outside location \"%V\"",
1259 &clcf
->name
, &pclcf
->name
);
1260 return NGX_CONF_ERROR
;
1263 if (pclcf
->locations
.elts
== NULL
) {
1264 ngx_init_array(pclcf
->locations
, cf
->pool
, 4, sizeof(void *),
1268 if (!(clcfp
= ngx_push_array(&pclcf
->locations
))) {
1269 return NGX_CONF_ERROR
;
1277 cf
->cmd_type
= NGX_HTTP_LOC_CONF
;
1279 rv
= ngx_conf_parse(cf
, NULL
);
1283 if (rv
!= NGX_CONF_OK
) {
1287 ngx_qsort(clcf
->locations
.elts
, (size_t) clcf
->locations
.nelts
,
1288 sizeof(ngx_http_core_loc_conf_t
*), ngx_http_core_cmp_locations
);
1295 ngx_http_core_cmp_locations(const void *one
, const void *two
)
1298 ngx_http_core_loc_conf_t
*first
, *second
;
1300 first
= *(ngx_http_core_loc_conf_t
**) one
;
1301 second
= *(ngx_http_core_loc_conf_t
**) two
;
1303 if (first
->noname
&& !second
->noname
) {
1304 /* shift no named locations to the end */
1308 if (!first
->noname
&& second
->noname
) {
1309 /* shift no named locations to the end */
1313 if (first
->noname
|| second
->noname
) {
1314 /* do not sort no named locations */
1320 if (first
->regex
&& !second
->regex
) {
1321 /* shift the regex matches to the end */
1325 if (!first
->regex
&& second
->regex
) {
1326 /* shift the regex matches to the end */
1330 if (first
->regex
|| second
->regex
) {
1331 /* do not sort the regex matches */
1337 rc
= ngx_strcmp(first
->name
.data
, second
->name
.data
);
1339 if (rc
== 0 && second
->exact_match
) {
1340 /* an exact match must be before the same inclusive one */
1349 ngx_http_core_types(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1355 cf
->handler
= ngx_http_core_type
;
1356 cf
->handler_conf
= conf
;
1358 rv
= ngx_conf_parse(cf
, NULL
);
1367 ngx_http_core_type(ngx_conf_t
*cf
, ngx_command_t
*dummy
, void *conf
)
1369 ngx_http_core_loc_conf_t
*lcf
= conf
;
1374 ngx_http_type_t
*type
;
1376 if (lcf
->types
== NULL
) {
1377 lcf
->types
= ngx_palloc(cf
->pool
, NGX_HTTP_TYPES_HASH_PRIME
1378 * sizeof(ngx_array_t
));
1379 if (lcf
->types
== NULL
) {
1380 return NGX_CONF_ERROR
;
1383 for (i
= 0; i
< NGX_HTTP_TYPES_HASH_PRIME
; i
++) {
1384 if (ngx_array_init(&lcf
->types
[i
], cf
->pool
, 5,
1385 sizeof(ngx_http_type_t
)) == NGX_ERROR
)
1387 return NGX_CONF_ERROR
;
1392 value
= cf
->args
->elts
;
1394 for (i
= 1; i
< cf
->args
->nelts
; i
++) {
1395 ngx_http_types_hash_key(key
, value
[i
]);
1397 if (!(type
= ngx_array_push(&lcf
->types
[key
]))) {
1398 return NGX_CONF_ERROR
;
1401 type
->exten
= value
[i
];
1402 type
->type
= value
[0];
1410 ngx_http_core_create_main_conf(ngx_conf_t
*cf
)
1412 ngx_http_core_main_conf_t
*cmcf
;
1414 if (!(cmcf
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_core_main_conf_t
)))) {
1415 return NGX_CONF_ERROR
;
1418 if (ngx_array_init(&cmcf
->servers
, cf
->pool
, 5,
1419 sizeof(ngx_http_core_srv_conf_t
*)) == NGX_ERROR
)
1421 return NGX_CONF_ERROR
;
1424 cmcf
->server_names_hash
= NGX_CONF_UNSET_UINT
;
1425 cmcf
->server_names_hash_threshold
= NGX_CONF_UNSET_UINT
;
1432 ngx_http_core_init_main_conf(ngx_conf_t
*cf
, void *conf
)
1434 ngx_http_core_main_conf_t
*cmcf
= conf
;
1436 if (cmcf
->server_names_hash
== NGX_CONF_UNSET_UINT
) {
1437 cmcf
->server_names_hash
= 1009;
1440 if (cmcf
->server_names_hash_threshold
== NGX_CONF_UNSET_UINT
) {
1441 cmcf
->server_names_hash_threshold
= 50;
1449 ngx_http_core_create_srv_conf(ngx_conf_t
*cf
)
1451 ngx_http_core_srv_conf_t
*cscf
;
1453 if (!(cscf
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_core_srv_conf_t
)))) {
1454 return NGX_CONF_ERROR
;
1458 * set by ngx_pcalloc():
1460 * conf->client_large_buffers.num = 0;
1463 if (ngx_array_init(&cscf
->locations
, cf
->pool
, 5, sizeof(void *))
1466 return NGX_CONF_ERROR
;
1469 if (ngx_array_init(&cscf
->listen
, cf
->pool
, 5, sizeof(ngx_http_listen_t
))
1472 return NGX_CONF_ERROR
;
1475 if (ngx_array_init(&cscf
->server_names
, cf
->pool
, 5,
1476 sizeof(ngx_http_server_name_t
)) == NGX_ERROR
)
1478 return NGX_CONF_ERROR
;
1481 cscf
->connection_pool_size
= NGX_CONF_UNSET_SIZE
;
1482 cscf
->post_accept_timeout
= NGX_CONF_UNSET_MSEC
;
1483 cscf
->request_pool_size
= NGX_CONF_UNSET_SIZE
;
1484 cscf
->client_header_timeout
= NGX_CONF_UNSET_MSEC
;
1485 cscf
->client_header_buffer_size
= NGX_CONF_UNSET_SIZE
;
1486 cscf
->restrict_host_names
= NGX_CONF_UNSET_UINT
;
1493 ngx_http_core_merge_srv_conf(ngx_conf_t
*cf
, void *parent
, void *child
)
1495 ngx_http_core_srv_conf_t
*prev
= parent
;
1496 ngx_http_core_srv_conf_t
*conf
= child
;
1498 ngx_http_listen_t
*ls
;
1499 ngx_http_server_name_t
*sn
;
1500 ngx_http_core_main_conf_t
*cmcf
;
1502 /* TODO: it does not merge, it inits only */
1504 if (conf
->listen
.nelts
== 0) {
1505 if (!(ls
= ngx_array_push(&conf
->listen
))) {
1506 return NGX_CONF_ERROR
;
1509 ls
->addr
= INADDR_ANY
;
1513 /* STUB: getuid() should be cached */
1514 ls
->port
= (getuid() == 0) ? 80 : 8000;
1516 ls
->family
= AF_INET
;
1519 if (conf
->server_names
.nelts
== 0) {
1520 if (!(sn
= ngx_array_push(&conf
->server_names
))) {
1521 return NGX_CONF_ERROR
;
1524 if (!(sn
->name
.data
= ngx_palloc(cf
->pool
, NGX_MAXHOSTNAMELEN
))) {
1525 return NGX_CONF_ERROR
;
1528 if (gethostname((char *) sn
->name
.data
, NGX_MAXHOSTNAMELEN
) == -1) {
1529 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, ngx_errno
,
1530 "gethostname() failed");
1531 return NGX_CONF_ERROR
;
1534 sn
->name
.len
= ngx_strlen(sn
->name
.data
);
1535 sn
->core_srv_conf
= conf
;
1538 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
1540 if (cmcf
->max_server_name_len
< sn
->name
.len
) {
1541 cmcf
->max_server_name_len
= sn
->name
.len
;
1545 ngx_conf_merge_size_value(conf
->connection_pool_size
,
1546 prev
->connection_pool_size
, 256);
1547 ngx_conf_merge_msec_value(conf
->post_accept_timeout
,
1548 prev
->post_accept_timeout
, 60000);
1549 ngx_conf_merge_size_value(conf
->request_pool_size
,
1550 prev
->request_pool_size
, 4096);
1551 ngx_conf_merge_msec_value(conf
->client_header_timeout
,
1552 prev
->client_header_timeout
, 60000);
1553 ngx_conf_merge_size_value(conf
->client_header_buffer_size
,
1554 prev
->client_header_buffer_size
, 1024);
1555 ngx_conf_merge_bufs_value(conf
->large_client_header_buffers
,
1556 prev
->large_client_header_buffers
,
1559 if (conf
->large_client_header_buffers
.size
< conf
->connection_pool_size
) {
1560 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1561 "the \"large_client_header_buffers\" size must be "
1562 "equal to or bigger than \"connection_pool_size\"");
1563 return NGX_CONF_ERROR
;
1566 ngx_conf_merge_unsigned_value(conf
->restrict_host_names
,
1567 prev
->restrict_host_names
, 0);
1574 ngx_http_core_create_loc_conf(ngx_conf_t
*cf
)
1576 ngx_http_core_loc_conf_t
*lcf
;
1578 if (!(lcf
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_core_loc_conf_t
)))) {
1579 return NGX_CONF_ERROR
;
1583 * set by ngx_pcalloc():
1585 * lcf->root.len = 0;
1586 * lcf->root.data = NULL;
1587 * lcf->types = NULL;
1588 * lcf->default_type.len = 0;
1589 * lcf->default_type.data = NULL;
1590 * lcf->err_log = NULL;
1591 * lcf->error_pages = NULL;
1592 * lcf->client_body_path = NULL;
1593 * lcf->regex = NULL;
1594 * lcf->exact_match = 0;
1595 * lcf->auto_redirect = 0;
1599 lcf
->client_max_body_size
= NGX_CONF_UNSET_SIZE
;
1600 lcf
->client_body_buffer_size
= NGX_CONF_UNSET_SIZE
;
1601 lcf
->client_body_timeout
= NGX_CONF_UNSET_MSEC
;
1602 lcf
->sendfile
= NGX_CONF_UNSET
;
1603 lcf
->tcp_nopush
= NGX_CONF_UNSET
;
1604 lcf
->tcp_nodelay
= NGX_CONF_UNSET
;
1605 lcf
->send_timeout
= NGX_CONF_UNSET_MSEC
;
1606 lcf
->send_lowat
= NGX_CONF_UNSET_SIZE
;
1607 lcf
->postpone_output
= NGX_CONF_UNSET_SIZE
;
1608 lcf
->limit_rate
= NGX_CONF_UNSET_SIZE
;
1609 lcf
->keepalive_timeout
= NGX_CONF_UNSET_MSEC
;
1610 lcf
->keepalive_header
= NGX_CONF_UNSET
;
1611 lcf
->lingering_time
= NGX_CONF_UNSET_MSEC
;
1612 lcf
->lingering_timeout
= NGX_CONF_UNSET_MSEC
;
1613 lcf
->reset_timedout_connection
= NGX_CONF_UNSET
;
1614 lcf
->msie_padding
= NGX_CONF_UNSET
;
1620 static ngx_http_type_t ngx_http_core_default_types
[] = {
1621 { ngx_string("html"), ngx_string("text/html") },
1622 { ngx_string("gif"), ngx_string("image/gif") },
1623 { ngx_string("jpg"), ngx_string("image/jpeg") },
1624 { ngx_null_string
, ngx_null_string
}
1629 ngx_http_core_merge_loc_conf(ngx_conf_t
*cf
,
1630 void *parent
, void *child
)
1632 ngx_http_core_loc_conf_t
*prev
= parent
;
1633 ngx_http_core_loc_conf_t
*conf
= child
;
1637 ngx_http_type_t
*type
;
1639 ngx_conf_merge_str_value(conf
->root
, prev
->root
, "html");
1641 if (ngx_conf_full_name(cf
->cycle
, &conf
->root
) == NGX_ERROR
) {
1642 return NGX_CONF_ERROR
;
1645 if (conf
->types
== NULL
) {
1647 conf
->types
= prev
->types
;
1650 conf
->types
= ngx_palloc(cf
->pool
, NGX_HTTP_TYPES_HASH_PRIME
1651 * sizeof(ngx_array_t
));
1652 if (conf
->types
== NULL
) {
1653 return NGX_CONF_ERROR
;
1656 for (i
= 0; i
< NGX_HTTP_TYPES_HASH_PRIME
; i
++) {
1657 if (ngx_array_init(&conf
->types
[i
], cf
->pool
, 5,
1658 sizeof(ngx_http_type_t
)) == NGX_ERROR
)
1660 return NGX_CONF_ERROR
;
1664 for (i
= 0; ngx_http_core_default_types
[i
].exten
.len
; i
++) {
1665 ngx_http_types_hash_key(key
,
1666 ngx_http_core_default_types
[i
].exten
);
1668 if (!(type
= ngx_array_push(&conf
->types
[key
]))) {
1669 return NGX_CONF_ERROR
;
1672 *type
= ngx_http_core_default_types
[i
];
1677 if (conf
->err_log
== NULL
) {
1678 if (prev
->err_log
) {
1679 conf
->err_log
= prev
->err_log
;
1681 conf
->err_log
= cf
->cycle
->new_log
;
1685 if (conf
->error_pages
== NULL
&& prev
->error_pages
) {
1686 conf
->error_pages
= prev
->error_pages
;
1689 ngx_conf_merge_str_value(conf
->default_type
,
1690 prev
->default_type
, "text/plain");
1692 ngx_conf_merge_size_value(conf
->client_max_body_size
,
1693 prev
->client_max_body_size
, 1 * 1024 * 1024);
1694 ngx_conf_merge_size_value(conf
->client_body_buffer_size
,
1695 prev
->client_body_buffer_size
,
1696 (size_t) 2 * ngx_pagesize
);
1697 ngx_conf_merge_msec_value(conf
->client_body_timeout
,
1698 prev
->client_body_timeout
, 60000);
1699 ngx_conf_merge_value(conf
->sendfile
, prev
->sendfile
, 0);
1700 ngx_conf_merge_value(conf
->tcp_nopush
, prev
->tcp_nopush
, 0);
1701 ngx_conf_merge_value(conf
->tcp_nodelay
, prev
->tcp_nodelay
, 0);
1702 ngx_conf_merge_msec_value(conf
->send_timeout
, prev
->send_timeout
, 60000);
1703 ngx_conf_merge_size_value(conf
->send_lowat
, prev
->send_lowat
, 0);
1704 ngx_conf_merge_size_value(conf
->postpone_output
, prev
->postpone_output
,
1706 ngx_conf_merge_size_value(conf
->limit_rate
, prev
->limit_rate
, 0);
1707 ngx_conf_merge_msec_value(conf
->keepalive_timeout
,
1708 prev
->keepalive_timeout
, 75000);
1709 ngx_conf_merge_sec_value(conf
->keepalive_header
,
1710 prev
->keepalive_header
, 0);
1711 ngx_conf_merge_msec_value(conf
->lingering_time
,
1712 prev
->lingering_time
, 30000);
1713 ngx_conf_merge_msec_value(conf
->lingering_timeout
,
1714 prev
->lingering_timeout
, 5000);
1716 ngx_conf_merge_path_value(conf
->client_body_temp_path
,
1717 prev
->client_body_temp_path
,
1718 NGX_HTTP_CLIENT_TEMP_PATH
, 0, 0, 0,
1719 ngx_garbage_collector_temp_handler
, cf
);
1721 ngx_conf_merge_value(conf
->reset_timedout_connection
,
1722 prev
->reset_timedout_connection
, 0);
1723 ngx_conf_merge_value(conf
->msie_padding
, prev
->msie_padding
, 1);
1725 if (conf
->open_files
== NULL
) {
1726 conf
->open_files
= prev
->open_files
;
1734 ngx_http_core_listen(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1736 ngx_http_core_srv_conf_t
*scf
= conf
;
1743 ngx_http_listen_t
*ls
;
1746 * TODO: check duplicate 'listen' directives,
1747 * add resolved name to server names ???
1750 if (!(ls
= ngx_array_push(&scf
->listen
))) {
1751 return NGX_CONF_ERROR
;
1756 ls
->family
= AF_INET
;
1757 ls
->default_server
= 0;
1758 ls
->file_name
= cf
->conf_file
->file
.name
;
1759 ls
->line
= cf
->conf_file
->line
;
1761 args
= cf
->args
->elts
;
1762 addr
= args
[1].data
;
1764 for (p
= 0; p
< args
[1].len
; p
++) {
1765 if (addr
[p
] == ':') {
1771 if (p
== args
[1].len
) {
1772 /* no ":" in the "listen" */
1776 port
= ngx_atoi(&addr
[p
], args
[1].len
- p
);
1778 if (port
== NGX_ERROR
&& p
== 0) {
1783 } else if ((port
== NGX_ERROR
&& p
!= 0) /* "listen host:NONNUMBER" */
1784 || (port
< 1 || port
> 65536)) { /* "listen 99999" */
1786 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1787 "invalid port \"%s\" in \"%V\" directive, "
1788 "it must be a number between 1 and 65535",
1789 &addr
[p
], &cmd
->name
);
1791 return NGX_CONF_ERROR
;
1793 } else if (p
== 0) {
1794 ls
->addr
= INADDR_ANY
;
1795 ls
->port
= (in_port_t
) port
;
1799 ls
->port
= (in_port_t
) port
;
1802 ls
->addr
= inet_addr((const char *) addr
);
1804 if (ls
->addr
== INADDR_NONE
) {
1805 h
= gethostbyname((const char *) addr
);
1807 if (h
== NULL
|| h
->h_addr_list
[0] == NULL
) {
1808 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1809 "can not resolve host \"%s\" "
1810 "in \"%V\" directive", addr
, &cmd
->name
);
1811 return NGX_CONF_ERROR
;
1814 ls
->addr
= *(in_addr_t
*)(h
->h_addr_list
[0]);
1822 ngx_http_core_server_name(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1824 ngx_http_core_srv_conf_t
*scf
= conf
;
1828 ngx_http_server_name_t
*sn
;
1829 ngx_http_core_main_conf_t
*cmcf
;
1831 /* TODO: warn about duplicate 'server_name' directives */
1833 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
1835 value
= cf
->args
->elts
;
1837 for (i
= 1; i
< cf
->args
->nelts
; i
++) {
1838 if (value
[i
].len
== 0) {
1839 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1840 "server name \"%V\" is invalid "
1841 "in \"%V\" directive",
1842 &value
[i
], &cmd
->name
);
1843 return NGX_CONF_ERROR
;
1846 if (!(sn
= ngx_array_push(&scf
->server_names
))) {
1847 return NGX_CONF_ERROR
;
1850 sn
->name
.len
= value
[i
].len
;
1851 sn
->name
.data
= value
[i
].data
;
1852 sn
->core_srv_conf
= scf
;
1854 if (sn
->name
.data
[0] == '*') {
1863 if (cmcf
->max_server_name_len
< sn
->name
.len
) {
1864 cmcf
->max_server_name_len
= sn
->name
.len
;
1873 ngx_http_core_root(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1875 ngx_http_core_loc_conf_t
*lcf
= conf
;
1880 alias
= (cmd
->name
.len
== sizeof("alias") - 1) ? 1 : 0;
1882 if (lcf
->root
.data
) {
1884 /* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */
1886 if ((ngx_uint_t
) lcf
->alias
== alias
) {
1887 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1888 "\"%V\" directive is duplicate",
1891 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1892 "\"%V\" directive is duplicate, "
1893 "\"%s\" directive is specified before",
1894 &cmd
->name
, lcf
->alias
? "alias" : "root");
1897 return NGX_CONF_ERROR
;
1900 value
= cf
->args
->elts
;
1903 lcf
->root
= value
[1];
1905 if (!alias
&& lcf
->root
.data
[lcf
->root
.len
- 1] == '/') {
1914 ngx_http_core_error_page(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1916 ngx_http_core_loc_conf_t
*lcf
= conf
;
1918 ngx_int_t overwrite
;
1921 ngx_http_err_page_t
*err
;
1923 if (lcf
->error_pages
== NULL
) {
1924 lcf
->error_pages
= ngx_array_create(cf
->pool
, 4,
1925 sizeof(ngx_http_err_page_t
));
1926 if (lcf
->error_pages
== NULL
) {
1927 return NGX_CONF_ERROR
;
1931 value
= cf
->args
->elts
;
1933 i
= cf
->args
->nelts
- 2;
1935 if (value
[i
].data
[0] == '=') {
1937 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1938 "invalid value \"%V\"", &value
[i
]);
1939 return NGX_CONF_ERROR
;
1942 overwrite
= ngx_atoi(&value
[i
].data
[1], value
[i
].len
- 1);
1944 if (overwrite
== NGX_ERROR
) {
1945 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1946 "invalid value \"%V\"", &value
[i
]);
1947 return NGX_CONF_ERROR
;
1957 for (i
= 1; i
< cf
->args
->nelts
- n
; i
++) {
1958 if (!(err
= ngx_array_push(lcf
->error_pages
))) {
1959 return NGX_CONF_ERROR
;
1962 err
->status
= ngx_atoi(value
[i
].data
, value
[i
].len
);
1964 if (err
->status
== NGX_ERROR
) {
1965 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1966 "invalid value \"%V\"", &value
[i
]);
1967 return NGX_CONF_ERROR
;
1970 if (err
->status
< 400 || err
->status
> 599) {
1971 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1972 "value \"%V\" must be between 400 and 599",
1974 return NGX_CONF_ERROR
;
1977 err
->overwrite
= overwrite
;
1978 err
->uri
= value
[cf
->args
->nelts
- 1];
1986 ngx_http_core_keepalive(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1988 ngx_http_core_loc_conf_t
*lcf
= conf
;
1992 if (lcf
->keepalive_timeout
!= NGX_CONF_UNSET_MSEC
) {
1993 return "is duplicate";
1996 value
= cf
->args
->elts
;
1998 lcf
->keepalive_timeout
= ngx_parse_time(&value
[1], 0);
2000 if (lcf
->keepalive_timeout
== (ngx_msec_t
) NGX_ERROR
) {
2001 return "invalid value";
2004 if (lcf
->keepalive_timeout
== (ngx_msec_t
) NGX_PARSE_LARGE_TIME
) {
2005 return "value must be less than 597 hours";
2008 if (cf
->args
->nelts
== 2) {
2012 lcf
->keepalive_header
= ngx_parse_time(&value
[2], 1);
2014 if (lcf
->keepalive_header
== NGX_ERROR
) {
2015 return "invalid value";
2018 if (lcf
->keepalive_header
== NGX_PARSE_LARGE_TIME
) {
2019 return "value must be less than 68 years";
2027 ngx_http_core_error_log(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
2029 ngx_http_core_loc_conf_t
*lcf
= conf
;
2031 if (!(lcf
->err_log
= ngx_log_create_errlog(cf
->cycle
, cf
->args
))) {
2032 return NGX_CONF_ERROR
;
2035 return ngx_set_error_log_levels(cf
, lcf
->err_log
);
2040 ngx_http_core_lowat_check(ngx_conf_t
*cf
, void *post
, void *data
)
2045 if (*np
>= ngx_freebsd_net_inet_tcp_sendspace
) {
2046 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
2047 "\"send_lowat\" must be less than %d "
2048 "(sysctl net.inet.tcp.sendspace)",
2049 ngx_freebsd_net_inet_tcp_sendspace
);
2051 return NGX_CONF_ERROR
;
2054 #elif !(NGX_HAVE_SO_SNDLOWAT)
2057 ngx_conf_log_error(NGX_LOG_WARN
, cf
, 0,
2058 "\"send_lowat\" is not supported, ignored");