undo "client_body_in_file_only any"
and introduce "client_body_in_file_only clean"
introduce ngx_pool_delete_file() to not break a possible third-party
ngx_pool_cleanup_file() usage that may lead to an removal of the useful files
delete unnecessary ngx_http_finalize_request_body()
Igor Sysoev
15 years ago
18 | 18 | |
19 | 19 | if (tf->file.fd == NGX_INVALID_FILE) { |
20 | 20 | rc = ngx_create_temp_file(&tf->file, tf->path, tf->pool, |
21 | tf->persistent, tf->access); | |
21 | tf->persistent, tf->clean, tf->access); | |
22 | 22 | |
23 | 23 | if (rc == NGX_ERROR || rc == NGX_AGAIN) { |
24 | 24 | return rc; |
36 | 36 | |
37 | 37 | ngx_int_t |
38 | 38 | ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool, |
39 | ngx_uint_t persistent, ngx_uint_t access) | |
39 | ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access) | |
40 | 40 | { |
41 | 41 | ngx_err_t err; |
42 | 42 | ngx_atomic_uint_t n; |
78 | 78 | |
79 | 79 | if (file->fd != NGX_INVALID_FILE) { |
80 | 80 | |
81 | cln->handler = ngx_pool_cleanup_file; | |
81 | cln->handler = clean ? ngx_pool_delete_file : ngx_pool_cleanup_file; | |
82 | 82 | clnf = cln->data; |
83 | 83 | |
84 | 84 | clnf->fd = file->fd; |
52 | 52 | |
53 | 53 | unsigned log_level:8; |
54 | 54 | unsigned persistent:1; |
55 | unsigned clean:1; | |
55 | 56 | } ngx_temp_file_t; |
56 | 57 | |
57 | 58 | |
80 | 81 | |
81 | 82 | ssize_t ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain); |
82 | 83 | ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, |
83 | ngx_pool_t *pool, ngx_uint_t persistent,ngx_uint_t access); | |
84 | ngx_pool_t *pool, ngx_uint_t persistent, ngx_uint_t clean, | |
85 | ngx_uint_t access); | |
84 | 86 | void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path); |
85 | 87 | ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path); |
86 | 88 | ngx_err_t ngx_create_full_path(u_char *dir, ngx_uint_t access); |
242 | 242 | } |
243 | 243 | |
244 | 244 | |
245 | void | |
246 | ngx_pool_delete_file(void *data) | |
247 | { | |
248 | ngx_pool_cleanup_file_t *c = data; | |
249 | ||
250 | ngx_err_t err; | |
251 | ||
252 | ngx_log_debug3(NGX_LOG_DEBUG_ALLOC, c->log, 0, "run cleanup: %p, fd:%d %s", | |
253 | c, c->fd, c->name); | |
254 | ||
255 | if (ngx_delete_file(c->name) == NGX_FILE_ERROR) { | |
256 | err = ngx_errno; | |
257 | ||
258 | if (err != NGX_ENOENT) { | |
259 | ngx_log_error(NGX_LOG_CRIT, c->log, err, | |
260 | ngx_delete_file_n " \"%s\" failed", c->name); | |
261 | } | |
262 | } | |
263 | ||
264 | if (ngx_close_file(c->fd) == NGX_FILE_ERROR) { | |
265 | ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
266 | ngx_close_file_n " \"%s\" failed", c->name); | |
267 | } | |
268 | } | |
269 | ||
270 | ||
245 | 271 | #if 0 |
246 | 272 | |
247 | 273 | static void * |
59 | 59 | } ngx_pool_cleanup_file_t; |
60 | 60 | |
61 | 61 | |
62 | ||
63 | 62 | void *ngx_alloc(size_t size, ngx_log_t *log); |
64 | 63 | void *ngx_calloc(size_t size, ngx_log_t *log); |
65 | 64 | |
73 | 72 | |
74 | 73 | ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size); |
75 | 74 | void ngx_pool_cleanup_file(void *data); |
75 | void ngx_pool_delete_file(void *data); | |
76 | 76 | |
77 | 77 | |
78 | 78 | #endif /* _NGX_PALLOC_H_INCLUDED_ */ |
134 | 134 | |
135 | 135 | r->request_body_in_file_only = 1; |
136 | 136 | r->request_body_in_persistent_file = 1; |
137 | r->request_body_delete_incomplete_file = 1; | |
137 | r->request_body_in_clean_file = 1; | |
138 | 138 | r->request_body_file_group_access = 1; |
139 | 139 | r->request_body_file_log_level = 0; |
140 | 140 |
362 | 362 | |
363 | 363 | r->request_body_in_single_buf = 1; |
364 | 364 | r->request_body_in_persistent_file = 1; |
365 | r->request_body_delete_incomplete_file = 1; | |
365 | r->request_body_in_clean_file = 1; | |
366 | 366 | |
367 | 367 | if (r->request_body_in_file_only) { |
368 | 368 | r->request_body_file_log_level = 0; |
24 | 24 | |
25 | 25 | #define NGX_HTTP_REQUEST_BODY_FILE_OFF 0 |
26 | 26 | #define NGX_HTTP_REQUEST_BODY_FILE_ON 1 |
27 | #define NGX_HTTP_REQUEST_BODY_FILE_ANY 2 | |
27 | #define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2 | |
28 | 28 | |
29 | 29 | |
30 | 30 | static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r, |
81 | 81 | static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = { |
82 | 82 | { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF }, |
83 | 83 | { ngx_string("on"), NGX_HTTP_REQUEST_BODY_FILE_ON }, |
84 | { ngx_string("any"), NGX_HTTP_REQUEST_BODY_FILE_ANY }, | |
84 | { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN }, | |
85 | 85 | { ngx_null_string, 0 } |
86 | 86 | }; |
87 | 87 | |
889 | 889 | if (clcf->client_body_in_file_only) { |
890 | 890 | r->request_body_in_file_only = 1; |
891 | 891 | r->request_body_in_persistent_file = 1; |
892 | r->request_body_in_clean_file = | |
893 | clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN; | |
892 | 894 | r->request_body_file_log_level = NGX_LOG_NOTICE; |
893 | ||
894 | if (clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_ON) { | |
895 | r->request_body_delete_incomplete_file = 1; | |
896 | } | |
897 | 895 | |
898 | 896 | } else { |
899 | 897 | r->request_body_file_log_level = NGX_LOG_WARN; |
408 | 408 | unsigned request_body_in_single_buf:1; |
409 | 409 | unsigned request_body_in_file_only:1; |
410 | 410 | unsigned request_body_in_persistent_file:1; |
411 | unsigned request_body_delete_incomplete_file:1; | |
411 | unsigned request_body_in_clean_file:1; | |
412 | 412 | unsigned request_body_file_group_access:1; |
413 | 413 | unsigned request_body_file_log_level:3; |
414 | 414 |
13 | 13 | static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r); |
14 | 14 | static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r, |
15 | 15 | ngx_chain_t *body); |
16 | static void ngx_http_finalize_request_body(ngx_http_request_t *r, ngx_int_t rc); | |
17 | 16 | static void ngx_http_read_discarded_body_handler(ngx_http_request_t *r); |
18 | 17 | static ngx_int_t ngx_http_read_discarded_body(ngx_http_request_t *r); |
19 | 18 | |
31 | 30 | { |
32 | 31 | size_t preread; |
33 | 32 | ssize_t size; |
34 | ngx_int_t rc; | |
35 | 33 | ngx_buf_t *b; |
36 | 34 | ngx_chain_t *cl, **next; |
37 | 35 | ngx_temp_file_t *tf; |
72 | 70 | tf->warn = "a client request body is buffered to a temporary file"; |
73 | 71 | tf->log_level = r->request_body_file_log_level; |
74 | 72 | tf->persistent = r->request_body_in_persistent_file; |
73 | tf->clean = r->request_body_in_clean_file; | |
75 | 74 | |
76 | 75 | if (r->request_body_file_group_access) { |
77 | 76 | tf->access = 0660; |
80 | 79 | rb->temp_file = tf; |
81 | 80 | |
82 | 81 | if (ngx_create_temp_file(&tf->file, tf->path, tf->pool, |
83 | tf->persistent, tf->access) | |
82 | tf->persistent, tf->clean, tf->access) | |
84 | 83 | != NGX_OK) |
85 | 84 | { |
86 | 85 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
167 | 166 | |
168 | 167 | r->read_event_handler = ngx_http_read_client_request_body_handler; |
169 | 168 | |
170 | rc = ngx_http_do_read_client_request_body(r); | |
171 | ||
172 | if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | |
173 | ngx_http_finalize_request_body(r, rc); | |
174 | return NGX_DONE; | |
175 | } | |
176 | ||
177 | return rc; | |
169 | return ngx_http_do_read_client_request_body(r); | |
178 | 170 | } |
179 | 171 | |
180 | 172 | next = &rb->bufs->next; |
234 | 226 | |
235 | 227 | r->read_event_handler = ngx_http_read_client_request_body_handler; |
236 | 228 | |
237 | rc = ngx_http_do_read_client_request_body(r); | |
238 | ||
239 | if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | |
240 | ngx_http_finalize_request_body(r, rc); | |
241 | return NGX_DONE; | |
242 | } | |
243 | ||
244 | return rc; | |
229 | return ngx_http_do_read_client_request_body(r); | |
245 | 230 | } |
246 | 231 | |
247 | 232 | |
252 | 237 | |
253 | 238 | if (r->connection->read->timedout) { |
254 | 239 | r->connection->timedout = 1; |
255 | ngx_http_finalize_request_body(r, NGX_HTTP_REQUEST_TIME_OUT); | |
240 | ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); | |
256 | 241 | return; |
257 | 242 | } |
258 | 243 | |
259 | 244 | rc = ngx_http_do_read_client_request_body(r); |
260 | 245 | |
261 | 246 | if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
262 | ngx_http_finalize_request_body(r, rc); | |
247 | ngx_http_finalize_request(r, rc); | |
263 | 248 | } |
264 | 249 | } |
265 | 250 | |
414 | 399 | tf->warn = "a client request body is buffered to a temporary file"; |
415 | 400 | tf->log_level = r->request_body_file_log_level; |
416 | 401 | tf->persistent = r->request_body_in_persistent_file; |
402 | tf->clean = r->request_body_in_clean_file; | |
417 | 403 | |
418 | 404 | if (r->request_body_file_group_access) { |
419 | 405 | tf->access = 0660; |
433 | 419 | rb->temp_file->offset += n; |
434 | 420 | |
435 | 421 | return NGX_OK; |
436 | } | |
437 | ||
438 | ||
439 | static void | |
440 | ngx_http_finalize_request_body(ngx_http_request_t *r, ngx_int_t rc) | |
441 | { | |
442 | if (r->request_body->temp_file | |
443 | && r->request_body_in_persistent_file | |
444 | && r->request_body_delete_incomplete_file) | |
445 | { | |
446 | if (ngx_delete_file(r->request_body->temp_file->file.name.data) | |
447 | == NGX_FILE_ERROR) | |
448 | { | |
449 | ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, | |
450 | ngx_delete_file_n " \"%s\" failed", | |
451 | r->request_body->temp_file->file.name.data); | |
452 | } | |
453 | } | |
454 | ||
455 | ngx_http_finalize_request(r, rc); | |
456 | 422 | } |
457 | 423 | |
458 | 424 |