blob: 46c90f8da441c778c97bae834e316cc86607ec6a [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 Sysoev74e95c22003-11-09 20:03:38 +000031static char *ngx_set_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoev890fc962003-07-20 21:15:59 +000032static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000033
Igor Sysoevb5faed22003-10-29 08:30:44 +000034static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data);
35
36static ngx_conf_post_t ngx_http_lowat_post = { ngx_http_lowat_check } ;
37
Igor Sysoev4e9393a2003-01-09 05:36:00 +000038
39static ngx_command_t ngx_http_core_commands[] = {
40
Igor Sysoev865c1502003-11-30 20:03:18 +000041 { ngx_string("server"),
42 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
43 ngx_server_block,
44 0,
45 0,
46 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +000047
Igor Sysoev865c1502003-11-30 20:03:18 +000048 { ngx_string("connection_pool_size"),
49 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
50 ngx_conf_set_size_slot,
51 NGX_HTTP_SRV_CONF_OFFSET,
52 offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
53 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +000054
Igor Sysoev865c1502003-11-30 20:03:18 +000055 { ngx_string("post_accept_timeout"),
56 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
57 ngx_conf_set_msec_slot,
58 NGX_HTTP_SRV_CONF_OFFSET,
59 offsetof(ngx_http_core_srv_conf_t, post_accept_timeout),
60 NULL },
Igor Sysoev187fcd82003-05-23 11:53:01 +000061
Igor Sysoev865c1502003-11-30 20:03:18 +000062 { ngx_string("request_pool_size"),
63 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
64 ngx_conf_set_size_slot,
65 NGX_HTTP_SRV_CONF_OFFSET,
66 offsetof(ngx_http_core_srv_conf_t, request_pool_size),
67 NULL },
Igor Sysoev187fcd82003-05-23 11:53:01 +000068
Igor Sysoev865c1502003-11-30 20:03:18 +000069 { ngx_string("client_header_timeout"),
70 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
71 ngx_conf_set_msec_slot,
72 NGX_HTTP_SRV_CONF_OFFSET,
73 offsetof(ngx_http_core_srv_conf_t, client_header_timeout),
74 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +000075
Igor Sysoev865c1502003-11-30 20:03:18 +000076 { ngx_string("client_header_buffer_size"),
77 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
78 ngx_conf_set_size_slot,
79 NGX_HTTP_SRV_CONF_OFFSET,
80 offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
81 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +000082
Igor Sysoev865c1502003-11-30 20:03:18 +000083 { ngx_string("large_client_header"),
84 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
85 ngx_conf_set_flag_slot,
86 NGX_HTTP_SRV_CONF_OFFSET,
87 offsetof(ngx_http_core_srv_conf_t, large_client_header),
88 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +000089
Igor Sysoev865c1502003-11-30 20:03:18 +000090 { ngx_string("location"),
91 NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
92 ngx_location_block,
93 NGX_HTTP_SRV_CONF_OFFSET,
94 0,
95 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +000096
Igor Sysoev865c1502003-11-30 20:03:18 +000097 { ngx_string("listen"),
Igor Sysoev7578ec92003-06-02 15:24:30 +000098#if 0
Igor Sysoev865c1502003-11-30 20:03:18 +000099 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
Igor Sysoev7578ec92003-06-02 15:24:30 +0000100#else
Igor Sysoev865c1502003-11-30 20:03:18 +0000101 NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
Igor Sysoev7578ec92003-06-02 15:24:30 +0000102#endif
Igor Sysoev865c1502003-11-30 20:03:18 +0000103 ngx_set_listen,
104 NGX_HTTP_SRV_CONF_OFFSET,
105 0,
106 NULL },
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000107
Igor Sysoev865c1502003-11-30 20:03:18 +0000108 { ngx_string("server_name"),
109 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
110 ngx_set_server_name,
111 NGX_HTTP_SRV_CONF_OFFSET,
112 0,
113 NULL },
Igor Sysoev13933252003-05-29 13:02:09 +0000114
Igor Sysoev865c1502003-11-30 20:03:18 +0000115 { ngx_string("types"),
116 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
117 |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
118 ngx_types_block,
119 NGX_HTTP_LOC_CONF_OFFSET,
120 0,
121 NULL },
Igor Sysoev79a80482003-05-14 17:13:13 +0000122
Igor Sysoev865c1502003-11-30 20:03:18 +0000123 { ngx_string("default_type"),
124 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
125 ngx_conf_set_str_slot,
126 NGX_HTTP_LOC_CONF_OFFSET,
127 offsetof(ngx_http_core_loc_conf_t, default_type),
128 NULL },
Igor Sysoev6253ca12003-05-27 12:18:54 +0000129
Igor Sysoev865c1502003-11-30 20:03:18 +0000130 { ngx_string("root"),
131 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
132 ngx_conf_set_str_slot,
133 NGX_HTTP_LOC_CONF_OFFSET,
134 offsetof(ngx_http_core_loc_conf_t, doc_root),
135 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000136
Igor Sysoev865c1502003-11-30 20:03:18 +0000137 { ngx_string("client_body_timeout"),
138 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
139 ngx_conf_set_msec_slot,
140 NGX_HTTP_LOC_CONF_OFFSET,
141 offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
142 NULL },
Igor Sysoev2b0c76c2003-10-27 21:01:00 +0000143
Igor Sysoev865c1502003-11-30 20:03:18 +0000144 { ngx_string("sendfile"),
145 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
146 ngx_conf_set_flag_slot,
147 NGX_HTTP_LOC_CONF_OFFSET,
148 offsetof(ngx_http_core_loc_conf_t, sendfile),
149 NULL },
Igor Sysoev5bf3d252003-10-22 07:05:29 +0000150
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000151 { ngx_string("tcp_nopush"),
152 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
153 ngx_conf_set_flag_slot,
154 NGX_HTTP_LOC_CONF_OFFSET,
155 offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
156 NULL },
157
Igor Sysoev865c1502003-11-30 20:03:18 +0000158 { ngx_string("send_timeout"),
159 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
160 ngx_conf_set_msec_slot,
161 NGX_HTTP_LOC_CONF_OFFSET,
162 offsetof(ngx_http_core_loc_conf_t, send_timeout),
163 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000164
Igor Sysoev865c1502003-11-30 20:03:18 +0000165 { ngx_string("send_lowat"),
166 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
167 ngx_conf_set_size_slot,
168 NGX_HTTP_LOC_CONF_OFFSET,
169 offsetof(ngx_http_core_loc_conf_t, send_lowat),
170 &ngx_http_lowat_post },
Igor Sysoevb5faed22003-10-29 08:30:44 +0000171
Igor Sysoev865c1502003-11-30 20:03:18 +0000172 { ngx_string("keepalive_timeout"),
173 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
174 ngx_conf_set_msec_slot,
175 NGX_HTTP_LOC_CONF_OFFSET,
176 offsetof(ngx_http_core_loc_conf_t, keepalive_timeout),
177 NULL },
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000178
Igor Sysoev865c1502003-11-30 20:03:18 +0000179 { ngx_string("lingering_time"),
180 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
181 ngx_conf_set_msec_slot,
182 NGX_HTTP_LOC_CONF_OFFSET,
183 offsetof(ngx_http_core_loc_conf_t, lingering_time),
184 NULL },
Igor Sysoevb7387572003-03-11 20:38:13 +0000185
Igor Sysoev865c1502003-11-30 20:03:18 +0000186 { ngx_string("lingering_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, lingering_timeout),
191 NULL },
Igor Sysoevb7387572003-03-11 20:38:13 +0000192
Igor Sysoev865c1502003-11-30 20:03:18 +0000193 { ngx_string("msie_padding"),
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, msie_padding),
198 NULL },
Igor Sysoev12b4b002003-10-24 06:53:41 +0000199
Igor Sysoev865c1502003-11-30 20:03:18 +0000200 { ngx_string("error_page"),
201 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
202 ngx_set_error_page,
203 NGX_HTTP_LOC_CONF_OFFSET,
204 0,
205 NULL },
Igor Sysoev74e95c22003-11-09 20:03:38 +0000206
Igor Sysoev865c1502003-11-30 20:03:18 +0000207 { ngx_string("error_log"),
208 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
209 ngx_set_error_log,
210 NGX_HTTP_LOC_CONF_OFFSET,
211 0,
212 NULL },
Igor Sysoev890fc962003-07-20 21:15:59 +0000213
Igor Sysoev865c1502003-11-30 20:03:18 +0000214 { ngx_string("open_file_cache"),
215 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE4,
216 ngx_http_set_cache_slot,
217 NGX_HTTP_LOC_CONF_OFFSET,
218 offsetof(ngx_http_core_loc_conf_t, open_files),
219 NULL },
220
221 ngx_null_command
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000222};
223
224
225ngx_http_module_t ngx_http_core_module_ctx = {
Igor Sysoev78329332003-11-10 17:17:31 +0000226 NULL, /* pre conf */
227
Igor Sysoeva9830112003-05-19 16:39:14 +0000228 ngx_http_core_create_main_conf, /* create main configuration */
229 ngx_http_core_init_main_conf, /* init main configuration */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000230
Igor Sysoeva9830112003-05-19 16:39:14 +0000231 ngx_http_core_create_srv_conf, /* create server configuration */
232 ngx_http_core_merge_srv_conf, /* merge server configuration */
233
234 ngx_http_core_create_loc_conf, /* create location configuration */
235 ngx_http_core_merge_loc_conf /* merge location configuration */
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000236};
237
238
239ngx_module_t ngx_http_core_module = {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000240 NGX_MODULE,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000241 &ngx_http_core_module_ctx, /* module context */
242 ngx_http_core_commands, /* module directives */
Igor Sysoev6253ca12003-05-27 12:18:54 +0000243 NGX_HTTP_MODULE, /* module type */
Igor Sysoev96c56c92003-07-02 14:41:17 +0000244 ngx_http_core_init, /* init module */
Igor Sysoev340b03b2003-07-04 15:10:33 +0000245 NULL /* init child */
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000246};
247
248
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000249void ngx_http_handler(ngx_http_request_t *r)
250{
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000251 ngx_http_log_ctx_t *lcx;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000252
253 r->connection->unexpected_eof = 0;
254
Igor Sysoev7578ec92003-06-02 15:24:30 +0000255 lcx = r->connection->log->data;
256 lcx->action = NULL;
257
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000258 switch (r->headers_in.connection_type) {
259 case 0:
260 if (r->http_version > NGX_HTTP_VERSION_10) {
261 r->keepalive = 1;
262 } else {
Igor Sysoev9760a132003-10-21 07:47:21 +0000263 r->keepalive = 0;
264 }
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000265 break;
266
267 case NGX_HTTP_CONNECTION_CLOSE:
268 r->keepalive = 0;
269 break;
270
271 case NGX_HTTP_CONNECTION_KEEP_ALIVE:
272 r->keepalive = 1;
273 break;
Igor Sysoev9760a132003-10-21 07:47:21 +0000274 }
275
Igor Sysoev10fc9ef2003-10-27 08:53:49 +0000276#if 0
Igor Sysoevdc9dd432003-10-22 16:38:26 +0000277 /* TEST STUB */ r->http_version = NGX_HTTP_VERSION_10;
Igor Sysoev9760a132003-10-21 07:47:21 +0000278 /* TEST STUB */ r->keepalive = 0;
279#endif
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000280
281 if (r->headers_in.content_length_n > 0) {
282 r->lingering_close = 1;
Igor Sysoev9760a132003-10-21 07:47:21 +0000283
284 } else {
285 r->lingering_close = 0;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000286 }
287
Igor Sysoev9760a132003-10-21 07:47:21 +0000288#if 0
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000289 /* TEST STUB */ r->lingering_close = 1;
Igor Sysoev9760a132003-10-21 07:47:21 +0000290#endif
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000291
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000292 r->connection->write->event_handler = ngx_http_phase_event_handler;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000293
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000294 ngx_http_run_phases(r);
295
296 return;
297}
Igor Sysoeve2a31542003-04-08 15:40:10 +0000298
299
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000300static void ngx_http_phase_event_handler(ngx_event_t *ev)
301{
302 ngx_connection_t *c;
303 ngx_http_request_t *r;
304
305 c = ev->data;
306 r = c->data;
307
Igor Sysoev0a280a32003-10-12 16:49:16 +0000308 ngx_log_debug(ev->log, "phase event handler");
309
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000310 ngx_http_run_phases(r);
311
312 return;
313}
314
315
316static void ngx_http_run_phases(ngx_http_request_t *r)
317{
Igor Sysoev865c1502003-11-30 20:03:18 +0000318 char *path;
319 ngx_int_t rc;
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000320 ngx_http_handler_pt *h;
Igor Sysoev865c1502003-11-30 20:03:18 +0000321 ngx_http_core_loc_conf_t *clcf;
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000322 ngx_http_core_main_conf_t *cmcf;
323
324 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
325
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000326 for (/* void */; r->phase < NGX_HTTP_LAST_PHASE; r->phase++) {
327
Igor Sysoev865c1502003-11-30 20:03:18 +0000328 if (r->phase == NGX_HTTP_CONTENT_PHASE && r->content_handler) {
329 r->connection->write->event_handler = ngx_http_empty_handler;
330 rc = r->content_handler(r);
331 ngx_http_finalize_request(r, rc);
332 return;
333 }
334
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000335 h = cmcf->phases[r->phase].handlers.elts;
336 for (r->phase_handler = cmcf->phases[r->phase].handlers.nelts - 1;
337 r->phase_handler >= 0;
338 r->phase_handler--)
339 {
340 rc = h[r->phase_handler](r);
341
Igor Sysoev9760a132003-10-21 07:47:21 +0000342 if (rc == NGX_DONE) {
Igor Sysoev865c1502003-11-30 20:03:18 +0000343
344 /*
345 * we should never use r here because
346 * it could point to already freed data
347 */
348
Igor Sysoev9760a132003-10-21 07:47:21 +0000349 return;
350 }
351
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000352 if (rc == NGX_DECLINED) {
353 continue;
354 }
355
Igor Sysoev865c1502003-11-30 20:03:18 +0000356 if (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_ERROR) {
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000357 ngx_http_finalize_request(r, rc);
358 return;
359 }
360
Igor Sysoeve3466a42003-12-15 13:57:13 +0000361 if (r->phase == NGX_HTTP_CONTENT_PHASE) {
362 ngx_http_finalize_request(r, rc);
363 return;
364 }
365
366 if (rc == NGX_AGAIN) {
Igor Sysoev865c1502003-11-30 20:03:18 +0000367 return;
368 }
369
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000370 if (rc == NGX_OK && cmcf->phases[r->phase].type == NGX_OK) {
371 break;
372 }
373 }
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000374 }
375
Igor Sysoev865c1502003-11-30 20:03:18 +0000376
377 if (r->uri.data[r->uri.len - 1] == '/') {
378
379 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
380
381 if (!(path = ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len))) {
382 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
383 return;
384 }
385
386 ngx_cpystrn(ngx_cpymem(path, clcf->doc_root.data, clcf->doc_root.len),
387 r->uri.data, r->uri.len + 1);
388
389 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
390 "directory index of \"%s\" is forbidden", path);
391
392 ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000393 return;
394 }
395
Igor Sysoev865c1502003-11-30 20:03:18 +0000396 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found");
397
398 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000399 return;
400}
401
402
403int ngx_http_find_location_config(ngx_http_request_t *r)
404{
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000405 ngx_int_t i, rc, exact;
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000406 ngx_str_t *auto_redirect;
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000407 ngx_http_core_loc_conf_t *clcf, **clcfp;
408 ngx_http_core_srv_conf_t *cscf;
Igor Sysoeve2a31542003-04-08 15:40:10 +0000409
Igor Sysoev6253ca12003-05-27 12:18:54 +0000410 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000411 auto_redirect = NULL;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000412 exact = 0;
Igor Sysoeve2a31542003-04-08 15:40:10 +0000413
Igor Sysoev6253ca12003-05-27 12:18:54 +0000414 clcfp = cscf->locations.elts;
415 for (i = 0; i < cscf->locations.nelts; i++) {
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000416
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000417#if (HAVE_PCRE)
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000418
419 if (clcfp[i]->regex) {
420 break;
421 }
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000422#endif
423
424 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
425 "find location: %s\"%s\"",
426 clcfp[i]->exact_match ? "= " : "",
427 clcfp[i]->name.data);
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000428
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000429 if (clcfp[i]->auto_redirect
430 && r->uri.len == clcfp[i]->name.len - 1
431 && ngx_strncmp(r->uri.data, clcfp[i]->name.data,
432 clcfp[i]->name.len - 1) == 0)
433 {
434 auto_redirect = &clcfp[i]->name;
435 continue;
436 }
437
Igor Sysoev890fc962003-07-20 21:15:59 +0000438 if (r->uri.len < clcfp[i]->name.len) {
439 continue;
440 }
Igor Sysoeve2a31542003-04-08 15:40:10 +0000441
Igor Sysoev65977492003-11-02 22:56:18 +0000442 rc = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len);
Igor Sysoeve2a31542003-04-08 15:40:10 +0000443
Igor Sysoev890fc962003-07-20 21:15:59 +0000444 if (rc < 0) {
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000445 /* locations are lexicographically sorted */
Igor Sysoev890fc962003-07-20 21:15:59 +0000446 break;
447 }
Igor Sysoeve2a31542003-04-08 15:40:10 +0000448
Igor Sysoev890fc962003-07-20 21:15:59 +0000449 if (rc == 0) {
450 r->loc_conf = clcfp[i]->loc_conf;
451 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
452 r->connection->log->file = clcf->err_log->file;
453 r->connection->log->log_level = clcf->err_log->log_level;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000454
455 if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) {
456 exact = 1;
457 break;
458 }
459 }
460 }
461
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000462#if (HAVE_PCRE)
463
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000464 if (!exact && !auto_redirect) {
465 /* regex matches */
466
467 for (/* void */; i < cscf->locations.nelts; i++) {
468
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000469 if (!clcfp[i]->regex) {
470 continue;
471 }
472
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000473 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
474 "find location: %s\"%s\"",
475 clcfp[i]->exact_match ? "= " :
476 clcfp[i]->regex ? "~ " : "",
477 clcfp[i]->name.data);
478
Igor Sysoev3b30a902003-12-25 20:26:58 +0000479 rc = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0);
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000480
481 if (rc == NGX_DECLINED) {
482 continue;
483 }
484
485 if (rc < 0) {
486 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
487 ngx_regex_exec_n
488 " failed: %d on \"%s\" using \"%s\"",
489 rc, r->uri.data, clcfp[i]->name.data);
490 return NGX_HTTP_INTERNAL_SERVER_ERROR;
491 }
492
493 /* match */
494
495 r->loc_conf = clcfp[i]->loc_conf;
496 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
497 r->connection->log->file = clcf->err_log->file;
498 r->connection->log->log_level = clcf->err_log->log_level;
499
500 break;
Igor Sysoev890fc962003-07-20 21:15:59 +0000501 }
Igor Sysoeve2a31542003-04-08 15:40:10 +0000502 }
503
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000504#endif /* HAVE_PCRE */
505
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000506 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
507
Igor Sysoev5bf3d252003-10-22 07:05:29 +0000508 if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) {
509 r->sendfile = 0;
510
511 } else {
512 r->sendfile = 1;
513 }
514
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000515 if (!clcf->tcp_nopush) {
516 /* disable TCP_NOPUSH/TCP_CORK use */
517 r->connection->tcp_nopush = -1;
518 }
519
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000520 if (auto_redirect) {
521 if (!(r->headers_out.location =
522 ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
523 {
524 return NGX_HTTP_INTERNAL_SERVER_ERROR;
525 }
526
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000527 r->headers_out.location->value = *auto_redirect;
528
529 return NGX_HTTP_MOVED_PERMANENTLY;
530 }
531
Igor Sysoev6253ca12003-05-27 12:18:54 +0000532 if (clcf->handler) {
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000533 r->content_handler = clcf->handler;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000534 }
535
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000536 return NGX_OK;
537}
538
539
Igor Sysoev865c1502003-11-30 20:03:18 +0000540ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r)
541{
542 uint32_t key;
543 ngx_int_t i;
544 ngx_http_type_t *type;
545 ngx_http_core_loc_conf_t *clcf;
546
547 if (!(r->headers_out.content_type =
548 ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
549 {
550 return NGX_HTTP_INTERNAL_SERVER_ERROR;
551 }
552
553 r->headers_out.content_type->key.len = 0;
554 r->headers_out.content_type->key.data = NULL;
555 r->headers_out.content_type->value.len = 0;
556 r->headers_out.content_type->value.data = NULL;
557
558 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
559
560 if (r->exten.len) {
561#if 0
562 key = ngx_crc(r->exten.data, r->exten.key);
563#endif
564 ngx_http_types_hash_key(key, r->exten);
565
566 type = clcf->types[key].elts;
567 for (i = 0; i < clcf->types[key].nelts; i++) {
568 if (r->exten.len != type[i].exten.len) {
569 continue;
570 }
571
572 if (ngx_memcmp(r->exten.data, type[i].exten.data, r->exten.len)
573 == 0)
574 {
575 r->headers_out.content_type->value = type[i].type;
576 break;
577 }
578 }
579 }
580
581 if (r->headers_out.content_type->value.len == 0) {
582 r->headers_out.content_type->value = clcf->default_type;
583 }
584
585 return NGX_OK;
586}
587
588
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000589int ngx_http_send_header(ngx_http_request_t *r)
590{
Igor Sysoev10fc9ef2003-10-27 08:53:49 +0000591 if (r->main) {
592 return NGX_OK;
593 }
594
Igor Sysoev27c30f92003-11-11 18:13:43 +0000595 if (r->err_ctx) {
Igor Sysoevd59a0472003-11-10 21:09:22 +0000596 r->headers_out.status = r->err_status;
597 r->headers_out.status_line.len = 0;
598 }
599
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000600 return (*ngx_http_top_header_filter)(r);
601}
602
603
604int ngx_http_redirect(ngx_http_request_t *r, int redirect)
605{
606 /* STUB */
607
608 /* log request */
609
Igor Sysoevd581fd52003-05-13 16:02:32 +0000610 ngx_http_close_request(r, 0);
611 return NGX_OK;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000612}
613
614
Igor Sysoev6253ca12003-05-27 12:18:54 +0000615int ngx_http_error(ngx_http_request_t *r, int error)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000616{
617 /* STUB */
618 ngx_log_debug(r->connection->log, "http error: %d" _ error);
619
620 /* log request */
621
Igor Sysoevdc479b42003-03-20 16:09:44 +0000622 ngx_http_special_response_handler(r, error);
Igor Sysoevd581fd52003-05-13 16:02:32 +0000623 ngx_http_close_request(r, 0);
624 return NGX_OK;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000625}
626
627
Igor Sysoev3b30a902003-12-25 20:26:58 +0000628ngx_int_t ngx_http_set_exten(ngx_http_request_t *r)
629{
630 ngx_int_t i;
631
632 r->exten.len = 0;
633 r->exten.data = NULL;
634
635 for (i = r->uri.len - 1; i > 1; i--) {
636 if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') {
637 r->exten.len = r->uri.len - i - 1;
638
639 if (r->exten.len > 0) {
640 if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) {
641 return NGX_ERROR;
642 }
643
644 ngx_cpystrn(r->exten.data, &r->uri.data[i + 1],
645 r->exten.len + 1);
646 }
647
648 break;
649
650 } else if (r->uri.data[i] == '/') {
651 break;
652 }
653 }
654
655 return NGX_OK;
656}
657
658
Igor Sysoev13933252003-05-29 13:02:09 +0000659int ngx_http_internal_redirect(ngx_http_request_t *r,
660 ngx_str_t *uri, ngx_str_t *args)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000661{
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000662 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
663 "internal redirect: \"%s\"", uri->data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000664
Igor Sysoev13933252003-05-29 13:02:09 +0000665 r->uri.len = uri->len;
666 r->uri.data = uri->data;
667
668 if (args) {
669 r->args.len = args->len;
670 r->args.data = args->data;
671 }
672
Igor Sysoev3b30a902003-12-25 20:26:58 +0000673 if (ngx_http_set_exten(r) != NGX_OK) {
674 return NGX_HTTP_INTERNAL_SERVER_ERROR;
Igor Sysoev13933252003-05-29 13:02:09 +0000675 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000676
Igor Sysoev27c30f92003-11-11 18:13:43 +0000677 if (r->err_ctx) {
Igor Sysoevd59a0472003-11-10 21:09:22 +0000678
Igor Sysoev27c30f92003-11-11 18:13:43 +0000679 /* allocate the new modules contexts */
680
Igor Sysoevd59a0472003-11-10 21:09:22 +0000681 r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
682 if (r->ctx == NULL) {
683 return NGX_HTTP_INTERNAL_SERVER_ERROR;
684 }
685
686 } else {
Igor Sysoev27c30f92003-11-11 18:13:43 +0000687
688 /* clear the modules contexts */
689
Igor Sysoevd59a0472003-11-10 21:09:22 +0000690 ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
691 }
Igor Sysoev0a280a32003-10-12 16:49:16 +0000692
693 r->phase = 0;
694 r->phase_handler = 0;
695
Igor Sysoev79a80482003-05-14 17:13:13 +0000696 ngx_http_handler(r);
Igor Sysoev13933252003-05-29 13:02:09 +0000697
Igor Sysoev9760a132003-10-21 07:47:21 +0000698 return NGX_DONE;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000699}
700
701
Igor Sysoev0a280a32003-10-12 16:49:16 +0000702#if 1 /* STUB: test the delay http handler */
703
704int ngx_http_delay_handler(ngx_http_request_t *r)
705{
706 static int on;
707
708 if (on++ == 0) {
709 ngx_log_debug(r->connection->log, "SET http delay");
710 ngx_add_timer(r->connection->write, 10000);
711 return NGX_AGAIN;
712 }
713
714 r->connection->write->timedout = 0;
715 ngx_log_debug(r->connection->log, "RESET http delay");
716 return NGX_DECLINED;
717}
718
719#endif
720
721
Igor Sysoev340b03b2003-07-04 15:10:33 +0000722static int ngx_http_core_init(ngx_cycle_t *cycle)
Igor Sysoevdc479b42003-03-20 16:09:44 +0000723{
Igor Sysoevd404c972003-10-16 20:19:16 +0000724#if 0
Igor Sysoev9d9f58f2003-07-02 18:51:41 +0000725 ngx_http_handler_pt *h;
Igor Sysoevd404c972003-10-16 20:19:16 +0000726#endif
Igor Sysoev9d9f58f2003-07-02 18:51:41 +0000727 ngx_http_conf_ctx_t *ctx;
728 ngx_http_core_main_conf_t *cmcf;
Igor Sysoevdc479b42003-03-20 16:09:44 +0000729
Igor Sysoev9d9f58f2003-07-02 18:51:41 +0000730 ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
731 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
732
Igor Sysoev0a280a32003-10-12 16:49:16 +0000733#if 0
734 ngx_test_null(h, ngx_push_array(
735 &cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
736 NGX_ERROR);
737 *h = ngx_http_delay_handler;
738#endif
739
Igor Sysoevdc479b42003-03-20 16:09:44 +0000740 return NGX_OK;
741}
742
743
Igor Sysoev6253ca12003-05-27 12:18:54 +0000744static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000745{
Igor Sysoev1c13c662003-05-20 15:37:55 +0000746 int m;
Igor Sysoeva9830112003-05-19 16:39:14 +0000747 char *rv;
748 ngx_http_module_t *module;
749 ngx_conf_t pcf;
750 ngx_http_conf_ctx_t *ctx, *hctx, *pctx;
751 ngx_http_core_main_conf_t *cmcf;
752 ngx_http_core_srv_conf_t *cscf, **cscfp;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000753
754 ngx_test_null(ctx,
755 ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
756 NGX_CONF_ERROR);
757
Igor Sysoeva9830112003-05-19 16:39:14 +0000758 hctx = (ngx_http_conf_ctx_t *) cf->ctx;
759 ctx->main_conf = hctx->main_conf;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000760
Igor Sysoeva9830112003-05-19 16:39:14 +0000761 /* the server{}'s srv_conf */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000762
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000763 ngx_test_null(ctx->srv_conf,
764 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
765 NGX_CONF_ERROR);
766
Igor Sysoeva9830112003-05-19 16:39:14 +0000767 /* the server{}'s loc_conf */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000768
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000769 ngx_test_null(ctx->loc_conf,
770 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
771 NGX_CONF_ERROR);
772
Igor Sysoev1c13c662003-05-20 15:37:55 +0000773 for (m = 0; ngx_modules[m]; m++) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000774 if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000775 continue;
776 }
777
Igor Sysoev6253ca12003-05-27 12:18:54 +0000778 module = ngx_modules[m]->ctx;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000779
780 if (module->create_srv_conf) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000781 ngx_test_null(ctx->srv_conf[ngx_modules[m]->ctx_index],
Igor Sysoev890fc962003-07-20 21:15:59 +0000782 module->create_srv_conf(cf),
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000783 NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000784 }
785
786 if (module->create_loc_conf) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000787 ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index],
Igor Sysoev890fc962003-07-20 21:15:59 +0000788 module->create_loc_conf(cf),
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000789 NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000790 }
791 }
792
Igor Sysoeva9830112003-05-19 16:39:14 +0000793 /* create links of the srv_conf's */
794
Igor Sysoev6253ca12003-05-27 12:18:54 +0000795 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
Igor Sysoeva9830112003-05-19 16:39:14 +0000796 cscf->ctx = ctx;
797
Igor Sysoev6253ca12003-05-27 12:18:54 +0000798 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
Igor Sysoeva9830112003-05-19 16:39:14 +0000799 ngx_test_null(cscfp, ngx_push_array(&cmcf->servers), NGX_CONF_ERROR);
800 *cscfp = cscf;
801
802 /* parse inside server{} */
803
Igor Sysoev79a80482003-05-14 17:13:13 +0000804 pcf = *cf;
805 pctx = cf->ctx;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000806 cf->ctx = ctx;
Igor Sysoev79a80482003-05-14 17:13:13 +0000807 cf->cmd_type = NGX_HTTP_SRV_CONF;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000808 rv = ngx_conf_parse(cf, NULL);
Igor Sysoev79a80482003-05-14 17:13:13 +0000809 *cf = pcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000810
Igor Sysoev13933252003-05-29 13:02:09 +0000811 if (rv != NGX_CONF_OK) {
812 return rv;
813 }
814
Igor Sysoevd9d0ca12003-11-21 06:30:49 +0000815 ngx_qsort(cscf->locations.elts, (size_t) cscf->locations.nelts,
Igor Sysoev13933252003-05-29 13:02:09 +0000816 sizeof(void *), ngx_cmp_locations);
817
Igor Sysoeva9830112003-05-19 16:39:14 +0000818 return rv;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000819}
820
821
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000822static int ngx_cmp_locations(const void *one, const void *two)
Igor Sysoev13933252003-05-29 13:02:09 +0000823{
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000824 ngx_http_core_loc_conf_t *first = *(ngx_http_core_loc_conf_t **) one;
825 ngx_http_core_loc_conf_t *second = *(ngx_http_core_loc_conf_t **) two;
Igor Sysoev13933252003-05-29 13:02:09 +0000826
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000827 ngx_int_t rc;
828
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000829#if (HAVE_PCRE)
830
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000831 if (first->regex && !second->regex) {
832 /* shift regex matches to the end */
833 return 1;
834 }
835
836 if (first->regex || second->regex) {
837 /* do not sort regex matches */
838 return 0;
839 }
840
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000841#endif
842
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000843 rc = ngx_strcmp(first->name.data, second->name.data);
844
845 if (rc == 0 && second->exact_match) {
846 /* an exact match must be before the same inclusive one */
847 return 1;
848 }
849
850 return rc;
Igor Sysoev13933252003-05-29 13:02:09 +0000851}
852
853
Igor Sysoev6253ca12003-05-27 12:18:54 +0000854static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000855{
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000856 char *rv;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000857 ngx_int_t m;
858 ngx_str_t *value, err;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000859 ngx_http_module_t *module;
Igor Sysoev74e95c22003-11-09 20:03:38 +0000860 ngx_conf_t pvcf;
861 ngx_http_conf_ctx_t *ctx, *pvctx;
Igor Sysoeva9830112003-05-19 16:39:14 +0000862 ngx_http_core_srv_conf_t *cscf;
863 ngx_http_core_loc_conf_t *clcf, **clcfp;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000864 char errstr[NGX_MAX_CONF_ERRSTR];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000865
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000866 if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) {
867 return NGX_CONF_ERROR;
868 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000869
Igor Sysoev74e95c22003-11-09 20:03:38 +0000870 pvctx = (ngx_http_conf_ctx_t *) cf->ctx;
871 ctx->main_conf = pvctx->main_conf;
872 ctx->srv_conf = pvctx->srv_conf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000873
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000874 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
875 if (ctx->loc_conf == NULL) {
876 return NGX_CONF_ERROR;
877 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000878
Igor Sysoev6253ca12003-05-27 12:18:54 +0000879 for (m = 0; ngx_modules[m]; m++) {
880 if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000881 continue;
882 }
883
Igor Sysoev6253ca12003-05-27 12:18:54 +0000884 module = ngx_modules[m]->ctx;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000885
886 if (module->create_loc_conf) {
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000887 ctx->loc_conf[ngx_modules[m]->ctx_index] =
888 module->create_loc_conf(cf);
889 if (ctx->loc_conf[ngx_modules[m]->ctx_index] == NULL) {
890 return NGX_CONF_ERROR;
891 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000892 }
893 }
894
Igor Sysoev6253ca12003-05-27 12:18:54 +0000895 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
Igor Sysoeva9830112003-05-19 16:39:14 +0000896 clcf->loc_conf = ctx->loc_conf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000897
Igor Sysoev3b30a902003-12-25 20:26:58 +0000898 value = cf->args->elts;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000899
900 if (cf->args->nelts == 3) {
901 if (value[1].len == 1 && value[1].data[0] == '=') {
902 clcf->name.len = value[2].len;
903 clcf->name.data = value[2].data;
904 clcf->exact_match = 1;
905
906 } else if ((value[1].len == 1 && value[1].data[0] == '~')
907 || (value[1].len == 2
908 && value[1].data[0] == '~'
909 && value[1].data[1] == '*'))
910 {
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000911#if (HAVE_PCRE)
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000912 err.len = NGX_MAX_CONF_ERRSTR;
913 err.data = errstr;
914
915 clcf->regex = ngx_regex_compile(&value[2],
916 value[1].len == 2 ? NGX_REGEX_CASELESS: 0,
917 cf->pool, &err);
918
919 if (clcf->regex == NULL) {
920 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
921 return NGX_CONF_ERROR;
922 }
923
Igor Sysoev3b30a902003-12-25 20:26:58 +0000924 clcf->name = value[2];
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000925#else
926 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
927 "the using of the regex \"%s\" "
928 "requires PCRE library",
929 value[2].data);
930 return NGX_CONF_ERROR;
931#endif
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000932
933 } else {
934 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
935 "invalid location modifier \"%s\"",
936 value[1].data);
937 return NGX_CONF_ERROR;
938 }
939
940 } else {
941 clcf->name.len = value[1].len;
942 clcf->name.data = value[1].data;
943 }
944
Igor Sysoev6253ca12003-05-27 12:18:54 +0000945 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000946 if (!(clcfp = ngx_push_array(&cscf->locations))) {
947 return NGX_CONF_ERROR;
948 }
Igor Sysoeva9830112003-05-19 16:39:14 +0000949 *clcfp = clcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000950
Igor Sysoev74e95c22003-11-09 20:03:38 +0000951 pvcf = *cf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000952 cf->ctx = ctx;
Igor Sysoev79a80482003-05-14 17:13:13 +0000953 cf->cmd_type = NGX_HTTP_LOC_CONF;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000954 rv = ngx_conf_parse(cf, NULL);
Igor Sysoev74e95c22003-11-09 20:03:38 +0000955 *cf = pvcf;
Igor Sysoev79a80482003-05-14 17:13:13 +0000956
957 return rv;
958}
959
960
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000961static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev79a80482003-05-14 17:13:13 +0000962{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000963 char *rv;
964 ngx_conf_t pcf;
965
966 pcf = *cf;
967 cf->handler = ngx_set_type;
968 cf->handler_conf = conf;
969 rv = ngx_conf_parse(cf, NULL);
970 *cf = pcf;
971
972 return rv;
973}
974
975
976static char *ngx_set_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
977{
978 ngx_http_core_loc_conf_t *lcf = conf;
Igor Sysoev79a80482003-05-14 17:13:13 +0000979
980 int i, key;
981 ngx_str_t *args;
Igor Sysoev865c1502003-11-30 20:03:18 +0000982 ngx_http_type_t *type;
Igor Sysoev79a80482003-05-14 17:13:13 +0000983
984 if (lcf->types == NULL) {
985 ngx_test_null(lcf->types,
986 ngx_palloc(cf->pool, NGX_HTTP_TYPES_HASH_PRIME
987 * sizeof(ngx_array_t)),
988 NGX_CONF_ERROR);
989
990 for (i = 0; i < NGX_HTTP_TYPES_HASH_PRIME; i++) {
991 ngx_init_array(lcf->types[i], cf->pool, 5, sizeof(ngx_http_type_t),
992 NGX_CONF_ERROR);
993 }
994 }
995
996 args = (ngx_str_t *) cf->args->elts;
997
998 for (i = 1; i < cf->args->nelts; i++) {
999 ngx_http_types_hash_key(key, args[i]);
1000
Igor Sysoev865c1502003-11-30 20:03:18 +00001001 ngx_test_null(type, ngx_push_array(&lcf->types[key]), NGX_CONF_ERROR);
1002 type->exten = args[i];
1003 type->type = args[0];
Igor Sysoev79a80482003-05-14 17:13:13 +00001004 }
1005
1006 return NGX_CONF_OK;
1007}
1008
1009
Igor Sysoev890fc962003-07-20 21:15:59 +00001010static void *ngx_http_core_create_main_conf(ngx_conf_t *cf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001011{
Igor Sysoeva9830112003-05-19 16:39:14 +00001012 ngx_http_core_main_conf_t *cmcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001013
Igor Sysoeva9830112003-05-19 16:39:14 +00001014 ngx_test_null(cmcf,
Igor Sysoevb3e73d82003-10-10 15:10:50 +00001015 ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t)),
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001016 NGX_CONF_ERROR);
1017
Igor Sysoev890fc962003-07-20 21:15:59 +00001018 ngx_init_array(cmcf->servers, cf->pool,
1019 5, sizeof(ngx_http_core_srv_conf_t *),
Igor Sysoevad22e012003-01-15 07:02:27 +00001020 NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001021
Igor Sysoeva9830112003-05-19 16:39:14 +00001022 return cmcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001023}
1024
1025
Igor Sysoev890fc962003-07-20 21:15:59 +00001026static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001027{
Igor Sysoev6253ca12003-05-27 12:18:54 +00001028 ngx_http_core_main_conf_t *cmcf = conf;
Igor Sysoeva9830112003-05-19 16:39:14 +00001029
Igor Sysoev239baac2003-06-11 15:28:34 +00001030 /* TODO: remove it if no directives */
Igor Sysoeva9830112003-05-19 16:39:14 +00001031
1032 return NGX_CONF_OK;
1033}
1034
1035
Igor Sysoev890fc962003-07-20 21:15:59 +00001036static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf)
Igor Sysoeva9830112003-05-19 16:39:14 +00001037{
1038 ngx_http_core_srv_conf_t *cscf;
1039
1040 ngx_test_null(cscf,
Igor Sysoev890fc962003-07-20 21:15:59 +00001041 ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t)),
Igor Sysoeva9830112003-05-19 16:39:14 +00001042 NGX_CONF_ERROR);
1043
Igor Sysoev890fc962003-07-20 21:15:59 +00001044 ngx_init_array(cscf->locations, cf->pool,
1045 5, sizeof(void *), NGX_CONF_ERROR);
1046 ngx_init_array(cscf->listen, cf->pool, 5, sizeof(ngx_http_listen_t),
Igor Sysoeva9830112003-05-19 16:39:14 +00001047 NGX_CONF_ERROR);
Igor Sysoev890fc962003-07-20 21:15:59 +00001048 ngx_init_array(cscf->server_names, cf->pool,
1049 5, sizeof(ngx_http_server_name_t), NGX_CONF_ERROR);
Igor Sysoeva9830112003-05-19 16:39:14 +00001050
Igor Sysoev239baac2003-06-11 15:28:34 +00001051 cscf->connection_pool_size = NGX_CONF_UNSET;
1052 cscf->post_accept_timeout = NGX_CONF_UNSET;
Igor Sysoev187fcd82003-05-23 11:53:01 +00001053 cscf->request_pool_size = NGX_CONF_UNSET;
1054 cscf->client_header_timeout = NGX_CONF_UNSET;
1055 cscf->client_header_buffer_size = NGX_CONF_UNSET;
1056 cscf->large_client_header = NGX_CONF_UNSET;
1057
Igor Sysoeva9830112003-05-19 16:39:14 +00001058 return cscf;
1059}
1060
1061
Igor Sysoev890fc962003-07-20 21:15:59 +00001062static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
Igor Sysoeva9830112003-05-19 16:39:14 +00001063 void *parent, void *child)
1064{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001065 ngx_http_core_srv_conf_t *prev = parent;
1066 ngx_http_core_srv_conf_t *conf = child;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001067
1068 ngx_http_listen_t *l;
Igor Sysoevad22e012003-01-15 07:02:27 +00001069 ngx_http_server_name_t *n;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001070
Igor Sysoev7578ec92003-06-02 15:24:30 +00001071 /* TODO: it does not merge, it inits only */
Igor Sysoeva9830112003-05-19 16:39:14 +00001072
1073 if (conf->listen.nelts == 0) {
1074 ngx_test_null(l, ngx_push_array(&conf->listen), NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001075 l->addr = INADDR_ANY;
Igor Sysoev1c104622003-06-03 15:42:58 +00001076#if (WIN32)
1077 l->port = 80;
1078#else
Igor Sysoev7578ec92003-06-02 15:24:30 +00001079 /* STUB: getuid() should be cached */
1080 l->port = (getuid() == 0) ? 80 : 8000;
Igor Sysoev1c104622003-06-03 15:42:58 +00001081#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001082 l->family = AF_INET;
1083 }
1084
Igor Sysoeva9830112003-05-19 16:39:14 +00001085 if (conf->server_names.nelts == 0) {
1086 ngx_test_null(n, ngx_push_array(&conf->server_names), NGX_CONF_ERROR);
Igor Sysoev890fc962003-07-20 21:15:59 +00001087 ngx_test_null(n->name.data, ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN),
Igor Sysoevad22e012003-01-15 07:02:27 +00001088 NGX_CONF_ERROR);
Igor Sysoev13933252003-05-29 13:02:09 +00001089
Igor Sysoevad22e012003-01-15 07:02:27 +00001090 if (gethostname(n->name.data, NGX_MAXHOSTNAMELEN) == -1) {
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00001091 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
1092 "gethostname() failed");
1093 return NGX_CONF_ERROR;
Igor Sysoevad22e012003-01-15 07:02:27 +00001094 }
Igor Sysoev13933252003-05-29 13:02:09 +00001095
Igor Sysoevad22e012003-01-15 07:02:27 +00001096 n->name.len = ngx_strlen(n->name.data);
1097 n->core_srv_conf = conf;
1098 }
1099
Igor Sysoev239baac2003-06-11 15:28:34 +00001100 ngx_conf_merge_size_value(conf->connection_pool_size,
1101 prev->connection_pool_size, 16384);
1102 ngx_conf_merge_msec_value(conf->post_accept_timeout,
1103 prev->post_accept_timeout, 30000);
Igor Sysoev187fcd82003-05-23 11:53:01 +00001104 ngx_conf_merge_size_value(conf->request_pool_size,
1105 prev->request_pool_size, 16384);
1106 ngx_conf_merge_msec_value(conf->client_header_timeout,
1107 prev->client_header_timeout, 60000);
1108 ngx_conf_merge_size_value(conf->client_header_buffer_size,
1109 prev->client_header_buffer_size, 1024);
1110 ngx_conf_merge_value(conf->large_client_header,
1111 prev->large_client_header, 1);
1112
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001113 return NGX_CONF_OK;
1114}
1115
1116
Igor Sysoev890fc962003-07-20 21:15:59 +00001117static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001118{
1119 ngx_http_core_loc_conf_t *lcf;
1120
1121 ngx_test_null(lcf,
Igor Sysoev890fc962003-07-20 21:15:59 +00001122 ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t)),
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001123 NGX_CONF_ERROR);
1124
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001125 /* set by ngx_pcalloc():
Igor Sysoev79a80482003-05-14 17:13:13 +00001126
1127 lcf->doc_root.len = 0;
1128 lcf->doc_root.data = NULL;
1129 lcf->types = NULL;
Igor Sysoev6253ca12003-05-27 12:18:54 +00001130 lcf->default_type.len = 0;
1131 lcf->default_type.data = NULL;
Igor Sysoev9d639522003-07-07 06:11:50 +00001132 lcf->err_log = NULL;
Igor Sysoev74e95c22003-11-09 20:03:38 +00001133 lcf->error_pages = NULL;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001134
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001135 lcf->regex = NULL;
1136 lcf->exact_match = 0;
1137 lcf->auto_redirect = 0;
1138
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001139 */
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001140
Igor Sysoev2b0c76c2003-10-27 21:01:00 +00001141 lcf->client_body_timeout = NGX_CONF_UNSET;
Igor Sysoev5bf3d252003-10-22 07:05:29 +00001142 lcf->sendfile = NGX_CONF_UNSET;
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001143 lcf->tcp_nopush = NGX_CONF_UNSET;
Igor Sysoev79a80482003-05-14 17:13:13 +00001144 lcf->send_timeout = NGX_CONF_UNSET;
Igor Sysoevb5faed22003-10-29 08:30:44 +00001145 lcf->send_lowat = NGX_CONF_UNSET;
Igor Sysoev79a80482003-05-14 17:13:13 +00001146 lcf->discarded_buffer_size = NGX_CONF_UNSET;
Igor Sysoevfa73aac2003-05-21 13:28:21 +00001147 lcf->keepalive_timeout = NGX_CONF_UNSET;
Igor Sysoev79a80482003-05-14 17:13:13 +00001148 lcf->lingering_time = NGX_CONF_UNSET;
1149 lcf->lingering_timeout = NGX_CONF_UNSET;
1150
Igor Sysoev12b4b002003-10-24 06:53:41 +00001151 lcf->msie_padding = NGX_CONF_UNSET;
1152
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001153 return lcf;
1154}
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001155
Igor Sysoev79a80482003-05-14 17:13:13 +00001156
1157static ngx_http_type_t default_types[] = {
1158 { ngx_string("html"), ngx_string("text/html") },
1159 { ngx_string("gif"), ngx_string("image/gif") },
1160 { ngx_string("jpg"), ngx_string("image/jpeg") },
1161 { ngx_null_string, ngx_null_string }
1162};
1163
1164
Igor Sysoev890fc962003-07-20 21:15:59 +00001165static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
Igor Sysoeve2a31542003-04-08 15:40:10 +00001166 void *parent, void *child)
1167{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001168 ngx_http_core_loc_conf_t *prev = parent;
1169 ngx_http_core_loc_conf_t *conf = child;
Igor Sysoev79a80482003-05-14 17:13:13 +00001170
1171 int i, key;
1172 ngx_http_type_t *t;
1173
Igor Sysoev7578ec92003-06-02 15:24:30 +00001174 ngx_conf_merge_str_value(conf->doc_root, prev->doc_root, "html");
Igor Sysoev79a80482003-05-14 17:13:13 +00001175
1176 if (conf->types == NULL) {
1177 if (prev->types) {
1178 conf->types = prev->types;
1179
1180 } else {
1181 ngx_test_null(conf->types,
Igor Sysoev890fc962003-07-20 21:15:59 +00001182 ngx_palloc(cf->pool, NGX_HTTP_TYPES_HASH_PRIME
Igor Sysoev79a80482003-05-14 17:13:13 +00001183 * sizeof(ngx_array_t)),
1184 NGX_CONF_ERROR);
1185
1186 for (i = 0; i < NGX_HTTP_TYPES_HASH_PRIME; i++) {
Igor Sysoev890fc962003-07-20 21:15:59 +00001187 ngx_init_array(conf->types[i], cf->pool,
1188 5, sizeof(ngx_http_type_t), NGX_CONF_ERROR);
Igor Sysoev79a80482003-05-14 17:13:13 +00001189 }
1190
1191 for (i = 0; default_types[i].exten.len; i++) {
1192 ngx_http_types_hash_key(key, default_types[i].exten);
1193
1194 ngx_test_null(t, ngx_push_array(&conf->types[key]),
1195 NGX_CONF_ERROR);
1196 t->exten.len = default_types[i].exten.len;
1197 t->exten.data = default_types[i].exten.data;
1198 t->type.len = default_types[i].type.len;
1199 t->type.data = default_types[i].type.data;
1200 }
1201 }
1202 }
1203
Igor Sysoev890fc962003-07-20 21:15:59 +00001204 if (conf->err_log == NULL) {
1205 if (prev->err_log) {
1206 conf->err_log = prev->err_log;
1207 } else {
1208 conf->err_log = cf->cycle->log;
1209 }
1210 }
1211
Igor Sysoev74e95c22003-11-09 20:03:38 +00001212 if (conf->error_pages == NULL && prev->error_pages) {
1213 conf->error_pages = prev->error_pages;
1214 }
1215
Igor Sysoev6253ca12003-05-27 12:18:54 +00001216 ngx_conf_merge_str_value(conf->default_type,
1217 prev->default_type, "text/plain");
1218
Igor Sysoev2b0c76c2003-10-27 21:01:00 +00001219 ngx_conf_merge_msec_value(conf->client_body_timeout,
1220 prev->client_body_timeout, 10000);
Igor Sysoev5bf3d252003-10-22 07:05:29 +00001221 ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001222 ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
Igor Sysoeva9830112003-05-19 16:39:14 +00001223 ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 10000);
Igor Sysoevb5faed22003-10-29 08:30:44 +00001224 ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
Igor Sysoeva9830112003-05-19 16:39:14 +00001225 ngx_conf_merge_size_value(conf->discarded_buffer_size,
1226 prev->discarded_buffer_size, 1500);
Igor Sysoev187fcd82003-05-23 11:53:01 +00001227 ngx_conf_merge_msec_value(conf->keepalive_timeout,
1228 prev->keepalive_timeout, 70000);
1229 ngx_conf_merge_msec_value(conf->lingering_time,
1230 prev->lingering_time, 30000);
1231 ngx_conf_merge_msec_value(conf->lingering_timeout,
1232 prev->lingering_timeout, 5000);
Igor Sysoev79a80482003-05-14 17:13:13 +00001233
Igor Sysoev12b4b002003-10-24 06:53:41 +00001234 ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
1235
Igor Sysoev865c1502003-11-30 20:03:18 +00001236 if (conf->open_files == NULL) {
1237 conf->open_files = prev->open_files;
1238 }
1239
Igor Sysoeve2a31542003-04-08 15:40:10 +00001240 return NGX_CONF_OK;
1241}
1242
Igor Sysoev79a80482003-05-14 17:13:13 +00001243
Igor Sysoev6253ca12003-05-27 12:18:54 +00001244static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001245{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001246 ngx_http_core_srv_conf_t *scf = conf;
Igor Sysoeva9830112003-05-19 16:39:14 +00001247
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001248 char *addr;
Igor Sysoev1c13c662003-05-20 15:37:55 +00001249 u_int p;
Igor Sysoev6253ca12003-05-27 12:18:54 +00001250 struct hostent *h;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001251 ngx_str_t *args;
1252 ngx_http_listen_t *ls;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001253
Igor Sysoev239baac2003-06-11 15:28:34 +00001254 /* TODO: check duplicate 'listen' directives,
Igor Sysoev13933252003-05-29 13:02:09 +00001255 add resolved name to server names ??? */
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001256
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001257 ngx_test_null(ls, ngx_push_array(&scf->listen), NGX_CONF_ERROR);
1258
1259 /* AF_INET only */
1260
1261 ls->family = AF_INET;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001262 ls->flags = 0;
Igor Sysoevfe5cb6b2003-01-29 07:25:51 +00001263 ls->file_name = cf->conf_file->file.name;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001264 ls->line = cf->conf_file->line;
1265
Igor Sysoev13933252003-05-29 13:02:09 +00001266 args = cf->args->elts;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001267 addr = args[1].data;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001268
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001269 for (p = 0; p < args[1].len; p++) {
1270 if (addr[p] == ':') {
1271 addr[p++] = '\0';
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001272 break;
1273 }
1274 }
1275
1276 if (p == args[1].len) {
Igor Sysoev13933252003-05-29 13:02:09 +00001277 /* no ":" in the "listen" */
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00001278 p = 0;
1279 }
1280
1281 ls->port = ngx_atoi(&addr[p], args[1].len - p);
Igor Sysoev13933252003-05-29 13:02:09 +00001282 if (ls->port == NGX_ERROR && p == 0) {
1283
1284 /* "listen host" */
1285 ls->port = 80;
1286
1287 } else if ((ls->port == NGX_ERROR && p != 0) /* "listen host:NONNUMBER" */
1288 || (ls->port < 1 || ls->port > 65536)) { /* "listen 99999" */
1289
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00001290 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1291 "invalid port \"%s\" in \"%s\" directive, "
1292 "it must be a number between 1 and 65535",
1293 &addr[p], cmd->name.data);
1294
1295 return NGX_CONF_ERROR;
Igor Sysoev13933252003-05-29 13:02:09 +00001296
1297 } else if (p == 0) {
1298 ls->addr = INADDR_ANY;
1299 return NGX_CONF_OK;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001300 }
1301
Igor Sysoev13933252003-05-29 13:02:09 +00001302 ls->addr = inet_addr(addr);
1303 if (ls->addr == INADDR_NONE) {
1304 h = gethostbyname(addr);
1305
1306 if (h == NULL || h->h_addr_list[0] == NULL) {
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00001307 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1308 "can not resolve host \"%s\" "
1309 "in \"%s\" directive", addr, cmd->name.data);
1310 return NGX_CONF_ERROR;
Igor Sysoev13933252003-05-29 13:02:09 +00001311 }
1312
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001313 ls->addr = *(in_addr_t *)(h->h_addr_list[0]);
Igor Sysoev13933252003-05-29 13:02:09 +00001314 }
1315
1316 return NGX_CONF_OK;
1317}
1318
1319
1320static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1321{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001322 ngx_http_core_srv_conf_t *scf = conf;
Igor Sysoev13933252003-05-29 13:02:09 +00001323
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001324 int i;
1325 ngx_str_t *value;
Igor Sysoev13933252003-05-29 13:02:09 +00001326 ngx_http_server_name_t *sn;
1327
1328 /* TODO: several names */
1329 /* TODO: warn about duplicate 'server_name' directives */
1330
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001331 value = cf->args->elts;
Igor Sysoev13933252003-05-29 13:02:09 +00001332
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001333 for (i = 1; i < cf->args->nelts; i++) {
1334 if (value[i].len == 0) {
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00001335 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1336 "server name \"%s\" is invalid "
1337 "in \"%s\" directive",
1338 value[i].data, cmd->name.data);
1339 return NGX_CONF_ERROR;
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001340 }
Igor Sysoev13933252003-05-29 13:02:09 +00001341
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001342 ngx_test_null(sn, ngx_push_array(&scf->server_names), NGX_CONF_ERROR);
1343
1344 sn->name.len = value[i].len;
1345 sn->name.data = value[i].data;
1346 sn->core_srv_conf = scf;
1347 }
Igor Sysoev13933252003-05-29 13:02:09 +00001348
Igor Sysoeva19a85e2003-01-28 15:56:37 +00001349 return NGX_CONF_OK;
1350}
Igor Sysoev9d639522003-07-07 06:11:50 +00001351
1352
Igor Sysoev74e95c22003-11-09 20:03:38 +00001353static char *ngx_set_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1354{
1355 ngx_http_core_loc_conf_t *lcf = conf;
1356
1357 int i;
1358 ngx_str_t *value;
1359 ngx_http_err_page_t *err;
1360
1361 if (lcf->error_pages == NULL) {
1362 lcf->error_pages = ngx_create_array(cf->pool, 5,
1363 sizeof(ngx_http_err_page_t));
1364 if (lcf->error_pages == NULL) {
1365 return NGX_CONF_ERROR;
1366 }
1367 }
1368
1369 value = cf->args->elts;
1370
1371 for (i = 1; i < cf->args->nelts - 1; i++) {
1372 ngx_test_null(err, ngx_push_array(lcf->error_pages), NGX_CONF_ERROR);
1373 err->code = ngx_atoi(value[i].data, value[i].len);
1374 if (err->code == NGX_ERROR) {
1375 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1376 "invalid value \"%s\"", value[i].data);
1377 return NGX_CONF_ERROR;
1378 }
1379
1380 if (err->code < 400 || err->code > 599) {
1381 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1382 "value \"%s\" must be between 400 and 599",
1383 value[i].data);
1384 return NGX_CONF_ERROR;
1385 }
1386
1387 err->uri = value[cf->args->nelts - 1];
1388 }
1389
1390 return NGX_CONF_OK;
1391}
1392
1393
Igor Sysoev9d639522003-07-07 06:11:50 +00001394static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1395{
1396 ngx_http_core_loc_conf_t *lcf = conf;
1397
Igor Sysoev5f800782003-12-08 20:48:12 +00001398#if 0
Igor Sysoev9d639522003-07-07 06:11:50 +00001399 ngx_str_t *value;
1400
1401 value = cf->args->elts;
Igor Sysoev5f800782003-12-08 20:48:12 +00001402#endif
Igor Sysoev9d639522003-07-07 06:11:50 +00001403
Igor Sysoevb8c367c2003-07-10 16:26:57 +00001404 ngx_test_null(lcf->err_log,
Igor Sysoev5f800782003-12-08 20:48:12 +00001405 ngx_log_create_errlog(cf->cycle, cf->args),
Igor Sysoev9d639522003-07-07 06:11:50 +00001406 NGX_CONF_ERROR);
1407
Igor Sysoev9d639522003-07-07 06:11:50 +00001408 return NGX_CONF_OK;
1409}
Igor Sysoevb5faed22003-10-29 08:30:44 +00001410
1411
1412static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data)
1413{
Igor Sysoevb5faed22003-10-29 08:30:44 +00001414#if (HAVE_LOWAT_EVENT)
1415
Igor Sysoev74e95c22003-11-09 20:03:38 +00001416 int *np = data;
1417
Igor Sysoevb5faed22003-10-29 08:30:44 +00001418 if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
1419 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1420 "\"send_lowat\" must be less than %d "
1421 "(sysctl net.inet.tcp.sendspace)",
1422 ngx_freebsd_net_inet_tcp_sendspace);
1423
1424 return NGX_CONF_ERROR;
1425 }
1426
1427#else
1428
1429 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1430 "\"send_lowat\" is not supported, ignored");
1431
1432#endif
1433
1434 return NGX_CONF_OK;
1435}