comparison src/http/modules/ngx_http_static_module.c @ 106:45f7329b4bd0 NGINX_0_3_0

nginx 0.3.0 *) Change: the 10-days live time limit of worker process was eliminated. The limit was introduced because of millisecond timers overflow.
author Igor Sysoev <http://sysoev.ru>
date Fri, 07 Oct 2005 00:00:00 +0400
parents f63280c59dd5
children 408f195b3482
comparison
equal deleted inserted replaced
105:531d62c2a28d 106:45f7329b4bd0
70 70
71 71
72 static ngx_int_t 72 static ngx_int_t
73 ngx_http_static_handler(ngx_http_request_t *r) 73 ngx_http_static_handler(ngx_http_request_t *r)
74 { 74 {
75 u_char *last; 75 u_char *last, *location;
76 ngx_fd_t fd; 76 ngx_fd_t fd;
77 ngx_int_t rc; 77 ngx_int_t rc;
78 ngx_uint_t level; 78 ngx_uint_t level;
79 ngx_str_t name, location; 79 ngx_str_t path;
80 ngx_err_t err; 80 ngx_err_t err;
81 ngx_log_t *log; 81 ngx_log_t *log;
82 ngx_buf_t *b; 82 ngx_buf_t *b;
83 ngx_chain_t out; 83 ngx_chain_t out;
84 ngx_file_info_t fi; 84 ngx_file_info_t fi;
85 ngx_pool_cleanup_file_t *cln; 85 ngx_pool_cleanup_file_t *cln;
86 ngx_http_core_loc_conf_t *clcf; 86 ngx_http_core_loc_conf_t *clcf;
87 87
88 if (r->uri.data[r->uri.len - 1] == '/') { 88 if (r->uri.data[r->uri.len - 1] == '/') {
89 return NGX_DECLINED; 89 return NGX_DECLINED;
90 } 90 }
91 91
104 return rc; 104 return rc;
105 } 105 }
106 106
107 log = r->connection->log; 107 log = r->connection->log;
108 108
109 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
110
111 /* 109 /*
112 * make a file name, reserve 2 bytes for a trailing '/' 110 * ngx_http_map_uri_to_path() allocates memory for terminating '\0'
113 * in a possible redirect and for the last '\0' 111 * so we do not need to reserve memory for '/' for possible redirect
114 */ 112 */
115 113
116 if (!clcf->alias) { 114 last = ngx_http_map_uri_to_path(r, &path, 0);
117 name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2); 115 if (last == NULL) {
118 if (name.data == NULL) { 116 return NGX_HTTP_INTERNAL_SERVER_ERROR;
119 return NGX_HTTP_INTERNAL_SERVER_ERROR;
120 }
121
122 location.data = ngx_cpymem(name.data, clcf->root.data, clcf->root.len);
123 last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1);
124
125 name.len = last - name.data;
126 location.len = last - location.data + 1;
127
128 } else {
129 name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2
130 - clcf->name.len);
131 if (name.data == NULL) {
132 return NGX_HTTP_INTERNAL_SERVER_ERROR;
133 }
134
135 last = ngx_cpymem(name.data, clcf->root.data, clcf->root.len);
136 last = ngx_cpystrn(last, r->uri.data + clcf->name.len,
137 r->uri.len + 1 - clcf->name.len);
138
139 name.len = last - name.data;
140
141 location.data = ngx_palloc(r->pool, r->uri.len + 2);
142 if (location.data == NULL) {
143 return NGX_HTTP_INTERNAL_SERVER_ERROR;
144 }
145
146 last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1);
147
148 location.len = last - location.data + 1;
149 } 117 }
150 118
151 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, 119 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
152 "http filename: \"%s\"", name.data); 120 "http filename: \"%s\"", path.data);
153 121
154 /* open file */ 122 fd = ngx_open_file(path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN);
155
156 #if (NGX_WIN9X)
157
158 if (ngx_win32_version < NGX_WIN_NT) {
159
160 /*
161 * there is no way to open a file or a directory in Win9X with
162 * one syscall because Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag
163 * so we need to check its type before the opening
164 */
165
166 if (ngx_file_info(name.data, &fi) == NGX_FILE_ERROR) {
167 err = ngx_errno;
168 ngx_log_error(NGX_LOG_ERR, log, err,
169 ngx_file_info_n " \"%s\" failed", name.data);
170
171 if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
172 return NGX_HTTP_NOT_FOUND;
173
174 } else if (err == NGX_EACCES) {
175 return NGX_HTTP_FORBIDDEN;
176
177 } else {
178 return NGX_HTTP_INTERNAL_SERVER_ERROR;
179 }
180 }
181
182 if (ngx_is_dir(&fi)) {
183 r->headers_out.location = ngx_http_add_header(&r->headers_out,
184 ngx_http_headers_out);
185 if (r->headers_out.location == NULL) {
186 return NGX_HTTP_INTERNAL_SERVER_ERROR;
187 }
188
189 *last++ = '/';
190 *last = '\0';
191 r->headers_out.location->value.len = last - location;
192 r->headers_out.location->value.data = location;
193
194 return NGX_HTTP_MOVED_PERMANENTLY;
195 }
196 }
197
198 #endif
199
200
201 fd = ngx_open_file(name.data, NGX_FILE_RDONLY, NGX_FILE_OPEN);
202 123
203 if (fd == NGX_INVALID_FILE) { 124 if (fd == NGX_INVALID_FILE) {
204 err = ngx_errno; 125 err = ngx_errno;
205 126
206 if (err == NGX_ENOENT 127 if (err == NGX_ENOENT
217 } else { 138 } else {
218 level = NGX_LOG_CRIT; 139 level = NGX_LOG_CRIT;
219 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; 140 rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
220 } 141 }
221 142
143 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
144
222 if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) { 145 if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
223 ngx_log_error(level, log, err, 146 ngx_log_error(level, log, err,
224 ngx_open_file_n " \"%s\" failed", name.data); 147 ngx_open_file_n " \"%s\" failed", path.data);
225 } 148 }
226 149
227 return rc; 150 return rc;
228 } 151 }
229 152
230 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", fd); 153 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", fd);
231 154
232 if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) { 155 if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
233 ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, 156 ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
234 ngx_fd_info_n " \"%s\" failed", name.data); 157 ngx_fd_info_n " \"%s\" failed", path.data);
235 158
236 if (ngx_close_file(fd) == NGX_FILE_ERROR) { 159 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
237 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, 160 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
238 ngx_close_file_n " \"%s\" failed", name.data); 161 ngx_close_file_n " \"%s\" failed", path.data);
239 } 162 }
240 163
241 return NGX_HTTP_INTERNAL_SERVER_ERROR; 164 return NGX_HTTP_INTERNAL_SERVER_ERROR;
242 } 165 }
243 166
245 168
246 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http dir"); 169 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http dir");
247 170
248 if (ngx_close_file(fd) == NGX_FILE_ERROR) { 171 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
249 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, 172 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
250 ngx_close_file_n " \"%s\" failed", name.data); 173 ngx_close_file_n " \"%s\" failed", path.data);
251 } 174 }
252
253 *last++ = '/';
254 *last = '\0';
255 175
256 r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t)); 176 r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
257 if (r->headers_out.location == NULL) { 177 if (r->headers_out.location == NULL) {
258 return NGX_HTTP_INTERNAL_SERVER_ERROR; 178 return NGX_HTTP_INTERNAL_SERVER_ERROR;
259 } 179 }
180
181 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
182
183 if (!clcf->alias) {
184 location = path.data + clcf->root.len;
185
186 } else {
187 location = ngx_palloc(r->pool, r->uri.len + 1);
188 if (location == NULL) {
189 return NGX_HTTP_INTERNAL_SERVER_ERROR;
190 }
191
192 last = ngx_cpymem(location, r->uri.data, r->uri.len);
193 }
194
195 *last = '/';
260 196
261 /* 197 /*
262 * we do not need to set the r->headers_out.location->hash and 198 * we do not need to set the r->headers_out.location->hash and
263 * r->headers_out.location->key fields 199 * r->headers_out.location->key fields
264 */ 200 */
265 201
266 r->headers_out.location->value = location; 202 r->headers_out.location->value.len = r->uri.len + 1;
203 r->headers_out.location->value.data = location;
267 204
268 return NGX_HTTP_MOVED_PERMANENTLY; 205 return NGX_HTTP_MOVED_PERMANENTLY;
269 } 206 }
270 207
271 #if !(NGX_WIN32) /* the not regular files are probably Unix specific */ 208 #if !(NGX_WIN32) /* the not regular files are probably Unix specific */
272 209
273 if (!ngx_is_file(&fi)) { 210 if (!ngx_is_file(&fi)) {
274 ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, 211 ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
275 "\"%s\" is not a regular file", name.data); 212 "\"%s\" is not a regular file", path.data);
276 213
277 if (ngx_close_file(fd) == NGX_FILE_ERROR) { 214 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
278 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, 215 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
279 ngx_close_file_n " \"%s\" failed", name.data); 216 ngx_close_file_n " \"%s\" failed", path.data);
280 } 217 }
281 218
282 return NGX_HTTP_NOT_FOUND; 219 return NGX_HTTP_NOT_FOUND;
283 } 220 }
284 221
290 if (cln == NULL) { 227 if (cln == NULL) {
291 return NGX_HTTP_INTERNAL_SERVER_ERROR; 228 return NGX_HTTP_INTERNAL_SERVER_ERROR;
292 } 229 }
293 230
294 cln->fd = fd; 231 cln->fd = fd;
295 cln->name = name.data; 232 cln->name = path.data;
296 cln->log = r->pool->log; 233 cln->log = r->pool->log;
297 234
298 if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) { 235 if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) {
299 return NGX_HTTP_INTERNAL_SERVER_ERROR; 236 return NGX_HTTP_INTERNAL_SERVER_ERROR;
300 } 237 }
347 284
348 b->file_pos = 0; 285 b->file_pos = 0;
349 b->file_last = ngx_file_size(&fi); 286 b->file_last = ngx_file_size(&fi);
350 287
351 b->file->fd = fd; 288 b->file->fd = fd;
352 b->file->name = name; 289 b->file->name = path;
353 b->file->log = log; 290 b->file->log = log;
354 291
355 out.buf = b; 292 out.buf = b;
356 out.next = NULL; 293 out.next = NULL;
357 294