blob: 51fda1a4a89ab161cdd22ab83339eeb3d55cce85 [file] [log] [blame]
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001
2#include <ngx_config.h>
Igor Sysoev4e9393a2003-01-09 05:36:00 +00003#include <ngx_core.h>
Igor Sysoevb3e73d82003-10-10 15:10:50 +00004#include <ngx_event.h>
Igor Sysoev6253ca12003-05-27 12:18:54 +00005#include <ngx_http.h>
Igor Sysoeva9830112003-05-19 16:39:14 +00006#include <nginx.h>
Igor Sysoev4e9393a2003-01-09 05:36:00 +00007
Igor Sysoev6253ca12003-05-27 12:18:54 +00008
Igor Sysoevb3e73d82003-10-10 15:10:50 +00009static void ngx_http_phase_event_handler(ngx_event_t *rev);
10static void ngx_http_run_phases(ngx_http_request_t *r);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000011
Igor Sysoev890fc962003-07-20 21:15:59 +000012static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
13static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
14static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
15static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
Igor Sysoeva9830112003-05-19 16:39:14 +000016 void *parent, void *child);
Igor Sysoev890fc962003-07-20 21:15:59 +000017static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf);
18static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
Igor Sysoeve2a31542003-04-08 15:40:10 +000019 void *parent, void *child);
Igor Sysoevdc479b42003-03-20 16:09:44 +000020
Igor Sysoev340b03b2003-07-04 15:10:33 +000021static int ngx_http_core_init(ngx_cycle_t *cycle);
Igor Sysoev6253ca12003-05-27 12:18:54 +000022static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy);
Igor Sysoev13933252003-05-29 13:02:09 +000023static int ngx_cmp_locations(const void *first, const void *second);
Igor Sysoevdc479b42003-03-20 16:09:44 +000024static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoev890fc962003-07-20 21:15:59 +000025 void *dummy);
Igor Sysoev6253ca12003-05-27 12:18:54 +000026static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoevaa3436c2003-05-30 14:27:59 +000027static char *ngx_set_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
Igor Sysoev6253ca12003-05-27 12:18:54 +000028static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoev13933252003-05-29 13:02:09 +000029static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoev890fc962003-07-20 21:15:59 +000030 void *conf);
Igor Sysoev10a543a2004-03-16 07:10:12 +000031static char *ngx_set_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoev74e95c22003-11-09 20:03:38 +000032static char *ngx_set_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoev890fc962003-07-20 21:15:59 +000033static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000034
Igor Sysoevb5faed22003-10-29 08:30:44 +000035static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data);
36
37static ngx_conf_post_t ngx_http_lowat_post = { ngx_http_lowat_check } ;
38
Igor Sysoev4e9393a2003-01-09 05:36:00 +000039
40static ngx_command_t ngx_http_core_commands[] = {
41
Igor Sysoev865c1502003-11-30 20:03:18 +000042 { ngx_string("server"),
43 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
44 ngx_server_block,
45 0,
46 0,
47 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +000048
Igor Sysoev865c1502003-11-30 20:03:18 +000049 { ngx_string("connection_pool_size"),
50 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
51 ngx_conf_set_size_slot,
52 NGX_HTTP_SRV_CONF_OFFSET,
53 offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
54 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +000055
Igor Sysoev865c1502003-11-30 20:03:18 +000056 { ngx_string("post_accept_timeout"),
57 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
58 ngx_conf_set_msec_slot,
59 NGX_HTTP_SRV_CONF_OFFSET,
60 offsetof(ngx_http_core_srv_conf_t, post_accept_timeout),
61 NULL },
Igor Sysoev187fcd82003-05-23 11:53:01 +000062
Igor Sysoev865c1502003-11-30 20:03:18 +000063 { ngx_string("request_pool_size"),
64 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
65 ngx_conf_set_size_slot,
66 NGX_HTTP_SRV_CONF_OFFSET,
67 offsetof(ngx_http_core_srv_conf_t, request_pool_size),
68 NULL },
Igor Sysoev187fcd82003-05-23 11:53:01 +000069
Igor Sysoev865c1502003-11-30 20:03:18 +000070 { ngx_string("client_header_timeout"),
71 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
72 ngx_conf_set_msec_slot,
73 NGX_HTTP_SRV_CONF_OFFSET,
74 offsetof(ngx_http_core_srv_conf_t, client_header_timeout),
75 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +000076
Igor Sysoev865c1502003-11-30 20:03:18 +000077 { ngx_string("client_header_buffer_size"),
78 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
79 ngx_conf_set_size_slot,
80 NGX_HTTP_SRV_CONF_OFFSET,
81 offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
82 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +000083
Igor Sysoev865c1502003-11-30 20:03:18 +000084 { ngx_string("large_client_header"),
85 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
86 ngx_conf_set_flag_slot,
87 NGX_HTTP_SRV_CONF_OFFSET,
88 offsetof(ngx_http_core_srv_conf_t, large_client_header),
89 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +000090
Igor Sysoev865c1502003-11-30 20:03:18 +000091 { ngx_string("location"),
92 NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
93 ngx_location_block,
94 NGX_HTTP_SRV_CONF_OFFSET,
95 0,
96 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +000097
Igor Sysoev865c1502003-11-30 20:03:18 +000098 { ngx_string("listen"),
Igor Sysoev7578ec92003-06-02 15:24:30 +000099#if 0
Igor Sysoev865c1502003-11-30 20:03:18 +0000100 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
Igor Sysoev7578ec92003-06-02 15:24:30 +0000101#else
Igor Sysoev865c1502003-11-30 20:03:18 +0000102 NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
Igor Sysoev7578ec92003-06-02 15:24:30 +0000103#endif
Igor Sysoev865c1502003-11-30 20:03:18 +0000104 ngx_set_listen,
105 NGX_HTTP_SRV_CONF_OFFSET,
106 0,
107 NULL },
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000108
Igor Sysoev865c1502003-11-30 20:03:18 +0000109 { ngx_string("server_name"),
110 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
111 ngx_set_server_name,
112 NGX_HTTP_SRV_CONF_OFFSET,
113 0,
114 NULL },
Igor Sysoev13933252003-05-29 13:02:09 +0000115
Igor Sysoev865c1502003-11-30 20:03:18 +0000116 { ngx_string("types"),
117 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
118 |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
119 ngx_types_block,
120 NGX_HTTP_LOC_CONF_OFFSET,
121 0,
122 NULL },
Igor Sysoev79a80482003-05-14 17:13:13 +0000123
Igor Sysoev865c1502003-11-30 20:03:18 +0000124 { ngx_string("default_type"),
125 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
126 ngx_conf_set_str_slot,
127 NGX_HTTP_LOC_CONF_OFFSET,
128 offsetof(ngx_http_core_loc_conf_t, default_type),
129 NULL },
Igor Sysoev6253ca12003-05-27 12:18:54 +0000130
Igor Sysoev865c1502003-11-30 20:03:18 +0000131 { ngx_string("root"),
132 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
Igor Sysoev10a543a2004-03-16 07:10:12 +0000133 ngx_set_root,
Igor Sysoev865c1502003-11-30 20:03:18 +0000134 NGX_HTTP_LOC_CONF_OFFSET,
Igor Sysoev10a543a2004-03-16 07:10:12 +0000135 0,
136 NULL },
137
138 { ngx_string("alias"),
139 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
140 ngx_set_root,
141 NGX_HTTP_LOC_CONF_OFFSET,
142 0,
Igor Sysoev865c1502003-11-30 20:03:18 +0000143 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000144
Igor Sysoevae02c192004-03-19 05:25:53 +0000145 { ngx_string("client_max_body_size"),
146 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
147 ngx_conf_set_size_slot,
148 NGX_HTTP_LOC_CONF_OFFSET,
149 offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
150 NULL },
151
Igor Sysoevdbb27762004-04-01 16:20:53 +0000152 { ngx_string("client_body_buffer_size"),
153 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
154 ngx_conf_set_size_slot,
155 NGX_HTTP_LOC_CONF_OFFSET,
156 offsetof(ngx_http_core_loc_conf_t, client_body_buffer_size),
157 NULL },
158
Igor Sysoev865c1502003-11-30 20:03:18 +0000159 { ngx_string("client_body_timeout"),
160 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
161 ngx_conf_set_msec_slot,
162 NGX_HTTP_LOC_CONF_OFFSET,
163 offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
164 NULL },
Igor Sysoev2b0c76c2003-10-27 21:01:00 +0000165
Igor Sysoev865c1502003-11-30 20:03:18 +0000166 { ngx_string("sendfile"),
167 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
168 ngx_conf_set_flag_slot,
169 NGX_HTTP_LOC_CONF_OFFSET,
170 offsetof(ngx_http_core_loc_conf_t, sendfile),
171 NULL },
Igor Sysoev5bf3d252003-10-22 07:05:29 +0000172
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000173 { ngx_string("tcp_nopush"),
174 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
175 ngx_conf_set_flag_slot,
176 NGX_HTTP_LOC_CONF_OFFSET,
177 offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
178 NULL },
179
Igor Sysoev865c1502003-11-30 20:03:18 +0000180 { ngx_string("send_timeout"),
181 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
182 ngx_conf_set_msec_slot,
183 NGX_HTTP_LOC_CONF_OFFSET,
184 offsetof(ngx_http_core_loc_conf_t, send_timeout),
185 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000186
Igor Sysoev865c1502003-11-30 20:03:18 +0000187 { ngx_string("send_lowat"),
188 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
189 ngx_conf_set_size_slot,
190 NGX_HTTP_LOC_CONF_OFFSET,
191 offsetof(ngx_http_core_loc_conf_t, send_lowat),
192 &ngx_http_lowat_post },
Igor Sysoevb5faed22003-10-29 08:30:44 +0000193
Igor Sysoev865c1502003-11-30 20:03:18 +0000194 { ngx_string("keepalive_timeout"),
195 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
196 ngx_conf_set_msec_slot,
197 NGX_HTTP_LOC_CONF_OFFSET,
198 offsetof(ngx_http_core_loc_conf_t, keepalive_timeout),
199 NULL },
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000200
Igor Sysoev865c1502003-11-30 20:03:18 +0000201 { ngx_string("lingering_time"),
202 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
203 ngx_conf_set_msec_slot,
204 NGX_HTTP_LOC_CONF_OFFSET,
205 offsetof(ngx_http_core_loc_conf_t, lingering_time),
206 NULL },
Igor Sysoevb7387572003-03-11 20:38:13 +0000207
Igor Sysoev865c1502003-11-30 20:03:18 +0000208 { ngx_string("lingering_timeout"),
209 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
210 ngx_conf_set_msec_slot,
211 NGX_HTTP_LOC_CONF_OFFSET,
212 offsetof(ngx_http_core_loc_conf_t, lingering_timeout),
213 NULL },
Igor Sysoevb7387572003-03-11 20:38:13 +0000214
Igor Sysoev865c1502003-11-30 20:03:18 +0000215 { ngx_string("msie_padding"),
216 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
217 ngx_conf_set_flag_slot,
218 NGX_HTTP_LOC_CONF_OFFSET,
219 offsetof(ngx_http_core_loc_conf_t, msie_padding),
220 NULL },
Igor Sysoev12b4b002003-10-24 06:53:41 +0000221
Igor Sysoev865c1502003-11-30 20:03:18 +0000222 { ngx_string("error_page"),
223 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
224 ngx_set_error_page,
225 NGX_HTTP_LOC_CONF_OFFSET,
226 0,
227 NULL },
Igor Sysoev74e95c22003-11-09 20:03:38 +0000228
Igor Sysoev865c1502003-11-30 20:03:18 +0000229 { ngx_string("error_log"),
Igor Sysoev03420a62004-01-20 20:40:08 +0000230 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
Igor Sysoev865c1502003-11-30 20:03:18 +0000231 ngx_set_error_log,
232 NGX_HTTP_LOC_CONF_OFFSET,
233 0,
234 NULL },
Igor Sysoev890fc962003-07-20 21:15:59 +0000235
Igor Sysoev67f88e92004-03-12 16:57:08 +0000236#if (NGX_HTTP_CACHE)
237
Igor Sysoev865c1502003-11-30 20:03:18 +0000238 { ngx_string("open_file_cache"),
239 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE4,
240 ngx_http_set_cache_slot,
241 NGX_HTTP_LOC_CONF_OFFSET,
242 offsetof(ngx_http_core_loc_conf_t, open_files),
243 NULL },
244
Igor Sysoev67f88e92004-03-12 16:57:08 +0000245#endif
246
Igor Sysoev865c1502003-11-30 20:03:18 +0000247 ngx_null_command
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000248};
249
250
251ngx_http_module_t ngx_http_core_module_ctx = {
Igor Sysoev78329332003-11-10 17:17:31 +0000252 NULL, /* pre conf */
253
Igor Sysoeva9830112003-05-19 16:39:14 +0000254 ngx_http_core_create_main_conf, /* create main configuration */
255 ngx_http_core_init_main_conf, /* init main configuration */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000256
Igor Sysoeva9830112003-05-19 16:39:14 +0000257 ngx_http_core_create_srv_conf, /* create server configuration */
258 ngx_http_core_merge_srv_conf, /* merge server configuration */
259
260 ngx_http_core_create_loc_conf, /* create location configuration */
261 ngx_http_core_merge_loc_conf /* merge location configuration */
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000262};
263
264
265ngx_module_t ngx_http_core_module = {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000266 NGX_MODULE,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000267 &ngx_http_core_module_ctx, /* module context */
268 ngx_http_core_commands, /* module directives */
Igor Sysoev6253ca12003-05-27 12:18:54 +0000269 NGX_HTTP_MODULE, /* module type */
Igor Sysoev96c56c92003-07-02 14:41:17 +0000270 ngx_http_core_init, /* init module */
Igor Sysoev340b03b2003-07-04 15:10:33 +0000271 NULL /* init child */
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000272};
273
274
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000275void ngx_http_handler(ngx_http_request_t *r)
276{
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000277 ngx_http_log_ctx_t *lcx;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000278
279 r->connection->unexpected_eof = 0;
280
Igor Sysoev7578ec92003-06-02 15:24:30 +0000281 lcx = r->connection->log->data;
282 lcx->action = NULL;
283
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000284 switch (r->headers_in.connection_type) {
285 case 0:
286 if (r->http_version > NGX_HTTP_VERSION_10) {
287 r->keepalive = 1;
288 } else {
Igor Sysoev9760a132003-10-21 07:47:21 +0000289 r->keepalive = 0;
290 }
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000291 break;
292
293 case NGX_HTTP_CONNECTION_CLOSE:
294 r->keepalive = 0;
295 break;
296
297 case NGX_HTTP_CONNECTION_KEEP_ALIVE:
298 r->keepalive = 1;
299 break;
Igor Sysoev9760a132003-10-21 07:47:21 +0000300 }
301
Igor Sysoev10fc9ef2003-10-27 08:53:49 +0000302#if 0
Igor Sysoevdc9dd432003-10-22 16:38:26 +0000303 /* TEST STUB */ r->http_version = NGX_HTTP_VERSION_10;
Igor Sysoev9760a132003-10-21 07:47:21 +0000304 /* TEST STUB */ r->keepalive = 0;
305#endif
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000306
307 if (r->headers_in.content_length_n > 0) {
308 r->lingering_close = 1;
Igor Sysoev9760a132003-10-21 07:47:21 +0000309
310 } else {
311 r->lingering_close = 0;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000312 }
313
Igor Sysoev9760a132003-10-21 07:47:21 +0000314#if 0
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000315 /* TEST STUB */ r->lingering_close = 1;
Igor Sysoev9760a132003-10-21 07:47:21 +0000316#endif
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000317
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000318 r->connection->write->event_handler = ngx_http_phase_event_handler;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000319
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000320 ngx_http_run_phases(r);
321
322 return;
323}
Igor Sysoeve2a31542003-04-08 15:40:10 +0000324
325
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000326static void ngx_http_phase_event_handler(ngx_event_t *ev)
327{
328 ngx_connection_t *c;
329 ngx_http_request_t *r;
330
331 c = ev->data;
332 r = c->data;
333
Igor Sysoev54498db2004-02-11 17:08:49 +0000334 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, "phase event handler");
Igor Sysoev0a280a32003-10-12 16:49:16 +0000335
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000336 ngx_http_run_phases(r);
337
338 return;
339}
340
341
342static void ngx_http_run_phases(ngx_http_request_t *r)
343{
Igor Sysoev865c1502003-11-30 20:03:18 +0000344 char *path;
345 ngx_int_t rc;
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000346 ngx_http_handler_pt *h;
Igor Sysoev865c1502003-11-30 20:03:18 +0000347 ngx_http_core_loc_conf_t *clcf;
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000348 ngx_http_core_main_conf_t *cmcf;
349
350 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
351
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000352 for (/* void */; r->phase < NGX_HTTP_LAST_PHASE; r->phase++) {
353
Igor Sysoev865c1502003-11-30 20:03:18 +0000354 if (r->phase == NGX_HTTP_CONTENT_PHASE && r->content_handler) {
355 r->connection->write->event_handler = ngx_http_empty_handler;
356 rc = r->content_handler(r);
357 ngx_http_finalize_request(r, rc);
358 return;
359 }
360
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000361 h = cmcf->phases[r->phase].handlers.elts;
362 for (r->phase_handler = cmcf->phases[r->phase].handlers.nelts - 1;
363 r->phase_handler >= 0;
364 r->phase_handler--)
365 {
366 rc = h[r->phase_handler](r);
367
Igor Sysoev9760a132003-10-21 07:47:21 +0000368 if (rc == NGX_DONE) {
Igor Sysoev865c1502003-11-30 20:03:18 +0000369
370 /*
371 * we should never use r here because
372 * it could point to already freed data
373 */
374
Igor Sysoev9760a132003-10-21 07:47:21 +0000375 return;
376 }
377
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000378 if (rc == NGX_DECLINED) {
379 continue;
380 }
381
Igor Sysoev865c1502003-11-30 20:03:18 +0000382 if (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_ERROR) {
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000383 ngx_http_finalize_request(r, rc);
384 return;
385 }
386
Igor Sysoeve3466a42003-12-15 13:57:13 +0000387 if (r->phase == NGX_HTTP_CONTENT_PHASE) {
388 ngx_http_finalize_request(r, rc);
389 return;
390 }
391
392 if (rc == NGX_AGAIN) {
Igor Sysoev865c1502003-11-30 20:03:18 +0000393 return;
394 }
395
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000396 if (rc == NGX_OK && cmcf->phases[r->phase].type == NGX_OK) {
397 break;
398 }
399 }
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000400 }
401
Igor Sysoev865c1502003-11-30 20:03:18 +0000402
403 if (r->uri.data[r->uri.len - 1] == '/') {
404
405 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
406
Igor Sysoev10a543a2004-03-16 07:10:12 +0000407 if (!(path = ngx_palloc(r->pool, clcf->root.len + r->uri.len))) {
Igor Sysoev865c1502003-11-30 20:03:18 +0000408 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
409 return;
410 }
411
Igor Sysoev10a543a2004-03-16 07:10:12 +0000412 ngx_cpystrn(ngx_cpymem(path, clcf->root.data, clcf->root.len),
Igor Sysoev865c1502003-11-30 20:03:18 +0000413 r->uri.data, r->uri.len + 1);
414
415 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
416 "directory index of \"%s\" is forbidden", path);
417
418 ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000419 return;
420 }
421
Igor Sysoev865c1502003-11-30 20:03:18 +0000422 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found");
423
424 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000425 return;
426}
427
428
429int ngx_http_find_location_config(ngx_http_request_t *r)
430{
Igor Sysoev10a543a2004-03-16 07:10:12 +0000431 int rc;
Igor Sysoev11dbe972004-03-29 17:43:58 +0000432 ngx_uint_t i;
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000433 ngx_str_t *auto_redirect;
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000434 ngx_http_core_loc_conf_t *clcf, **clcfp;
435 ngx_http_core_srv_conf_t *cscf;
Igor Sysoev11dbe972004-03-29 17:43:58 +0000436#if (HAVE_PCRE)
437 ngx_uint_t exact;
438#endif
Igor Sysoeve2a31542003-04-08 15:40:10 +0000439
Igor Sysoev6253ca12003-05-27 12:18:54 +0000440 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000441 auto_redirect = NULL;
Igor Sysoev11dbe972004-03-29 17:43:58 +0000442#if (HAVE_PCRE)
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000443 exact = 0;
Igor Sysoev11dbe972004-03-29 17:43:58 +0000444#endif
Igor Sysoeve2a31542003-04-08 15:40:10 +0000445
Igor Sysoev6253ca12003-05-27 12:18:54 +0000446 clcfp = cscf->locations.elts;
447 for (i = 0; i < cscf->locations.nelts; i++) {
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000448
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000449#if (HAVE_PCRE)
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000450
451 if (clcfp[i]->regex) {
452 break;
453 }
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000454#endif
455
456 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
457 "find location: %s\"%s\"",
458 clcfp[i]->exact_match ? "= " : "",
459 clcfp[i]->name.data);
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000460
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000461 if (clcfp[i]->auto_redirect
462 && r->uri.len == clcfp[i]->name.len - 1
463 && ngx_strncmp(r->uri.data, clcfp[i]->name.data,
464 clcfp[i]->name.len - 1) == 0)
465 {
466 auto_redirect = &clcfp[i]->name;
467 continue;
468 }
469
Igor Sysoev890fc962003-07-20 21:15:59 +0000470 if (r->uri.len < clcfp[i]->name.len) {
471 continue;
472 }
Igor Sysoeve2a31542003-04-08 15:40:10 +0000473
Igor Sysoev65977492003-11-02 22:56:18 +0000474 rc = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len);
Igor Sysoeve2a31542003-04-08 15:40:10 +0000475
Igor Sysoev890fc962003-07-20 21:15:59 +0000476 if (rc < 0) {
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000477 /* locations are lexicographically sorted */
Igor Sysoev890fc962003-07-20 21:15:59 +0000478 break;
479 }
Igor Sysoeve2a31542003-04-08 15:40:10 +0000480
Igor Sysoev890fc962003-07-20 21:15:59 +0000481 if (rc == 0) {
482 r->loc_conf = clcfp[i]->loc_conf;
483 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
484 r->connection->log->file = clcf->err_log->file;
Igor Sysoevfff32322004-04-08 15:58:25 +0000485 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
486 r->connection->log->log_level = clcf->err_log->log_level;
487 }
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000488
489 if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) {
Igor Sysoev11dbe972004-03-29 17:43:58 +0000490#if (HAVE_PCRE)
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000491 exact = 1;
Igor Sysoev11dbe972004-03-29 17:43:58 +0000492#endif
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000493 break;
494 }
495 }
496 }
497
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000498#if (HAVE_PCRE)
499
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000500 if (!exact && !auto_redirect) {
501 /* regex matches */
502
503 for (/* void */; i < cscf->locations.nelts; i++) {
504
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000505 if (!clcfp[i]->regex) {
506 continue;
507 }
508
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000509 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
510 "find location: %s\"%s\"",
511 clcfp[i]->exact_match ? "= " :
512 clcfp[i]->regex ? "~ " : "",
513 clcfp[i]->name.data);
514
Igor Sysoev3b30a902003-12-25 20:26:58 +0000515 rc = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0);
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000516
517 if (rc == NGX_DECLINED) {
518 continue;
519 }
520
521 if (rc < 0) {
522 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
523 ngx_regex_exec_n
524 " failed: %d on \"%s\" using \"%s\"",
525 rc, r->uri.data, clcfp[i]->name.data);
526 return NGX_HTTP_INTERNAL_SERVER_ERROR;
527 }
528
529 /* match */
530
531 r->loc_conf = clcfp[i]->loc_conf;
532 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
533 r->connection->log->file = clcf->err_log->file;
Igor Sysoevfff32322004-04-08 15:58:25 +0000534 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
535 r->connection->log->log_level = clcf->err_log->log_level;
536 }
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000537
538 break;
Igor Sysoev890fc962003-07-20 21:15:59 +0000539 }
Igor Sysoeve2a31542003-04-08 15:40:10 +0000540 }
541
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000542#endif /* HAVE_PCRE */
543
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000544 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
545
Igor Sysoev5bf3d252003-10-22 07:05:29 +0000546 if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) {
547 r->sendfile = 0;
548
549 } else {
550 r->sendfile = 1;
551 }
552
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000553 if (!clcf->tcp_nopush) {
554 /* disable TCP_NOPUSH/TCP_CORK use */
555 r->connection->tcp_nopush = -1;
556 }
557
Igor Sysoev89690bf2004-03-23 06:01:52 +0000558
559 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
560 "http cl: " SIZE_T_FMT " max: " SIZE_T_FMT,
561 r->headers_in.content_length_n,
562 clcf->client_max_body_size);
563
564 if (r->headers_in.content_length_n != -1
565 && clcf->client_max_body_size
566 && clcf->client_max_body_size < (size_t) r->headers_in.content_length_n)
567 {
568 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
569 "client intented to send too large body: "
570 SIZE_T_FMT " bytes",
571 r->headers_in.content_length_n);
572
573 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
574 }
575
576
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000577 if (auto_redirect) {
578 if (!(r->headers_out.location =
579 ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
580 {
581 return NGX_HTTP_INTERNAL_SERVER_ERROR;
582 }
583
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000584 r->headers_out.location->value = *auto_redirect;
585
586 return NGX_HTTP_MOVED_PERMANENTLY;
587 }
588
Igor Sysoev6253ca12003-05-27 12:18:54 +0000589 if (clcf->handler) {
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000590 r->content_handler = clcf->handler;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000591 }
592
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000593 return NGX_OK;
594}
595
596
Igor Sysoev865c1502003-11-30 20:03:18 +0000597ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r)
598{
599 uint32_t key;
Igor Sysoev10a543a2004-03-16 07:10:12 +0000600 ngx_uint_t i;
Igor Sysoev865c1502003-11-30 20:03:18 +0000601 ngx_http_type_t *type;
602 ngx_http_core_loc_conf_t *clcf;
603
604 if (!(r->headers_out.content_type =
605 ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
606 {
607 return NGX_HTTP_INTERNAL_SERVER_ERROR;
608 }
609
610 r->headers_out.content_type->key.len = 0;
611 r->headers_out.content_type->key.data = NULL;
612 r->headers_out.content_type->value.len = 0;
613 r->headers_out.content_type->value.data = NULL;
614
615 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
616
617 if (r->exten.len) {
618#if 0
619 key = ngx_crc(r->exten.data, r->exten.key);
620#endif
621 ngx_http_types_hash_key(key, r->exten);
622
623 type = clcf->types[key].elts;
624 for (i = 0; i < clcf->types[key].nelts; i++) {
625 if (r->exten.len != type[i].exten.len) {
626 continue;
627 }
628
629 if (ngx_memcmp(r->exten.data, type[i].exten.data, r->exten.len)
630 == 0)
631 {
632 r->headers_out.content_type->value = type[i].type;
633 break;
634 }
635 }
636 }
637
638 if (r->headers_out.content_type->value.len == 0) {
639 r->headers_out.content_type->value = clcf->default_type;
640 }
641
642 return NGX_OK;
643}
644
645
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000646int ngx_http_send_header(ngx_http_request_t *r)
647{
Igor Sysoev10fc9ef2003-10-27 08:53:49 +0000648 if (r->main) {
649 return NGX_OK;
650 }
651
Igor Sysoev27c30f92003-11-11 18:13:43 +0000652 if (r->err_ctx) {
Igor Sysoevd59a0472003-11-10 21:09:22 +0000653 r->headers_out.status = r->err_status;
654 r->headers_out.status_line.len = 0;
655 }
656
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000657 return (*ngx_http_top_header_filter)(r);
658}
659
660
661int ngx_http_redirect(ngx_http_request_t *r, int redirect)
662{
663 /* STUB */
664
665 /* log request */
666
Igor Sysoevd581fd52003-05-13 16:02:32 +0000667 ngx_http_close_request(r, 0);
668 return NGX_OK;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000669}
670
671
Igor Sysoev3b30a902003-12-25 20:26:58 +0000672ngx_int_t ngx_http_set_exten(ngx_http_request_t *r)
673{
674 ngx_int_t i;
675
676 r->exten.len = 0;
677 r->exten.data = NULL;
678
679 for (i = r->uri.len - 1; i > 1; i--) {
680 if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') {
681 r->exten.len = r->uri.len - i - 1;
682
683 if (r->exten.len > 0) {
684 if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) {
685 return NGX_ERROR;
686 }
687
688 ngx_cpystrn(r->exten.data, &r->uri.data[i + 1],
689 r->exten.len + 1);
690 }
691
692 break;
693
694 } else if (r->uri.data[i] == '/') {
695 break;
696 }
697 }
698
699 return NGX_OK;
700}
701
702
Igor Sysoev13933252003-05-29 13:02:09 +0000703int ngx_http_internal_redirect(ngx_http_request_t *r,
704 ngx_str_t *uri, ngx_str_t *args)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000705{
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000706 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
707 "internal redirect: \"%s\"", uri->data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000708
Igor Sysoev13933252003-05-29 13:02:09 +0000709 r->uri.len = uri->len;
710 r->uri.data = uri->data;
711
712 if (args) {
713 r->args.len = args->len;
714 r->args.data = args->data;
715 }
716
Igor Sysoev3b30a902003-12-25 20:26:58 +0000717 if (ngx_http_set_exten(r) != NGX_OK) {
718 return NGX_HTTP_INTERNAL_SERVER_ERROR;
Igor Sysoev13933252003-05-29 13:02:09 +0000719 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000720
Igor Sysoev27c30f92003-11-11 18:13:43 +0000721 if (r->err_ctx) {
Igor Sysoevd59a0472003-11-10 21:09:22 +0000722
Igor Sysoev27c30f92003-11-11 18:13:43 +0000723 /* allocate the new modules contexts */
724
Igor Sysoevd59a0472003-11-10 21:09:22 +0000725 r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
726 if (r->ctx == NULL) {
727 return NGX_HTTP_INTERNAL_SERVER_ERROR;
728 }
729
730 } else {
Igor Sysoev27c30f92003-11-11 18:13:43 +0000731
732 /* clear the modules contexts */
733
Igor Sysoevd59a0472003-11-10 21:09:22 +0000734 ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
735 }
Igor Sysoev0a280a32003-10-12 16:49:16 +0000736
737 r->phase = 0;
738 r->phase_handler = 0;
739
Igor Sysoev79a80482003-05-14 17:13:13 +0000740 ngx_http_handler(r);
Igor Sysoev13933252003-05-29 13:02:09 +0000741
Igor Sysoev9760a132003-10-21 07:47:21 +0000742 return NGX_DONE;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000743}
744
745
Igor Sysoev0a280a32003-10-12 16:49:16 +0000746#if 1 /* STUB: test the delay http handler */
747
748int ngx_http_delay_handler(ngx_http_request_t *r)
749{
750 static int on;
751
752 if (on++ == 0) {
Igor Sysoev54498db2004-02-11 17:08:49 +0000753 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
754 "http set delay");
Igor Sysoev0a280a32003-10-12 16:49:16 +0000755 ngx_add_timer(r->connection->write, 10000);
756 return NGX_AGAIN;
757 }
758
759 r->connection->write->timedout = 0;
Igor Sysoev54498db2004-02-11 17:08:49 +0000760 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
761 "http reset delay");
Igor Sysoev0a280a32003-10-12 16:49:16 +0000762 return NGX_DECLINED;
763}
764
765#endif
766
767
Igor Sysoev340b03b2003-07-04 15:10:33 +0000768static int ngx_http_core_init(ngx_cycle_t *cycle)
Igor Sysoevdc479b42003-03-20 16:09:44 +0000769{
Igor Sysoevd404c972003-10-16 20:19:16 +0000770#if 0
Igor Sysoev9d9f58f2003-07-02 18:51:41 +0000771 ngx_http_handler_pt *h;
772 ngx_http_conf_ctx_t *ctx;
773 ngx_http_core_main_conf_t *cmcf;
Igor Sysoevdc479b42003-03-20 16:09:44 +0000774
Igor Sysoev9d9f58f2003-07-02 18:51:41 +0000775 ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
776 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
777
Igor Sysoev0a280a32003-10-12 16:49:16 +0000778 ngx_test_null(h, ngx_push_array(
779 &cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
780 NGX_ERROR);
781 *h = ngx_http_delay_handler;
782#endif
783
Igor Sysoevdc479b42003-03-20 16:09:44 +0000784 return NGX_OK;
785}
786
787
Igor Sysoev6253ca12003-05-27 12:18:54 +0000788static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000789{
Igor Sysoev1c13c662003-05-20 15:37:55 +0000790 int m;
Igor Sysoeva9830112003-05-19 16:39:14 +0000791 char *rv;
792 ngx_http_module_t *module;
793 ngx_conf_t pcf;
Igor Sysoev11dbe972004-03-29 17:43:58 +0000794 ngx_http_conf_ctx_t *ctx, *hctx;
Igor Sysoeva9830112003-05-19 16:39:14 +0000795 ngx_http_core_main_conf_t *cmcf;
796 ngx_http_core_srv_conf_t *cscf, **cscfp;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000797
798 ngx_test_null(ctx,
799 ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
800 NGX_CONF_ERROR);
801
Igor Sysoeva9830112003-05-19 16:39:14 +0000802 hctx = (ngx_http_conf_ctx_t *) cf->ctx;
803 ctx->main_conf = hctx->main_conf;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000804
Igor Sysoeva9830112003-05-19 16:39:14 +0000805 /* the server{}'s srv_conf */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000806
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000807 ngx_test_null(ctx->srv_conf,
808 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
809 NGX_CONF_ERROR);
810
Igor Sysoeva9830112003-05-19 16:39:14 +0000811 /* the server{}'s loc_conf */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000812
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000813 ngx_test_null(ctx->loc_conf,
814 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
815 NGX_CONF_ERROR);
816
Igor Sysoev1c13c662003-05-20 15:37:55 +0000817 for (m = 0; ngx_modules[m]; m++) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000818 if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000819 continue;
820 }
821
Igor Sysoev6253ca12003-05-27 12:18:54 +0000822 module = ngx_modules[m]->ctx;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000823
824 if (module->create_srv_conf) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000825 ngx_test_null(ctx->srv_conf[ngx_modules[m]->ctx_index],
Igor Sysoev890fc962003-07-20 21:15:59 +0000826 module->create_srv_conf(cf),
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000827 NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000828 }
829
830 if (module->create_loc_conf) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000831 ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index],
Igor Sysoev890fc962003-07-20 21:15:59 +0000832 module->create_loc_conf(cf),
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000833 NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000834 }
835 }
836
Igor Sysoeva9830112003-05-19 16:39:14 +0000837 /* create links of the srv_conf's */
838
Igor Sysoev6253ca12003-05-27 12:18:54 +0000839 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
Igor Sysoeva9830112003-05-19 16:39:14 +0000840 cscf->ctx = ctx;
841
Igor Sysoev6253ca12003-05-27 12:18:54 +0000842 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
Igor Sysoeva9830112003-05-19 16:39:14 +0000843 ngx_test_null(cscfp, ngx_push_array(&cmcf->servers), NGX_CONF_ERROR);
844 *cscfp = cscf;
845
846 /* parse inside server{} */
847
Igor Sysoev79a80482003-05-14 17:13:13 +0000848 pcf = *cf;
Igor Sysoev11dbe972004-03-29 17:43:58 +0000849#if 0
Igor Sysoev79a80482003-05-14 17:13:13 +0000850 pctx = cf->ctx;
Igor Sysoev11dbe972004-03-29 17:43:58 +0000851#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000852 cf->ctx = ctx;
Igor Sysoev79a80482003-05-14 17:13:13 +0000853 cf->cmd_type = NGX_HTTP_SRV_CONF;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000854 rv = ngx_conf_parse(cf, NULL);
Igor Sysoev79a80482003-05-14 17:13:13 +0000855 *cf = pcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000856
Igor Sysoev13933252003-05-29 13:02:09 +0000857 if (rv != NGX_CONF_OK) {
858 return rv;
859 }
860
Igor Sysoevd9d0ca12003-11-21 06:30:49 +0000861 ngx_qsort(cscf->locations.elts, (size_t) cscf->locations.nelts,
Igor Sysoev13933252003-05-29 13:02:09 +0000862 sizeof(void *), ngx_cmp_locations);
863
Igor Sysoeva9830112003-05-19 16:39:14 +0000864 return rv;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000865}
866
867
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000868static int ngx_cmp_locations(const void *one, const void *two)
Igor Sysoev13933252003-05-29 13:02:09 +0000869{
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000870 ngx_http_core_loc_conf_t *first = *(ngx_http_core_loc_conf_t **) one;
871 ngx_http_core_loc_conf_t *second = *(ngx_http_core_loc_conf_t **) two;
Igor Sysoev13933252003-05-29 13:02:09 +0000872
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000873 ngx_int_t rc;
874
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000875#if (HAVE_PCRE)
876
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000877 if (first->regex && !second->regex) {
878 /* shift regex matches to the end */
879 return 1;
880 }
881
882 if (first->regex || second->regex) {
883 /* do not sort regex matches */
884 return 0;
885 }
886
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000887#endif
888
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000889 rc = ngx_strcmp(first->name.data, second->name.data);
890
891 if (rc == 0 && second->exact_match) {
892 /* an exact match must be before the same inclusive one */
893 return 1;
894 }
895
896 return rc;
Igor Sysoev13933252003-05-29 13:02:09 +0000897}
898
899
Igor Sysoev6253ca12003-05-27 12:18:54 +0000900static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000901{
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000902 char *rv;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000903 ngx_int_t m;
Igor Sysoevfc5a10a2004-03-09 19:47:07 +0000904 ngx_str_t *value;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000905 ngx_http_module_t *module;
Igor Sysoev74e95c22003-11-09 20:03:38 +0000906 ngx_conf_t pvcf;
907 ngx_http_conf_ctx_t *ctx, *pvctx;
Igor Sysoeva9830112003-05-19 16:39:14 +0000908 ngx_http_core_srv_conf_t *cscf;
909 ngx_http_core_loc_conf_t *clcf, **clcfp;
Igor Sysoevfc5a10a2004-03-09 19:47:07 +0000910#if (HAVE_PCRE)
911 ngx_str_t err;
Igor Sysoev10a543a2004-03-16 07:10:12 +0000912 u_char errstr[NGX_MAX_CONF_ERRSTR];
Igor Sysoevfc5a10a2004-03-09 19:47:07 +0000913#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000914
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000915 if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) {
916 return NGX_CONF_ERROR;
917 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000918
Igor Sysoev74e95c22003-11-09 20:03:38 +0000919 pvctx = (ngx_http_conf_ctx_t *) cf->ctx;
920 ctx->main_conf = pvctx->main_conf;
921 ctx->srv_conf = pvctx->srv_conf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000922
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000923 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
924 if (ctx->loc_conf == NULL) {
925 return NGX_CONF_ERROR;
926 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000927
Igor Sysoev6253ca12003-05-27 12:18:54 +0000928 for (m = 0; ngx_modules[m]; m++) {
929 if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000930 continue;
931 }
932
Igor Sysoev6253ca12003-05-27 12:18:54 +0000933 module = ngx_modules[m]->ctx;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000934
935 if (module->create_loc_conf) {
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000936 ctx->loc_conf[ngx_modules[m]->ctx_index] =
937 module->create_loc_conf(cf);
938 if (ctx->loc_conf[ngx_modules[m]->ctx_index] == NULL) {
939 return NGX_CONF_ERROR;
940 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000941 }
942 }
943
Igor Sysoev6253ca12003-05-27 12:18:54 +0000944 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
Igor Sysoeva9830112003-05-19 16:39:14 +0000945 clcf->loc_conf = ctx->loc_conf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000946
Igor Sysoev3b30a902003-12-25 20:26:58 +0000947 value = cf->args->elts;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000948
949 if (cf->args->nelts == 3) {
950 if (value[1].len == 1 && value[1].data[0] == '=') {
951 clcf->name.len = value[2].len;
952 clcf->name.data = value[2].data;
953 clcf->exact_match = 1;
954
955 } else if ((value[1].len == 1 && value[1].data[0] == '~')
956 || (value[1].len == 2
957 && value[1].data[0] == '~'
958 && value[1].data[1] == '*'))
959 {
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000960#if (HAVE_PCRE)
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000961 err.len = NGX_MAX_CONF_ERRSTR;
962 err.data = errstr;
963
964 clcf->regex = ngx_regex_compile(&value[2],
965 value[1].len == 2 ? NGX_REGEX_CASELESS: 0,
966 cf->pool, &err);
967
968 if (clcf->regex == NULL) {
969 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
970 return NGX_CONF_ERROR;
971 }
972
Igor Sysoev3b30a902003-12-25 20:26:58 +0000973 clcf->name = value[2];
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000974#else
975 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
976 "the using of the regex \"%s\" "
977 "requires PCRE library",
978 value[2].data);
979 return NGX_CONF_ERROR;
980#endif
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000981
982 } else {
983 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
984 "invalid location modifier \"%s\"",
985 value[1].data);
986 return NGX_CONF_ERROR;
987 }
988
989 } else {
990 clcf->name.len = value[1].len;
991 clcf->name.data = value[1].data;
992 }
993
Igor Sysoev6253ca12003-05-27 12:18:54 +0000994 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000995 if (!(clcfp = ngx_push_array(&cscf->locations))) {
996 return NGX_CONF_ERROR;
997 }
Igor Sysoeva9830112003-05-19 16:39:14 +0000998 *clcfp = clcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000999
Igor Sysoev74e95c22003-11-09 20:03:38 +00001000 pvcf = *cf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001001 cf->ctx = ctx;
Igor Sysoev79a80482003-05-14 17:13:13 +00001002 cf->cmd_type = NGX_HTTP_LOC_CONF;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001003 rv = ngx_conf_parse(cf, NULL);
Igor Sysoev74e95c22003-11-09 20:03:38 +00001004 *cf = pvcf;
Igor Sysoev79a80482003-05-14 17:13:13 +00001005
1006 return rv;
1007}
1008
1009
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001010static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev79a80482003-05-14 17:13:13 +00001011{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001012 char *rv;
1013 ngx_conf_t pcf;
1014
1015 pcf = *cf;
1016 cf->handler = ngx_set_type;
1017 cf->handler_conf = conf;
1018 rv = ngx_conf_parse(cf, NULL);
1019 *cf = pcf;
1020
1021 return rv;
1022}
1023
1024
1025static char *ngx_set_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
1026{
1027 ngx_http_core_loc_conf_t *lcf = conf;
Igor Sysoev79a80482003-05-14 17:13:13 +00001028
Igor Sysoev10a543a2004-03-16 07:10:12 +00001029 uint32_t key;
1030 ngx_uint_t i;
Igor Sysoev79a80482003-05-14 17:13:13 +00001031 ngx_str_t *args;
Igor Sysoev865c1502003-11-30 20:03:18 +00001032 ngx_http_type_t *type;
Igor Sysoev79a80482003-05-14 17:13:13 +00001033
1034 if (lcf->types == NULL) {
1035 ngx_test_null(lcf->types,
1036 ngx_palloc(cf->pool, NGX_HTTP_TYPES_HASH_PRIME
1037 * sizeof(ngx_array_t)),
1038 NGX_CONF_ERROR);
1039
1040 for (i = 0; i < NGX_HTTP_TYPES_HASH_PRIME; i++) {
1041 ngx_init_array(lcf->types[i], cf->pool, 5, sizeof(ngx_http_type_t),
1042 NGX_CONF_ERROR);
1043 }
1044 }
1045
1046 args = (ngx_str_t *) cf->args->elts;
1047
1048 for (i = 1; i < cf->args->nelts; i++) {
1049 ngx_http_types_hash_key(key, args[i]);
1050
Igor Sysoev865c1502003-11-30 20:03:18 +00001051 ngx_test_null(type, ngx_push_array(&lcf->types[key]), NGX_CONF_ERROR);
1052 type->exten = args[i];
1053 type->type = args[0];
Igor Sysoev79a80482003-05-14 17:13:13 +00001054 }
1055
1056 return NGX_CONF_OK;
1057}
1058
1059
Igor Sysoev890fc962003-07-20 21:15:59 +00001060static void *ngx_http_core_create_main_conf(ngx_conf_t *cf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001061{
Igor Sysoeva9830112003-05-19 16:39:14 +00001062 ngx_http_core_main_conf_t *cmcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001063
Igor Sysoeva9830112003-05-19 16:39:14 +00001064 ngx_test_null(cmcf,
Igor Sysoevb3e73d82003-10-10 15:10:50 +00001065 ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t)),
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001066 NGX_CONF_ERROR);
1067
Igor Sysoev890fc962003-07-20 21:15:59 +00001068 ngx_init_array(cmcf->servers, cf->pool,
1069 5, sizeof(ngx_http_core_srv_conf_t *),
Igor Sysoevad22e012003-01-15 07:02:27 +00001070 NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001071
Igor Sysoeva9830112003-05-19 16:39:14 +00001072 return cmcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001073}
1074
1075
Igor Sysoev890fc962003-07-20 21:15:59 +00001076static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001077{
Igor Sysoev10a543a2004-03-16 07:10:12 +00001078#if 0
Igor Sysoev6253ca12003-05-27 12:18:54 +00001079 ngx_http_core_main_conf_t *cmcf = conf;
Igor Sysoeva9830112003-05-19 16:39:14 +00001080
Igor Sysoev239baac2003-06-11 15:28:34 +00001081 /* TODO: remove it if no directives */
Igor Sysoev10a543a2004-03-16 07:10:12 +00001082#endif
Igor Sysoeva9830112003-05-19 16:39:14 +00001083
1084 return NGX_CONF_OK;
1085}
1086
1087
Igor Sysoev890fc962003-07-20 21:15:59 +00001088static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf)
Igor Sysoeva9830112003-05-19 16:39:14 +00001089{
1090 ngx_http_core_srv_conf_t *cscf;
1091
1092 ngx_test_null(cscf,
Igor Sysoev890fc962003-07-20 21:15:59 +00001093 ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t)),
Igor Sysoeva9830112003-05-19 16:39:14 +00001094 NGX_CONF_ERROR);
1095
Igor Sysoev890fc962003-07-20 21:15:59 +00001096 ngx_init_array(cscf->locations, cf->pool,
1097 5, sizeof(void *), NGX_CONF_ERROR);
1098 ngx_init_array(cscf->listen, cf->pool, 5, sizeof(ngx_http_listen_t),
Igor Sysoeva9830112003-05-19 16:39:14 +00001099 NGX_CONF_ERROR);
Igor Sysoev890fc962003-07-20 21:15:59 +00001100 ngx_init_array(cscf->server_names, cf->pool,
1101 5, sizeof(ngx_http_server_name_t), NGX_CONF_ERROR);
Igor Sysoeva9830112003-05-19 16:39:14 +00001102
Igor Sysoev10a543a2004-03-16 07:10:12 +00001103 cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
1104 cscf->post_accept_timeout = NGX_CONF_UNSET_MSEC;
1105 cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
1106 cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
1107 cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
Igor Sysoev187fcd82003-05-23 11:53:01 +00001108 cscf->large_client_header = NGX_CONF_UNSET;
1109
Igor Sysoeva9830112003-05-19 16:39:14 +00001110 return cscf;
1111}
1112
1113
Igor Sysoev890fc962003-07-20 21:15:59 +00001114static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
Igor Sysoeva9830112003-05-19 16:39:14 +00001115 void *parent, void *child)
1116{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001117 ngx_http_core_srv_conf_t *prev = parent;
1118 ngx_http_core_srv_conf_t *conf = child;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001119
1120 ngx_http_listen_t *l;
Igor Sysoevad22e012003-01-15 07:02:27 +00001121 ngx_http_server_name_t *n;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001122
Igor Sysoev7578ec92003-06-02 15:24:30 +00001123 /* TODO: it does not merge, it inits only */
Igor Sysoeva9830112003-05-19 16:39:14 +00001124
1125 if (conf->listen.nelts == 0) {
1126 ngx_test_null(l, ngx_push_array(&conf->listen), NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001127 l->addr = INADDR_ANY;
Igor Sysoev1c104622003-06-03 15:42:58 +00001128#if (WIN32)
1129 l->port = 80;
1130#else
Igor Sysoev7578ec92003-06-02 15:24:30 +00001131 /* STUB: getuid() should be cached */
1132 l->port = (getuid() == 0) ? 80 : 8000;
Igor Sysoev1c104622003-06-03 15:42:58 +00001133#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001134 l->family = AF_INET;
1135 }
1136
Igor Sysoeva9830112003-05-19 16:39:14 +00001137 if (conf->server_names.nelts == 0) {
1138 ngx_test_null(n, ngx_push_array(&conf->server_names), NGX_CONF_ERROR);
Igor Sysoev890fc962003-07-20 21:15:59 +00001139 ngx_test_null(n->name.data, ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN),
Igor Sysoevad22e012003-01-15 07:02:27 +00001140 NGX_CONF_ERROR);
Igor Sysoev13933252003-05-29 13:02:09 +00001141
Igor Sysoev10a543a2004-03-16 07:10:12 +00001142 if (gethostname((char *) n->name.data, NGX_MAXHOSTNAMELEN) == -1) {
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00001143 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
1144 "gethostname() failed");
1145 return NGX_CONF_ERROR;
Igor Sysoevad22e012003-01-15 07:02:27 +00001146 }
Igor Sysoev13933252003-05-29 13:02:09 +00001147
Igor Sysoevad22e012003-01-15 07:02:27 +00001148 n->name.len = ngx_strlen(n->name.data);
1149 n->core_srv_conf = conf;
1150 }
1151
Igor Sysoev239baac2003-06-11 15:28:34 +00001152 ngx_conf_merge_size_value(conf->connection_pool_size,
1153 prev->connection_pool_size, 16384);
1154 ngx_conf_merge_msec_value(conf->post_accept_timeout,
1155 prev->post_accept_timeout, 30000);
Igor Sysoev187fcd82003-05-23 11:53:01 +00001156 ngx_conf_merge_size_value(conf->request_pool_size,
1157 prev->request_pool_size, 16384);
1158 ngx_conf_merge_msec_value(conf->client_header_timeout,
1159 prev->client_header_timeout, 60000);
1160 ngx_conf_merge_size_value(conf->client_header_buffer_size,
1161 prev->client_header_buffer_size, 1024);
1162 ngx_conf_merge_value(conf->large_client_header,
1163 prev->large_client_header, 1);
1164
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001165 return NGX_CONF_OK;
1166}
1167
1168
Igor Sysoev890fc962003-07-20 21:15:59 +00001169static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001170{
1171 ngx_http_core_loc_conf_t *lcf;
1172
1173 ngx_test_null(lcf,
Igor Sysoev890fc962003-07-20 21:15:59 +00001174 ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t)),
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001175 NGX_CONF_ERROR);
1176
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001177 /* set by ngx_pcalloc():
Igor Sysoev79a80482003-05-14 17:13:13 +00001178
Igor Sysoev10a543a2004-03-16 07:10:12 +00001179 lcf->root.len = 0;
1180 lcf->root.data = NULL;
Igor Sysoev79a80482003-05-14 17:13:13 +00001181 lcf->types = NULL;
Igor Sysoev6253ca12003-05-27 12:18:54 +00001182 lcf->default_type.len = 0;
1183 lcf->default_type.data = NULL;
Igor Sysoev9d639522003-07-07 06:11:50 +00001184 lcf->err_log = NULL;
Igor Sysoev74e95c22003-11-09 20:03:38 +00001185 lcf->error_pages = NULL;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001186
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001187 lcf->regex = NULL;
1188 lcf->exact_match = 0;
1189 lcf->auto_redirect = 0;
Igor Sysoev10a543a2004-03-16 07:10:12 +00001190 lcf->alias = 0;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001191
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001192 */
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001193
Igor Sysoevae02c192004-03-19 05:25:53 +00001194 lcf->client_max_body_size = NGX_CONF_UNSET_SIZE;
Igor Sysoevdbb27762004-04-01 16:20:53 +00001195 lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
Igor Sysoev10a543a2004-03-16 07:10:12 +00001196 lcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
Igor Sysoev5bf3d252003-10-22 07:05:29 +00001197 lcf->sendfile = NGX_CONF_UNSET;
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001198 lcf->tcp_nopush = NGX_CONF_UNSET;
Igor Sysoev10a543a2004-03-16 07:10:12 +00001199 lcf->send_timeout = NGX_CONF_UNSET_MSEC;
1200 lcf->send_lowat = NGX_CONF_UNSET_SIZE;
1201 lcf->discarded_buffer_size = NGX_CONF_UNSET_SIZE;
1202 lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
1203 lcf->lingering_time = NGX_CONF_UNSET_MSEC;
1204 lcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
Igor Sysoev79a80482003-05-14 17:13:13 +00001205
Igor Sysoev12b4b002003-10-24 06:53:41 +00001206 lcf->msie_padding = NGX_CONF_UNSET;
1207
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001208 return lcf;
1209}
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001210
Igor Sysoev79a80482003-05-14 17:13:13 +00001211
1212static ngx_http_type_t default_types[] = {
1213 { ngx_string("html"), ngx_string("text/html") },
1214 { ngx_string("gif"), ngx_string("image/gif") },
1215 { ngx_string("jpg"), ngx_string("image/jpeg") },
1216 { ngx_null_string, ngx_null_string }
1217};
1218
1219
Igor Sysoev890fc962003-07-20 21:15:59 +00001220static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
Igor Sysoeve2a31542003-04-08 15:40:10 +00001221 void *parent, void *child)
1222{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001223 ngx_http_core_loc_conf_t *prev = parent;
1224 ngx_http_core_loc_conf_t *conf = child;
Igor Sysoev79a80482003-05-14 17:13:13 +00001225
1226 int i, key;
1227 ngx_http_type_t *t;
1228
Igor Sysoev10a543a2004-03-16 07:10:12 +00001229 ngx_conf_merge_str_value(conf->root, prev->root, "html");
Igor Sysoev79a80482003-05-14 17:13:13 +00001230
1231 if (conf->types == NULL) {
1232 if (prev->types) {
1233 conf->types = prev->types;
1234
1235 } else {
1236 ngx_test_null(conf->types,
Igor Sysoev890fc962003-07-20 21:15:59 +00001237 ngx_palloc(cf->pool, NGX_HTTP_TYPES_HASH_PRIME
Igor Sysoev79a80482003-05-14 17:13:13 +00001238 * sizeof(ngx_array_t)),
1239 NGX_CONF_ERROR);
1240
1241 for (i = 0; i < NGX_HTTP_TYPES_HASH_PRIME; i++) {
Igor Sysoev890fc962003-07-20 21:15:59 +00001242 ngx_init_array(conf->types[i], cf->pool,
1243 5, sizeof(ngx_http_type_t), NGX_CONF_ERROR);
Igor Sysoev79a80482003-05-14 17:13:13 +00001244 }
1245
1246 for (i = 0; default_types[i].exten.len; i++) {
1247 ngx_http_types_hash_key(key, default_types[i].exten);
1248
1249 ngx_test_null(t, ngx_push_array(&conf->types[key]),
1250 NGX_CONF_ERROR);
1251 t->exten.len = default_types[i].exten.len;
1252 t->exten.data = default_types[i].exten.data;
1253 t->type.len = default_types[i].type.len;
1254 t->type.data = default_types[i].type.data;
1255 }
1256 }
1257 }
1258
Igor Sysoev890fc962003-07-20 21:15:59 +00001259 if (conf->err_log == NULL) {
1260 if (prev->err_log) {
1261 conf->err_log = prev->err_log;
1262 } else {
Igor Sysoev630ad0c2004-04-16 05:14:16 +00001263 conf->err_log = cf->cycle->new_log;
Igor Sysoev890fc962003-07-20 21:15:59 +00001264 }
1265 }
1266
Igor Sysoev74e95c22003-11-09 20:03:38 +00001267 if (conf->error_pages == NULL && prev->error_pages) {
1268 conf->error_pages = prev->error_pages;
1269 }
1270
Igor Sysoev6253ca12003-05-27 12:18:54 +00001271 ngx_conf_merge_str_value(conf->default_type,
1272 prev->default_type, "text/plain");
1273
Igor Sysoevae02c192004-03-19 05:25:53 +00001274 ngx_conf_merge_size_value(conf->client_max_body_size,
1275 prev->client_max_body_size, 10 * 1024 * 1024);
Igor Sysoevdbb27762004-04-01 16:20:53 +00001276 ngx_conf_merge_size_value(conf->client_body_buffer_size,
1277 prev->client_body_buffer_size, 8192);
Igor Sysoev2b0c76c2003-10-27 21:01:00 +00001278 ngx_conf_merge_msec_value(conf->client_body_timeout,
Igor Sysoev7af6b162004-02-09 07:46:43 +00001279 prev->client_body_timeout, 60000);
Igor Sysoev5bf3d252003-10-22 07:05:29 +00001280 ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001281 ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
Igor Sysoev7af6b162004-02-09 07:46:43 +00001282 ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
Igor Sysoevb5faed22003-10-29 08:30:44 +00001283 ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
Igor Sysoeva9830112003-05-19 16:39:14 +00001284 ngx_conf_merge_size_value(conf->discarded_buffer_size,
1285 prev->discarded_buffer_size, 1500);
Igor Sysoev187fcd82003-05-23 11:53:01 +00001286 ngx_conf_merge_msec_value(conf->keepalive_timeout,
1287 prev->keepalive_timeout, 70000);
1288 ngx_conf_merge_msec_value(conf->lingering_time,
1289 prev->lingering_time, 30000);
1290 ngx_conf_merge_msec_value(conf->lingering_timeout,
1291 prev->lingering_timeout, 5000);
Igor Sysoev79a80482003-05-14 17:13:13 +00001292
Igor Sysoev12b4b002003-10-24 06:53:41 +00001293 ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
1294
Igor Sysoev865c1502003-11-30 20:03:18 +00001295 if (conf->open_files == NULL) {
1296 conf->open_files = prev->open_files;
1297 }
1298
Igor Sysoeve2a31542003-04-08 15:40:10 +00001299 return NGX_CONF_OK;
1300}
1301
Igor Sysoev79a80482003-05-14 17:13:13 +00001302
Igor Sysoev6253ca12003-05-27 12:18:54 +00001303static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001304{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001305 ngx_http_core_srv_conf_t *scf = conf;
Igor Sysoeva9830112003-05-19 16:39:14 +00001306
Igor Sysoev10a543a2004-03-16 07:10:12 +00001307 u_char *addr;
Igor Sysoev1c13c662003-05-20 15:37:55 +00001308 u_int p;
Igor Sysoev6253ca12003-05-27 12:18:54 +00001309 struct hostent *h;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001310 ngx_str_t *args;
1311 ngx_http_listen_t *ls;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001312
Igor Sysoev239baac2003-06-11 15:28:34 +00001313 /* TODO: check duplicate 'listen' directives,
Igor Sysoev13933252003-05-29 13:02:09 +00001314 add resolved name to server names ??? */
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001315
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001316 ngx_test_null(ls, ngx_push_array(&scf->listen), NGX_CONF_ERROR);
1317
1318 /* AF_INET only */
1319
1320 ls->family = AF_INET;
Igor Sysoev10a543a2004-03-16 07:10:12 +00001321 ls->default_server = 0;
Igor Sysoevfe5cb6b2003-01-29 07:25:51 +00001322 ls->file_name = cf->conf_file->file.name;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001323 ls->line = cf->conf_file->line;
1324
Igor Sysoev13933252003-05-29 13:02:09 +00001325 args = cf->args->elts;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001326 addr = args[1].data;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001327
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001328 for (p = 0; p < args[1].len; p++) {
1329 if (addr[p] == ':') {
1330 addr[p++] = '\0';
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001331 break;
1332 }
1333 }
1334
1335 if (p == args[1].len) {
Igor Sysoev13933252003-05-29 13:02:09 +00001336 /* no ":" in the "listen" */
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001337 p = 0;
1338 }
1339
1340 ls->port = ngx_atoi(&addr[p], args[1].len - p);
Igor Sysoev13933252003-05-29 13:02:09 +00001341 if (ls->port == NGX_ERROR && p == 0) {
1342
1343 /* "listen host" */
1344 ls->port = 80;
1345
1346 } else if ((ls->port == NGX_ERROR && p != 0) /* "listen host:NONNUMBER" */
1347 || (ls->port < 1 || ls->port > 65536)) { /* "listen 99999" */
1348
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00001349 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1350 "invalid port \"%s\" in \"%s\" directive, "
1351 "it must be a number between 1 and 65535",
1352 &addr[p], cmd->name.data);
1353
1354 return NGX_CONF_ERROR;
Igor Sysoev13933252003-05-29 13:02:09 +00001355
1356 } else if (p == 0) {
1357 ls->addr = INADDR_ANY;
1358 return NGX_CONF_OK;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001359 }
1360
Igor Sysoev10a543a2004-03-16 07:10:12 +00001361 ls->addr = inet_addr((const char *) addr);
Igor Sysoev13933252003-05-29 13:02:09 +00001362 if (ls->addr == INADDR_NONE) {
Igor Sysoev10a543a2004-03-16 07:10:12 +00001363 h = gethostbyname((const char *) addr);
Igor Sysoev13933252003-05-29 13:02:09 +00001364
1365 if (h == NULL || h->h_addr_list[0] == NULL) {
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00001366 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1367 "can not resolve host \"%s\" "
1368 "in \"%s\" directive", addr, cmd->name.data);
1369 return NGX_CONF_ERROR;
Igor Sysoev13933252003-05-29 13:02:09 +00001370 }
1371
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001372 ls->addr = *(in_addr_t *)(h->h_addr_list[0]);
Igor Sysoev13933252003-05-29 13:02:09 +00001373 }
1374
1375 return NGX_CONF_OK;
1376}
1377
1378
1379static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1380{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001381 ngx_http_core_srv_conf_t *scf = conf;
Igor Sysoev13933252003-05-29 13:02:09 +00001382
Igor Sysoev10a543a2004-03-16 07:10:12 +00001383 ngx_uint_t i;
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001384 ngx_str_t *value;
Igor Sysoev13933252003-05-29 13:02:09 +00001385 ngx_http_server_name_t *sn;
1386
1387 /* TODO: several names */
1388 /* TODO: warn about duplicate 'server_name' directives */
1389
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001390 value = cf->args->elts;
Igor Sysoev13933252003-05-29 13:02:09 +00001391
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001392 for (i = 1; i < cf->args->nelts; i++) {
1393 if (value[i].len == 0) {
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00001394 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1395 "server name \"%s\" is invalid "
1396 "in \"%s\" directive",
1397 value[i].data, cmd->name.data);
1398 return NGX_CONF_ERROR;
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001399 }
Igor Sysoev13933252003-05-29 13:02:09 +00001400
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001401 ngx_test_null(sn, ngx_push_array(&scf->server_names), NGX_CONF_ERROR);
1402
1403 sn->name.len = value[i].len;
1404 sn->name.data = value[i].data;
1405 sn->core_srv_conf = scf;
1406 }
Igor Sysoev13933252003-05-29 13:02:09 +00001407
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001408 return NGX_CONF_OK;
1409}
Igor Sysoev9d639522003-07-07 06:11:50 +00001410
1411
Igor Sysoev10a543a2004-03-16 07:10:12 +00001412static char *ngx_set_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1413{
1414 ngx_http_core_loc_conf_t *lcf = conf;
1415
1416 ngx_uint_t alias;
1417 ngx_str_t *value;
1418
1419 alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;
1420
1421 if (lcf->root.data) {
Igor Sysoeva741f8d2004-03-30 20:31:58 +00001422
1423 /* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */
1424
1425 if ((ngx_uint_t) lcf->alias == alias) {
Igor Sysoev10a543a2004-03-16 07:10:12 +00001426 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1427 "\"%s\" directive is duplicate",
1428 cmd->name.data);
1429 } else {
1430 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1431 "\"%s\" directive is duplicate, "
1432 "\"%s\" directive is specified before",
1433 cmd->name.data, lcf->alias ? "alias" : "root");
1434 }
1435
1436 return NGX_CONF_ERROR;
1437 }
1438
1439 value = cf->args->elts;
1440
1441 lcf->alias = alias;
1442 lcf->root = value[1];
1443
1444 return NGX_CONF_OK;
1445}
1446
1447
Igor Sysoev74e95c22003-11-09 20:03:38 +00001448static char *ngx_set_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1449{
1450 ngx_http_core_loc_conf_t *lcf = conf;
1451
Igor Sysoev10a543a2004-03-16 07:10:12 +00001452 ngx_uint_t i;
Igor Sysoev74e95c22003-11-09 20:03:38 +00001453 ngx_str_t *value;
1454 ngx_http_err_page_t *err;
1455
1456 if (lcf->error_pages == NULL) {
1457 lcf->error_pages = ngx_create_array(cf->pool, 5,
1458 sizeof(ngx_http_err_page_t));
1459 if (lcf->error_pages == NULL) {
1460 return NGX_CONF_ERROR;
1461 }
1462 }
1463
1464 value = cf->args->elts;
1465
1466 for (i = 1; i < cf->args->nelts - 1; i++) {
1467 ngx_test_null(err, ngx_push_array(lcf->error_pages), NGX_CONF_ERROR);
1468 err->code = ngx_atoi(value[i].data, value[i].len);
1469 if (err->code == NGX_ERROR) {
1470 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1471 "invalid value \"%s\"", value[i].data);
1472 return NGX_CONF_ERROR;
1473 }
1474
1475 if (err->code < 400 || err->code > 599) {
1476 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1477 "value \"%s\" must be between 400 and 599",
1478 value[i].data);
1479 return NGX_CONF_ERROR;
1480 }
1481
1482 err->uri = value[cf->args->nelts - 1];
1483 }
1484
1485 return NGX_CONF_OK;
1486}
1487
1488
Igor Sysoev9d639522003-07-07 06:11:50 +00001489static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1490{
1491 ngx_http_core_loc_conf_t *lcf = conf;
1492
Igor Sysoev03420a62004-01-20 20:40:08 +00001493 if (!(lcf->err_log = ngx_log_create_errlog(cf->cycle, cf->args))) {
1494 return NGX_CONF_ERROR;
1495 }
Igor Sysoev9d639522003-07-07 06:11:50 +00001496
Igor Sysoev03420a62004-01-20 20:40:08 +00001497 return ngx_set_error_log_levels(cf, lcf->err_log);
Igor Sysoev9d639522003-07-07 06:11:50 +00001498}
Igor Sysoevb5faed22003-10-29 08:30:44 +00001499
1500
1501static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data)
1502{
Igor Sysoevb5faed22003-10-29 08:30:44 +00001503#if (HAVE_LOWAT_EVENT)
1504
Igor Sysoev10a543a2004-03-16 07:10:12 +00001505 ssize_t *np = data;
Igor Sysoev74e95c22003-11-09 20:03:38 +00001506
Igor Sysoevb5faed22003-10-29 08:30:44 +00001507 if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
1508 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1509 "\"send_lowat\" must be less than %d "
1510 "(sysctl net.inet.tcp.sendspace)",
1511 ngx_freebsd_net_inet_tcp_sendspace);
1512
1513 return NGX_CONF_ERROR;
1514 }
1515
1516#else
1517
1518 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1519 "\"send_lowat\" is not supported, ignored");
1520
1521#endif
1522
1523 return NGX_CONF_OK;
1524}