Mercurial > hg > nginx-vendor-0-7
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, ©.path, &root, 0); | 670 ngx_http_map_uri_to_path(r, ©.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, ©.path, &ext) == NGX_OK) { | 803 if (ngx_ext_rename_file(&path, ©.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 * |