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