Mercurial > hg > nginx-vendor-0-7
comparison src/http/modules/ngx_http_static_module.c @ 58:b55cbf18157e NGINX_0_1_29
nginx 0.1.29
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; bug appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Thu, 12 May 2005 00:00:00 +0400 |
parents | 72eb30262aac |
children | da9a3b14312d |
comparison
equal
deleted
inserted
replaced
57:5df375c55338 | 58:b55cbf18157e |
---|---|
15 | 15 |
16 | 16 |
17 static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r); | 17 static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r); |
18 static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf); | 18 static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf); |
19 static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf, | 19 static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf, |
20 void *parent, void *child); | 20 void *parent, void *child); |
21 static ngx_int_t ngx_http_static_init(ngx_cycle_t *cycle); | 21 static ngx_int_t ngx_http_static_init(ngx_cycle_t *cycle); |
22 | 22 |
23 | 23 |
24 static ngx_command_t ngx_http_static_commands[] = { | 24 static ngx_command_t ngx_http_static_commands[] = { |
25 | 25 |
36 | 36 |
37 ngx_null_command | 37 ngx_null_command |
38 }; | 38 }; |
39 | 39 |
40 | 40 |
41 | |
42 ngx_http_module_t ngx_http_static_module_ctx = { | 41 ngx_http_module_t ngx_http_static_module_ctx = { |
43 NULL, /* pre conf */ | 42 NULL, /* preconfiguration */ |
43 NULL, /* postconfiguration */ | |
44 | 44 |
45 NULL, /* create main configuration */ | 45 NULL, /* create main configuration */ |
46 NULL, /* init main configuration */ | 46 NULL, /* init main configuration */ |
47 | 47 |
48 NULL, /* create server configuration */ | 48 NULL, /* create server configuration */ |
52 ngx_http_static_merge_loc_conf /* merge location configuration */ | 52 ngx_http_static_merge_loc_conf /* merge location configuration */ |
53 }; | 53 }; |
54 | 54 |
55 | 55 |
56 ngx_module_t ngx_http_static_module = { | 56 ngx_module_t ngx_http_static_module = { |
57 NGX_MODULE, | 57 NGX_MODULE_V1, |
58 &ngx_http_static_module_ctx, /* module context */ | 58 &ngx_http_static_module_ctx, /* module context */ |
59 ngx_http_static_commands, /* module directives */ | 59 ngx_http_static_commands, /* module directives */ |
60 NGX_HTTP_MODULE, /* module type */ | 60 NGX_HTTP_MODULE, /* module type */ |
61 ngx_http_static_init, /* init module */ | 61 ngx_http_static_init, /* init module */ |
62 NULL /* init process */ | 62 NULL /* init process */ |
63 }; | 63 }; |
64 | 64 |
65 | 65 |
66 static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r) | 66 static ngx_int_t |
67 ngx_http_static_handler(ngx_http_request_t *r) | |
67 { | 68 { |
68 u_char *last; | 69 u_char *last; |
69 ngx_fd_t fd; | 70 ngx_fd_t fd; |
70 ngx_int_t rc; | 71 ngx_int_t rc; |
71 ngx_uint_t level; | 72 ngx_uint_t level; |
73 ngx_err_t err; | 74 ngx_err_t err; |
74 ngx_log_t *log; | 75 ngx_log_t *log; |
75 ngx_buf_t *b; | 76 ngx_buf_t *b; |
76 ngx_chain_t out; | 77 ngx_chain_t out; |
77 ngx_file_info_t fi; | 78 ngx_file_info_t fi; |
78 ngx_http_cleanup_t *file_cleanup; | 79 ngx_pool_cleanup_file_t *cln; |
79 #if (NGX_HTTP_CACHE) | |
80 ngx_http_cleanup_t *redirect_cleanup; | |
81 #endif | |
82 ngx_http_core_loc_conf_t *clcf; | 80 ngx_http_core_loc_conf_t *clcf; |
83 #if (NGX_HTTP_CACHE) | |
84 ngx_http_static_loc_conf_t *slcf; | |
85 uint32_t file_crc, redirect_crc; | |
86 ngx_http_cache_t *file, *redirect; | |
87 #endif | |
88 | 81 |
89 if (r->uri.data[r->uri.len - 1] == '/') { | 82 if (r->uri.data[r->uri.len - 1] == '/') { |
90 return NGX_DECLINED; | 83 return NGX_DECLINED; |
91 } | 84 } |
92 | 85 |
102 rc = ngx_http_discard_body(r); | 95 rc = ngx_http_discard_body(r); |
103 | 96 |
104 if (rc != NGX_OK && rc != NGX_AGAIN) { | 97 if (rc != NGX_OK && rc != NGX_AGAIN) { |
105 return rc; | 98 return rc; |
106 } | 99 } |
107 | |
108 #if (NGX_HTTP_CACHE) | |
109 | |
110 /* | |
111 * there is a valid cached open file, i.e by the index handler, | |
112 * and it should be already registered in r->cleanup | |
113 */ | |
114 | |
115 if (r->cache && !r->cache->expired) { | |
116 return ngx_http_send_cached(r); | |
117 } | |
118 | |
119 #endif | |
120 | 100 |
121 log = r->connection->log; | 101 log = r->connection->log; |
122 | 102 |
123 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 103 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
124 | 104 |
125 /* | 105 /* |
126 * make a file name, reserve 2 bytes for a trailing '/' | 106 * make a file name, reserve 2 bytes for a trailing '/' |
127 * in a possible redirect and for the last '\0' | 107 * in a possible redirect and for the last '\0' |
128 */ | 108 */ |
129 | 109 |
130 if (clcf->alias) { | 110 if (!clcf->alias) { |
111 name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2); | |
112 if (name.data == NULL) { | |
113 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
114 } | |
115 | |
116 location.data = ngx_cpymem(name.data, clcf->root.data, clcf->root.len); | |
117 last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1); | |
118 | |
119 name.len = last - name.data; | |
120 location.len = last - location.data + 1; | |
121 | |
122 } else { | |
131 name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2 | 123 name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2 |
132 - clcf->name.len); | 124 - clcf->name.len); |
133 if (name.data == NULL) { | 125 if (name.data == NULL) { |
134 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 126 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
135 } | 127 } |
145 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 137 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
146 } | 138 } |
147 | 139 |
148 last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1); | 140 last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1); |
149 | 141 |
150 #if 0 | |
151 /* | |
152 * aliases usually have trailling "/", | |
153 * set it in the start of the possible redirect | |
154 */ | |
155 | |
156 if (*location.data != '/') { | |
157 location.data--; | |
158 } | |
159 #endif | |
160 | |
161 location.len = last - location.data + 1; | |
162 | |
163 } else { | |
164 name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2); | |
165 if (name.data == NULL) { | |
166 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
167 } | |
168 | |
169 location.data = ngx_cpymem(name.data, clcf->root.data, clcf->root.len); | |
170 last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1); | |
171 | |
172 name.len = last - name.data; | |
173 location.len = last - location.data + 1; | 142 location.len = last - location.data + 1; |
174 } | 143 } |
175 | 144 |
176 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, | 145 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, |
177 "http filename: \"%s\"", name.data); | 146 "http filename: \"%s\"", name.data); |
178 | 147 |
179 | 148 /* open file */ |
180 /* allocate cleanups */ | 149 |
181 | 150 #if (NGX_WIN9X) |
182 file_cleanup = ngx_array_push(&r->cleanup); | 151 |
183 if (file_cleanup == NULL) { | 152 if (ngx_win32_version < NGX_WIN_NT) { |
184 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 153 |
185 } | 154 /* |
186 file_cleanup->valid = 0; | 155 * there is no way to open a file or a directory in Win9X with |
187 | 156 * one syscall because Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag |
188 #if (NGX_HTTP_CACHE) | 157 * so we need to check its type before the opening |
189 | 158 */ |
190 slcf = ngx_http_get_module_loc_conf(r, ngx_http_static_module); | 159 |
191 if (slcf->redirect_cache) { | 160 if (ngx_file_info(name.data, &fi) == NGX_FILE_ERROR) { |
192 redirect_cleanup = ngx_array_push(&r->cleanup); | 161 err = ngx_errno; |
193 if (redirect_cleanup == NULL) { | 162 ngx_log_error(NGX_LOG_ERR, log, err, |
194 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 163 ngx_file_info_n " \"%s\" failed", name.data); |
195 } | 164 |
196 redirect_cleanup->valid = 0; | 165 if (err == NGX_ENOENT || err == NGX_ENOTDIR) { |
197 | 166 return NGX_HTTP_NOT_FOUND; |
198 } else { | 167 |
199 redirect_cleanup = NULL; | 168 } else if (err == NGX_EACCES) { |
200 } | 169 return NGX_HTTP_FORBIDDEN; |
201 | 170 |
202 /* look up an open files cache */ | 171 } else { |
203 | 172 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
204 if (clcf->open_files) { | 173 } |
205 file = ngx_http_cache_get(clcf->open_files, file_cleanup, | 174 } |
206 &name, &file_crc); | 175 |
207 | 176 if (ngx_is_dir(&fi)) { |
208 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, | |
209 "http open file cache get: %p", file); | |
210 | |
211 if (file && !file->expired) { | |
212 r->cache = file; | |
213 return ngx_http_send_cached(r); | |
214 } | |
215 | |
216 } else { | |
217 file = NULL; | |
218 } | |
219 | |
220 | |
221 /* look up an redirect cache */ | |
222 | |
223 if (slcf->redirect_cache) { | |
224 redirect = ngx_http_cache_get(slcf->redirect_cache, redirect_cleanup, | |
225 &name, &redirect_crc); | |
226 | |
227 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, | |
228 "http redirect cache get: %p", redirect); | |
229 | |
230 if (redirect && !redirect->expired) { | |
231 | |
232 /* | |
233 * We do not copy a cached value so the cache entry is locked | |
234 * until the end of the request. In a single threaded model | |
235 * the redirected request should complete before other event | |
236 * will be processed. In a multithreaded model this locking | |
237 * should keep more popular redirects in cache. | |
238 */ | |
239 | |
240 r->headers_out.location = ngx_http_add_header(&r->headers_out, | 177 r->headers_out.location = ngx_http_add_header(&r->headers_out, |
241 ngx_http_headers_out); | 178 ngx_http_headers_out); |
242 if (r->headers_out.location == NULL) { | 179 if (r->headers_out.location == NULL) { |
243 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 180 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
244 } | 181 } |
245 | 182 |
246 r->headers_out.location->value = redirect->data.value; | |
247 | |
248 return NGX_HTTP_MOVED_PERMANENTLY; | |
249 } | |
250 | |
251 } else { | |
252 redirect = NULL; | |
253 } | |
254 | |
255 #endif | |
256 | |
257 /* open file */ | |
258 | |
259 #if (NGX_WIN9X) | |
260 | |
261 /* TODO: redirect cache */ | |
262 | |
263 if (ngx_win32_version < NGX_WIN_NT) { | |
264 | |
265 /* | |
266 * there is no way to open a file or a directory in Win9X with | |
267 * one syscall because Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag | |
268 * so we need to check its type before the opening | |
269 */ | |
270 | |
271 if (ngx_file_info(name.data, &fi) == NGX_FILE_ERROR) { | |
272 err = ngx_errno; | |
273 ngx_log_error(NGX_LOG_ERR, log, err, | |
274 ngx_file_info_n " \"%s\" failed", name.data); | |
275 | |
276 if (err == NGX_ENOENT || err == NGX_ENOTDIR) { | |
277 return NGX_HTTP_NOT_FOUND; | |
278 | |
279 } else if (err == NGX_EACCES) { | |
280 return NGX_HTTP_FORBIDDEN; | |
281 | |
282 } else { | |
283 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
284 } | |
285 } | |
286 | |
287 if (ngx_is_dir(&fi)) { | |
288 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, | |
289 "HTTP DIR: \"%s\"", name.data); | |
290 | |
291 r->headers_out.location = ngx_http_add_header(&r->headers_out, | |
292 ngx_http_headers_out); | |
293 if (r->headers_out.location == NULL) { | |
294 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
295 } | |
296 | |
297 *last++ = '/'; | 183 *last++ = '/'; |
298 *last = '\0'; | 184 *last = '\0'; |
299 r->headers_out.location->value.len = last - location; | 185 r->headers_out.location->value.len = last - location; |
300 r->headers_out.location->value.data = location; | 186 r->headers_out.location->value.data = location; |
301 | 187 |
354 } | 240 } |
355 | 241 |
356 *last++ = '/'; | 242 *last++ = '/'; |
357 *last = '\0'; | 243 *last = '\0'; |
358 | 244 |
359 r->headers_out.location = ngx_list_push(&r->headers_out.headers); | 245 r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t)); |
360 if (r->headers_out.location == NULL) { | 246 if (r->headers_out.location == NULL) { |
361 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 247 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
362 } | 248 } |
363 | 249 |
250 /* | |
251 * we do not need to set the r->headers_out.location->hash and | |
252 * r->headers_out.location->key fields | |
253 */ | |
254 | |
364 r->headers_out.location->value = location; | 255 r->headers_out.location->value = location; |
365 | |
366 #if (NGX_HTTP_CACHE) | |
367 | |
368 if (slcf->redirect_cache) { | |
369 if (redirect) { | |
370 if (location.len == redirect->data.value.len | |
371 && ngx_memcmp(redirect->data.value.data, location.data, | |
372 location.len) == 0) | |
373 { | |
374 redirect->accessed = ngx_cached_time; | |
375 redirect->updated = ngx_cached_time; | |
376 | |
377 /* | |
378 * we can unlock the cache entry because | |
379 * we have the local copy anyway | |
380 */ | |
381 | |
382 ngx_http_cache_unlock(slcf->redirect_cache, redirect, log); | |
383 redirect_cleanup->valid = 0; | |
384 | |
385 return NGX_HTTP_MOVED_PERMANENTLY; | |
386 } | |
387 } | |
388 | |
389 location.len++; | |
390 redirect = ngx_http_cache_alloc(slcf->redirect_cache, redirect, | |
391 redirect_cleanup, | |
392 &name, redirect_crc, | |
393 &location, log); | |
394 location.len--; | |
395 | |
396 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, | |
397 "http redirect cache alloc: %p", redirect); | |
398 | |
399 if (redirect) { | |
400 redirect->fd = NGX_INVALID_FILE; | |
401 redirect->accessed = ngx_cached_time; | |
402 redirect->last_modified = 0; | |
403 redirect->updated = ngx_cached_time; | |
404 redirect->memory = 1; | |
405 ngx_http_cache_unlock(slcf->redirect_cache, redirect, log); | |
406 redirect_cleanup->valid = 0; | |
407 } | |
408 | |
409 } | |
410 | |
411 #endif | |
412 | 256 |
413 return NGX_HTTP_MOVED_PERMANENTLY; | 257 return NGX_HTTP_MOVED_PERMANENTLY; |
414 } | 258 } |
415 | 259 |
416 #if !(NGX_WIN32) /* the not regular files are probably Unix specific */ | 260 #if !(NGX_WIN32) /* the not regular files are probably Unix specific */ |
427 return NGX_HTTP_NOT_FOUND; | 271 return NGX_HTTP_NOT_FOUND; |
428 } | 272 } |
429 | 273 |
430 #endif | 274 #endif |
431 | 275 |
432 | |
433 #if (NGX_HTTP_CACHE) | |
434 | |
435 if (clcf->open_files) { | |
436 | |
437 #if (NGX_USE_HTTP_FILE_CACHE_UNIQ) | |
438 | |
439 if (file && file->uniq == ngx_file_uniq(&fi)) { | |
440 if (ngx_close_file(fd) == NGX_FILE_ERROR) { | |
441 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
442 ngx_close_file_n " \"%s\" failed", name.data); | |
443 } | |
444 file->accessed = ngx_cached_time; | |
445 file->updated = ngx_cached_time; | |
446 file->expired = 0; | |
447 r->cache = file; | |
448 | |
449 return ngx_http_send_cached(r); | |
450 | |
451 } else { | |
452 if (file) { | |
453 ngx_http_cache_unlock(clcf->open_files, file, log); | |
454 file = NULL; | |
455 } | |
456 | |
457 file = ngx_http_cache_alloc(clcf->open_files, file, | |
458 file_cleanup, | |
459 &name, file_crc, NULL, log); | |
460 if (file) { | |
461 file->uniq = ngx_file_uniq(&fi); | |
462 } | |
463 } | |
464 | |
465 #else | |
466 file = ngx_http_cache_alloc(clcf->open_files, file, | |
467 file_cleanup, | |
468 &name, file_crc, NULL, log); | |
469 #endif | |
470 | |
471 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, | |
472 "http open file cache alloc: %p", file); | |
473 | |
474 if (file) { | |
475 file->fd = fd; | |
476 file->data.size = ngx_file_size(&fi); | |
477 file->accessed = ngx_cached_time; | |
478 file->last_modified = ngx_file_mtime(&fi); | |
479 file->updated = ngx_cached_time; | |
480 r->cache = file; | |
481 } | |
482 | |
483 return ngx_http_send_cached(r); | |
484 } | |
485 | |
486 #endif | |
487 | |
488 log->action = "sending response to client"; | 276 log->action = "sending response to client"; |
489 | 277 |
490 file_cleanup->data.file.fd = fd; | 278 cln = ngx_palloc(r->pool, sizeof(ngx_pool_cleanup_file_t)); |
491 file_cleanup->data.file.name = name.data; | 279 if (cln == NULL) { |
492 file_cleanup->valid = 1; | 280 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
493 file_cleanup->cache = 0; | 281 } |
282 | |
283 cln->fd = fd; | |
284 cln->name = name.data; | |
285 cln->log = r->pool->log; | |
286 | |
287 if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) { | |
288 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
289 } | |
494 | 290 |
495 r->headers_out.status = NGX_HTTP_OK; | 291 r->headers_out.status = NGX_HTTP_OK; |
496 r->headers_out.content_length_n = ngx_file_size(&fi); | 292 r->headers_out.content_length_n = ngx_file_size(&fi); |
497 r->headers_out.last_modified_time = ngx_file_mtime(&fi); | 293 r->headers_out.last_modified_time = ngx_file_mtime(&fi); |
498 | 294 |
530 return rc; | 326 return rc; |
531 } | 327 } |
532 | 328 |
533 b->in_file = 1; | 329 b->in_file = 1; |
534 | 330 |
535 if (!r->main) { | 331 if (r->main == NULL) { |
536 b->last_buf = 1; | 332 b->last_buf = 1; |
537 } | 333 } |
334 | |
335 b->last_in_chain = 1; | |
538 | 336 |
539 b->file_pos = 0; | 337 b->file_pos = 0; |
540 b->file_last = ngx_file_size(&fi); | 338 b->file_last = ngx_file_size(&fi); |
541 | 339 |
542 b->file->fd = fd; | 340 b->file->fd = fd; |
548 | 346 |
549 return ngx_http_output_filter(r, &out); | 347 return ngx_http_output_filter(r, &out); |
550 } | 348 } |
551 | 349 |
552 | 350 |
553 static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf) | 351 static void * |
352 ngx_http_static_create_loc_conf(ngx_conf_t *cf) | |
554 { | 353 { |
555 ngx_http_static_loc_conf_t *conf; | 354 ngx_http_static_loc_conf_t *conf; |
556 | 355 |
557 conf = ngx_palloc(cf->pool, sizeof(ngx_http_static_loc_conf_t)); | 356 conf = ngx_palloc(cf->pool, sizeof(ngx_http_static_loc_conf_t)); |
558 if (conf == NULL) { | 357 if (conf == NULL) { |
563 | 362 |
564 return conf; | 363 return conf; |
565 } | 364 } |
566 | 365 |
567 | 366 |
568 static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf, | 367 static char * |
569 void *parent, void *child) | 368 ngx_http_static_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) |
570 { | 369 { |
571 ngx_http_static_loc_conf_t *prev = parent; | 370 ngx_http_static_loc_conf_t *prev = parent; |
572 ngx_http_static_loc_conf_t *conf = child; | 371 ngx_http_static_loc_conf_t *conf = child; |
573 | 372 |
574 if (conf->redirect_cache == NULL) { | 373 if (conf->redirect_cache == NULL) { |
577 | 376 |
578 return NGX_CONF_OK; | 377 return NGX_CONF_OK; |
579 } | 378 } |
580 | 379 |
581 | 380 |
582 static ngx_int_t ngx_http_static_init(ngx_cycle_t *cycle) | 381 static ngx_int_t |
382 ngx_http_static_init(ngx_cycle_t *cycle) | |
583 { | 383 { |
584 ngx_http_handler_pt *h; | 384 ngx_http_handler_pt *h; |
585 ngx_http_core_main_conf_t *cmcf; | 385 ngx_http_core_main_conf_t *cmcf; |
586 | 386 |
587 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); | 387 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); |