blob: 9acc866fb11e76eee4fe0d214e5911dc7b86fa60 [file] [log] [blame]
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001
2#include <ngx_config.h>
3
Igor Sysoeva19a85e2003-01-28 15:56:37 +00004#include <ngx_listen.h>
5
Igor Sysoev4e9393a2003-01-09 05:36:00 +00006#include <ngx_core.h>
7#include <ngx_conf_file.h>
8
9#include <ngx_http.h>
10#include <ngx_http_config.h>
11#include <ngx_http_core_module.h>
12
Igor Sysoev73009772003-02-06 17:21:13 +000013/* STUB for r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; */
Igor Sysoev4e9393a2003-01-09 05:36:00 +000014#include <ngx_http_output_filter.h>
Igor Sysoev4e9393a2003-01-09 05:36:00 +000015
Igor Sysoev4e9393a2003-01-09 05:36:00 +000016int ngx_http_static_handler(ngx_http_request_t *r);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000017int ngx_http_proxy_handler(ngx_http_request_t *r);
18/**/
19
Igor Sysoevb2620632003-01-10 06:09:20 +000020static int ngx_http_core_index_handler(ngx_http_request_t *r);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000021
Igor Sysoevdc479b42003-03-20 16:09:44 +000022static int ngx_http_core_init(ngx_pool_t *pool);
23
Igor Sysoev4e9393a2003-01-09 05:36:00 +000024static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool);
25static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf);
26static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool);
Igor Sysoeve2a31542003-04-08 15:40:10 +000027static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool,
28 void *parent, void *child);
Igor Sysoevdc479b42003-03-20 16:09:44 +000029
30static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
31static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd,
32 char *dummy);
Igor Sysoeva19a85e2003-01-28 15:56:37 +000033static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000034
35
36static ngx_command_t ngx_http_core_commands[] = {
37
38 {ngx_string("server"),
39 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
40 ngx_server_block,
41 0,
42 0},
43
Igor Sysoev6a644c62003-03-04 06:33:48 +000044 {ngx_string("post_accept_timeout"),
45 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
46 ngx_conf_set_time_slot,
47 0,
48 addressof(ngx_http_post_accept_timeout)},
49
50 {ngx_string("connection_pool_size"),
51 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
52 ngx_conf_set_size_slot,
53 0,
54 addressof(ngx_http_connection_pool_size)},
55
56 {ngx_string("request_pool_size"),
57 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
58 ngx_conf_set_size_slot,
59 0,
60 addressof(ngx_http_request_pool_size)},
61
62 {ngx_string("client_header_timeout"),
63 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
64 ngx_conf_set_time_slot,
65 0,
66 addressof(ngx_http_client_header_timeout)},
67
68 {ngx_string("client_header_buffer_size"),
69 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
70 ngx_conf_set_size_slot,
71 0,
72 addressof(ngx_http_client_header_buffer_size)},
73
74 {ngx_string("large_client_header"),
75 NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
76 ngx_conf_set_flag_slot,
77 0,
78 addressof(ngx_http_large_client_header)},
79
Igor Sysoev4e9393a2003-01-09 05:36:00 +000080 {ngx_string("location"),
81 NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
82 ngx_location_block,
Igor Sysoeve2a31542003-04-08 15:40:10 +000083 NGX_HTTP_SRV_CONF_OFFSET,
Igor Sysoev4e9393a2003-01-09 05:36:00 +000084 0},
85
Igor Sysoeva19a85e2003-01-28 15:56:37 +000086 {ngx_string("listen"),
87 NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
88 ngx_set_listen,
Igor Sysoeve2a31542003-04-08 15:40:10 +000089 NGX_HTTP_SRV_CONF_OFFSET,
Igor Sysoeva19a85e2003-01-28 15:56:37 +000090 0},
91
Igor Sysoev4e9393a2003-01-09 05:36:00 +000092 {ngx_string("root"),
Igor Sysoeva19a85e2003-01-28 15:56:37 +000093 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
Igor Sysoev4e9393a2003-01-09 05:36:00 +000094 ngx_conf_set_str_slot,
95 NGX_HTTP_LOC_CONF_OFFSET,
96 offsetof(ngx_http_core_loc_conf_t, doc_root)},
97
Igor Sysoeve2a31542003-04-08 15:40:10 +000098 {ngx_string("sendfile"),
99 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
100 ngx_conf_set_flag_slot,
101 NGX_HTTP_LOC_CONF_OFFSET,
102 offsetof(ngx_http_core_loc_conf_t, sendfile)},
103
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000104 {ngx_string("send_timeout"),
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000105 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000106 ngx_conf_set_time_slot,
107 NGX_HTTP_LOC_CONF_OFFSET,
108 offsetof(ngx_http_core_loc_conf_t, send_timeout)},
109
Igor Sysoevb7387572003-03-11 20:38:13 +0000110 {ngx_string("lingering_time"),
Igor Sysoeve2a31542003-04-08 15:40:10 +0000111 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
Igor Sysoevb7387572003-03-11 20:38:13 +0000112 ngx_conf_set_time_slot,
113 NGX_HTTP_LOC_CONF_OFFSET,
114 offsetof(ngx_http_core_loc_conf_t, lingering_time)},
115
116 {ngx_string("lingering_timeout"),
Igor Sysoeve2a31542003-04-08 15:40:10 +0000117 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
Igor Sysoevb7387572003-03-11 20:38:13 +0000118 ngx_conf_set_time_slot,
119 NGX_HTTP_LOC_CONF_OFFSET,
120 offsetof(ngx_http_core_loc_conf_t, lingering_timeout)},
121
Igor Sysoevdc479b42003-03-20 16:09:44 +0000122 {ngx_null_string, 0, NULL, 0, 0}
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000123};
124
125
126ngx_http_module_t ngx_http_core_module_ctx = {
Igor Sysoeve2a31542003-04-08 15:40:10 +0000127 NGX_HTTP_MODULE,
128
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000129 ngx_http_core_create_srv_conf, /* create server config */
130 ngx_http_core_init_srv_conf, /* init server config */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000131
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000132 ngx_http_core_create_loc_conf, /* create location config */
Igor Sysoeve2a31542003-04-08 15:40:10 +0000133 ngx_http_core_merge_loc_conf /* merge location config */
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000134};
135
136
137ngx_module_t ngx_http_core_module = {
138 0, /* module index */
139 &ngx_http_core_module_ctx, /* module context */
140 ngx_http_core_commands, /* module directives */
141 NGX_HTTP_MODULE_TYPE, /* module type */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000142 ngx_http_core_init /* init module */
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000143};
144
145
146int ngx_http_handler(ngx_http_request_t *r)
147{
Igor Sysoeve2a31542003-04-08 15:40:10 +0000148 int rc, a, n, i;
149 ngx_http_handler_pt *h;
150 ngx_http_module_t *module;
151 ngx_http_conf_ctx_t *ctx;
152 ngx_http_in_port_t *in_port;
153 ngx_http_in_addr_t *in_addr;
154 ngx_http_server_name_t *name;
155 ngx_http_core_srv_conf_t *scf;
156 ngx_http_core_loc_conf_t *lcf, **plcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000157
158 r->connection->unexpected_eof = 0;
Igor Sysoev73009772003-02-06 17:21:13 +0000159
Igor Sysoevdc479b42003-03-20 16:09:44 +0000160 r->keepalive = 1;
Igor Sysoev1e7ec9d2003-02-11 07:14:40 +0000161 r->lingering_close = 1;
Igor Sysoev73009772003-02-06 17:21:13 +0000162
Igor Sysoeve2a31542003-04-08 15:40:10 +0000163#if 0
164ngx_log_debug(r->connection->log, "servers: %0x" _ r->connection->servers);
Igor Sysoev73009772003-02-06 17:21:13 +0000165#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000166
Igor Sysoeve2a31542003-04-08 15:40:10 +0000167 /* find server config */
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000168
169 if (r->connection->servers == NULL) {
170 ctx = (ngx_http_conf_ctx_t *) r->connection->ctx;
171
172 } else {
Igor Sysoevfe5cb6b2003-01-29 07:25:51 +0000173
174 /* AF_INET only */
175
176 in_port = (ngx_http_in_port_t *) r->connection->servers;
Igor Sysoev1b8b1192003-01-29 17:02:48 +0000177 in_addr = (ngx_http_in_addr_t *) in_port->addr.elts;
Igor Sysoevfe5cb6b2003-01-29 07:25:51 +0000178
179 a = 0;
180
181 if (in_port->addr.nelts > 1) {
182 /* find r->in_addr, getsockname() */
183
Igor Sysoevfe5cb6b2003-01-29 07:25:51 +0000184 for ( /* void */ ; a < in_port->addr.nelts; a++) {
185
186 if (in_addr[a].addr == INADDR_ANY) {
187 break;
188 }
189
190 if (in_addr[a].addr == r->in_addr) {
191 break;
192 }
193 }
194 }
195
196 ctx = in_addr[a].core_srv_conf->ctx;
197
198 if (r->headers_in.host_name_len > 0) {
199
200 name = (ngx_http_server_name_t *) in_addr[a].names.elts;
201 for (n = 0; n < in_addr[a].names.nelts; n++) {
202 if (r->headers_in.host_name_len != name[n].name.len) {
203 continue;
204 }
205
206 if (ngx_strncasecmp(r->headers_in.host->value.data,
207 name[n].name.data,
208 r->headers_in.host_name_len) == 0) {
209 ctx = name->core_srv_conf->ctx;
210 break;
211 }
212 }
213 }
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000214 }
215
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000216 r->srv_conf = ctx->srv_conf;
217 r->loc_conf = ctx->loc_conf;
218
Igor Sysoeve2a31542003-04-08 15:40:10 +0000219#if 0
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000220ngx_log_debug(r->connection->log, "cxt: %08x" _ ctx);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000221ngx_log_debug(r->connection->log, "srv_conf: %0x" _ r->srv_conf);
222ngx_log_debug(r->connection->log, "loc_conf: %0x" _ r->loc_conf);
Igor Sysoeve2a31542003-04-08 15:40:10 +0000223#endif
224
225 /* run rewrite url phase */
226
227
228 /* find location config */
229
230 scf = (ngx_http_core_srv_conf_t *)
231 ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx);
232
233 plcf = (ngx_http_core_loc_conf_t **) scf->locations.elts;
234 for (i = 0; i < scf->locations.nelts; i++) {
235#if 0
236ngx_log_debug(r->connection->log, "trans: %s" _ plcf[i]->name.data);
237#endif
238 if (r->uri.len < plcf[i]->name.len) {
239 continue;
240 }
241
242 rc = ngx_strncmp(r->uri.data, plcf[i]->name.data, plcf[i]->name.len);
243
244 if (rc < 0) {
245 break;
246 }
247
248 if (rc == 0) {
249 r->loc_conf = plcf[i]->loc_conf;
250 }
251 }
252
253 lcf = (ngx_http_core_loc_conf_t *)
254 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
255
256 if (lcf->sendfile == 0) {
257 r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
258 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000259
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000260 /* run translation phase */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000261
262 h = (ngx_http_handler_pt *) ngx_http_translate_handlers.elts;
Igor Sysoeve2a31542003-04-08 15:40:10 +0000263 for (i = ngx_http_translate_handlers.nelts; i > 0; /* void */) {
264 rc = h[--i](r);
Igor Sysoevdc479b42003-03-20 16:09:44 +0000265
266 if (rc == NGX_DECLINED) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000267 continue;
268 }
269
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000270 if (rc == NGX_OK) {
271 break;
272 }
273
274 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
Igor Sysoevdc479b42003-03-20 16:09:44 +0000275 return rc;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000276 }
277 }
278
Igor Sysoevdc479b42003-03-20 16:09:44 +0000279 return r->handler(r);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000280}
281
282
283int ngx_http_core_translate_handler(ngx_http_request_t *r)
284{
Igor Sysoev1b8b1192003-01-29 17:02:48 +0000285 int i, rc, len, port_len, f_offset, l_offset;
Igor Sysoevad22e012003-01-15 07:02:27 +0000286 char *buf, *location, *last;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000287 ngx_err_t err;
288 ngx_table_elt_t *h;
Igor Sysoevad22e012003-01-15 07:02:27 +0000289 ngx_http_server_name_t *s_name;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000290 ngx_http_core_srv_conf_t *scf;
Igor Sysoeve2a31542003-04-08 15:40:10 +0000291 ngx_http_core_loc_conf_t *lcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000292
Igor Sysoeve2a31542003-04-08 15:40:10 +0000293 lcf = (ngx_http_core_loc_conf_t *)
294 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000295
Igor Sysoeve2a31542003-04-08 15:40:10 +0000296 if (lcf->handler) {
297 r->handler = lcf->handler;
298 return NGX_OK;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000299 }
300
Igor Sysoeve2a31542003-04-08 15:40:10 +0000301 scf = (ngx_http_core_srv_conf_t *)
302 ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx);
Igor Sysoevb7387572003-03-11 20:38:13 +0000303
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000304 if (r->uri.data[r->uri.len - 1] == '/') {
Igor Sysoevb2620632003-01-10 06:09:20 +0000305 r->handler = ngx_http_core_index_handler;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000306 return NGX_OK;
307 }
308
Igor Sysoevdc479b42003-03-20 16:09:44 +0000309ngx_log_debug(r->connection->log, "doc_root: %08x" _ &lcf->doc_root);
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000310
Igor Sysoevad22e012003-01-15 07:02:27 +0000311 s_name = (ngx_http_server_name_t *) scf->server_names.elts;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000312
Igor Sysoev1b8b1192003-01-29 17:02:48 +0000313 if (r->port == 0) {
314#if 0
315 struct sockaddr_in *addr_in;
316 addr_in = (struct sockaddr_in *) r->connection->sockaddr;
317 r->port = ntohs(addr_in->sin_port);
318#else
319 ngx_http_in_port_t *in_port;
320 in_port = (ngx_http_in_port_t *) r->connection->servers;
321 r->port = in_port->port;
322#endif
323 if (r->port != 80) {
324 ngx_test_null(r->port_name.data, ngx_palloc(r->pool, 7),
325 NGX_HTTP_INTERNAL_SERVER_ERROR);
326 r->port_name.len = ngx_snprintf(r->port_name.data, 7, ":%d",
327 r->port);
328 }
329 }
330
331 port_len = (r->port != 80) ? r->port_name.len : 0;
332
Igor Sysoevad22e012003-01-15 07:02:27 +0000333 /* "+ 7" is "http://" */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000334 if (lcf->doc_root.len > 7 + s_name[0].name.len + port_len) {
335 len = lcf->doc_root.len;
Igor Sysoevad22e012003-01-15 07:02:27 +0000336 f_offset = 0;
Igor Sysoev1b8b1192003-01-29 17:02:48 +0000337 l_offset = len - (7 + s_name[0].name.len + port_len);
Igor Sysoevad22e012003-01-15 07:02:27 +0000338
339 } else {
Igor Sysoev1b8b1192003-01-29 17:02:48 +0000340 len = 7 + s_name[0].name.len + port_len;
Igor Sysoevdc479b42003-03-20 16:09:44 +0000341 f_offset = len - lcf->doc_root.len;
Igor Sysoevad22e012003-01-15 07:02:27 +0000342 l_offset = 0;
343 }
344
345 /* "+ 2" is for trailing '/' in redirect and '\0' */
346 len += r->uri.len + 2;
347
348 ngx_test_null(buf, ngx_palloc(r->pool, len),
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000349 NGX_HTTP_INTERNAL_SERVER_ERROR);
350
Igor Sysoevad22e012003-01-15 07:02:27 +0000351 r->file.name.data = buf + f_offset;
352 location = buf + l_offset;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000353
Igor Sysoevdc479b42003-03-20 16:09:44 +0000354 last = ngx_cpystrn(ngx_cpystrn(r->file.name.data, lcf->doc_root.data,
355 lcf->doc_root.len + 1),
Igor Sysoevad22e012003-01-15 07:02:27 +0000356 r->uri.data, r->uri.len + 1);
357
358 r->file.name.len = last - r->file.name.data;
359
360ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000361
362#if (WIN9X)
363
Igor Sysoevdc479b42003-03-20 16:09:44 +0000364 /* There is no way to open a file or a directory in Win9X with
365 one syscall: Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag.
366 so we need to check its type before the opening */
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000367
368 r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data);
369 if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
370 err = ngx_errno;
371 ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
372 "ngx_http_core_translate_handler: "
373 ngx_file_type_n " %s failed", r->file.name.data);
374
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000375 if (err == NGX_ENOENT) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000376 return NGX_HTTP_NOT_FOUND;
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000377
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000378 } else if (err == ERROR_PATH_NOT_FOUND) {
379 return NGX_HTTP_NOT_FOUND;
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000380
Igor Sysoevad22e012003-01-15 07:02:27 +0000381 } else if (err == NGX_EACCES) {
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000382 return NGX_HTTP_FORBIDDEN;
383
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000384 } else {
385 return NGX_HTTP_INTERNAL_SERVER_ERROR;
386 }
387 }
388
389#else
390
391 if (r->file.fd == NGX_INVALID_FILE) {
392 r->file.fd = ngx_open_file(r->file.name.data, NGX_FILE_RDONLY);
393 }
394
395 if (r->file.fd == NGX_INVALID_FILE) {
396 err = ngx_errno;
397 ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
398 "ngx_http_core_handler: "
399 ngx_open_file_n " %s failed", r->file.name.data);
400
401 if (err == NGX_ENOENT) {
402 return NGX_HTTP_NOT_FOUND;
403#if (WIN32)
404 } else if (err == ERROR_PATH_NOT_FOUND) {
405 return NGX_HTTP_NOT_FOUND;
Igor Sysoevb2620632003-01-10 06:09:20 +0000406#else
407 } else if (err == NGX_ENOTDIR) {
408 return NGX_HTTP_NOT_FOUND;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000409#endif
Igor Sysoevad22e012003-01-15 07:02:27 +0000410 } else if (err == NGX_EACCES) {
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000411 return NGX_HTTP_FORBIDDEN;
412
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000413 } else {
414 return NGX_HTTP_INTERNAL_SERVER_ERROR;
415 }
416 }
417
418 if (!r->file.info_valid) {
419 if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
Igor Sysoevad22e012003-01-15 07:02:27 +0000420 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000421 "ngx_http_core_handler: "
422 ngx_stat_fd_n " %s failed", r->file.name.data);
423
424 if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
Igor Sysoevad22e012003-01-15 07:02:27 +0000425 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000426 "ngx_http_core_handler: "
427 ngx_close_file_n " %s failed", r->file.name.data);
428 }
429
430 return NGX_HTTP_INTERNAL_SERVER_ERROR;
431 }
432
433 r->file.info_valid = 1;
434 }
435#endif
436
437 if (ngx_is_dir(r->file.info)) {
Igor Sysoevad22e012003-01-15 07:02:27 +0000438ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000439
440#if !(WIN9X)
441 if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
Igor Sysoevad22e012003-01-15 07:02:27 +0000442 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000443 "ngx_http_core_handler: "
444 ngx_close_file_n " %s failed", r->file.name.data);
445 }
446#endif
447
448 /* BROKEN: need to include server name */
449
450 ngx_test_null(h, ngx_push_table(r->headers_out.headers),
451 NGX_HTTP_INTERNAL_SERVER_ERROR);
452
Igor Sysoevad22e012003-01-15 07:02:27 +0000453 ngx_memcpy(location, "http://", 7);
454 ngx_memcpy(location + 7, s_name[0].name.data, s_name[0].name.len);
Igor Sysoev1b8b1192003-01-29 17:02:48 +0000455 if (port_len) {
456 ngx_memcpy(location + 7 + s_name[0].name.len, r->port_name.data,
457 port_len);
458 }
Igor Sysoevad22e012003-01-15 07:02:27 +0000459
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000460 *last++ = '/';
461 *last = '\0';
462 h->key.len = 8;
463 h->key.data = "Location" ;
464 h->value.len = last - location;
465 h->value.data = location;
466 r->headers_out.location = h;
467
468 return NGX_HTTP_MOVED_PERMANENTLY;
469 }
470
Igor Sysoeve2a31542003-04-08 15:40:10 +0000471 r->handler = ngx_http_static_handler;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000472
473 return NGX_OK;
474}
475
476
Igor Sysoevb2620632003-01-10 06:09:20 +0000477static int ngx_http_core_index_handler(ngx_http_request_t *r)
478{
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000479 int i, rc;
Igor Sysoevb2620632003-01-10 06:09:20 +0000480 ngx_http_handler_pt *h;
481
482 h = (ngx_http_handler_pt *) ngx_http_index_handlers.elts;
Igor Sysoeve2a31542003-04-08 15:40:10 +0000483 for (i = ngx_http_index_handlers.nelts; i > 0; /* void */) {
484 rc = h[--i](r);
Igor Sysoevb2620632003-01-10 06:09:20 +0000485
486 if (rc != NGX_DECLINED) {
Igor Sysoevad22e012003-01-15 07:02:27 +0000487
488 if (rc == NGX_HTTP_NOT_FOUND) {
489 ngx_log_error(NGX_LOG_ERR, r->connection->log, r->path_err,
490 "%s is not found", r->path.data);
491 }
492
493 if (rc == NGX_HTTP_FORBIDDEN) {
494 ngx_log_error(NGX_LOG_ERR, r->connection->log, r->path_err,
495 "%s is forbidden", r->path.data);
496 }
497
Igor Sysoevb2620632003-01-10 06:09:20 +0000498 return rc;
499 }
500 }
501
Igor Sysoevad22e012003-01-15 07:02:27 +0000502 r->path.data[r->path.len] = '\0';
503 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
504 "directory index of %s is forbidden", r->path.data);
505
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000506 return NGX_HTTP_FORBIDDEN;
Igor Sysoevb2620632003-01-10 06:09:20 +0000507}
508
509
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000510int ngx_http_send_header(ngx_http_request_t *r)
511{
512 return (*ngx_http_top_header_filter)(r);
513}
514
515
516int ngx_http_redirect(ngx_http_request_t *r, int redirect)
517{
518 /* STUB */
519
520 /* log request */
521
Igor Sysoevdc479b42003-03-20 16:09:44 +0000522 return ngx_http_close_request(r, 0);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000523}
524
525
526int ngx_http_error(ngx_http_request_t *r, int error)
527{
528 /* STUB */
529 ngx_log_debug(r->connection->log, "http error: %d" _ error);
530
531 /* log request */
532
Igor Sysoevdc479b42003-03-20 16:09:44 +0000533 ngx_http_special_response_handler(r, error);
534 return ngx_http_close_request(r, 0);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000535}
536
537
Igor Sysoevdc479b42003-03-20 16:09:44 +0000538int ngx_http_close_request(ngx_http_request_t *r, int error)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000539{
Igor Sysoevb7387572003-03-11 20:38:13 +0000540 ngx_connection_t *c;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000541 ngx_http_log_ctx_t *ctx;
542
Igor Sysoevb7387572003-03-11 20:38:13 +0000543 c = r->connection;
Igor Sysoevdc479b42003-03-20 16:09:44 +0000544 if (error) {
545 r->headers_out.status = error;
546 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000547
548 ngx_http_log_handler(r);
549
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000550 if (r->file.fd != NGX_INVALID_FILE) {
551 if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
Igor Sysoevb7387572003-03-11 20:38:13 +0000552 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000553 ngx_close_file_n " failed");
554 }
555 }
556
Igor Sysoev6a644c62003-03-04 06:33:48 +0000557 /* ctx->url was allocated from r->pool */
Igor Sysoevb7387572003-03-11 20:38:13 +0000558 ctx = (ngx_http_log_ctx_t *) c->log->data;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000559 ctx->url = NULL;
560
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000561 ngx_destroy_pool(r->pool);
562
Igor Sysoevb7387572003-03-11 20:38:13 +0000563 if (c->read->timer_set) {
564 ngx_del_timer(c->read);
565 c->read->timer_set = 0;
Igor Sysoev73009772003-02-06 17:21:13 +0000566 }
567
Igor Sysoevb7387572003-03-11 20:38:13 +0000568 if (c->write->timer_set) {
569 ngx_del_timer(c->write);
570 c->write->timer_set = 0;
Igor Sysoev73009772003-02-06 17:21:13 +0000571 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000572
Igor Sysoevb7387572003-03-11 20:38:13 +0000573 ngx_log_debug(c->log, "http closed");
574
Igor Sysoeve2a31542003-04-08 15:40:10 +0000575 return NGX_ERROR; /* to close connection */
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000576}
577
578
579int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri)
580{
581 ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri.data);
582
583 r->uri.len = uri.len;
584 r->uri.data = uri.data;
585
586 /* NEEDED ? */
587 r->uri_start = uri.data;
588 r->uri_end = uri.data + uri.len;
589 /**/
590
591 return ngx_http_handler(r);
592}
593
594
Igor Sysoevdc479b42003-03-20 16:09:44 +0000595static int ngx_http_core_init(ngx_pool_t *pool)
596{
597 ngx_http_handler_pt *h;
598
599 ngx_test_null(h, ngx_push_array(&ngx_http_translate_handlers), NGX_ERROR);
600
601 *h = ngx_http_core_translate_handler;
602
603 return NGX_OK;
604}
605
606
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000607static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
608{
Igor Sysoevdc479b42003-03-20 16:09:44 +0000609 int i, j;
610 char *rv;
611 ngx_http_module_t *module;
612 ngx_http_conf_ctx_t *ctx, *prev;
613 ngx_http_core_srv_conf_t *scf;
614 ngx_http_core_loc_conf_t **plcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000615
616 ngx_test_null(ctx,
617 ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
618 NGX_CONF_ERROR);
619
620 /* server config */
621 ngx_test_null(ctx->srv_conf,
622 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
623 NGX_CONF_ERROR);
624
625 /* server location config */
626 ngx_test_null(ctx->loc_conf,
627 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
628 NGX_CONF_ERROR);
629
630 for (i = 0; ngx_modules[i]; i++) {
631 if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
632 continue;
633 }
634
635 module = (ngx_http_module_t *) ngx_modules[i]->ctx;
636
637 if (module->create_srv_conf) {
Igor Sysoeve2a31542003-04-08 15:40:10 +0000638 ngx_test_null(ctx->srv_conf[module->index],
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000639 module->create_srv_conf(cf->pool),
640 NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000641 }
642
643 if (module->create_loc_conf) {
Igor Sysoeve2a31542003-04-08 15:40:10 +0000644 ngx_test_null(ctx->loc_conf[module->index],
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000645 module->create_loc_conf(cf->pool),
646 NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000647 }
648 }
649
650 prev = cf->ctx;
651 cf->ctx = ctx;
652 rv = ngx_conf_parse(cf, NULL);
653 cf->ctx = prev;
654
655 if (rv != NGX_CONF_OK)
656 return rv;
657
658
Igor Sysoeve2a31542003-04-08 15:40:10 +0000659 scf = ctx->srv_conf[ngx_http_core_module_ctx.index];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000660 scf->ctx = ctx;
661
Igor Sysoevdc479b42003-03-20 16:09:44 +0000662 plcf = (ngx_http_core_loc_conf_t **)scf->locations.elts;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000663
664 for (i = 0; ngx_modules[i]; i++) {
665 if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
666 continue;
667 }
668
669 module = (ngx_http_module_t *) ngx_modules[i]->ctx;
670
671 if (module->init_srv_conf) {
672 if (module->init_srv_conf(cf->pool,
Igor Sysoeve2a31542003-04-08 15:40:10 +0000673 ctx->srv_conf[module->index])
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000674 == NGX_CONF_ERROR) {
675 return NGX_CONF_ERROR;
676 }
677 }
678
679 if (module->merge_loc_conf) {
680 if (module->merge_loc_conf(cf->pool,
Igor Sysoeve2a31542003-04-08 15:40:10 +0000681 prev->loc_conf[module->index],
682 ctx->loc_conf[module->index])
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000683 == NGX_CONF_ERROR) {
684 return NGX_CONF_ERROR;
685 }
686
687 for (j = 0; j < scf->locations.nelts; j++) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000688 if (module->merge_loc_conf(cf->pool,
Igor Sysoeve2a31542003-04-08 15:40:10 +0000689 ctx->loc_conf[module->index],
690 plcf[j]->loc_conf[module->index])
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000691 == NGX_CONF_ERROR) {
692 return NGX_CONF_ERROR;
693 }
694 }
695 }
696 }
697
698 return NGX_CONF_OK;
699}
700
701
702static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
703{
704 int i;
705 char *rv;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000706 ngx_str_t *location;
707 ngx_http_module_t *module;
708 ngx_http_conf_ctx_t *ctx, *prev;
709 ngx_http_core_srv_conf_t *scf;
Igor Sysoevdc479b42003-03-20 16:09:44 +0000710 ngx_http_core_loc_conf_t *lcf, **plcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000711
712 ngx_test_null(ctx,
713 ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
714 NGX_CONF_ERROR);
715
716 prev = (ngx_http_conf_ctx_t *) cf->ctx;
717 ctx->srv_conf = prev->srv_conf;
718
719 ngx_test_null(ctx->loc_conf,
720 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
721 NGX_CONF_ERROR);
722
723 for (i = 0; ngx_modules[i]; i++) {
724 if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
725 continue;
726 }
727
728 module = (ngx_http_module_t *) ngx_modules[i]->ctx;
729
730 if (module->create_loc_conf) {
Igor Sysoeve2a31542003-04-08 15:40:10 +0000731 ngx_test_null(ctx->loc_conf[module->index],
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000732 module->create_loc_conf(cf->pool),
733 NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000734 }
735 }
736
737 lcf = (ngx_http_core_loc_conf_t *)
Igor Sysoeve2a31542003-04-08 15:40:10 +0000738 ctx->loc_conf[ngx_http_core_module_ctx.index];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000739 location = (ngx_str_t *) cf->args->elts;
740 lcf->name.len = location[1].len;
741 lcf->name.data = location[1].data;
742 lcf->loc_conf = ctx->loc_conf;
743
744 scf = (ngx_http_core_srv_conf_t *)
Igor Sysoeve2a31542003-04-08 15:40:10 +0000745 ctx->srv_conf[ngx_http_core_module_ctx.index];
Igor Sysoevdc479b42003-03-20 16:09:44 +0000746 ngx_test_null(plcf, ngx_push_array(&scf->locations), NGX_CONF_ERROR);
747 *plcf = lcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000748
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000749 cf->ctx = ctx;
750 rv = ngx_conf_parse(cf, NULL);
751 cf->ctx = prev;
752
753 return rv;
754}
755
756
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000757static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool)
758{
759 ngx_http_core_srv_conf_t *scf, **cf;
760
761 ngx_test_null(scf,
762 ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)),
763 NGX_CONF_ERROR);
764
765 ngx_init_array(scf->locations, pool, 5, sizeof(void *), NGX_CONF_ERROR);
766 ngx_init_array(scf->listen, pool, 5, sizeof(ngx_http_listen_t),
767 NGX_CONF_ERROR);
Igor Sysoevad22e012003-01-15 07:02:27 +0000768 ngx_init_array(scf->server_names, pool, 5, sizeof(ngx_http_server_name_t),
769 NGX_CONF_ERROR);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000770
771 ngx_test_null(cf, ngx_push_array(&ngx_http_servers), NGX_CONF_ERROR);
772 *cf = scf;
773
774 return scf;
775}
776
777
778static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf)
779{
780 ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf;
781
782 ngx_http_listen_t *l;
Igor Sysoevad22e012003-01-15 07:02:27 +0000783 ngx_http_server_name_t *n;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000784
785 if (scf->listen.nelts == 0) {
786 ngx_test_null(l, ngx_push_array(&scf->listen), NGX_CONF_ERROR);
787 l->addr = INADDR_ANY;
788 l->port = 8000;
789 l->family = AF_INET;
790 }
791
Igor Sysoevad22e012003-01-15 07:02:27 +0000792 if (scf->server_names.nelts == 0) {
793 ngx_test_null(n, ngx_push_array(&scf->server_names), NGX_CONF_ERROR);
794 ngx_test_null(n->name.data, ngx_palloc(pool, NGX_MAXHOSTNAMELEN),
795 NGX_CONF_ERROR);
796 if (gethostname(n->name.data, NGX_MAXHOSTNAMELEN) == -1) {
797/* STUB: no log here */
798#if 0
799 ngx_log_error(NGX_LOG_EMERG, scf->log, ngx_errno,
800 "gethostname() failed");
801#endif
802 return NGX_CONF_ERROR;
803 }
804 n->name.len = ngx_strlen(n->name.data);
805 n->core_srv_conf = conf;
806 }
807
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000808 return NGX_CONF_OK;
809}
810
811
812static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool)
813{
814 ngx_http_core_loc_conf_t *lcf;
815
816 ngx_test_null(lcf,
817 ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)),
818 NGX_CONF_ERROR);
819
820 lcf->doc_root.len = 4;
821 lcf->doc_root.data = "html";
822
Igor Sysoeve2a31542003-04-08 15:40:10 +0000823 lcf->sendfile = 0;
824
Igor Sysoevdc479b42003-03-20 16:09:44 +0000825 lcf->send_timeout = 10000;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000826 lcf->discarded_buffer_size = 1500;
Igor Sysoevb7387572003-03-11 20:38:13 +0000827 lcf->lingering_time = 30000;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000828 lcf->lingering_timeout = 5000;
829
830/*
831 lcf->send_timeout = NGX_CONF_UNSET;
832*/
833
834 return lcf;
835}
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000836
Igor Sysoeve2a31542003-04-08 15:40:10 +0000837static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool,
838 void *parent, void *child)
839{
840 return NGX_CONF_OK;
841}
842
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000843static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
844{
845 ngx_str_t *args;
846 ngx_http_listen_t *ls;
847 ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf;
848
849 ngx_test_null(ls, ngx_push_array(&scf->listen), NGX_CONF_ERROR);
850
851 /* AF_INET only */
852
853 ls->family = AF_INET;
854 ls->addr = INADDR_ANY;
855 ls->flags = 0;
Igor Sysoevfe5cb6b2003-01-29 07:25:51 +0000856 ls->file_name = cf->conf_file->file.name;
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000857 ls->line = cf->conf_file->line;
858
859 args = (ngx_str_t *) cf->args->elts;
860
861 ls->port = atoi(args[1].data);
Igor Sysoevb7387572003-03-11 20:38:13 +0000862 if (ls->port < 1 || ls->port > 65536) {
863 return "port must be between 1 and 65535";
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000864 }
865
866 return NGX_CONF_OK;
867}