Mercurial > hg > nginx-vendor-1-0
comparison src/http/ngx_http_core_module.c @ 0:f0b350454894 NGINX_0_1_0
nginx 0.1.0
*) The first public version.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 04 Oct 2004 00:00:00 +0400 |
parents | |
children | cc9f381affaa |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0b350454894 |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_event.h> | |
10 #include <ngx_http.h> | |
11 #include <nginx.h> | |
12 | |
13 /* STUB */ | |
14 #define NGX_HTTP_LOCATION_EXACT 1 | |
15 #define NGX_HTTP_LOCATION_AUTO_REDIRECT 2 | |
16 #define NGX_HTTP_LOCATION_REGEX 3 | |
17 | |
18 | |
19 static void ngx_http_phase_event_handler(ngx_event_t *rev); | |
20 static void ngx_http_run_phases(ngx_http_request_t *r); | |
21 static ngx_int_t ngx_http_find_location(ngx_http_request_t *r, | |
22 ngx_array_t *locations, size_t len); | |
23 | |
24 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf); | |
25 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf); | |
26 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf); | |
27 static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf, | |
28 void *parent, void *child); | |
29 static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf); | |
30 static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf, | |
31 void *parent, void *child); | |
32 | |
33 static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); | |
34 static int ngx_cmp_locations(const void *first, const void *second); | |
35 static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, | |
36 void *dummy); | |
37 static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
38 static char *ngx_set_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); | |
39 static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
40 static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, | |
41 void *conf); | |
42 static char *ngx_set_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
43 static char *ngx_set_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
44 static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
45 static char *ngx_set_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
46 | |
47 static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data); | |
48 | |
49 static ngx_conf_post_t ngx_http_lowat_post = { ngx_http_lowat_check } ; | |
50 | |
51 | |
52 static ngx_conf_enum_t ngx_http_restrict_host_names[] = { | |
53 { ngx_string("off"), NGX_HTTP_RESTRICT_HOST_OFF }, | |
54 { ngx_string("on"), NGX_HTTP_RESTRICT_HOST_ON }, | |
55 { ngx_string("close"), NGX_HTTP_RESTRICT_HOST_CLOSE }, | |
56 { ngx_null_string, 0 } | |
57 }; | |
58 | |
59 | |
60 static ngx_command_t ngx_http_core_commands[] = { | |
61 | |
62 { ngx_string("server"), | |
63 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, | |
64 ngx_server_block, | |
65 0, | |
66 0, | |
67 NULL }, | |
68 | |
69 { ngx_string("connection_pool_size"), | |
70 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
71 ngx_conf_set_size_slot, | |
72 NGX_HTTP_SRV_CONF_OFFSET, | |
73 offsetof(ngx_http_core_srv_conf_t, connection_pool_size), | |
74 NULL }, | |
75 | |
76 { ngx_string("post_accept_timeout"), | |
77 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
78 ngx_conf_set_msec_slot, | |
79 NGX_HTTP_SRV_CONF_OFFSET, | |
80 offsetof(ngx_http_core_srv_conf_t, post_accept_timeout), | |
81 NULL }, | |
82 | |
83 { ngx_string("request_pool_size"), | |
84 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
85 ngx_conf_set_size_slot, | |
86 NGX_HTTP_SRV_CONF_OFFSET, | |
87 offsetof(ngx_http_core_srv_conf_t, request_pool_size), | |
88 NULL }, | |
89 | |
90 { ngx_string("client_header_timeout"), | |
91 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
92 ngx_conf_set_msec_slot, | |
93 NGX_HTTP_SRV_CONF_OFFSET, | |
94 offsetof(ngx_http_core_srv_conf_t, client_header_timeout), | |
95 NULL }, | |
96 | |
97 { ngx_string("client_header_buffer_size"), | |
98 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
99 ngx_conf_set_size_slot, | |
100 NGX_HTTP_SRV_CONF_OFFSET, | |
101 offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size), | |
102 NULL }, | |
103 | |
104 { ngx_string("large_client_header_buffers"), | |
105 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2, | |
106 ngx_conf_set_bufs_slot, | |
107 NGX_HTTP_SRV_CONF_OFFSET, | |
108 offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers), | |
109 NULL }, | |
110 | |
111 { ngx_string("restrict_host_names"), | |
112 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
113 ngx_conf_set_enum_slot, | |
114 NGX_HTTP_SRV_CONF_OFFSET, | |
115 offsetof(ngx_http_core_srv_conf_t, restrict_host_names), | |
116 &ngx_http_restrict_host_names }, | |
117 | |
118 { ngx_string("location"), | |
119 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, | |
120 ngx_location_block, | |
121 NGX_HTTP_SRV_CONF_OFFSET, | |
122 0, | |
123 NULL }, | |
124 | |
125 { ngx_string("listen"), | |
126 #if 0 | |
127 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
128 #else | |
129 NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
130 #endif | |
131 ngx_set_listen, | |
132 NGX_HTTP_SRV_CONF_OFFSET, | |
133 0, | |
134 NULL }, | |
135 | |
136 { ngx_string("server_name"), | |
137 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE, | |
138 ngx_set_server_name, | |
139 NGX_HTTP_SRV_CONF_OFFSET, | |
140 0, | |
141 NULL }, | |
142 | |
143 { ngx_string("types"), | |
144 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF | |
145 |NGX_CONF_BLOCK|NGX_CONF_NOARGS, | |
146 ngx_types_block, | |
147 NGX_HTTP_LOC_CONF_OFFSET, | |
148 0, | |
149 NULL }, | |
150 | |
151 { ngx_string("default_type"), | |
152 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
153 ngx_conf_set_str_slot, | |
154 NGX_HTTP_LOC_CONF_OFFSET, | |
155 offsetof(ngx_http_core_loc_conf_t, default_type), | |
156 NULL }, | |
157 | |
158 { ngx_string("root"), | |
159 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
160 ngx_set_root, | |
161 NGX_HTTP_LOC_CONF_OFFSET, | |
162 0, | |
163 NULL }, | |
164 | |
165 { ngx_string("alias"), | |
166 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
167 ngx_set_root, | |
168 NGX_HTTP_LOC_CONF_OFFSET, | |
169 0, | |
170 NULL }, | |
171 | |
172 { ngx_string("client_max_body_size"), | |
173 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
174 ngx_conf_set_size_slot, | |
175 NGX_HTTP_LOC_CONF_OFFSET, | |
176 offsetof(ngx_http_core_loc_conf_t, client_max_body_size), | |
177 NULL }, | |
178 | |
179 { ngx_string("client_body_buffer_size"), | |
180 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
181 ngx_conf_set_size_slot, | |
182 NGX_HTTP_LOC_CONF_OFFSET, | |
183 offsetof(ngx_http_core_loc_conf_t, client_body_buffer_size), | |
184 NULL }, | |
185 | |
186 { ngx_string("client_body_timeout"), | |
187 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
188 ngx_conf_set_msec_slot, | |
189 NGX_HTTP_LOC_CONF_OFFSET, | |
190 offsetof(ngx_http_core_loc_conf_t, client_body_timeout), | |
191 NULL }, | |
192 | |
193 { ngx_string("sendfile"), | |
194 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
195 ngx_conf_set_flag_slot, | |
196 NGX_HTTP_LOC_CONF_OFFSET, | |
197 offsetof(ngx_http_core_loc_conf_t, sendfile), | |
198 NULL }, | |
199 | |
200 { ngx_string("tcp_nopush"), | |
201 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
202 ngx_conf_set_flag_slot, | |
203 NGX_HTTP_LOC_CONF_OFFSET, | |
204 offsetof(ngx_http_core_loc_conf_t, tcp_nopush), | |
205 NULL }, | |
206 | |
207 { ngx_string("send_timeout"), | |
208 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
209 ngx_conf_set_msec_slot, | |
210 NGX_HTTP_LOC_CONF_OFFSET, | |
211 offsetof(ngx_http_core_loc_conf_t, send_timeout), | |
212 NULL }, | |
213 | |
214 { ngx_string("send_lowat"), | |
215 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
216 ngx_conf_set_size_slot, | |
217 NGX_HTTP_LOC_CONF_OFFSET, | |
218 offsetof(ngx_http_core_loc_conf_t, send_lowat), | |
219 &ngx_http_lowat_post }, | |
220 | |
221 { ngx_string("postpone_output"), | |
222 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
223 ngx_conf_set_size_slot, | |
224 NGX_HTTP_LOC_CONF_OFFSET, | |
225 offsetof(ngx_http_core_loc_conf_t, postpone_output), | |
226 NULL }, | |
227 | |
228 { ngx_string("limit_rate"), | |
229 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
230 ngx_conf_set_size_slot, | |
231 NGX_HTTP_LOC_CONF_OFFSET, | |
232 offsetof(ngx_http_core_loc_conf_t, limit_rate), | |
233 NULL }, | |
234 | |
235 { ngx_string("keepalive_timeout"), | |
236 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, | |
237 ngx_set_keepalive, | |
238 NGX_HTTP_LOC_CONF_OFFSET, | |
239 0, | |
240 NULL }, | |
241 | |
242 { ngx_string("lingering_time"), | |
243 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
244 ngx_conf_set_msec_slot, | |
245 NGX_HTTP_LOC_CONF_OFFSET, | |
246 offsetof(ngx_http_core_loc_conf_t, lingering_time), | |
247 NULL }, | |
248 | |
249 { ngx_string("lingering_timeout"), | |
250 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
251 ngx_conf_set_msec_slot, | |
252 NGX_HTTP_LOC_CONF_OFFSET, | |
253 offsetof(ngx_http_core_loc_conf_t, lingering_timeout), | |
254 NULL }, | |
255 | |
256 { ngx_string("reset_timedout_connection"), | |
257 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
258 ngx_conf_set_flag_slot, | |
259 NGX_HTTP_LOC_CONF_OFFSET, | |
260 offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection), | |
261 NULL }, | |
262 | |
263 { ngx_string("msie_padding"), | |
264 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
265 ngx_conf_set_flag_slot, | |
266 NGX_HTTP_LOC_CONF_OFFSET, | |
267 offsetof(ngx_http_core_loc_conf_t, msie_padding), | |
268 NULL }, | |
269 | |
270 { ngx_string("error_page"), | |
271 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE, | |
272 ngx_set_error_page, | |
273 NGX_HTTP_LOC_CONF_OFFSET, | |
274 0, | |
275 NULL }, | |
276 | |
277 { ngx_string("error_log"), | |
278 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
279 ngx_set_error_log, | |
280 NGX_HTTP_LOC_CONF_OFFSET, | |
281 0, | |
282 NULL }, | |
283 | |
284 #if (NGX_HTTP_CACHE) | |
285 | |
286 { ngx_string("open_file_cache"), | |
287 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE4, | |
288 ngx_http_set_cache_slot, | |
289 NGX_HTTP_LOC_CONF_OFFSET, | |
290 offsetof(ngx_http_core_loc_conf_t, open_files), | |
291 NULL }, | |
292 | |
293 #endif | |
294 | |
295 ngx_null_command | |
296 }; | |
297 | |
298 | |
299 ngx_http_module_t ngx_http_core_module_ctx = { | |
300 NULL, /* pre conf */ | |
301 | |
302 ngx_http_core_create_main_conf, /* create main configuration */ | |
303 ngx_http_core_init_main_conf, /* init main configuration */ | |
304 | |
305 ngx_http_core_create_srv_conf, /* create server configuration */ | |
306 ngx_http_core_merge_srv_conf, /* merge server configuration */ | |
307 | |
308 ngx_http_core_create_loc_conf, /* create location configuration */ | |
309 ngx_http_core_merge_loc_conf /* merge location configuration */ | |
310 }; | |
311 | |
312 | |
313 ngx_module_t ngx_http_core_module = { | |
314 NGX_MODULE, | |
315 &ngx_http_core_module_ctx, /* module context */ | |
316 ngx_http_core_commands, /* module directives */ | |
317 NGX_HTTP_MODULE, /* module type */ | |
318 NULL, /* init module */ | |
319 NULL /* init process */ | |
320 }; | |
321 | |
322 | |
323 void ngx_http_handler(ngx_http_request_t *r) | |
324 { | |
325 ngx_http_log_ctx_t *lcx; | |
326 | |
327 r->connection->unexpected_eof = 0; | |
328 | |
329 lcx = r->connection->log->data; | |
330 lcx->action = NULL; | |
331 | |
332 switch (r->headers_in.connection_type) { | |
333 case 0: | |
334 if (r->http_version > NGX_HTTP_VERSION_10) { | |
335 r->keepalive = 1; | |
336 } else { | |
337 r->keepalive = 0; | |
338 } | |
339 break; | |
340 | |
341 case NGX_HTTP_CONNECTION_CLOSE: | |
342 r->keepalive = 0; | |
343 break; | |
344 | |
345 case NGX_HTTP_CONNECTION_KEEP_ALIVE: | |
346 r->keepalive = 1; | |
347 break; | |
348 } | |
349 | |
350 if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) { | |
351 | |
352 /* | |
353 * MSIE may wait for some time if the response for the POST request | |
354 * is sent over the keepalive connection | |
355 */ | |
356 | |
357 r->keepalive = 0; | |
358 } | |
359 | |
360 #if 0 | |
361 /* TEST STUB */ r->http_version = NGX_HTTP_VERSION_10; | |
362 /* TEST STUB */ r->keepalive = 0; | |
363 #endif | |
364 | |
365 if (r->headers_in.content_length_n > 0) { | |
366 r->lingering_close = 1; | |
367 | |
368 } else { | |
369 r->lingering_close = 0; | |
370 } | |
371 | |
372 #if 0 | |
373 /* TEST STUB */ r->lingering_close = 1; | |
374 #endif | |
375 | |
376 r->connection->write->event_handler = ngx_http_phase_event_handler; | |
377 | |
378 ngx_http_run_phases(r); | |
379 | |
380 return; | |
381 } | |
382 | |
383 | |
384 static void ngx_http_phase_event_handler(ngx_event_t *ev) | |
385 { | |
386 ngx_connection_t *c; | |
387 ngx_http_request_t *r; | |
388 | |
389 c = ev->data; | |
390 r = c->data; | |
391 | |
392 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, "phase event handler"); | |
393 | |
394 ngx_http_run_phases(r); | |
395 | |
396 return; | |
397 } | |
398 | |
399 | |
400 static void ngx_http_run_phases(ngx_http_request_t *r) | |
401 { | |
402 char *path; | |
403 ngx_int_t rc; | |
404 ngx_http_handler_pt *h; | |
405 ngx_http_core_loc_conf_t *clcf; | |
406 ngx_http_core_main_conf_t *cmcf; | |
407 | |
408 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
409 | |
410 for (/* void */; r->phase < NGX_HTTP_LAST_PHASE; r->phase++) { | |
411 | |
412 if (r->phase == NGX_HTTP_CONTENT_PHASE && r->content_handler) { | |
413 r->connection->write->event_handler = ngx_http_empty_handler; | |
414 rc = r->content_handler(r); | |
415 ngx_http_finalize_request(r, rc); | |
416 return; | |
417 } | |
418 | |
419 h = cmcf->phases[r->phase].handlers.elts; | |
420 for (r->phase_handler = cmcf->phases[r->phase].handlers.nelts - 1; | |
421 r->phase_handler >= 0; | |
422 r->phase_handler--) | |
423 { | |
424 rc = h[r->phase_handler](r); | |
425 | |
426 if (rc == NGX_DONE) { | |
427 | |
428 /* | |
429 * we should never use r here because | |
430 * it could point to already freed data | |
431 */ | |
432 | |
433 return; | |
434 } | |
435 | |
436 if (rc == NGX_DECLINED) { | |
437 continue; | |
438 } | |
439 | |
440 if (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_ERROR) { | |
441 ngx_http_finalize_request(r, rc); | |
442 return; | |
443 } | |
444 | |
445 if (r->phase == NGX_HTTP_CONTENT_PHASE) { | |
446 ngx_http_finalize_request(r, rc); | |
447 return; | |
448 } | |
449 | |
450 if (rc == NGX_AGAIN) { | |
451 return; | |
452 } | |
453 | |
454 if (rc == NGX_OK && cmcf->phases[r->phase].type == NGX_OK) { | |
455 break; | |
456 } | |
457 } | |
458 } | |
459 | |
460 | |
461 if (r->uri.data[r->uri.len - 1] == '/') { | |
462 | |
463 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
464 | |
465 if (!(path = ngx_palloc(r->pool, clcf->root.len + r->uri.len))) { | |
466 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
467 return; | |
468 } | |
469 | |
470 ngx_cpystrn(ngx_cpymem(path, clcf->root.data, clcf->root.len), | |
471 r->uri.data, r->uri.len + 1); | |
472 | |
473 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
474 "directory index of \"%s\" is forbidden", path); | |
475 | |
476 ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN); | |
477 return; | |
478 } | |
479 | |
480 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found"); | |
481 | |
482 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND); | |
483 return; | |
484 } | |
485 | |
486 | |
487 ngx_int_t ngx_http_find_location_config(ngx_http_request_t *r) | |
488 { | |
489 ngx_int_t rc; | |
490 ngx_http_core_loc_conf_t *clcf; | |
491 ngx_http_core_srv_conf_t *cscf; | |
492 | |
493 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | |
494 | |
495 rc = ngx_http_find_location(r, &cscf->locations, 0); | |
496 | |
497 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { | |
498 return rc; | |
499 } | |
500 | |
501 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
502 | |
503 r->connection->log->file = clcf->err_log->file; | |
504 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { | |
505 r->connection->log->log_level = clcf->err_log->log_level; | |
506 } | |
507 | |
508 if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) { | |
509 r->sendfile = 0; | |
510 | |
511 } else { | |
512 r->sendfile = 1; | |
513 } | |
514 | |
515 if (!clcf->tcp_nopush) { | |
516 /* disable TCP_NOPUSH/TCP_CORK use */ | |
517 r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; | |
518 } | |
519 | |
520 | |
521 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
522 "http cl: " SIZE_T_FMT " max: " SIZE_T_FMT, | |
523 r->headers_in.content_length_n, | |
524 clcf->client_max_body_size); | |
525 | |
526 if (r->headers_in.content_length_n != -1 | |
527 && clcf->client_max_body_size | |
528 && clcf->client_max_body_size < (size_t) r->headers_in.content_length_n) | |
529 { | |
530 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
531 "client intented to send too large body: " | |
532 SIZE_T_FMT " bytes", | |
533 r->headers_in.content_length_n); | |
534 | |
535 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; | |
536 } | |
537 | |
538 | |
539 if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) { | |
540 r->headers_out.location = ngx_list_push(&r->headers_out.headers); | |
541 if (r->headers_out.location == NULL) { | |
542 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
543 } | |
544 | |
545 r->headers_out.location->value = clcf->name; | |
546 | |
547 return NGX_HTTP_MOVED_PERMANENTLY; | |
548 } | |
549 | |
550 if (clcf->handler) { | |
551 r->content_handler = clcf->handler; | |
552 } | |
553 | |
554 return NGX_OK; | |
555 } | |
556 | |
557 | |
558 static ngx_int_t ngx_http_find_location(ngx_http_request_t *r, | |
559 ngx_array_t *locations, size_t len) | |
560 { | |
561 ngx_int_t n, rc; | |
562 ngx_uint_t i, found; | |
563 ngx_http_core_loc_conf_t *clcf, **clcfp; | |
564 | |
565 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "find location"); | |
566 | |
567 found = 0; | |
568 | |
569 clcfp = locations->elts; | |
570 for (i = 0; i < locations->nelts; i++) { | |
571 | |
572 #if (HAVE_PCRE) | |
573 if (clcfp[i]->regex) { | |
574 break; | |
575 } | |
576 #endif | |
577 | |
578 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
579 "find location: %s\"%s\"", | |
580 clcfp[i]->exact_match ? "= " : "", | |
581 clcfp[i]->name.data); | |
582 | |
583 if (clcfp[i]->auto_redirect | |
584 && r->uri.len == clcfp[i]->name.len - 1 | |
585 && ngx_strncmp(r->uri.data, clcfp[i]->name.data, | |
586 clcfp[i]->name.len - 1) == 0) | |
587 { | |
588 /* the locations are lexicographically sorted */ | |
589 | |
590 r->loc_conf = clcfp[i]->loc_conf; | |
591 | |
592 return NGX_HTTP_LOCATION_AUTO_REDIRECT; | |
593 } | |
594 | |
595 if (r->uri.len < clcfp[i]->name.len) { | |
596 continue; | |
597 } | |
598 | |
599 n = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len); | |
600 | |
601 if (n < 0) { | |
602 /* the locations are lexicographically sorted */ | |
603 break; | |
604 } | |
605 | |
606 if (n == 0) { | |
607 if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) { | |
608 r->loc_conf = clcfp[i]->loc_conf; | |
609 return NGX_HTTP_LOCATION_EXACT; | |
610 } | |
611 | |
612 if (len > clcfp[i]->name.len) { | |
613 /* the previous match is longer */ | |
614 break; | |
615 } | |
616 | |
617 r->loc_conf = clcfp[i]->loc_conf; | |
618 found = 1; | |
619 } | |
620 } | |
621 | |
622 if (found) { | |
623 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
624 | |
625 if (clcf->locations.nelts) { | |
626 rc = ngx_http_find_location(r, &clcf->locations, len); | |
627 | |
628 if (rc != NGX_OK) { | |
629 return rc; | |
630 } | |
631 } | |
632 } | |
633 | |
634 #if (HAVE_PCRE) | |
635 | |
636 /* regex matches */ | |
637 | |
638 for (/* void */; i < locations->nelts; i++) { | |
639 | |
640 if (!clcfp[i]->regex) { | |
641 continue; | |
642 } | |
643 | |
644 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
645 "find location: ~ \"%s\"", | |
646 clcfp[i]->name.data); | |
647 | |
648 n = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0); | |
649 | |
650 if (n == NGX_DECLINED) { | |
651 continue; | |
652 } | |
653 | |
654 if (n < 0) { | |
655 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
656 ngx_regex_exec_n | |
657 " failed: %d on \"%s\" using \"%s\"", | |
658 n, r->uri.data, clcfp[i]->name.data); | |
659 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
660 } | |
661 | |
662 /* match */ | |
663 | |
664 r->loc_conf = clcfp[i]->loc_conf; | |
665 | |
666 return NGX_HTTP_LOCATION_REGEX; | |
667 } | |
668 | |
669 #endif /* HAVE_PCRE */ | |
670 | |
671 return NGX_OK; | |
672 } | |
673 | |
674 | |
675 ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r) | |
676 { | |
677 uint32_t key; | |
678 ngx_uint_t i; | |
679 ngx_http_type_t *type; | |
680 ngx_http_core_loc_conf_t *clcf; | |
681 | |
682 r->headers_out.content_type = ngx_list_push(&r->headers_out.headers); | |
683 if (r->headers_out.content_type == NULL) { | |
684 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
685 } | |
686 | |
687 r->headers_out.content_type->key.len = 0; | |
688 r->headers_out.content_type->key.data = NULL; | |
689 r->headers_out.content_type->value.len = 0; | |
690 r->headers_out.content_type->value.data = NULL; | |
691 | |
692 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
693 | |
694 if (r->exten.len) { | |
695 #if 0 | |
696 key = ngx_crc(r->exten.data, r->exten.key); | |
697 #endif | |
698 ngx_http_types_hash_key(key, r->exten); | |
699 | |
700 type = clcf->types[key].elts; | |
701 for (i = 0; i < clcf->types[key].nelts; i++) { | |
702 if (r->exten.len != type[i].exten.len) { | |
703 continue; | |
704 } | |
705 | |
706 if (ngx_memcmp(r->exten.data, type[i].exten.data, r->exten.len) | |
707 == 0) | |
708 { | |
709 r->headers_out.content_type->value = type[i].type; | |
710 break; | |
711 } | |
712 } | |
713 } | |
714 | |
715 if (r->headers_out.content_type->value.len == 0) { | |
716 r->headers_out.content_type->value = clcf->default_type; | |
717 } | |
718 | |
719 return NGX_OK; | |
720 } | |
721 | |
722 | |
723 ngx_int_t ngx_http_send_header(ngx_http_request_t *r) | |
724 { | |
725 if (r->main) { | |
726 return NGX_OK; | |
727 } | |
728 | |
729 if (r->err_ctx) { | |
730 r->headers_out.status = r->err_status; | |
731 r->headers_out.status_line.len = 0; | |
732 } | |
733 | |
734 return (*ngx_http_top_header_filter)(r); | |
735 } | |
736 | |
737 | |
738 ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
739 { | |
740 ngx_int_t rc; | |
741 | |
742 if (r->connection->write->error) { | |
743 return NGX_ERROR; | |
744 } | |
745 | |
746 rc = ngx_http_top_body_filter(r, in); | |
747 | |
748 if (rc == NGX_ERROR) { | |
749 | |
750 /* NGX_ERROR could be returned by any filter */ | |
751 | |
752 r->connection->write->error = 1; | |
753 } | |
754 | |
755 return rc; | |
756 } | |
757 | |
758 | |
759 int ngx_http_redirect(ngx_http_request_t *r, int redirect) | |
760 { | |
761 /* STUB */ | |
762 | |
763 /* log request */ | |
764 | |
765 ngx_http_close_request(r, 0); | |
766 return NGX_OK; | |
767 } | |
768 | |
769 | |
770 ngx_int_t ngx_http_set_exten(ngx_http_request_t *r) | |
771 { | |
772 ngx_int_t i; | |
773 | |
774 r->exten.len = 0; | |
775 r->exten.data = NULL; | |
776 | |
777 for (i = r->uri.len - 1; i > 1; i--) { | |
778 if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') { | |
779 r->exten.len = r->uri.len - i - 1; | |
780 | |
781 if (r->exten.len > 0) { | |
782 if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) { | |
783 return NGX_ERROR; | |
784 } | |
785 | |
786 ngx_cpystrn(r->exten.data, &r->uri.data[i + 1], | |
787 r->exten.len + 1); | |
788 } | |
789 | |
790 break; | |
791 | |
792 } else if (r->uri.data[i] == '/') { | |
793 break; | |
794 } | |
795 } | |
796 | |
797 return NGX_OK; | |
798 } | |
799 | |
800 | |
801 ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r, | |
802 ngx_str_t *uri, ngx_str_t *args) | |
803 { | |
804 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
805 "internal redirect: \"%s\"", uri->data); | |
806 | |
807 r->uri.len = uri->len; | |
808 r->uri.data = uri->data; | |
809 | |
810 if (args) { | |
811 r->args.len = args->len; | |
812 r->args.data = args->data; | |
813 } | |
814 | |
815 if (ngx_http_set_exten(r) != NGX_OK) { | |
816 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
817 } | |
818 | |
819 if (r->err_ctx) { | |
820 | |
821 /* allocate the new modules contexts */ | |
822 | |
823 r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module); | |
824 if (r->ctx == NULL) { | |
825 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
826 } | |
827 | |
828 } else { | |
829 | |
830 /* clear the modules contexts */ | |
831 | |
832 ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module); | |
833 } | |
834 | |
835 r->phase = 0; | |
836 r->phase_handler = 0; | |
837 | |
838 ngx_http_handler(r); | |
839 | |
840 return NGX_DONE; | |
841 } | |
842 | |
843 | |
844 #if 0 /* STUB: test the delay http handler */ | |
845 | |
846 int ngx_http_delay_handler(ngx_http_request_t *r) | |
847 { | |
848 static int on; | |
849 | |
850 if (on++ == 0) { | |
851 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
852 "http set delay"); | |
853 ngx_add_timer(r->connection->write, 10000); | |
854 return NGX_AGAIN; | |
855 } | |
856 | |
857 r->connection->write->timedout = 0; | |
858 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
859 "http reset delay"); | |
860 return NGX_DECLINED; | |
861 } | |
862 | |
863 #endif | |
864 | |
865 | |
866 #if 0 | |
867 | |
868 static ngx_int_t ngx_http_core_init_process(ngx_cycle_t *cycle) | |
869 { | |
870 ngx_uint_t i; | |
871 ngx_http_core_srv_conf_t **cscfp; | |
872 ngx_http_core_main_conf_t *cmcf; | |
873 | |
874 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); | |
875 | |
876 #if 0 | |
877 ngx_http_core_init_module: | |
878 | |
879 ngx_http_handler_pt *h; | |
880 | |
881 ngx_test_null(h, ngx_push_array( | |
882 &cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers), | |
883 NGX_ERROR); | |
884 *h = ngx_http_delay_handler; | |
885 #endif | |
886 | |
887 cscfp = cmcf->servers.elts; | |
888 | |
889 for (i = 0; i < cmcf->servers.nelts; i++) { | |
890 if (cscfp[i]->recv == NULL) { | |
891 cscfp[i]->recv = ngx_io.recv; | |
892 cscfp[i]->send_chain = ngx_io.send_chain; | |
893 } | |
894 } | |
895 | |
896 return NGX_OK; | |
897 } | |
898 | |
899 #endif | |
900 | |
901 | |
902 static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) | |
903 { | |
904 int m; | |
905 char *rv; | |
906 ngx_http_module_t *module; | |
907 ngx_conf_t pvcf; | |
908 ngx_http_conf_ctx_t *ctx, *http_ctx; | |
909 ngx_http_core_main_conf_t *cmcf; | |
910 ngx_http_core_srv_conf_t *cscf, **cscfp; | |
911 | |
912 ngx_test_null(ctx, | |
913 ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), | |
914 NGX_CONF_ERROR); | |
915 | |
916 http_ctx = cf->ctx; | |
917 ctx->main_conf = http_ctx->main_conf; | |
918 | |
919 /* the server{}'s srv_conf */ | |
920 | |
921 ngx_test_null(ctx->srv_conf, | |
922 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), | |
923 NGX_CONF_ERROR); | |
924 | |
925 /* the server{}'s loc_conf */ | |
926 | |
927 ngx_test_null(ctx->loc_conf, | |
928 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), | |
929 NGX_CONF_ERROR); | |
930 | |
931 for (m = 0; ngx_modules[m]; m++) { | |
932 if (ngx_modules[m]->type != NGX_HTTP_MODULE) { | |
933 continue; | |
934 } | |
935 | |
936 module = ngx_modules[m]->ctx; | |
937 | |
938 if (module->create_srv_conf) { | |
939 ngx_test_null(ctx->srv_conf[ngx_modules[m]->ctx_index], | |
940 module->create_srv_conf(cf), | |
941 NGX_CONF_ERROR); | |
942 } | |
943 | |
944 if (module->create_loc_conf) { | |
945 ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index], | |
946 module->create_loc_conf(cf), | |
947 NGX_CONF_ERROR); | |
948 } | |
949 } | |
950 | |
951 /* create links of the srv_conf's */ | |
952 | |
953 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; | |
954 cscf->ctx = ctx; | |
955 | |
956 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; | |
957 ngx_test_null(cscfp, ngx_push_array(&cmcf->servers), NGX_CONF_ERROR); | |
958 *cscfp = cscf; | |
959 | |
960 /* parse inside server{} */ | |
961 | |
962 pvcf = *cf; | |
963 cf->ctx = ctx; | |
964 cf->cmd_type = NGX_HTTP_SRV_CONF; | |
965 rv = ngx_conf_parse(cf, NULL); | |
966 *cf = pvcf; | |
967 | |
968 if (rv != NGX_CONF_OK) { | |
969 return rv; | |
970 } | |
971 | |
972 ngx_qsort(cscf->locations.elts, (size_t) cscf->locations.nelts, | |
973 sizeof(ngx_http_core_loc_conf_t *), ngx_cmp_locations); | |
974 | |
975 return rv; | |
976 } | |
977 | |
978 | |
979 static int ngx_cmp_locations(const void *one, const void *two) | |
980 { | |
981 ngx_int_t rc; | |
982 ngx_http_core_loc_conf_t *first, *second; | |
983 | |
984 first = *(ngx_http_core_loc_conf_t **) one; | |
985 second = *(ngx_http_core_loc_conf_t **) two; | |
986 | |
987 #if (HAVE_PCRE) | |
988 | |
989 if (first->regex && !second->regex) { | |
990 /* shift the regex matches to the end */ | |
991 return 1; | |
992 } | |
993 | |
994 if (first->regex || second->regex) { | |
995 /* do not sort the regex matches */ | |
996 return 0; | |
997 } | |
998 | |
999 #endif | |
1000 | |
1001 rc = ngx_strcmp(first->name.data, second->name.data); | |
1002 | |
1003 if (rc == 0 && second->exact_match) { | |
1004 /* an exact match must be before the same inclusive one */ | |
1005 return 1; | |
1006 } | |
1007 | |
1008 return rc; | |
1009 } | |
1010 | |
1011 | |
1012 static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) | |
1013 { | |
1014 char *rv; | |
1015 ngx_int_t m; | |
1016 ngx_str_t *value; | |
1017 ngx_conf_t pcf; | |
1018 ngx_http_module_t *module; | |
1019 ngx_http_conf_ctx_t *ctx, *pctx; | |
1020 ngx_http_core_srv_conf_t *cscf; | |
1021 ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp; | |
1022 #if (HAVE_PCRE) | |
1023 ngx_str_t err; | |
1024 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
1025 #endif | |
1026 | |
1027 if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) { | |
1028 return NGX_CONF_ERROR; | |
1029 } | |
1030 | |
1031 pctx = cf->ctx; | |
1032 ctx->main_conf = pctx->main_conf; | |
1033 ctx->srv_conf = pctx->srv_conf; | |
1034 | |
1035 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | |
1036 if (ctx->loc_conf == NULL) { | |
1037 return NGX_CONF_ERROR; | |
1038 } | |
1039 | |
1040 for (m = 0; ngx_modules[m]; m++) { | |
1041 if (ngx_modules[m]->type != NGX_HTTP_MODULE) { | |
1042 continue; | |
1043 } | |
1044 | |
1045 module = ngx_modules[m]->ctx; | |
1046 | |
1047 if (module->create_loc_conf) { | |
1048 ctx->loc_conf[ngx_modules[m]->ctx_index] = | |
1049 module->create_loc_conf(cf); | |
1050 if (ctx->loc_conf[ngx_modules[m]->ctx_index] == NULL) { | |
1051 return NGX_CONF_ERROR; | |
1052 } | |
1053 } | |
1054 } | |
1055 | |
1056 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; | |
1057 clcf->loc_conf = ctx->loc_conf; | |
1058 | |
1059 value = cf->args->elts; | |
1060 | |
1061 if (cf->args->nelts == 3) { | |
1062 if (value[1].len == 1 && value[1].data[0] == '=') { | |
1063 clcf->name.len = value[2].len; | |
1064 clcf->name.data = value[2].data; | |
1065 clcf->exact_match = 1; | |
1066 | |
1067 } else if ((value[1].len == 1 && value[1].data[0] == '~') | |
1068 || (value[1].len == 2 | |
1069 && value[1].data[0] == '~' | |
1070 && value[1].data[1] == '*')) | |
1071 { | |
1072 #if (HAVE_PCRE) | |
1073 err.len = NGX_MAX_CONF_ERRSTR; | |
1074 err.data = errstr; | |
1075 | |
1076 clcf->regex = ngx_regex_compile(&value[2], | |
1077 value[1].len == 2 ? NGX_REGEX_CASELESS: 0, | |
1078 cf->pool, &err); | |
1079 | |
1080 if (clcf->regex == NULL) { | |
1081 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
1082 return NGX_CONF_ERROR; | |
1083 } | |
1084 | |
1085 clcf->name = value[2]; | |
1086 #else | |
1087 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1088 "the using of the regex \"%s\" " | |
1089 "requires PCRE library", | |
1090 value[2].data); | |
1091 return NGX_CONF_ERROR; | |
1092 #endif | |
1093 | |
1094 } else { | |
1095 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1096 "invalid location modifier \"%s\"", | |
1097 value[1].data); | |
1098 return NGX_CONF_ERROR; | |
1099 } | |
1100 | |
1101 } else { | |
1102 clcf->name.len = value[1].len; | |
1103 clcf->name.data = value[1].data; | |
1104 } | |
1105 | |
1106 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; | |
1107 | |
1108 if (pclcf->name.len == 0) { | |
1109 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; | |
1110 if (!(clcfp = ngx_push_array(&cscf->locations))) { | |
1111 return NGX_CONF_ERROR; | |
1112 } | |
1113 | |
1114 } else { | |
1115 clcf->prev_location = pclcf; | |
1116 | |
1117 if (pclcf->exact_match) { | |
1118 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1119 "location \"%s\" could not be inside " | |
1120 "the exact location \"%s\"", | |
1121 clcf->name.data, pclcf->name.data); | |
1122 return NGX_CONF_ERROR; | |
1123 } | |
1124 | |
1125 #if (HAVE_PCRE) | |
1126 if (clcf->regex == NULL | |
1127 && ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len) | |
1128 != 0) | |
1129 #else | |
1130 if (ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len) | |
1131 != 0) | |
1132 #endif | |
1133 { | |
1134 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1135 "location \"%s\" is outside location \"%s\"", | |
1136 clcf->name.data, pclcf->name.data); | |
1137 return NGX_CONF_ERROR; | |
1138 } | |
1139 | |
1140 if (pclcf->locations.elts == NULL) { | |
1141 ngx_init_array(pclcf->locations, cf->pool, 5, sizeof(void *), | |
1142 NGX_CONF_ERROR); | |
1143 } | |
1144 | |
1145 if (!(clcfp = ngx_push_array(&pclcf->locations))) { | |
1146 return NGX_CONF_ERROR; | |
1147 } | |
1148 } | |
1149 | |
1150 *clcfp = clcf; | |
1151 | |
1152 pcf = *cf; | |
1153 cf->ctx = ctx; | |
1154 cf->cmd_type = NGX_HTTP_LOC_CONF; | |
1155 rv = ngx_conf_parse(cf, NULL); | |
1156 *cf = pcf; | |
1157 | |
1158 return rv; | |
1159 } | |
1160 | |
1161 | |
1162 static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1163 { | |
1164 char *rv; | |
1165 ngx_conf_t pcf; | |
1166 | |
1167 pcf = *cf; | |
1168 cf->handler = ngx_set_type; | |
1169 cf->handler_conf = conf; | |
1170 rv = ngx_conf_parse(cf, NULL); | |
1171 *cf = pcf; | |
1172 | |
1173 return rv; | |
1174 } | |
1175 | |
1176 | |
1177 static char *ngx_set_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) | |
1178 { | |
1179 ngx_http_core_loc_conf_t *lcf = conf; | |
1180 | |
1181 uint32_t key; | |
1182 ngx_uint_t i; | |
1183 ngx_str_t *args; | |
1184 ngx_http_type_t *type; | |
1185 | |
1186 if (lcf->types == NULL) { | |
1187 lcf->types = ngx_palloc(cf->pool, NGX_HTTP_TYPES_HASH_PRIME | |
1188 * sizeof(ngx_array_t)); | |
1189 if (lcf->types == NULL) { | |
1190 return NGX_CONF_ERROR; | |
1191 } | |
1192 | |
1193 for (i = 0; i < NGX_HTTP_TYPES_HASH_PRIME; i++) { | |
1194 if (ngx_array_init(&lcf->types[i], cf->pool, 5, | |
1195 sizeof(ngx_http_type_t)) == NGX_ERROR) | |
1196 { | |
1197 return NGX_CONF_ERROR; | |
1198 } | |
1199 } | |
1200 } | |
1201 | |
1202 args = (ngx_str_t *) cf->args->elts; | |
1203 | |
1204 for (i = 1; i < cf->args->nelts; i++) { | |
1205 ngx_http_types_hash_key(key, args[i]); | |
1206 | |
1207 if (!(type = ngx_array_push(&lcf->types[key]))) { | |
1208 return NGX_CONF_ERROR; | |
1209 } | |
1210 | |
1211 type->exten = args[i]; | |
1212 type->type = args[0]; | |
1213 } | |
1214 | |
1215 return NGX_CONF_OK; | |
1216 } | |
1217 | |
1218 | |
1219 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf) | |
1220 { | |
1221 ngx_http_core_main_conf_t *cmcf; | |
1222 | |
1223 ngx_test_null(cmcf, | |
1224 ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t)), | |
1225 NGX_CONF_ERROR); | |
1226 | |
1227 ngx_init_array(cmcf->servers, cf->pool, | |
1228 5, sizeof(ngx_http_core_srv_conf_t *), | |
1229 NGX_CONF_ERROR); | |
1230 | |
1231 return cmcf; | |
1232 } | |
1233 | |
1234 | |
1235 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf) | |
1236 { | |
1237 #if 0 | |
1238 ngx_http_core_main_conf_t *cmcf = conf; | |
1239 | |
1240 /* TODO: remove it if no directives */ | |
1241 #endif | |
1242 | |
1243 return NGX_CONF_OK; | |
1244 } | |
1245 | |
1246 | |
1247 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf) | |
1248 { | |
1249 ngx_http_core_srv_conf_t *cscf; | |
1250 | |
1251 ngx_test_null(cscf, | |
1252 ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t)), | |
1253 NGX_CONF_ERROR); | |
1254 | |
1255 /* | |
1256 | |
1257 set by ngx_pcalloc(): | |
1258 | |
1259 conf->client_large_buffers.num = 0; | |
1260 | |
1261 */ | |
1262 | |
1263 | |
1264 ngx_init_array(cscf->locations, cf->pool, | |
1265 5, sizeof(void *), NGX_CONF_ERROR); | |
1266 ngx_init_array(cscf->listen, cf->pool, 5, sizeof(ngx_http_listen_t), | |
1267 NGX_CONF_ERROR); | |
1268 ngx_init_array(cscf->server_names, cf->pool, | |
1269 5, sizeof(ngx_http_server_name_t), NGX_CONF_ERROR); | |
1270 | |
1271 cscf->connection_pool_size = NGX_CONF_UNSET_SIZE; | |
1272 cscf->post_accept_timeout = NGX_CONF_UNSET_MSEC; | |
1273 cscf->request_pool_size = NGX_CONF_UNSET_SIZE; | |
1274 cscf->client_header_timeout = NGX_CONF_UNSET_MSEC; | |
1275 cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE; | |
1276 cscf->restrict_host_names = NGX_CONF_UNSET_UINT; | |
1277 | |
1278 return cscf; | |
1279 } | |
1280 | |
1281 | |
1282 static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf, | |
1283 void *parent, void *child) | |
1284 { | |
1285 ngx_http_core_srv_conf_t *prev = parent; | |
1286 ngx_http_core_srv_conf_t *conf = child; | |
1287 | |
1288 ngx_http_listen_t *l; | |
1289 ngx_http_server_name_t *n; | |
1290 ngx_http_core_main_conf_t *cmcf; | |
1291 | |
1292 /* TODO: it does not merge, it inits only */ | |
1293 | |
1294 if (conf->listen.nelts == 0) { | |
1295 ngx_test_null(l, ngx_push_array(&conf->listen), NGX_CONF_ERROR); | |
1296 l->addr = INADDR_ANY; | |
1297 #if (WIN32) | |
1298 l->port = 80; | |
1299 #else | |
1300 /* STUB: getuid() should be cached */ | |
1301 l->port = (getuid() == 0) ? 80 : 8000; | |
1302 #endif | |
1303 l->family = AF_INET; | |
1304 } | |
1305 | |
1306 if (conf->server_names.nelts == 0) { | |
1307 ngx_test_null(n, ngx_push_array(&conf->server_names), NGX_CONF_ERROR); | |
1308 ngx_test_null(n->name.data, ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN), | |
1309 NGX_CONF_ERROR); | |
1310 | |
1311 if (gethostname((char *) n->name.data, NGX_MAXHOSTNAMELEN) == -1) { | |
1312 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, | |
1313 "gethostname() failed"); | |
1314 return NGX_CONF_ERROR; | |
1315 } | |
1316 | |
1317 n->name.len = ngx_strlen(n->name.data); | |
1318 n->core_srv_conf = conf; | |
1319 | |
1320 #if 0 | |
1321 ctx = (ngx_http_conf_ctx_t *) | |
1322 cf->cycle->conf_ctx[ngx_http_module.index]; | |
1323 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; | |
1324 #endif | |
1325 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
1326 | |
1327 if (cmcf->max_server_name_len < n->name.len) { | |
1328 cmcf->max_server_name_len = n->name.len; | |
1329 } | |
1330 } | |
1331 | |
1332 ngx_conf_merge_size_value(conf->connection_pool_size, | |
1333 prev->connection_pool_size, 256); | |
1334 ngx_conf_merge_msec_value(conf->post_accept_timeout, | |
1335 prev->post_accept_timeout, 60000); | |
1336 ngx_conf_merge_size_value(conf->request_pool_size, | |
1337 prev->request_pool_size, 4096); | |
1338 ngx_conf_merge_msec_value(conf->client_header_timeout, | |
1339 prev->client_header_timeout, 60000); | |
1340 ngx_conf_merge_size_value(conf->client_header_buffer_size, | |
1341 prev->client_header_buffer_size, 1024); | |
1342 ngx_conf_merge_bufs_value(conf->large_client_header_buffers, | |
1343 prev->large_client_header_buffers, | |
1344 4, ngx_pagesize); | |
1345 | |
1346 if (conf->large_client_header_buffers.size < conf->connection_pool_size) { | |
1347 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1348 "the \"large_client_header_buffers\" size must be " | |
1349 "equal to or bigger than \"connection_pool_size\""); | |
1350 return NGX_CONF_ERROR; | |
1351 } | |
1352 | |
1353 ngx_conf_merge_unsigned_value(conf->restrict_host_names, | |
1354 prev->restrict_host_names, 0); | |
1355 | |
1356 return NGX_CONF_OK; | |
1357 } | |
1358 | |
1359 | |
1360 static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf) | |
1361 { | |
1362 ngx_http_core_loc_conf_t *lcf; | |
1363 | |
1364 ngx_test_null(lcf, | |
1365 ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t)), | |
1366 NGX_CONF_ERROR); | |
1367 | |
1368 /* set by ngx_pcalloc(): | |
1369 | |
1370 lcf->root.len = 0; | |
1371 lcf->root.data = NULL; | |
1372 lcf->types = NULL; | |
1373 lcf->default_type.len = 0; | |
1374 lcf->default_type.data = NULL; | |
1375 lcf->err_log = NULL; | |
1376 lcf->error_pages = NULL; | |
1377 | |
1378 lcf->regex = NULL; | |
1379 lcf->exact_match = 0; | |
1380 lcf->auto_redirect = 0; | |
1381 lcf->alias = 0; | |
1382 | |
1383 */ | |
1384 | |
1385 lcf->client_max_body_size = NGX_CONF_UNSET_SIZE; | |
1386 lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE; | |
1387 lcf->client_body_timeout = NGX_CONF_UNSET_MSEC; | |
1388 lcf->sendfile = NGX_CONF_UNSET; | |
1389 lcf->tcp_nopush = NGX_CONF_UNSET; | |
1390 lcf->send_timeout = NGX_CONF_UNSET_MSEC; | |
1391 lcf->send_lowat = NGX_CONF_UNSET_SIZE; | |
1392 lcf->postpone_output = NGX_CONF_UNSET_SIZE; | |
1393 lcf->limit_rate = NGX_CONF_UNSET_SIZE; | |
1394 lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC; | |
1395 lcf->keepalive_header = NGX_CONF_UNSET; | |
1396 lcf->lingering_time = NGX_CONF_UNSET_MSEC; | |
1397 lcf->lingering_timeout = NGX_CONF_UNSET_MSEC; | |
1398 lcf->reset_timedout_connection = NGX_CONF_UNSET; | |
1399 lcf->msie_padding = NGX_CONF_UNSET; | |
1400 | |
1401 return lcf; | |
1402 } | |
1403 | |
1404 | |
1405 static ngx_http_type_t default_types[] = { | |
1406 { ngx_string("html"), ngx_string("text/html") }, | |
1407 { ngx_string("gif"), ngx_string("image/gif") }, | |
1408 { ngx_string("jpg"), ngx_string("image/jpeg") }, | |
1409 { ngx_null_string, ngx_null_string } | |
1410 }; | |
1411 | |
1412 | |
1413 static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf, | |
1414 void *parent, void *child) | |
1415 { | |
1416 ngx_http_core_loc_conf_t *prev = parent; | |
1417 ngx_http_core_loc_conf_t *conf = child; | |
1418 | |
1419 int i, key; | |
1420 ngx_http_type_t *t; | |
1421 | |
1422 ngx_conf_merge_str_value(conf->root, prev->root, "html"); | |
1423 | |
1424 if (ngx_conf_full_name(cf->cycle, &conf->root) == NGX_ERROR) { | |
1425 return NGX_CONF_ERROR; | |
1426 } | |
1427 | |
1428 if (conf->types == NULL) { | |
1429 if (prev->types) { | |
1430 conf->types = prev->types; | |
1431 | |
1432 } else { | |
1433 ngx_test_null(conf->types, | |
1434 ngx_palloc(cf->pool, NGX_HTTP_TYPES_HASH_PRIME | |
1435 * sizeof(ngx_array_t)), | |
1436 NGX_CONF_ERROR); | |
1437 | |
1438 for (i = 0; i < NGX_HTTP_TYPES_HASH_PRIME; i++) { | |
1439 ngx_init_array(conf->types[i], cf->pool, | |
1440 5, sizeof(ngx_http_type_t), NGX_CONF_ERROR); | |
1441 } | |
1442 | |
1443 for (i = 0; default_types[i].exten.len; i++) { | |
1444 ngx_http_types_hash_key(key, default_types[i].exten); | |
1445 | |
1446 ngx_test_null(t, ngx_push_array(&conf->types[key]), | |
1447 NGX_CONF_ERROR); | |
1448 t->exten.len = default_types[i].exten.len; | |
1449 t->exten.data = default_types[i].exten.data; | |
1450 t->type.len = default_types[i].type.len; | |
1451 t->type.data = default_types[i].type.data; | |
1452 } | |
1453 } | |
1454 } | |
1455 | |
1456 if (conf->err_log == NULL) { | |
1457 if (prev->err_log) { | |
1458 conf->err_log = prev->err_log; | |
1459 } else { | |
1460 conf->err_log = cf->cycle->new_log; | |
1461 } | |
1462 } | |
1463 | |
1464 if (conf->error_pages == NULL && prev->error_pages) { | |
1465 conf->error_pages = prev->error_pages; | |
1466 } | |
1467 | |
1468 ngx_conf_merge_str_value(conf->default_type, | |
1469 prev->default_type, "text/plain"); | |
1470 | |
1471 ngx_conf_merge_size_value(conf->client_max_body_size, | |
1472 prev->client_max_body_size, 1 * 1024 * 1024); | |
1473 ngx_conf_merge_size_value(conf->client_body_buffer_size, | |
1474 prev->client_body_buffer_size, | |
1475 (size_t) 2 * ngx_pagesize); | |
1476 ngx_conf_merge_msec_value(conf->client_body_timeout, | |
1477 prev->client_body_timeout, 60000); | |
1478 ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0); | |
1479 ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0); | |
1480 ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000); | |
1481 ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0); | |
1482 ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output, | |
1483 1460); | |
1484 ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0); | |
1485 ngx_conf_merge_msec_value(conf->keepalive_timeout, | |
1486 prev->keepalive_timeout, 75000); | |
1487 ngx_conf_merge_sec_value(conf->keepalive_header, | |
1488 prev->keepalive_header, 0); | |
1489 ngx_conf_merge_msec_value(conf->lingering_time, | |
1490 prev->lingering_time, 30000); | |
1491 ngx_conf_merge_msec_value(conf->lingering_timeout, | |
1492 prev->lingering_timeout, 5000); | |
1493 | |
1494 ngx_conf_merge_value(conf->reset_timedout_connection, | |
1495 prev->reset_timedout_connection, 0); | |
1496 ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1); | |
1497 | |
1498 if (conf->open_files == NULL) { | |
1499 conf->open_files = prev->open_files; | |
1500 } | |
1501 | |
1502 return NGX_CONF_OK; | |
1503 } | |
1504 | |
1505 | |
1506 static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1507 { | |
1508 ngx_http_core_srv_conf_t *scf = conf; | |
1509 | |
1510 u_char *addr; | |
1511 ngx_int_t port; | |
1512 ngx_uint_t p; | |
1513 struct hostent *h; | |
1514 ngx_str_t *args; | |
1515 ngx_http_listen_t *ls; | |
1516 | |
1517 /* | |
1518 * TODO: check duplicate 'listen' directives, | |
1519 * add resolved name to server names ??? | |
1520 */ | |
1521 | |
1522 if (!(ls = ngx_array_push(&scf->listen))) { | |
1523 return NGX_CONF_ERROR; | |
1524 } | |
1525 | |
1526 /* AF_INET only */ | |
1527 | |
1528 ls->family = AF_INET; | |
1529 ls->default_server = 0; | |
1530 ls->file_name = cf->conf_file->file.name; | |
1531 ls->line = cf->conf_file->line; | |
1532 | |
1533 args = cf->args->elts; | |
1534 addr = args[1].data; | |
1535 | |
1536 for (p = 0; p < args[1].len; p++) { | |
1537 if (addr[p] == ':') { | |
1538 addr[p++] = '\0'; | |
1539 break; | |
1540 } | |
1541 } | |
1542 | |
1543 if (p == args[1].len) { | |
1544 /* no ":" in the "listen" */ | |
1545 p = 0; | |
1546 } | |
1547 | |
1548 port = ngx_atoi(&addr[p], args[1].len - p); | |
1549 | |
1550 if (port == NGX_ERROR && p == 0) { | |
1551 | |
1552 /* "listen host" */ | |
1553 ls->port = 80; | |
1554 | |
1555 } else if ((port == NGX_ERROR && p != 0) /* "listen host:NONNUMBER" */ | |
1556 || (port < 1 || port > 65536)) { /* "listen 99999" */ | |
1557 | |
1558 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1559 "invalid port \"%s\" in \"%s\" directive, " | |
1560 "it must be a number between 1 and 65535", | |
1561 &addr[p], cmd->name.data); | |
1562 | |
1563 return NGX_CONF_ERROR; | |
1564 | |
1565 } else if (p == 0) { | |
1566 ls->addr = INADDR_ANY; | |
1567 ls->port = (in_port_t) port; | |
1568 return NGX_CONF_OK; | |
1569 | |
1570 } else { | |
1571 ls->port = (in_port_t) port; | |
1572 } | |
1573 | |
1574 ls->addr = inet_addr((const char *) addr); | |
1575 if (ls->addr == INADDR_NONE) { | |
1576 h = gethostbyname((const char *) addr); | |
1577 | |
1578 if (h == NULL || h->h_addr_list[0] == NULL) { | |
1579 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1580 "can not resolve host \"%s\" " | |
1581 "in \"%s\" directive", addr, cmd->name.data); | |
1582 return NGX_CONF_ERROR; | |
1583 } | |
1584 | |
1585 ls->addr = *(in_addr_t *)(h->h_addr_list[0]); | |
1586 } | |
1587 | |
1588 return NGX_CONF_OK; | |
1589 } | |
1590 | |
1591 | |
1592 static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1593 { | |
1594 ngx_http_core_srv_conf_t *scf = conf; | |
1595 | |
1596 ngx_uint_t i; | |
1597 ngx_str_t *value; | |
1598 ngx_http_server_name_t *sn; | |
1599 ngx_http_core_main_conf_t *cmcf; | |
1600 | |
1601 /* TODO: several names */ | |
1602 /* TODO: warn about duplicate 'server_name' directives */ | |
1603 | |
1604 #if 0 | |
1605 ctx = (ngx_http_conf_ctx_t *) cf->cycle->conf_ctx[ngx_http_module.index]; | |
1606 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; | |
1607 #endif | |
1608 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
1609 | |
1610 value = cf->args->elts; | |
1611 | |
1612 for (i = 1; i < cf->args->nelts; i++) { | |
1613 if (value[i].len == 0) { | |
1614 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1615 "server name \"%s\" is invalid " | |
1616 "in \"%s\" directive", | |
1617 value[i].data, cmd->name.data); | |
1618 return NGX_CONF_ERROR; | |
1619 } | |
1620 | |
1621 ngx_test_null(sn, ngx_push_array(&scf->server_names), NGX_CONF_ERROR); | |
1622 | |
1623 sn->name.len = value[i].len; | |
1624 sn->name.data = value[i].data; | |
1625 sn->core_srv_conf = scf; | |
1626 | |
1627 if (cmcf->max_server_name_len < sn->name.len) { | |
1628 cmcf->max_server_name_len = sn->name.len; | |
1629 } | |
1630 } | |
1631 | |
1632 return NGX_CONF_OK; | |
1633 } | |
1634 | |
1635 | |
1636 static char *ngx_set_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1637 { | |
1638 ngx_http_core_loc_conf_t *lcf = conf; | |
1639 | |
1640 ngx_uint_t alias; | |
1641 ngx_str_t *value; | |
1642 | |
1643 alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0; | |
1644 | |
1645 if (lcf->root.data) { | |
1646 | |
1647 /* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */ | |
1648 | |
1649 if ((ngx_uint_t) lcf->alias == alias) { | |
1650 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1651 "\"%s\" directive is duplicate", | |
1652 cmd->name.data); | |
1653 } else { | |
1654 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1655 "\"%s\" directive is duplicate, " | |
1656 "\"%s\" directive is specified before", | |
1657 cmd->name.data, lcf->alias ? "alias" : "root"); | |
1658 } | |
1659 | |
1660 return NGX_CONF_ERROR; | |
1661 } | |
1662 | |
1663 value = cf->args->elts; | |
1664 | |
1665 lcf->alias = alias; | |
1666 lcf->root = value[1]; | |
1667 | |
1668 if (!alias && lcf->root.data[lcf->root.len - 1] == '/') { | |
1669 lcf->root.len--; | |
1670 } | |
1671 | |
1672 return NGX_CONF_OK; | |
1673 } | |
1674 | |
1675 | |
1676 static char *ngx_set_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1677 { | |
1678 ngx_http_core_loc_conf_t *lcf = conf; | |
1679 | |
1680 int overwrite; | |
1681 ngx_uint_t i, n; | |
1682 ngx_str_t *value; | |
1683 ngx_http_err_page_t *err; | |
1684 | |
1685 if (lcf->error_pages == NULL) { | |
1686 lcf->error_pages = ngx_create_array(cf->pool, 5, | |
1687 sizeof(ngx_http_err_page_t)); | |
1688 if (lcf->error_pages == NULL) { | |
1689 return NGX_CONF_ERROR; | |
1690 } | |
1691 } | |
1692 | |
1693 value = cf->args->elts; | |
1694 | |
1695 i = cf->args->nelts - 2; | |
1696 | |
1697 if (value[i].data[0] == '=') { | |
1698 if (i == 1) { | |
1699 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1700 "invalid value \"%s\"", value[i].data); | |
1701 return NGX_CONF_ERROR; | |
1702 } | |
1703 | |
1704 overwrite = ngx_atoi(&value[i].data[1], value[i].len - 1); | |
1705 | |
1706 if (overwrite == NGX_ERROR) { | |
1707 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1708 "invalid value \"%s\"", value[i].data); | |
1709 return NGX_CONF_ERROR; | |
1710 } | |
1711 | |
1712 n = 2; | |
1713 | |
1714 } else { | |
1715 overwrite = 0; | |
1716 n = 1; | |
1717 } | |
1718 | |
1719 for (i = 1; i < cf->args->nelts - n; i++) { | |
1720 if (!(err = ngx_push_array(lcf->error_pages))) { | |
1721 return NGX_CONF_ERROR; | |
1722 } | |
1723 | |
1724 err->status = ngx_atoi(value[i].data, value[i].len); | |
1725 if (err->status == NGX_ERROR) { | |
1726 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1727 "invalid value \"%s\"", value[i].data); | |
1728 return NGX_CONF_ERROR; | |
1729 } | |
1730 | |
1731 if (err->status < 400 || err->status > 599) { | |
1732 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1733 "value \"%s\" must be between 400 and 599", | |
1734 value[i].data); | |
1735 return NGX_CONF_ERROR; | |
1736 } | |
1737 | |
1738 err->overwrite = overwrite; | |
1739 err->uri = value[cf->args->nelts - 1]; | |
1740 } | |
1741 | |
1742 return NGX_CONF_OK; | |
1743 } | |
1744 | |
1745 | |
1746 static char *ngx_set_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1747 { | |
1748 ngx_http_core_loc_conf_t *lcf = conf; | |
1749 | |
1750 ngx_str_t *value; | |
1751 | |
1752 if (lcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) { | |
1753 return "is duplicate"; | |
1754 } | |
1755 | |
1756 value = cf->args->elts; | |
1757 | |
1758 lcf->keepalive_timeout = ngx_parse_time(&value[1], 0); | |
1759 if (lcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) { | |
1760 return "invalid value"; | |
1761 } | |
1762 | |
1763 if (lcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) { | |
1764 return "value must be less than 597 hours"; | |
1765 } | |
1766 | |
1767 if (cf->args->nelts == 2) { | |
1768 return NGX_CONF_OK; | |
1769 } | |
1770 | |
1771 lcf->keepalive_header = ngx_parse_time(&value[2], 1); | |
1772 if (lcf->keepalive_header == NGX_ERROR) { | |
1773 return "invalid value"; | |
1774 } | |
1775 | |
1776 if (lcf->keepalive_header == NGX_PARSE_LARGE_TIME) { | |
1777 return "value must be less than 68 years"; | |
1778 } | |
1779 | |
1780 return NGX_CONF_OK; | |
1781 } | |
1782 | |
1783 | |
1784 static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1785 { | |
1786 ngx_http_core_loc_conf_t *lcf = conf; | |
1787 | |
1788 if (!(lcf->err_log = ngx_log_create_errlog(cf->cycle, cf->args))) { | |
1789 return NGX_CONF_ERROR; | |
1790 } | |
1791 | |
1792 return ngx_set_error_log_levels(cf, lcf->err_log); | |
1793 } | |
1794 | |
1795 | |
1796 static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data) | |
1797 { | |
1798 #if (HAVE_LOWAT_EVENT) | |
1799 | |
1800 ssize_t *np = data; | |
1801 | |
1802 if (*np >= ngx_freebsd_net_inet_tcp_sendspace) { | |
1803 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1804 "\"send_lowat\" must be less than %d " | |
1805 "(sysctl net.inet.tcp.sendspace)", | |
1806 ngx_freebsd_net_inet_tcp_sendspace); | |
1807 | |
1808 return NGX_CONF_ERROR; | |
1809 } | |
1810 | |
1811 #else | |
1812 | |
1813 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | |
1814 "\"send_lowat\" is not supported, ignored"); | |
1815 | |
1816 #endif | |
1817 | |
1818 return NGX_CONF_OK; | |
1819 } |