comparison src/http/modules/ngx_http_dav_module.c @ 502:89dc5654117c NGINX_0_7_63

nginx 0.7.63 *) Security: now "/../" are disabled in "Destination" request header line. *) Change: minimum supported OpenSSL version is 0.9.7. *) Change: the "ask" parameter of the "ssl_verify_client" directive was changed to the "optional" parameter and now it checks a client certificate if it was offered. Thanks to Brice Figureau. *) Feature: now the "-V" switch shows TLS SNI support. *) Feature: the $ssl_client_verify variable. Thanks to Brice Figureau. *) Feature: the "ssl_crl" directive. Thanks to Brice Figureau. *) Bugfix: the $ssl_client_cert variable usage corrupted memory; the bug had appeared in 0.7.7. Thanks to Sergey Zhuravlev. *) Feature: now the start cache loader runs in a separate process; this should improve large caches handling. *) Feature: now temporary files and permanent storage area may reside at different file systems. *) Bugfix: nginx counted incorrectly disk cache size. *) Change: now directive "gzip_disable msie6" does not disable gzipping for MSIE 6.0 SV1. *) Bugfix: nginx always added "Vary: Accept-Encoding" response header line, if both "gzip_static" and "gzip_vary" were on. *) Feature: the "proxy" parameter of the "geo" directive. *) Feature: the ngx_http_geoip_module. *) Feature: the "limit_rate_after" directive. Thanks to Ivan Debnar. *) Feature: the "limit_req_log_level" and "limit_conn_log_level" directives. *) Bugfix: now "limit_req" directive conforms to the leaky bucket algorithm. Thanks to Maxim Dounin. *) Bugfix: in ngx_http_limit_req_module. Thanks to Maxim Dounin. *) Bugfix: now nginx allows underscores in a request method. *) Bugfix: "proxy_pass_header" and "fastcgi_pass_header" directives did not pass to a client the "X-Accel-Redirect", "X-Accel-Limit-Rate", "X-Accel-Buffering", and "X-Accel-Charset" lines from backend response header. Thanks to Maxim Dounin. *) Bugfix: in handling "Last-Modified" and "Accept-Ranges" backend response header lines; the bug had appeared in 0.7.44. Thanks to Maxim Dounin. *) Feature: the "image_filter_transparency" directive. *) Feature: the "image_filter" directive supports variables for setting size. *) Bugfix: in PNG alpha-channel support in the ngx_http_image_filter_module. *) Bugfix: in transparency support in the ngx_http_image_filter_module. *) Feature: now several "perl_modules" directives may be used. *) Bugfix: ngx_http_perl_module responses did not work in subrequests. *) Bugfix: nginx sent '\0' in a "Location" response header line on MKCOL request. Thanks to Xie Zhenye. *) Bugfix: an "error_page" directive did not redirect a 413 error; the bug had appeared in 0.6.10. *) Bugfix: in memory allocation error handling. Thanks to Maxim Dounin and Kirill A. Korinskiy.
author Igor Sysoev <http://sysoev.ru>
date Mon, 26 Oct 2009 00:00:00 +0300
parents ed5e10fb40fc
children 68c0ae0a4959
comparison
equal deleted inserted replaced
501:dc87c92181c7 502:89dc5654117c
51 static ngx_int_t ngx_http_dav_copy_dir(ngx_tree_ctx_t *ctx, ngx_str_t *path); 51 static ngx_int_t ngx_http_dav_copy_dir(ngx_tree_ctx_t *ctx, ngx_str_t *path);
52 static ngx_int_t ngx_http_dav_copy_dir_time(ngx_tree_ctx_t *ctx, 52 static ngx_int_t ngx_http_dav_copy_dir_time(ngx_tree_ctx_t *ctx,
53 ngx_str_t *path); 53 ngx_str_t *path);
54 static ngx_int_t ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, 54 static ngx_int_t ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx,
55 ngx_str_t *path); 55 ngx_str_t *path);
56 static ngx_int_t ngx_http_dav_copy_file(ngx_tree_ctx_t *ctx, u_char *from,
57 u_char *to);
58 56
59 static ngx_int_t ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt); 57 static ngx_int_t ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt);
60 static ngx_int_t ngx_http_dav_error(ngx_log_t *log, ngx_err_t err, 58 static ngx_int_t ngx_http_dav_error(ngx_log_t *log, ngx_err_t err,
61 ngx_int_t not_found, char *failed, u_char *path); 59 ngx_int_t not_found, char *failed, u_char *path);
62 static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r, u_char *path); 60 static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r, u_char *path);
214 ngx_ext_rename_file_t ext; 212 ngx_ext_rename_file_t ext;
215 ngx_http_dav_loc_conf_t *dlcf; 213 ngx_http_dav_loc_conf_t *dlcf;
216 214
217 ngx_http_map_uri_to_path(r, &path, &root, 0); 215 ngx_http_map_uri_to_path(r, &path, &root, 0);
218 216
217 path.len--;
218
219 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 219 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
220 "http put filename: \"%s\"", path.data); 220 "http put filename: \"%s\"", path.data);
221 221
222 temp = &r->request_body->temp_file->file.name; 222 temp = &r->request_body->temp_file->file.name;
223 223
247 ext.access = dlcf->access; 247 ext.access = dlcf->access;
248 ext.path_access = dlcf->access; 248 ext.path_access = dlcf->access;
249 ext.time = -1; 249 ext.time = -1;
250 ext.create_path = dlcf->create_full_put_path; 250 ext.create_path = dlcf->create_full_put_path;
251 ext.delete_file = 1; 251 ext.delete_file = 1;
252 ext.log_rename_error = 1;
253 ext.log = r->connection->log; 252 ext.log = r->connection->log;
254 253
255 if (r->headers_in.date) { 254 if (r->headers_in.date) {
256 date = ngx_http_parse_time(r->headers_in.date->value.data, 255 date = ngx_http_parse_time(r->headers_in.date->value.data,
257 r->headers_in.date->value.len); 256 r->headers_in.date->value.len);
489 } 488 }
490 489
491 p = ngx_http_map_uri_to_path(r, &path, &root, 0); 490 p = ngx_http_map_uri_to_path(r, &path, &root, 0);
492 491
493 *(p - 1) = '\0'; 492 *(p - 1) = '\0';
493 r->uri.len--;
494 494
495 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 495 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
496 "http mkcol path: \"%s\"", path.data); 496 "http mkcol path: \"%s\"", path.data);
497 497
498 if (ngx_create_dir(path.data, ngx_dir_access(dlcf->access)) 498 if (ngx_create_dir(path.data, ngx_dir_access(dlcf->access))
515 { 515 {
516 u_char *p, *host, *last, ch; 516 u_char *p, *host, *last, ch;
517 size_t len, root; 517 size_t len, root;
518 ngx_err_t err; 518 ngx_err_t err;
519 ngx_int_t rc, depth; 519 ngx_int_t rc, depth;
520 ngx_uint_t overwrite, slash, dir; 520 ngx_uint_t overwrite, slash, dir, flags;
521 ngx_str_t path, uri; 521 ngx_str_t path, uri, duri, args;
522 ngx_tree_ctx_t tree; 522 ngx_tree_ctx_t tree;
523 ngx_copy_file_t cf;
523 ngx_file_info_t fi; 524 ngx_file_info_t fi;
524 ngx_table_elt_t *dest, *over; 525 ngx_table_elt_t *dest, *over;
525 ngx_ext_rename_file_t ext; 526 ngx_ext_rename_file_t ext;
526 ngx_http_dav_copy_ctx_t copy; 527 ngx_http_dav_copy_ctx_t copy;
527 ngx_http_dav_loc_conf_t *dlcf; 528 ngx_http_dav_loc_conf_t *dlcf;
591 "client sent invalid \"Destination\" header: \"%V\"", 592 "client sent invalid \"Destination\" header: \"%V\"",
592 &dest->value); 593 &dest->value);
593 return NGX_HTTP_BAD_REQUEST; 594 return NGX_HTTP_BAD_REQUEST;
594 595
595 destination_done: 596 destination_done:
597
598 duri.len = last - p;
599 duri.data = p;
600 flags = 0;
601
602 if (ngx_http_parse_unsafe_uri(r, &duri, &args, &flags) != NGX_OK) {
603 goto invalid_destination;
604 }
596 605
597 if ((r->uri.data[r->uri.len - 1] == '/' && *(last - 1) != '/') 606 if ((r->uri.data[r->uri.len - 1] == '/' && *(last - 1) != '/')
598 || (r->uri.data[r->uri.len - 1] != '/' && *(last - 1) == '/')) 607 || (r->uri.data[r->uri.len - 1] != '/' && *(last - 1) == '/'))
599 { 608 {
600 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 609 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
654 663
655 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 664 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
656 "http copy from: \"%s\"", path.data); 665 "http copy from: \"%s\"", path.data);
657 666
658 uri = r->uri; 667 uri = r->uri;
659 668 r->uri = duri;
660 r->uri.len = last - p;
661 r->uri.data = p;
662 669
663 ngx_http_map_uri_to_path(r, &copy.path, &root, 0); 670 ngx_http_map_uri_to_path(r, &copy.path, &root, 0);
664 671
665 r->uri = uri; 672 r->uri = uri;
666 673
789 ext.access = 0; 796 ext.access = 0;
790 ext.path_access = dlcf->access; 797 ext.path_access = dlcf->access;
791 ext.time = -1; 798 ext.time = -1;
792 ext.create_path = 1; 799 ext.create_path = 1;
793 ext.delete_file = 0; 800 ext.delete_file = 0;
794 ext.log_rename_error = 0;
795 ext.log = r->connection->log; 801 ext.log = r->connection->log;
796 802
797 if (ngx_ext_rename_file(&path, &copy.path, &ext) == NGX_OK) { 803 if (ngx_ext_rename_file(&path, &copy.path, &ext) == NGX_OK) {
798 return NGX_HTTP_NO_CONTENT; 804 return NGX_HTTP_NO_CONTENT;
799 } 805 }
800 806
801 if (ext.rename_error != NGX_EXDEV) { 807 return NGX_HTTP_INTERNAL_SERVER_ERROR;
802
803 if (ext.rename_error) {
804 ngx_log_error(NGX_LOG_CRIT, r->connection->log,
805 ext.rename_error,
806 ngx_rename_file_n " \"%s\" to \"%s\" failed",
807 path.data, copy.path.data);
808 }
809
810 return NGX_HTTP_INTERNAL_SERVER_ERROR;
811 }
812 } 808 }
813 809
814 dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); 810 dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
815 811
816 tree.size = ngx_file_size(&fi); 812 cf.size = ngx_file_size(&fi);
817 tree.mtime = ngx_file_mtime(&fi); 813 cf.buf_size = 0;
818 tree.access = dlcf->access; 814 cf.access = dlcf->access;
819 tree.log = r->connection->log; 815 cf.time = ngx_file_mtime(&fi);
820 816 cf.log = r->connection->log;
821 if (ngx_http_dav_copy_file(&tree, path.data, copy.path.data) == NGX_OK) 817
822 { 818 if (ngx_copy_file(path.data, copy.path.data, &cf) == NGX_OK) {
823 if (r->method == NGX_HTTP_MOVE) {
824 rc = ngx_http_dav_delete_path(r, &path, 0);
825
826 if (rc != NGX_OK) {
827 return rc;
828 }
829 }
830
831 return NGX_HTTP_NO_CONTENT; 819 return NGX_HTTP_NO_CONTENT;
832 } 820 }
833 } 821 }
834 822
835 return NGX_HTTP_INTERNAL_SERVER_ERROR; 823 return NGX_HTTP_INTERNAL_SERVER_ERROR;
939 static ngx_int_t 927 static ngx_int_t
940 ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, ngx_str_t *path) 928 ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
941 { 929 {
942 u_char *p, *file; 930 u_char *p, *file;
943 size_t len; 931 size_t len;
932 ngx_copy_file_t cf;
944 ngx_http_dav_copy_ctx_t *copy; 933 ngx_http_dav_copy_ctx_t *copy;
945 934
946 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0, 935 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
947 "http copy file: \"%s\"", path->data); 936 "http copy file: \"%s\"", path->data);
948 937
959 (void) ngx_cpystrn(p, path->data + copy->len, path->len - copy->len + 1); 948 (void) ngx_cpystrn(p, path->data + copy->len, path->len - copy->len + 1);
960 949
961 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0, 950 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
962 "http copy file to: \"%s\"", file); 951 "http copy file to: \"%s\"", file);
963 952
964 (void) ngx_http_dav_copy_file(ctx, path->data, file); 953 cf.size = ctx->size;
954 cf.buf_size = 0;
955 cf.access = ctx->access;
956 cf.time = ctx->mtime;
957 cf.log = ctx->log;
958
959 (void) ngx_copy_file(path->data, file, &cf);
965 960
966 ngx_free(file); 961 ngx_free(file);
967 962
968 return NGX_OK; 963 return NGX_OK;
969 }
970
971
972 static ngx_int_t
973 ngx_http_dav_copy_file(ngx_tree_ctx_t *ctx, u_char *from, u_char *to)
974 {
975 off_t size;
976 ssize_t n;
977 ngx_fd_t fd, cfd;
978 ngx_int_t rc;
979 u_char buf[NGX_HTTP_DAV_COPY_BLOCK];
980
981 fd = ngx_open_file(from, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
982
983 if (fd == NGX_INVALID_FILE) {
984 (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_open_file_n,
985 from);
986 return NGX_ERROR;
987 }
988
989 cfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN,
990 ctx->access);
991
992 rc = NGX_ERROR;
993
994 if (cfd == NGX_INVALID_FILE) {
995 (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_open_file_n, to);
996 goto failed;
997 }
998
999 for (size = ctx->size; size > 0; size -= n) {
1000
1001 n = ngx_read_fd(fd, buf, NGX_HTTP_DAV_COPY_BLOCK);
1002
1003 if (n == NGX_FILE_ERROR) {
1004 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
1005 ngx_read_fd_n " \"%s\" failed", from);
1006 goto failed;
1007 }
1008
1009 if (ngx_write_fd(cfd, buf, n) == NGX_FILE_ERROR) {
1010 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
1011 ngx_write_fd_n " \"%s\" failed", to);
1012 goto failed;
1013 }
1014 }
1015
1016 if (ngx_set_file_time(to, cfd, ctx->mtime) != NGX_OK) {
1017 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
1018 ngx_set_file_time_n " \"%s\" failed", to);
1019 goto failed;
1020 }
1021
1022 if (ngx_close_file(cfd) == NGX_FILE_ERROR) {
1023 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
1024 ngx_close_file_n " \"%s\" failed", to);
1025 goto failed;
1026 }
1027
1028 rc = NGX_OK;
1029
1030 failed:
1031
1032 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1033 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
1034 ngx_close_file_n " \"%s\" failed", from);
1035 }
1036
1037 return rc;
1038 } 964 }
1039 965
1040 966
1041 static ngx_int_t 967 static ngx_int_t
1042 ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt) 968 ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt)
1152 { 1078 {
1153 ngx_http_dav_loc_conf_t *conf; 1079 ngx_http_dav_loc_conf_t *conf;
1154 1080
1155 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_dav_loc_conf_t)); 1081 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_dav_loc_conf_t));
1156 if (conf == NULL) { 1082 if (conf == NULL) {
1157 return NGX_CONF_ERROR; 1083 return NULL;
1158 } 1084 }
1159 1085
1160 /* 1086 /*
1161 * set by ngx_pcalloc(): 1087 * set by ngx_pcalloc():
1162 * 1088 *