Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_dav_module.c @ 7374:de50fa05fbeb
Cache: fixed minimum cache keys zone size limit.
Size of a shared memory zones must be at least two pages - one page
for slab allocator internal data, and another page for actual allocations.
Using 8192 instead is wrong, as there are systems with page sizes other
than 4096.
Note well that two pages is usually too low as well. In particular, cache
is likely to use two allocations of different sizes for global structures,
and at least four pages will be needed to properly allocate cache nodes.
Except in a few very special cases, with keys zone of just two pages nginx
won't be able to start. Other uses of shared memory impose a limit
of 8 pages, which provides some room for global allocations. This patch
doesn't try to address this though.
Inspired by ticket #1665.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 31 Oct 2018 16:49:39 +0300 |
parents | bb40db0e380d |
children | c1a7d3672653 |
rev | line source |
---|---|
633 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
633 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
1116 | 13 #define NGX_HTTP_DAV_OFF 2 |
14 | |
15 | |
16 #define NGX_HTTP_DAV_NO_DEPTH -3 | |
17 #define NGX_HTTP_DAV_INVALID_DEPTH -2 | |
18 #define NGX_HTTP_DAV_INFINITY_DEPTH -1 | |
19 | |
633 | 20 |
21 typedef struct { | |
22 ngx_uint_t methods; | |
1816 | 23 ngx_uint_t access; |
24 ngx_uint_t min_delete_depth; | |
637 | 25 ngx_flag_t create_full_put_path; |
633 | 26 } ngx_http_dav_loc_conf_t; |
27 | |
28 | |
1116 | 29 typedef struct { |
30 ngx_str_t path; | |
31 size_t len; | |
32 } ngx_http_dav_copy_ctx_t; | |
33 | |
34 | |
633 | 35 static ngx_int_t ngx_http_dav_handler(ngx_http_request_t *r); |
1116 | 36 |
37 static void ngx_http_dav_put_handler(ngx_http_request_t *r); | |
38 | |
39 static ngx_int_t ngx_http_dav_delete_handler(ngx_http_request_t *r); | |
1820 | 40 static ngx_int_t ngx_http_dav_delete_path(ngx_http_request_t *r, |
41 ngx_str_t *path, ngx_uint_t dir); | |
957 | 42 static ngx_int_t ngx_http_dav_delete_dir(ngx_tree_ctx_t *ctx, ngx_str_t *path); |
43 static ngx_int_t ngx_http_dav_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path); | |
1820 | 44 static ngx_int_t ngx_http_dav_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path); |
1116 | 45 |
46 static ngx_int_t ngx_http_dav_mkcol_handler(ngx_http_request_t *r, | |
47 ngx_http_dav_loc_conf_t *dlcf); | |
48 | |
49 static ngx_int_t ngx_http_dav_copy_move_handler(ngx_http_request_t *r); | |
50 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_time(ngx_tree_ctx_t *ctx, | |
52 ngx_str_t *path); | |
1825
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
53 static ngx_int_t ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
54 ngx_str_t *path); |
1116 | 55 |
56 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_error(ngx_log_t *log, ngx_err_t err, | |
637 | 58 ngx_int_t not_found, char *failed, u_char *path); |
59 static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r, u_char *path); | |
633 | 60 static void *ngx_http_dav_create_loc_conf(ngx_conf_t *cf); |
61 static char *ngx_http_dav_merge_loc_conf(ngx_conf_t *cf, | |
62 void *parent, void *child); | |
681 | 63 static ngx_int_t ngx_http_dav_init(ngx_conf_t *cf); |
633 | 64 |
65 | |
66 static ngx_conf_bitmask_t ngx_http_dav_methods_mask[] = { | |
67 { ngx_string("off"), NGX_HTTP_DAV_OFF }, | |
68 { ngx_string("put"), NGX_HTTP_PUT }, | |
69 { ngx_string("delete"), NGX_HTTP_DELETE }, | |
637 | 70 { ngx_string("mkcol"), NGX_HTTP_MKCOL }, |
1116 | 71 { ngx_string("copy"), NGX_HTTP_COPY }, |
72 { ngx_string("move"), NGX_HTTP_MOVE }, | |
633 | 73 { ngx_null_string, 0 } |
74 }; | |
75 | |
76 | |
77 static ngx_command_t ngx_http_dav_commands[] = { | |
78 | |
79 { ngx_string("dav_methods"), | |
80 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
81 ngx_conf_set_bitmask_slot, | |
82 NGX_HTTP_LOC_CONF_OFFSET, | |
83 offsetof(ngx_http_dav_loc_conf_t, methods), | |
84 &ngx_http_dav_methods_mask }, | |
85 | |
637 | 86 { ngx_string("create_full_put_path"), |
87 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
88 ngx_conf_set_flag_slot, | |
89 NGX_HTTP_LOC_CONF_OFFSET, | |
90 offsetof(ngx_http_dav_loc_conf_t, create_full_put_path), | |
91 NULL }, | |
92 | |
1816 | 93 { ngx_string("min_delete_depth"), |
94 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
95 ngx_conf_set_num_slot, | |
96 NGX_HTTP_LOC_CONF_OFFSET, | |
97 offsetof(ngx_http_dav_loc_conf_t, min_delete_depth), | |
98 NULL }, | |
99 | |
669 | 100 { ngx_string("dav_access"), |
675 | 101 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123, |
1296
9fcfca54b208
dav_access uses ngx_conf_set_access_slot()
Igor Sysoev <igor@sysoev.ru>
parents:
1289
diff
changeset
|
102 ngx_conf_set_access_slot, |
669 | 103 NGX_HTTP_LOC_CONF_OFFSET, |
1296
9fcfca54b208
dav_access uses ngx_conf_set_access_slot()
Igor Sysoev <igor@sysoev.ru>
parents:
1289
diff
changeset
|
104 offsetof(ngx_http_dav_loc_conf_t, access), |
669 | 105 NULL }, |
106 | |
633 | 107 ngx_null_command |
108 }; | |
109 | |
110 | |
667 | 111 static ngx_http_module_t ngx_http_dav_module_ctx = { |
633 | 112 NULL, /* preconfiguration */ |
681 | 113 ngx_http_dav_init, /* postconfiguration */ |
633 | 114 |
115 NULL, /* create main configuration */ | |
116 NULL, /* init main configuration */ | |
117 | |
118 NULL, /* create server configuration */ | |
119 NULL, /* merge server configuration */ | |
120 | |
121 ngx_http_dav_create_loc_conf, /* create location configuration */ | |
122 ngx_http_dav_merge_loc_conf /* merge location configuration */ | |
123 }; | |
124 | |
125 | |
126 ngx_module_t ngx_http_dav_module = { | |
127 NGX_MODULE_V1, | |
128 &ngx_http_dav_module_ctx, /* module context */ | |
129 ngx_http_dav_commands, /* module directives */ | |
130 NGX_HTTP_MODULE, /* module type */ | |
131 NULL, /* init master */ | |
681 | 132 NULL, /* init module */ |
633 | 133 NULL, /* init process */ |
134 NULL, /* init thread */ | |
135 NULL, /* exit thread */ | |
136 NULL, /* exit process */ | |
137 NULL, /* exit master */ | |
138 NGX_MODULE_V1_PADDING | |
139 }; | |
140 | |
141 | |
142 static ngx_int_t | |
143 ngx_http_dav_handler(ngx_http_request_t *r) | |
144 { | |
145 ngx_int_t rc; | |
146 ngx_http_dav_loc_conf_t *dlcf; | |
147 | |
148 dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); | |
149 | |
150 if (!(r->method & dlcf->methods)) { | |
151 return NGX_DECLINED; | |
152 } | |
153 | |
154 switch (r->method) { | |
155 | |
156 case NGX_HTTP_PUT: | |
157 | |
158 if (r->uri.data[r->uri.len - 1] == '/') { | |
1813
d3f80e0be8fa
change status code and add log message
Igor Sysoev <igor@sysoev.ru>
parents:
1804
diff
changeset
|
159 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
4133
59b99f217c6d
Replaced "can not" with "cannot" and "could not" in a bunch of places.
Ruslan Ermilov <ru@nginx.com>
parents:
3612
diff
changeset
|
160 "cannot PUT to a collection"); |
1813
d3f80e0be8fa
change status code and add log message
Igor Sysoev <igor@sysoev.ru>
parents:
1804
diff
changeset
|
161 return NGX_HTTP_CONFLICT; |
633 | 162 } |
163 | |
6538
055cbb52ac1d
Dav: return 501 on PUT with ranges (ticket #948).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6474
diff
changeset
|
164 if (r->headers_in.content_range) { |
055cbb52ac1d
Dav: return 501 on PUT with ranges (ticket #948).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6474
diff
changeset
|
165 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
055cbb52ac1d
Dav: return 501 on PUT with ranges (ticket #948).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6474
diff
changeset
|
166 "PUT with range is unsupported"); |
055cbb52ac1d
Dav: return 501 on PUT with ranges (ticket #948).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6474
diff
changeset
|
167 return NGX_HTTP_NOT_IMPLEMENTED; |
055cbb52ac1d
Dav: return 501 on PUT with ranges (ticket #948).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6474
diff
changeset
|
168 } |
055cbb52ac1d
Dav: return 501 on PUT with ranges (ticket #948).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6474
diff
changeset
|
169 |
633 | 170 r->request_body_in_file_only = 1; |
171 r->request_body_in_persistent_file = 1; | |
1075
4d203f76b757
undo "client_body_in_file_only any"
Igor Sysoev <igor@sysoev.ru>
parents:
1060
diff
changeset
|
172 r->request_body_in_clean_file = 1; |
633 | 173 r->request_body_file_group_access = 1; |
637 | 174 r->request_body_file_log_level = 0; |
633 | 175 |
176 rc = ngx_http_read_client_request_body(r, ngx_http_dav_put_handler); | |
177 | |
178 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | |
179 return rc; | |
180 } | |
181 | |
182 return NGX_DONE; | |
183 | |
184 case NGX_HTTP_DELETE: | |
185 | |
1116 | 186 return ngx_http_dav_delete_handler(r); |
637 | 187 |
188 case NGX_HTTP_MKCOL: | |
189 | |
1116 | 190 return ngx_http_dav_mkcol_handler(r, dlcf); |
637 | 191 |
1116 | 192 case NGX_HTTP_COPY: |
637 | 193 |
1116 | 194 return ngx_http_dav_copy_move_handler(r); |
637 | 195 |
1116 | 196 case NGX_HTTP_MOVE: |
637 | 197 |
1116 | 198 return ngx_http_dav_copy_move_handler(r); |
633 | 199 } |
200 | |
201 return NGX_DECLINED; | |
202 } | |
203 | |
204 | |
205 static void | |
206 ngx_http_dav_put_handler(ngx_http_request_t *r) | |
207 { | |
773 | 208 size_t root; |
681 | 209 time_t date; |
637 | 210 ngx_str_t *temp, path; |
1828
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
211 ngx_uint_t status; |
637 | 212 ngx_file_info_t fi; |
1828
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
213 ngx_ext_rename_file_t ext; |
637 | 214 ngx_http_dav_loc_conf_t *dlcf; |
633 | 215 |
7198
573f20116163
Dav: added error logging.
Roman Arutyunyan <arut@nginx.com>
parents:
6986
diff
changeset
|
216 if (r->request_body == NULL) { |
573f20116163
Dav: added error logging.
Roman Arutyunyan <arut@nginx.com>
parents:
6986
diff
changeset
|
217 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
573f20116163
Dav: added error logging.
Roman Arutyunyan <arut@nginx.com>
parents:
6986
diff
changeset
|
218 "PUT request body is unavailable"); |
573f20116163
Dav: added error logging.
Roman Arutyunyan <arut@nginx.com>
parents:
6986
diff
changeset
|
219 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
573f20116163
Dav: added error logging.
Roman Arutyunyan <arut@nginx.com>
parents:
6986
diff
changeset
|
220 return; |
573f20116163
Dav: added error logging.
Roman Arutyunyan <arut@nginx.com>
parents:
6986
diff
changeset
|
221 } |
573f20116163
Dav: added error logging.
Roman Arutyunyan <arut@nginx.com>
parents:
6986
diff
changeset
|
222 |
573f20116163
Dav: added error logging.
Roman Arutyunyan <arut@nginx.com>
parents:
6986
diff
changeset
|
223 if (r->request_body->temp_file == NULL) { |
573f20116163
Dav: added error logging.
Roman Arutyunyan <arut@nginx.com>
parents:
6986
diff
changeset
|
224 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
573f20116163
Dav: added error logging.
Roman Arutyunyan <arut@nginx.com>
parents:
6986
diff
changeset
|
225 "PUT request body must be in a file"); |
4918
e7467ae41626
Dav: fixed segfault on PUT if body was already read (ticket #238).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
226 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
e7467ae41626
Dav: fixed segfault on PUT if body was already read (ticket #238).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
227 return; |
e7467ae41626
Dav: fixed segfault on PUT if body was already read (ticket #238).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
228 } |
e7467ae41626
Dav: fixed segfault on PUT if body was already read (ticket #238).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
229 |
5781
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
230 if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) { |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
231 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
232 return; |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
233 } |
633 | 234 |
3032
524ba56ba9f7
fix copy destination name length, introduced in r3025
Igor Sysoev <igor@sysoev.ru>
parents:
3024
diff
changeset
|
235 path.len--; |
524ba56ba9f7
fix copy destination name length, introduced in r3025
Igor Sysoev <igor@sysoev.ru>
parents:
3024
diff
changeset
|
236 |
633 | 237 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
238 "http put filename: \"%s\"", path.data); | |
239 | |
240 temp = &r->request_body->temp_file->file.name; | |
241 | |
2782
4bd7825fab80
uniform ngx_file_info() interface with ngx_fd_info()
Igor Sysoev <igor@sysoev.ru>
parents:
2721
diff
changeset
|
242 if (ngx_file_info(path.data, &fi) == NGX_FILE_ERROR) { |
633 | 243 status = NGX_HTTP_CREATED; |
244 | |
245 } else { | |
246 status = NGX_HTTP_NO_CONTENT; | |
663 | 247 |
248 if (ngx_is_dir(&fi)) { | |
249 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_EISDIR, | |
250 "\"%s\" could not be created", path.data); | |
633 | 251 |
663 | 252 if (ngx_delete_file(temp->data) == NGX_FILE_ERROR) { |
253 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, | |
254 ngx_delete_file_n " \"%s\" failed", | |
255 temp->data); | |
256 } | |
257 | |
258 ngx_http_finalize_request(r, NGX_HTTP_CONFLICT); | |
259 return; | |
661 | 260 } |
637 | 261 } |
262 | |
669 | 263 dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); |
264 | |
1828
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
265 ext.access = dlcf->access; |
2394
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
266 ext.path_access = dlcf->access; |
1828
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
267 ext.time = -1; |
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
268 ext.create_path = dlcf->create_full_put_path; |
1909 | 269 ext.delete_file = 1; |
1828
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
270 ext.log = r->connection->log; |
669 | 271 |
681 | 272 if (r->headers_in.date) { |
6180
8b6fa4842133
Moved ngx_http_parse_time() to core, renamed accordingly.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5781
diff
changeset
|
273 date = ngx_parse_http_time(r->headers_in.date->value.data, |
681 | 274 r->headers_in.date->value.len); |
275 | |
276 if (date != NGX_ERROR) { | |
1828
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
277 ext.time = date; |
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
278 ext.fd = r->request_body->temp_file->file.fd; |
681 | 279 } |
280 } | |
281 | |
1828
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
282 if (ngx_ext_rename_file(temp, &path, &ext) != NGX_OK) { |
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
283 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
1f3c2b6607e0
use ngx_ext_rename_file() in PUT
Igor Sysoev <igor@sysoev.ru>
parents:
1825
diff
changeset
|
284 return; |
637 | 285 } |
286 | |
633 | 287 if (status == NGX_HTTP_CREATED) { |
637 | 288 if (ngx_http_dav_location(r, path.data) != NGX_OK) { |
633 | 289 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
290 return; | |
291 } | |
639 | 292 |
293 r->headers_out.content_length_n = 0; | |
633 | 294 } |
295 | |
296 r->headers_out.status = status; | |
297 r->header_only = 1; | |
298 | |
299 ngx_http_finalize_request(r, ngx_http_send_header(r)); | |
300 return; | |
301 } | |
302 | |
303 | |
637 | 304 static ngx_int_t |
1116 | 305 ngx_http_dav_delete_handler(ngx_http_request_t *r) |
306 { | |
1816 | 307 size_t root; |
308 ngx_err_t err; | |
309 ngx_int_t rc, depth; | |
310 ngx_uint_t i, d, dir; | |
311 ngx_str_t path; | |
312 ngx_file_info_t fi; | |
313 ngx_http_dav_loc_conf_t *dlcf; | |
1116 | 314 |
315 if (r->headers_in.content_length_n > 0) { | |
1815 | 316 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
317 "DELETE with body is unsupported"); | |
1116 | 318 return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE; |
319 } | |
320 | |
1816 | 321 dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); |
322 | |
323 if (dlcf->min_delete_depth) { | |
324 d = 0; | |
325 | |
326 for (i = 0; i < r->uri.len; /* void */) { | |
327 if (r->uri.data[i++] == '/') { | |
328 if (++d >= dlcf->min_delete_depth && i < r->uri.len) { | |
329 goto ok; | |
330 } | |
331 } | |
332 } | |
333 | |
334 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
335 "insufficient URI depth:%i to DELETE", d); | |
336 return NGX_HTTP_CONFLICT; | |
337 } | |
338 | |
339 ok: | |
340 | |
5781
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
341 if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) { |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
342 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
343 } |
1116 | 344 |
345 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
346 "http delete filename: \"%s\"", path.data); | |
347 | |
3501
423ff11e3018
use lstat() for WebDAV DELETE, COPY, and MOVE to handle symlinks
Igor Sysoev <igor@sysoev.ru>
parents:
3182
diff
changeset
|
348 if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) { |
1815 | 349 err = ngx_errno; |
350 | |
351 rc = (err == NGX_ENOTDIR) ? NGX_HTTP_CONFLICT : NGX_HTTP_NOT_FOUND; | |
352 | |
353 return ngx_http_dav_error(r->connection->log, err, | |
3501
423ff11e3018
use lstat() for WebDAV DELETE, COPY, and MOVE to handle symlinks
Igor Sysoev <igor@sysoev.ru>
parents:
3182
diff
changeset
|
354 rc, ngx_link_info_n, path.data); |
1116 | 355 } |
356 | |
357 if (ngx_is_dir(&fi)) { | |
358 | |
359 if (r->uri.data[r->uri.len - 1] != '/') { | |
1815 | 360 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_EISDIR, |
361 "DELETE \"%s\" failed", path.data); | |
362 return NGX_HTTP_CONFLICT; | |
1116 | 363 } |
364 | |
365 depth = ngx_http_dav_depth(r, NGX_HTTP_DAV_INFINITY_DEPTH); | |
366 | |
367 if (depth != NGX_HTTP_DAV_INFINITY_DEPTH) { | |
1815 | 368 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
369 "\"Depth\" header must be infinity"); | |
1116 | 370 return NGX_HTTP_BAD_REQUEST; |
371 } | |
372 | |
373 path.len -= 2; /* omit "/\0" */ | |
374 | |
375 dir = 1; | |
376 | |
377 } else { | |
378 | |
1823 | 379 /* |
380 * we do not need to test (r->uri.data[r->uri.len - 1] == '/') | |
3501
423ff11e3018
use lstat() for WebDAV DELETE, COPY, and MOVE to handle symlinks
Igor Sysoev <igor@sysoev.ru>
parents:
3182
diff
changeset
|
381 * because ngx_link_info("/file/") returned NGX_ENOTDIR above |
1823 | 382 */ |
383 | |
1116 | 384 depth = ngx_http_dav_depth(r, 0); |
385 | |
386 if (depth != 0 && depth != NGX_HTTP_DAV_INFINITY_DEPTH) { | |
1815 | 387 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
388 "\"Depth\" header must be 0 or infinity"); | |
1116 | 389 return NGX_HTTP_BAD_REQUEST; |
390 } | |
391 | |
392 dir = 0; | |
393 } | |
394 | |
395 rc = ngx_http_dav_delete_path(r, &path, dir); | |
396 | |
397 if (rc == NGX_OK) { | |
398 return NGX_HTTP_NO_CONTENT; | |
399 } | |
400 | |
401 return rc; | |
402 } | |
403 | |
404 | |
405 static ngx_int_t | |
1820 | 406 ngx_http_dav_delete_path(ngx_http_request_t *r, ngx_str_t *path, ngx_uint_t dir) |
1116 | 407 { |
1820 | 408 char *failed; |
409 ngx_tree_ctx_t tree; | |
410 | |
411 if (dir) { | |
412 | |
413 tree.init_handler = NULL; | |
414 tree.file_handler = ngx_http_dav_delete_file; | |
415 tree.pre_tree_handler = ngx_http_dav_noop; | |
416 tree.post_tree_handler = ngx_http_dav_delete_dir; | |
417 tree.spec_handler = ngx_http_dav_delete_file; | |
418 tree.data = NULL; | |
419 tree.alloc = 0; | |
420 tree.log = r->connection->log; | |
421 | |
422 /* TODO: 207 */ | |
423 | |
424 if (ngx_walk_tree(&tree, path) != NGX_OK) { | |
425 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
426 } | |
427 | |
428 if (ngx_delete_dir(path->data) != NGX_FILE_ERROR) { | |
429 return NGX_OK; | |
430 } | |
431 | |
432 failed = ngx_delete_dir_n; | |
433 | |
434 } else { | |
435 | |
436 if (ngx_delete_file(path->data) != NGX_FILE_ERROR) { | |
437 return NGX_OK; | |
438 } | |
439 | |
440 failed = ngx_delete_file_n; | |
441 } | |
442 | |
443 return ngx_http_dav_error(r->connection->log, ngx_errno, | |
444 NGX_HTTP_NOT_FOUND, failed, path->data); | |
1116 | 445 } |
446 | |
447 | |
448 static ngx_int_t | |
449 ngx_http_dav_delete_dir(ngx_tree_ctx_t *ctx, ngx_str_t *path) | |
450 { | |
451 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0, | |
452 "http delete dir: \"%s\"", path->data); | |
453 | |
454 if (ngx_delete_dir(path->data) == NGX_FILE_ERROR) { | |
455 | |
456 /* TODO: add to 207 */ | |
457 | |
458 (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_delete_dir_n, | |
459 path->data); | |
460 } | |
461 | |
462 return NGX_OK; | |
463 } | |
464 | |
465 | |
466 static ngx_int_t | |
467 ngx_http_dav_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path) | |
468 { | |
469 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0, | |
470 "http delete file: \"%s\"", path->data); | |
471 | |
472 if (ngx_delete_file(path->data) == NGX_FILE_ERROR) { | |
473 | |
474 /* TODO: add to 207 */ | |
475 | |
476 (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_delete_file_n, | |
477 path->data); | |
478 } | |
479 | |
480 return NGX_OK; | |
481 } | |
482 | |
483 | |
484 static ngx_int_t | |
1820 | 485 ngx_http_dav_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path) |
486 { | |
487 return NGX_OK; | |
488 } | |
489 | |
490 | |
491 static ngx_int_t | |
1116 | 492 ngx_http_dav_mkcol_handler(ngx_http_request_t *r, ngx_http_dav_loc_conf_t *dlcf) |
493 { | |
1819
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
494 u_char *p; |
1116 | 495 size_t root; |
496 ngx_str_t path; | |
497 | |
498 if (r->headers_in.content_length_n > 0) { | |
1819
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
499 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
500 "MKCOL with body is unsupported"); |
1116 | 501 return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE; |
502 } | |
503 | |
1819
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
504 if (r->uri.data[r->uri.len - 1] != '/') { |
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
505 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
506 "MKCOL can create a collection only"); |
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
507 return NGX_HTTP_CONFLICT; |
1116 | 508 } |
509 | |
1819
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
510 p = ngx_http_map_uri_to_path(r, &path, &root, 0); |
5781
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
511 if (p == NULL) { |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
512 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
513 } |
1819
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
514 |
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
515 *(p - 1) = '\0'; |
3182
6ddaac3e0bf7
omit '\0' from "Location" header on MKCOL request
Igor Sysoev <igor@sysoev.ru>
parents:
3161
diff
changeset
|
516 r->uri.len--; |
1116 | 517 |
518 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
519 "http mkcol path: \"%s\"", path.data); | |
520 | |
521 if (ngx_create_dir(path.data, ngx_dir_access(dlcf->access)) | |
522 != NGX_FILE_ERROR) | |
523 { | |
524 if (ngx_http_dav_location(r, path.data) != NGX_OK) { | |
525 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
526 } | |
527 | |
528 return NGX_HTTP_CREATED; | |
529 } | |
530 | |
531 return ngx_http_dav_error(r->connection->log, ngx_errno, | |
1819
0f907513dd3c
change status code, add log message, and test collection URI
Igor Sysoev <igor@sysoev.ru>
parents:
1818
diff
changeset
|
532 NGX_HTTP_CONFLICT, ngx_create_dir_n, path.data); |
1116 | 533 } |
534 | |
535 | |
536 static ngx_int_t | |
537 ngx_http_dav_copy_move_handler(ngx_http_request_t *r) | |
538 { | |
2007
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1909
diff
changeset
|
539 u_char *p, *host, *last, ch; |
1804
d457a1576532
several changes in server_name:
Igor Sysoev <igor@sysoev.ru>
parents:
1803
diff
changeset
|
540 size_t len, root; |
1116 | 541 ngx_err_t err; |
542 ngx_int_t rc, depth; | |
3161 | 543 ngx_uint_t overwrite, slash, dir, flags; |
544 ngx_str_t path, uri, duri, args; | |
1116 | 545 ngx_tree_ctx_t tree; |
3024
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
546 ngx_copy_file_t cf; |
1116 | 547 ngx_file_info_t fi; |
2007
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1909
diff
changeset
|
548 ngx_table_elt_t *dest, *over; |
2394
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
549 ngx_ext_rename_file_t ext; |
1116 | 550 ngx_http_dav_copy_ctx_t copy; |
1825
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
551 ngx_http_dav_loc_conf_t *dlcf; |
1116 | 552 |
553 if (r->headers_in.content_length_n > 0) { | |
554 return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE; | |
555 } | |
556 | |
557 dest = r->headers_in.destination; | |
558 | |
559 if (dest == NULL) { | |
560 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
561 "client sent no \"Destination\" header"); | |
562 return NGX_HTTP_BAD_REQUEST; | |
563 } | |
564 | |
3612
f9a96545fee7
allow Destination URL without host
Igor Sysoev <igor@sysoev.ru>
parents:
3527
diff
changeset
|
565 p = dest->value.data; |
f9a96545fee7
allow Destination URL without host
Igor Sysoev <igor@sysoev.ru>
parents:
3527
diff
changeset
|
566 /* there is always '\0' even after empty header value */ |
f9a96545fee7
allow Destination URL without host
Igor Sysoev <igor@sysoev.ru>
parents:
3527
diff
changeset
|
567 if (p[0] == '/') { |
f9a96545fee7
allow Destination URL without host
Igor Sysoev <igor@sysoev.ru>
parents:
3527
diff
changeset
|
568 last = p + dest->value.len; |
f9a96545fee7
allow Destination URL without host
Igor Sysoev <igor@sysoev.ru>
parents:
3527
diff
changeset
|
569 goto destination_done; |
f9a96545fee7
allow Destination URL without host
Igor Sysoev <igor@sysoev.ru>
parents:
3527
diff
changeset
|
570 } |
f9a96545fee7
allow Destination URL without host
Igor Sysoev <igor@sysoev.ru>
parents:
3527
diff
changeset
|
571 |
2007
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1909
diff
changeset
|
572 len = r->headers_in.server.len; |
1804
d457a1576532
several changes in server_name:
Igor Sysoev <igor@sysoev.ru>
parents:
1803
diff
changeset
|
573 |
2007
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1909
diff
changeset
|
574 if (len == 0) { |
1804
d457a1576532
several changes in server_name:
Igor Sysoev <igor@sysoev.ru>
parents:
1803
diff
changeset
|
575 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
d457a1576532
several changes in server_name:
Igor Sysoev <igor@sysoev.ru>
parents:
1803
diff
changeset
|
576 "client sent no \"Host\" header"); |
d457a1576532
several changes in server_name:
Igor Sysoev <igor@sysoev.ru>
parents:
1803
diff
changeset
|
577 return NGX_HTTP_BAD_REQUEST; |
1116 | 578 } |
579 | |
580 #if (NGX_HTTP_SSL) | |
581 | |
582 if (r->connection->ssl) { | |
583 if (ngx_strncmp(dest->value.data, "https://", sizeof("https://") - 1) | |
584 != 0) | |
585 { | |
586 goto invalid_destination; | |
587 } | |
588 | |
2007
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1909
diff
changeset
|
589 host = dest->value.data + sizeof("https://") - 1; |
1116 | 590 |
591 } else | |
592 #endif | |
593 { | |
594 if (ngx_strncmp(dest->value.data, "http://", sizeof("http://") - 1) | |
595 != 0) | |
596 { | |
597 goto invalid_destination; | |
598 } | |
599 | |
2007
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1909
diff
changeset
|
600 host = dest->value.data + sizeof("http://") - 1; |
1116 | 601 } |
602 | |
2007
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1909
diff
changeset
|
603 if (ngx_strncmp(host, r->headers_in.server.data, len) != 0) { |
1116 | 604 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
1822
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
605 "\"Destination\" URI \"%V\" is handled by " |
1116 | 606 "different repository than the source URI", |
607 &dest->value); | |
608 return NGX_HTTP_BAD_REQUEST; | |
609 } | |
610 | |
611 last = dest->value.data + dest->value.len; | |
612 | |
2007
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1909
diff
changeset
|
613 for (p = host + len; p < last; p++) { |
1116 | 614 if (*p == '/') { |
615 goto destination_done; | |
616 } | |
617 } | |
618 | |
619 invalid_destination: | |
620 | |
621 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
622 "client sent invalid \"Destination\" header: \"%V\"", | |
623 &dest->value); | |
624 return NGX_HTTP_BAD_REQUEST; | |
625 | |
626 destination_done: | |
627 | |
3161 | 628 duri.len = last - p; |
629 duri.data = p; | |
5492
5c52ff68f380
Dav: emit a warning about unsafe URI.
Ruslan Ermilov <ru@nginx.com>
parents:
5409
diff
changeset
|
630 flags = NGX_HTTP_LOG_UNSAFE; |
3161 | 631 |
632 if (ngx_http_parse_unsafe_uri(r, &duri, &args, &flags) != NGX_OK) { | |
633 goto invalid_destination; | |
634 } | |
635 | |
1822
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
636 if ((r->uri.data[r->uri.len - 1] == '/' && *(last - 1) != '/') |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
637 || (r->uri.data[r->uri.len - 1] != '/' && *(last - 1) == '/')) |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
638 { |
6474 | 639 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
640 "both URI \"%V\" and \"Destination\" URI \"%V\" " | |
641 "should be either collections or non-collections", | |
642 &r->uri, &dest->value); | |
643 return NGX_HTTP_CONFLICT; | |
1822
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
644 } |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
645 |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
646 depth = ngx_http_dav_depth(r, NGX_HTTP_DAV_INFINITY_DEPTH); |
1116 | 647 |
1822
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
648 if (depth != NGX_HTTP_DAV_INFINITY_DEPTH) { |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
649 |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
650 if (r->method == NGX_HTTP_COPY) { |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
651 if (depth != 0) { |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
652 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
653 "\"Depth\" header must be 0 or infinity"); |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
654 return NGX_HTTP_BAD_REQUEST; |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
655 } |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
656 |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
657 } else { |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
658 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
659 "\"Depth\" header must be infinity"); |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
660 return NGX_HTTP_BAD_REQUEST; |
935427c55e04
test URI/Destination collection/non-collection and Depth
Igor Sysoev <igor@sysoev.ru>
parents:
1821
diff
changeset
|
661 } |
1116 | 662 } |
1174
6be5ee17d80b
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
1116
diff
changeset
|
663 |
1116 | 664 over = r->headers_in.overwrite; |
665 | |
666 if (over) { | |
667 if (over->value.len == 1) { | |
668 ch = over->value.data[0]; | |
669 | |
670 if (ch == 'T' || ch == 't') { | |
671 overwrite = 1; | |
672 goto overwrite_done; | |
673 } | |
674 | |
675 if (ch == 'F' || ch == 'f') { | |
676 overwrite = 0; | |
677 goto overwrite_done; | |
678 } | |
679 | |
680 } | |
681 | |
682 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
683 "client sent invalid \"Overwrite\" header: \"%V\"", | |
684 &over->value); | |
685 return NGX_HTTP_BAD_REQUEST; | |
686 } | |
687 | |
688 overwrite = 1; | |
689 | |
690 overwrite_done: | |
691 | |
5781
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
692 if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) { |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
693 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
694 } |
1116 | 695 |
696 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
697 "http copy from: \"%s\"", path.data); | |
698 | |
699 uri = r->uri; | |
3161 | 700 r->uri = duri; |
1116 | 701 |
5781
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
702 if (ngx_http_map_uri_to_path(r, ©.path, &root, 0) == NULL) { |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
703 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
1f70fe0d9576
Dav: ngx_http_map_uri_to_path() errors were not checked.
FengGu <flygoast@126.com>
parents:
5492
diff
changeset
|
704 } |
1116 | 705 |
706 r->uri = uri; | |
707 | |
708 copy.path.len--; /* omit "\0" */ | |
709 | |
710 if (copy.path.data[copy.path.len - 1] == '/') { | |
711 slash = 1; | |
712 copy.path.len--; | |
713 copy.path.data[copy.path.len] = '\0'; | |
714 | |
715 } else { | |
716 slash = 0; | |
717 } | |
718 | |
719 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
720 "http copy to: \"%s\"", copy.path.data); | |
721 | |
3501
423ff11e3018
use lstat() for WebDAV DELETE, COPY, and MOVE to handle symlinks
Igor Sysoev <igor@sysoev.ru>
parents:
3182
diff
changeset
|
722 if (ngx_link_info(copy.path.data, &fi) == NGX_FILE_ERROR) { |
1116 | 723 err = ngx_errno; |
724 | |
725 if (err != NGX_ENOENT) { | |
726 return ngx_http_dav_error(r->connection->log, err, | |
3501
423ff11e3018
use lstat() for WebDAV DELETE, COPY, and MOVE to handle symlinks
Igor Sysoev <igor@sysoev.ru>
parents:
3182
diff
changeset
|
727 NGX_HTTP_NOT_FOUND, ngx_link_info_n, |
1116 | 728 copy.path.data); |
729 } | |
730 | |
731 /* destination does not exist */ | |
732 | |
1825
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
733 overwrite = 0; |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
734 dir = 0; |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
735 |
1116 | 736 } else { |
737 | |
738 /* destination exists */ | |
739 | |
740 if (ngx_is_dir(&fi) && !slash) { | |
1824 | 741 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
742 "\"%V\" could not be %Ved to collection \"%V\"", | |
743 &r->uri, &r->method_name, &dest->value); | |
1116 | 744 return NGX_HTTP_CONFLICT; |
745 } | |
746 | |
747 if (!overwrite) { | |
1824 | 748 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_EEXIST, |
749 "\"%s\" could not be created", copy.path.data); | |
1116 | 750 return NGX_HTTP_PRECONDITION_FAILED; |
751 } | |
752 | |
1825
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
753 dir = ngx_is_dir(&fi); |
1116 | 754 } |
755 | |
3501
423ff11e3018
use lstat() for WebDAV DELETE, COPY, and MOVE to handle symlinks
Igor Sysoev <igor@sysoev.ru>
parents:
3182
diff
changeset
|
756 if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) { |
1116 | 757 return ngx_http_dav_error(r->connection->log, ngx_errno, |
3501
423ff11e3018
use lstat() for WebDAV DELETE, COPY, and MOVE to handle symlinks
Igor Sysoev <igor@sysoev.ru>
parents:
3182
diff
changeset
|
758 NGX_HTTP_NOT_FOUND, ngx_link_info_n, |
1116 | 759 path.data); |
760 } | |
761 | |
762 if (ngx_is_dir(&fi)) { | |
763 | |
764 if (r->uri.data[r->uri.len - 1] != '/') { | |
1825
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
765 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
766 "\"%V\" is collection", &r->uri); |
1116 | 767 return NGX_HTTP_BAD_REQUEST; |
768 } | |
769 | |
1825
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
770 if (overwrite) { |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
771 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
772 "http delete: \"%s\"", copy.path.data); |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
773 |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
774 rc = ngx_http_dav_delete_path(r, ©.path, dir); |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
775 |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
776 if (rc != NGX_OK) { |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
777 return rc; |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
778 } |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
779 } |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
780 } |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
781 |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
782 if (ngx_is_dir(&fi)) { |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
783 |
1116 | 784 path.len -= 2; /* omit "/\0" */ |
785 | |
786 if (r->method == NGX_HTTP_MOVE) { | |
787 if (ngx_rename_file(path.data, copy.path.data) != NGX_FILE_ERROR) { | |
788 return NGX_HTTP_CREATED; | |
789 } | |
790 } | |
791 | |
792 if (ngx_create_dir(copy.path.data, ngx_file_access(&fi)) | |
793 == NGX_FILE_ERROR) | |
794 { | |
795 return ngx_http_dav_error(r->connection->log, ngx_errno, | |
796 NGX_HTTP_NOT_FOUND, | |
797 ngx_create_dir_n, copy.path.data); | |
798 } | |
799 | |
800 copy.len = path.len; | |
801 | |
1769
a35bc4007ec3
tree.init_handler is never called
Igor Sysoev <igor@sysoev.ru>
parents:
1749
diff
changeset
|
802 tree.init_handler = NULL; |
1825
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
803 tree.file_handler = ngx_http_dav_copy_tree_file; |
1116 | 804 tree.pre_tree_handler = ngx_http_dav_copy_dir; |
805 tree.post_tree_handler = ngx_http_dav_copy_dir_time; | |
806 tree.spec_handler = ngx_http_dav_noop; | |
807 tree.data = © | |
808 tree.alloc = 0; | |
809 tree.log = r->connection->log; | |
810 | |
811 if (ngx_walk_tree(&tree, &path) == NGX_OK) { | |
812 | |
813 if (r->method == NGX_HTTP_MOVE) { | |
814 rc = ngx_http_dav_delete_path(r, &path, 1); | |
815 | |
816 if (rc != NGX_OK) { | |
817 return rc; | |
818 } | |
819 } | |
820 | |
821 return NGX_HTTP_CREATED; | |
822 } | |
823 | |
824 } else { | |
825 | |
826 if (r->method == NGX_HTTP_MOVE) { | |
2394
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
827 |
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
828 dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); |
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
829 |
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
830 ext.access = 0; |
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
831 ext.path_access = dlcf->access; |
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
832 ext.time = -1; |
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
833 ext.create_path = 1; |
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
834 ext.delete_file = 0; |
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
835 ext.log = r->connection->log; |
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
836 |
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
837 if (ngx_ext_rename_file(&path, ©.path, &ext) == NGX_OK) { |
1116 | 838 return NGX_HTTP_NO_CONTENT; |
839 } | |
2394
dbe746851b31
use ngx_ext_rename_file() for single file MOVE
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
840 |
3024
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
841 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
1116 | 842 } |
843 | |
3024
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
844 cf.size = ngx_file_size(&fi); |
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
845 cf.buf_size = 0; |
7330
8e7a5de61664
Dav: changed COPY of a file to preserve access mask.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7198
diff
changeset
|
846 cf.access = ngx_file_access(&fi); |
3024
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
847 cf.time = ngx_file_mtime(&fi); |
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
848 cf.log = r->connection->log; |
1116 | 849 |
3024
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
850 if (ngx_copy_file(path.data, copy.path.data, &cf) == NGX_OK) { |
1116 | 851 return NGX_HTTP_NO_CONTENT; |
852 } | |
853 } | |
854 | |
855 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
856 } | |
857 | |
858 | |
859 static ngx_int_t | |
860 ngx_http_dav_copy_dir(ngx_tree_ctx_t *ctx, ngx_str_t *path) | |
861 { | |
862 u_char *p, *dir; | |
863 size_t len; | |
864 ngx_http_dav_copy_ctx_t *copy; | |
865 | |
866 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0, | |
867 "http copy dir: \"%s\"", path->data); | |
868 | |
869 copy = ctx->data; | |
870 | |
871 len = copy->path.len + path->len; | |
872 | |
873 dir = ngx_alloc(len + 1, ctx->log); | |
874 if (dir == NULL) { | |
875 return NGX_ABORT; | |
876 } | |
877 | |
878 p = ngx_cpymem(dir, copy->path.data, copy->path.len); | |
879 (void) ngx_cpystrn(p, path->data + copy->len, path->len - copy->len + 1); | |
880 | |
881 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0, | |
882 "http copy dir to: \"%s\"", dir); | |
883 | |
884 if (ngx_create_dir(dir, ngx_dir_access(ctx->access)) == NGX_FILE_ERROR) { | |
885 (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_create_dir_n, | |
886 dir); | |
887 } | |
888 | |
889 ngx_free(dir); | |
890 | |
891 return NGX_OK; | |
892 } | |
893 | |
894 | |
895 static ngx_int_t | |
896 ngx_http_dav_copy_dir_time(ngx_tree_ctx_t *ctx, ngx_str_t *path) | |
897 { | |
898 u_char *p, *dir; | |
899 size_t len; | |
900 ngx_http_dav_copy_ctx_t *copy; | |
901 | |
902 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0, | |
903 "http copy dir time: \"%s\"", path->data); | |
904 | |
905 copy = ctx->data; | |
906 | |
907 len = copy->path.len + path->len; | |
908 | |
909 dir = ngx_alloc(len + 1, ctx->log); | |
910 if (dir == NULL) { | |
911 return NGX_ABORT; | |
912 } | |
913 | |
914 p = ngx_cpymem(dir, copy->path.data, copy->path.len); | |
915 (void) ngx_cpystrn(p, path->data + copy->len, path->len - copy->len + 1); | |
916 | |
917 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0, | |
918 "http copy dir time to: \"%s\"", dir); | |
919 | |
1803
7405719e4848
condition declarations inside blocks update missed in r1705
Igor Sysoev <igor@sysoev.ru>
parents:
1769
diff
changeset
|
920 #if (NGX_WIN32) |
7405719e4848
condition declarations inside blocks update missed in r1705
Igor Sysoev <igor@sysoev.ru>
parents:
1769
diff
changeset
|
921 { |
7405719e4848
condition declarations inside blocks update missed in r1705
Igor Sysoev <igor@sysoev.ru>
parents:
1769
diff
changeset
|
922 ngx_fd_t fd; |
1116 | 923 |
924 fd = ngx_open_file(dir, NGX_FILE_RDWR, NGX_FILE_OPEN, 0); | |
925 | |
926 if (fd == NGX_INVALID_FILE) { | |
927 (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_open_file_n, dir); | |
928 goto failed; | |
929 } | |
930 | |
931 if (ngx_set_file_time(NULL, fd, ctx->mtime) != NGX_OK) { | |
932 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno, | |
933 ngx_set_file_time_n " \"%s\" failed", dir); | |
934 } | |
935 | |
936 if (ngx_close_file(fd) == NGX_FILE_ERROR) { | |
937 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno, | |
938 ngx_close_file_n " \"%s\" failed", dir); | |
939 } | |
1803
7405719e4848
condition declarations inside blocks update missed in r1705
Igor Sysoev <igor@sysoev.ru>
parents:
1769
diff
changeset
|
940 } |
1116 | 941 |
942 failed: | |
943 | |
944 #else | |
945 | |
946 if (ngx_set_file_time(dir, 0, ctx->mtime) != NGX_OK) { | |
947 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno, | |
948 ngx_set_file_time_n " \"%s\" failed", dir); | |
949 } | |
950 | |
951 #endif | |
952 | |
953 ngx_free(dir); | |
954 | |
955 return NGX_OK; | |
956 } | |
957 | |
958 | |
959 static ngx_int_t | |
1825
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
960 ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, ngx_str_t *path) |
1116 | 961 { |
962 u_char *p, *file; | |
963 size_t len; | |
3024
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
964 ngx_copy_file_t cf; |
1116 | 965 ngx_http_dav_copy_ctx_t *copy; |
966 | |
967 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0, | |
968 "http copy file: \"%s\"", path->data); | |
969 | |
970 copy = ctx->data; | |
971 | |
972 len = copy->path.len + path->len; | |
973 | |
974 file = ngx_alloc(len + 1, ctx->log); | |
975 if (file == NULL) { | |
976 return NGX_ABORT; | |
977 } | |
978 | |
979 p = ngx_cpymem(file, copy->path.data, copy->path.len); | |
980 (void) ngx_cpystrn(p, path->data + copy->len, path->len - copy->len + 1); | |
981 | |
982 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0, | |
983 "http copy file to: \"%s\"", file); | |
984 | |
3024
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
985 cf.size = ctx->size; |
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
986 cf.buf_size = 0; |
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
987 cf.access = ctx->access; |
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
988 cf.time = ctx->mtime; |
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
989 cf.log = ctx->log; |
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
990 |
8101d9101ed8
allow cross device temporary files atomic copying:
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
991 (void) ngx_copy_file(path->data, file, &cf); |
1825
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
992 |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
993 ngx_free(file); |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
994 |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
995 return NGX_OK; |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
996 } |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
997 |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
998 |
2e0fbfef56d4
do not delete target until all tests will be done,
Igor Sysoev <igor@sysoev.ru>
parents:
1824
diff
changeset
|
999 static ngx_int_t |
1116 | 1000 ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt) |
1001 { | |
1002 ngx_table_elt_t *depth; | |
1174
6be5ee17d80b
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
1116
diff
changeset
|
1003 |
1116 | 1004 depth = r->headers_in.depth; |
1005 | |
1006 if (depth == NULL) { | |
1007 return dflt; | |
1008 } | |
1009 | |
1010 if (depth->value.len == 1) { | |
1011 | |
1012 if (depth->value.data[0] == '0') { | |
1013 return 0; | |
1014 } | |
1015 | |
1016 if (depth->value.data[0] == '1') { | |
1017 return 1; | |
1018 } | |
1019 | |
1020 } else { | |
1021 | |
1022 if (depth->value.len == sizeof("infinity") - 1 | |
1023 && ngx_strcmp(depth->value.data, "infinity") == 0) | |
1024 { | |
1025 return NGX_HTTP_DAV_INFINITY_DEPTH; | |
1026 } | |
1027 } | |
1028 | |
1029 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
1030 "client sent invalid \"Depth\" header: \"%V\"", | |
1031 &depth->value); | |
1032 | |
1033 return NGX_HTTP_DAV_INVALID_DEPTH; | |
1034 } | |
1035 | |
1036 | |
1037 static ngx_int_t | |
1038 ngx_http_dav_error(ngx_log_t *log, ngx_err_t err, ngx_int_t not_found, | |
637 | 1039 char *failed, u_char *path) |
1040 { | |
1041 ngx_int_t rc; | |
1042 ngx_uint_t level; | |
1043 | |
1044 if (err == NGX_ENOENT || err == NGX_ENOTDIR || err == NGX_ENAMETOOLONG) { | |
1045 level = NGX_LOG_ERR; | |
1046 rc = not_found; | |
1047 | |
1048 } else if (err == NGX_EACCES || err == NGX_EPERM) { | |
1049 level = NGX_LOG_ERR; | |
1050 rc = NGX_HTTP_FORBIDDEN; | |
1051 | |
1052 } else if (err == NGX_EEXIST) { | |
1053 level = NGX_LOG_ERR; | |
1054 rc = NGX_HTTP_NOT_ALLOWED; | |
1055 | |
1056 } else if (err == NGX_ENOSPC) { | |
1057 level = NGX_LOG_CRIT; | |
1058 rc = NGX_HTTP_INSUFFICIENT_STORAGE; | |
1059 | |
1060 } else { | |
1061 level = NGX_LOG_CRIT; | |
1062 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
1063 } | |
1064 | |
1116 | 1065 ngx_log_error(level, log, err, "%s \"%s\" failed", failed, path); |
637 | 1066 |
1067 return rc; | |
1068 } | |
1069 | |
1070 | |
1071 static ngx_int_t | |
1072 ngx_http_dav_location(ngx_http_request_t *r, u_char *path) | |
1073 { | |
1074 u_char *location; | |
1075 ngx_http_core_loc_conf_t *clcf; | |
1076 | |
6853
c85dfd99a2dd
Fixed missing "Location" field with some relative redirects.
Ruslan Ermilov <ru@nginx.com>
parents:
6538
diff
changeset
|
1077 r->headers_out.location = ngx_list_push(&r->headers_out.headers); |
637 | 1078 if (r->headers_out.location == NULL) { |
1079 return NGX_ERROR; | |
1080 } | |
1081 | |
1082 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1083 | |
1084 if (!clcf->alias && clcf->root_lengths == NULL) { | |
1085 location = path + clcf->root.len; | |
1086 | |
1087 } else { | |
2049 | 1088 location = ngx_pnalloc(r->pool, r->uri.len); |
637 | 1089 if (location == NULL) { |
6986
0cdee26605f3
Cleaned up r->headers_out.headers allocation error handling.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6853
diff
changeset
|
1090 ngx_http_clear_location(r); |
637 | 1091 return NGX_ERROR; |
1092 } | |
1093 | |
1094 ngx_memcpy(location, r->uri.data, r->uri.len); | |
1095 } | |
1096 | |
6853
c85dfd99a2dd
Fixed missing "Location" field with some relative redirects.
Ruslan Ermilov <ru@nginx.com>
parents:
6538
diff
changeset
|
1097 r->headers_out.location->hash = 1; |
c85dfd99a2dd
Fixed missing "Location" field with some relative redirects.
Ruslan Ermilov <ru@nginx.com>
parents:
6538
diff
changeset
|
1098 ngx_str_set(&r->headers_out.location->key, "Location"); |
637 | 1099 r->headers_out.location->value.len = r->uri.len; |
1100 r->headers_out.location->value.data = location; | |
1101 | |
1102 return NGX_OK; | |
1103 } | |
1104 | |
1105 | |
633 | 1106 static void * |
1107 ngx_http_dav_create_loc_conf(ngx_conf_t *cf) | |
1108 { | |
1109 ngx_http_dav_loc_conf_t *conf; | |
1110 | |
1111 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_dav_loc_conf_t)); | |
1112 if (conf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2782
diff
changeset
|
1113 return NULL; |
633 | 1114 } |
1115 | |
1116 /* | |
1117 * set by ngx_pcalloc(): | |
1118 * | |
1119 * conf->methods = 0; | |
1120 */ | |
1121 | |
1864
524831ec3e69
fix building by msvc introduced in r1817
Igor Sysoev <igor@sysoev.ru>
parents:
1834
diff
changeset
|
1122 conf->min_delete_depth = NGX_CONF_UNSET_UINT; |
1816 | 1123 conf->access = NGX_CONF_UNSET_UINT; |
637 | 1124 conf->create_full_put_path = NGX_CONF_UNSET; |
1125 | |
633 | 1126 return conf; |
1127 } | |
1128 | |
1129 | |
1130 static char * | |
1131 ngx_http_dav_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
1132 { | |
1133 ngx_http_dav_loc_conf_t *prev = parent; | |
1134 ngx_http_dav_loc_conf_t *conf = child; | |
1135 | |
1136 ngx_conf_merge_bitmask_value(conf->methods, prev->methods, | |
637 | 1137 (NGX_CONF_BITMASK_SET|NGX_HTTP_DAV_OFF)); |
1138 | |
1816 | 1139 ngx_conf_merge_uint_value(conf->min_delete_depth, |
1140 prev->min_delete_depth, 0); | |
633 | 1141 |
669 | 1142 ngx_conf_merge_uint_value(conf->access, prev->access, 0600); |
1143 | |
1816 | 1144 ngx_conf_merge_value(conf->create_full_put_path, |
1145 prev->create_full_put_path, 0); | |
1146 | |
633 | 1147 return NGX_CONF_OK; |
1148 } | |
1149 | |
1150 | |
1151 static ngx_int_t | |
681 | 1152 ngx_http_dav_init(ngx_conf_t *cf) |
633 | 1153 { |
1154 ngx_http_handler_pt *h; | |
1155 ngx_http_core_main_conf_t *cmcf; | |
1156 | |
681 | 1157 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
633 | 1158 |
1159 h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); | |
1160 if (h == NULL) { | |
1161 return NGX_ERROR; | |
1162 } | |
1163 | |
1164 *h = ngx_http_dav_handler; | |
1165 | |
1166 return NGX_OK; | |
1167 } |