Mercurial > hg > nginx-vendor-0-6
comparison src/http/modules/ngx_http_dav_module.c @ 218:1bf60f8c5c9e NGINX_0_3_56
nginx 0.3.56
*) Feature: the "dav_access" directive.
*) Feature: the "if" directive supports the "-d", "!-d", "-e", "!-e",
"-x", and "!-x" operators.
*) Bugfix: a segmentation fault occurred if an request returned an
redirect and some sent to client header lines were logged in the
access log.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Fri, 04 Aug 2006 00:00:00 +0400 |
parents | fa32d59d9a15 |
children | 9909a161eb28 |
comparison
equal
deleted
inserted
replaced
217:a346c23fc94e | 218:1bf60f8c5c9e |
---|---|
12 #define NGX_HTTP_DAV_OFF 2 | 12 #define NGX_HTTP_DAV_OFF 2 |
13 | 13 |
14 typedef struct { | 14 typedef struct { |
15 ngx_uint_t methods; | 15 ngx_uint_t methods; |
16 ngx_flag_t create_full_put_path; | 16 ngx_flag_t create_full_put_path; |
17 ngx_uint_t access; | |
17 } ngx_http_dav_loc_conf_t; | 18 } ngx_http_dav_loc_conf_t; |
18 | 19 |
19 | 20 |
20 static ngx_int_t ngx_http_dav_handler(ngx_http_request_t *r); | 21 static ngx_int_t ngx_http_dav_handler(ngx_http_request_t *r); |
21 static void ngx_http_dav_put_handler(ngx_http_request_t *r); | 22 static void ngx_http_dav_put_handler(ngx_http_request_t *r); |
22 static ngx_int_t ngx_http_dav_error(ngx_http_request_t *, ngx_err_t err, | 23 static ngx_int_t ngx_http_dav_error(ngx_http_request_t *, ngx_err_t err, |
23 ngx_int_t not_found, char *failed, u_char *path); | 24 ngx_int_t not_found, char *failed, u_char *path); |
24 static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r, u_char *path); | 25 static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r, u_char *path); |
26 static char *ngx_http_dav_access(ngx_conf_t *cf, ngx_command_t *cmd, | |
27 void *conf); | |
25 static void *ngx_http_dav_create_loc_conf(ngx_conf_t *cf); | 28 static void *ngx_http_dav_create_loc_conf(ngx_conf_t *cf); |
26 static char *ngx_http_dav_merge_loc_conf(ngx_conf_t *cf, | 29 static char *ngx_http_dav_merge_loc_conf(ngx_conf_t *cf, |
27 void *parent, void *child); | 30 void *parent, void *child); |
28 static ngx_int_t ngx_http_dav_init(ngx_cycle_t *cycle); | 31 static ngx_int_t ngx_http_dav_init(ngx_cycle_t *cycle); |
29 | 32 |
49 { ngx_string("create_full_put_path"), | 52 { ngx_string("create_full_put_path"), |
50 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 53 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
51 ngx_conf_set_flag_slot, | 54 ngx_conf_set_flag_slot, |
52 NGX_HTTP_LOC_CONF_OFFSET, | 55 NGX_HTTP_LOC_CONF_OFFSET, |
53 offsetof(ngx_http_dav_loc_conf_t, create_full_put_path), | 56 offsetof(ngx_http_dav_loc_conf_t, create_full_put_path), |
57 NULL }, | |
58 | |
59 { ngx_string("dav_access"), | |
60 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, | |
61 ngx_http_dav_access, | |
62 NGX_HTTP_LOC_CONF_OFFSET, | |
63 0, | |
54 NULL }, | 64 NULL }, |
55 | 65 |
56 ngx_null_command | 66 ngx_null_command |
57 }; | 67 }; |
58 | 68 |
212 ngx_http_map_uri_to_path(r, &path, 0); | 222 ngx_http_map_uri_to_path(r, &path, 0); |
213 | 223 |
214 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 224 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
215 "http mkcol path: \"%s\"", path.data); | 225 "http mkcol path: \"%s\"", path.data); |
216 | 226 |
217 if (ngx_create_dir(path.data) != NGX_FILE_ERROR) { | 227 if (ngx_create_dir(path.data, dlcf->access) != NGX_FILE_ERROR) { |
218 if (ngx_http_dav_location(r, path.data) != NGX_OK) { | 228 if (ngx_http_dav_location(r, path.data) != NGX_OK) { |
219 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 229 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
220 } | 230 } |
221 | 231 |
222 return NGX_HTTP_CREATED; | 232 return NGX_HTTP_CREATED; |
231 | 241 |
232 | 242 |
233 static void | 243 static void |
234 ngx_http_dav_put_handler(ngx_http_request_t *r) | 244 ngx_http_dav_put_handler(ngx_http_request_t *r) |
235 { | 245 { |
246 char *failed; | |
247 u_char *name; | |
236 ngx_err_t err; | 248 ngx_err_t err; |
237 ngx_str_t *temp, path; | 249 ngx_str_t *temp, path; |
238 ngx_uint_t status; | 250 ngx_uint_t status; |
239 ngx_file_info_t fi; | 251 ngx_file_info_t fi; |
240 ngx_http_dav_loc_conf_t *dlcf; | 252 ngx_http_dav_loc_conf_t *dlcf; |
265 ngx_http_finalize_request(r, NGX_HTTP_CONFLICT); | 277 ngx_http_finalize_request(r, NGX_HTTP_CONFLICT); |
266 return; | 278 return; |
267 } | 279 } |
268 } | 280 } |
269 | 281 |
282 dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); | |
283 | |
284 #if !(NGX_WIN32) | |
285 | |
286 if (ngx_change_file_access(temp->data, dlcf->access & ~0111) | |
287 == NGX_FILE_ERROR) | |
288 { | |
289 err = ngx_errno; | |
290 failed = ngx_change_file_access_n; | |
291 name = temp->data; | |
292 | |
293 goto failed; | |
294 } | |
295 | |
296 #endif | |
297 | |
298 failed = ngx_rename_file_n; | |
299 name = path.data; | |
300 | |
270 if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) { | 301 if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) { |
271 goto ok; | 302 goto ok; |
272 } | 303 } |
273 | 304 |
274 err = ngx_errno; | 305 err = ngx_errno; |
275 | 306 |
276 if (err == NGX_ENOENT) { | 307 if (err == NGX_ENOENT) { |
277 | 308 |
278 dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); | |
279 | |
280 if (dlcf->create_full_put_path) { | 309 if (dlcf->create_full_put_path) { |
281 err = ngx_create_full_path(path.data); | 310 err = ngx_create_full_path(path.data, dlcf->access); |
282 | 311 |
283 if (err == 0) { | 312 if (err == 0) { |
284 if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) { | 313 if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) { |
285 goto ok; | 314 goto ok; |
286 } | 315 } |
301 } | 330 } |
302 | 331 |
303 err = ngx_errno; | 332 err = ngx_errno; |
304 } | 333 } |
305 | 334 |
335 | |
336 #else | |
337 | |
338 failed: | |
339 | |
306 #endif | 340 #endif |
307 | 341 |
308 if (ngx_delete_file(temp->data) == NGX_FILE_ERROR) { | 342 if (ngx_delete_file(temp->data) == NGX_FILE_ERROR) { |
309 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, | 343 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, |
310 ngx_delete_file_n " \"%s\" failed", | 344 ngx_delete_file_n " \"%s\" failed", |
311 temp->data); | 345 temp->data); |
312 } | 346 } |
313 | 347 |
314 ngx_http_finalize_request(r, ngx_http_dav_error(r, err, NGX_HTTP_CONFLICT, | 348 ngx_http_finalize_request(r, |
315 ngx_rename_file_n, | 349 ngx_http_dav_error(r, err, NGX_HTTP_CONFLICT, failed, name)); |
316 path.data)); | 350 |
317 return; | 351 return; |
318 | 352 |
319 ok: | 353 ok: |
320 | 354 |
321 if (status == NGX_HTTP_CREATED) { | 355 if (status == NGX_HTTP_CREATED) { |
402 | 436 |
403 r->headers_out.location->value.len = r->uri.len; | 437 r->headers_out.location->value.len = r->uri.len; |
404 r->headers_out.location->value.data = location; | 438 r->headers_out.location->value.data = location; |
405 | 439 |
406 return NGX_OK; | 440 return NGX_OK; |
441 } | |
442 | |
443 | |
444 static char * | |
445 ngx_http_dav_access(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
446 { | |
447 ngx_http_dav_loc_conf_t *lcf = conf; | |
448 | |
449 u_char *p; | |
450 ngx_str_t *value; | |
451 ngx_uint_t i, right, shift; | |
452 | |
453 if (lcf->access != NGX_CONF_UNSET_UINT) { | |
454 return "is duplicate"; | |
455 } | |
456 | |
457 value = cf->args->elts; | |
458 | |
459 lcf->access = 0700; | |
460 | |
461 for (i = 1; i < 3; i++) { | |
462 | |
463 p = value[i].data; | |
464 | |
465 if (ngx_strncmp(p, "user:", sizeof("user:") - 1) == 0) { | |
466 shift = 6; | |
467 p += sizeof("user:") - 1; | |
468 | |
469 } else if (ngx_strncmp(p, "group:", sizeof("group:") - 1) == 0) { | |
470 shift = 3; | |
471 p += sizeof("group:") - 1; | |
472 | |
473 } else if (ngx_strncmp(p, "all:", sizeof("all:") - 1) == 0) { | |
474 shift = 0; | |
475 p += sizeof("all:") - 1; | |
476 | |
477 } else { | |
478 goto invalid; | |
479 } | |
480 | |
481 if (ngx_strcmp(p, "rw") == 0) { | |
482 right = 7; | |
483 | |
484 } else if (ngx_strcmp(p, "r") == 0) { | |
485 right = 5; | |
486 | |
487 } else { | |
488 goto invalid; | |
489 } | |
490 | |
491 lcf->access += right << shift; | |
492 } | |
493 | |
494 return NGX_CONF_OK; | |
495 | |
496 invalid: | |
497 | |
498 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
499 "invalid value \"%V\"", &value[i]); | |
500 return NGX_CONF_ERROR; | |
407 } | 501 } |
408 | 502 |
409 | 503 |
410 static void * | 504 static void * |
411 ngx_http_dav_create_loc_conf(ngx_conf_t *cf) | 505 ngx_http_dav_create_loc_conf(ngx_conf_t *cf) |
422 * | 516 * |
423 * conf->methods = 0; | 517 * conf->methods = 0; |
424 */ | 518 */ |
425 | 519 |
426 conf->create_full_put_path = NGX_CONF_UNSET; | 520 conf->create_full_put_path = NGX_CONF_UNSET; |
521 conf->access = NGX_CONF_UNSET_UINT; | |
427 | 522 |
428 return conf; | 523 return conf; |
429 } | 524 } |
430 | 525 |
431 | 526 |
438 ngx_conf_merge_bitmask_value(conf->methods, prev->methods, | 533 ngx_conf_merge_bitmask_value(conf->methods, prev->methods, |
439 (NGX_CONF_BITMASK_SET|NGX_HTTP_DAV_OFF)); | 534 (NGX_CONF_BITMASK_SET|NGX_HTTP_DAV_OFF)); |
440 | 535 |
441 ngx_conf_merge_value(conf->create_full_put_path, prev->create_full_put_path, | 536 ngx_conf_merge_value(conf->create_full_put_path, prev->create_full_put_path, |
442 0); | 537 0); |
538 | |
539 ngx_conf_merge_uint_value(conf->access, prev->access, 0600); | |
443 | 540 |
444 return NGX_CONF_OK; | 541 return NGX_CONF_OK; |
445 } | 542 } |
446 | 543 |
447 | 544 |