2
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
3
* Copyright (c) 2004-2008 Breach Security, Inc. (http://www.breach.com/)
5
* This product is released under the terms of the General Public Licence,
6
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
7
* distribution) which contains the complete text of the licence.
9
* There are special exceptions to the terms and conditions of the GPL
10
* as it is applied to this software. View the full text of the exception in
11
* file MODSECURITY_LICENSING_EXCEPTION in the directory of this software
14
* If any of the files related to licensing are missing or if you have any
15
* other questions related to licensing please contact Breach Security, Inc.
16
* directly using the email address support@breach.com.
19
#include "modsecurity.h"
20
#include "msc_parsers.h"
22
#define CHUNK_CAPACITY 8192
25
* Prepare to accept the request body (part 2).
27
static apr_status_t modsecurity_request_body_start_init(modsec_rec *msr, char **error_msg) {
30
if(msr->msc_reqbody_storage == MSC_REQBODY_MEMORY) {
31
/* Prepare to store request body in memory. */
33
msr->msc_reqbody_chunks = apr_array_make(msr->msc_reqbody_mp,
34
32, sizeof(msc_data_chunk *));
35
if (msr->msc_reqbody_chunks == NULL) {
36
*error_msg = apr_pstrdup(msr->mp, "Input filter: Failed to prepare in-memory storage.");
40
/* Prepare to store request body on disk. */
42
msr->msc_reqbody_filename = apr_psprintf(msr->mp, "%s/%s-%s-request_body-XXXXXX",
43
msr->txcfg->tmp_dir, current_filetime(msr->mp), msr->txid);
44
if (msr->msc_reqbody_filename == NULL) {
45
*error_msg = apr_pstrdup(msr->mp, "Input filter: Failed to generate an on-disk filename.");
49
msr->msc_reqbody_fd = msc_mkstemp((char *)msr->msc_reqbody_filename);
50
if (msr->msc_reqbody_fd < 0) {
51
*error_msg = apr_psprintf(msr->mp, "Input filter: Failed to create temporary file: %s",
52
msr->msc_reqbody_filename);
56
msr_log(msr, 4, "Input filter: Created temporary file to store request body: %s",
57
msr->msc_reqbody_filename);
64
* Prepare to accept the request body (part 1).
66
apr_status_t modsecurity_request_body_start(modsec_rec *msr, char **error_msg) {
68
msr->msc_reqbody_length = 0;
70
/* Create a separate memory pool that will be used
71
* to allocate structures from (not data, which is allocated
74
apr_pool_create(&msr->msc_reqbody_mp, NULL);
76
/* Initialise request body processors, if any. */
78
if (msr->msc_reqbody_processor != NULL) {
79
char *my_error_msg = NULL;
81
if (strcmp(msr->msc_reqbody_processor, "MULTIPART") == 0) {
82
if (multipart_init(msr, &my_error_msg) < 0) {
83
*error_msg = apr_psprintf(msr->mp, "Multipart parsing error (init): %s", my_error_msg);
84
msr->msc_reqbody_error = 1;
85
msr->msc_reqbody_error_msg = my_error_msg;
86
msr_log(msr, 2, "%s", *error_msg);
90
if (strcmp(msr->msc_reqbody_processor, "XML") == 0) {
91
if (xml_init(msr, &my_error_msg) < 0) {
92
*error_msg = apr_psprintf(msr->mp, "XML parsing error (init): %s", my_error_msg);
93
msr->msc_reqbody_error = 1;
94
msr->msc_reqbody_error_msg = my_error_msg;
95
msr_log(msr, 2, "%s", *error_msg);
99
if (strcmp(msr->msc_reqbody_processor, "URLENCODED") == 0) {
100
/* Do nothing, URLENCODED processor does not support streaming yet. */
103
*error_msg = apr_psprintf(msr->mp, "Unknown request body processor: %s",
104
msr->msc_reqbody_processor);
109
return modsecurity_request_body_start_init(msr, error_msg);
113
* Stores a chunk of request body data to disk.
115
static apr_status_t modsecurity_request_body_store_disk(modsec_rec *msr,
116
const char *data, apr_size_t length, char **error_msg)
122
i = write(msr->msc_reqbody_fd, data, length);
124
*error_msg = apr_psprintf(msr->mp, "Input filter: Failed writing %" APR_SIZE_T_FMT
125
" bytes to temporary file (rc %" APR_SIZE_T_FMT ").", length, i);
133
* Stores one chunk of request body data in memory.
135
static apr_status_t modsecurity_request_body_store_memory(modsec_rec *msr,
136
const char *data, apr_size_t length, char **error_msg)
140
/* Would storing this chunk mean going over the limit? */
141
if ((msr->msc_reqbody_spilltodisk)
142
&& (msr->msc_reqbody_length + length > (apr_size_t)msr->txcfg->reqbody_inmemory_limit))
144
msc_data_chunk **chunks;
145
unsigned int disklen = 0;
148
msr_log(msr, 4, "Input filter: Request too large to store in memory, switching to disk.");
150
/* NOTE Must use modsecurity_request_body_store_disk() here
151
* to prevent data to be sent to the streaming
155
/* Initialise disk storage */
156
msr->msc_reqbody_storage = MSC_REQBODY_DISK;
157
if (modsecurity_request_body_start_init(msr, error_msg) < 0) return -1;
159
/* Write the data we keep in memory */
160
chunks = (msc_data_chunk **)msr->msc_reqbody_chunks->elts;
161
for(i = 0; i < msr->msc_reqbody_chunks->nelts; i++) {
162
disklen += chunks[i]->length;
164
if (modsecurity_request_body_store_disk(msr, chunks[i]->data, chunks[i]->length, error_msg) < 0) {
168
free(chunks[i]->data);
169
chunks[i]->data = NULL;
172
/* Clear the memory pool as we no longer need the bits. */
174
/* IMP1 But since we only used apr_pool_clear memory might
175
* not be released back to the OS straight away?
177
msr->msc_reqbody_chunks = NULL;
178
apr_pool_clear(msr->msc_reqbody_mp);
180
msr_log(msr, 4, "Input filter: Wrote %u bytes from memory to disk.", disklen);
182
/* Continue with disk storage from now on */
183
return modsecurity_request_body_store_disk(msr, data, length, error_msg);
186
/* If we're here that means we are not over the
187
* request body in-memory limit yet.
190
unsigned long int bucket_offset, bucket_left;
193
bucket_left = length;
195
/* Although we store the request body in chunks we don't
196
* want to use the same chunk sizes as the incoming memory
197
* buffers. They are often of very small sizes and that
198
* would make us waste a lot of memory. That's why we
199
* use our own chunks of CHUNK_CAPACITY sizes.
202
/* Loop until we empty this bucket into our chunks. */
203
while(bucket_left > 0) {
204
/* Allocate a new chunk if we have to. */
205
if (msr->msc_reqbody_chunk_current == NULL) {
206
msr->msc_reqbody_chunk_current = (msc_data_chunk *)
207
apr_pcalloc(msr->msc_reqbody_mp, sizeof(msc_data_chunk));
208
if (msr->msc_reqbody_chunk_current == NULL) {
209
*error_msg = apr_psprintf(msr->mp, "Input filter: Failed to allocate %lu bytes "
210
"for request body chunk.", (unsigned long)sizeof(msc_data_chunk));
214
msr->msc_reqbody_chunk_current->data = malloc(CHUNK_CAPACITY);
215
if (msr->msc_reqbody_chunk_current->data == NULL) {
216
*error_msg = apr_psprintf(msr->mp, "Input filter: Failed to allocate %d bytes "
217
"for request body chunk data.", CHUNK_CAPACITY);
221
msr->msc_reqbody_chunk_current->length = 0;
222
msr->msc_reqbody_chunk_current->is_permanent = 1;
224
*(const msc_data_chunk **)apr_array_push(msr->msc_reqbody_chunks)
225
= msr->msc_reqbody_chunk_current;
228
if (bucket_left < (CHUNK_CAPACITY - msr->msc_reqbody_chunk_current->length)) {
229
/* There's enough space in the current chunk. */
230
memcpy(msr->msc_reqbody_chunk_current->data +
231
msr->msc_reqbody_chunk_current->length, data + bucket_offset, bucket_left);
232
msr->msc_reqbody_chunk_current->length += bucket_left;
235
/* Fill the existing chunk. */
236
unsigned long int copy_length = CHUNK_CAPACITY -
237
msr->msc_reqbody_chunk_current->length;
239
memcpy(msr->msc_reqbody_chunk_current->data +
240
msr->msc_reqbody_chunk_current->length, data + bucket_offset, copy_length);
241
bucket_offset += copy_length;
242
bucket_left -= copy_length;
243
msr->msc_reqbody_chunk_current->length += copy_length;
245
/* We're done with this chunk. Setting the pointer
246
* to NULL is going to force a new chunk to be allocated
249
msr->msc_reqbody_chunk_current = NULL;
253
msr->msc_reqbody_length += length;
260
* Stores one chunk of request body data. Returns -1 on error.
262
apr_status_t modsecurity_request_body_store(modsec_rec *msr,
263
const char *data, apr_size_t length, char **error_msg)
267
/* If we have a processor for this request body send
268
* data to it first (but only if it did not report an
269
* error on previous invocations).
271
if ((msr->msc_reqbody_processor != NULL)&&(msr->msc_reqbody_error == 0)) {
272
char *my_error_msg = NULL;
274
if (strcmp(msr->msc_reqbody_processor, "MULTIPART") == 0) {
275
/* The per-request data length counter will
276
* be updated by the multipart parser.
279
/* Process data as multipart/form-data. */
280
if (multipart_process_chunk(msr, data, length, &my_error_msg) < 0) {
281
*error_msg = apr_psprintf(msr->mp, "Multipart parsing error: %s", my_error_msg);
282
msr->msc_reqbody_error = 1;
283
msr->msc_reqbody_error_msg = *error_msg;
284
msr_log(msr, 2, "%s", *error_msg);
288
if (strcmp(msr->msc_reqbody_processor, "XML") == 0) {
289
/* Increase per-request data length counter. */
290
msr->msc_reqbody_no_files_length += length;
292
/* Process data as XML. */
293
if (xml_process_chunk(msr, data, length, &my_error_msg) < 0) {
294
*error_msg = apr_psprintf(msr->mp, "XML parsing error: %s", my_error_msg);
295
msr->msc_reqbody_error = 1;
296
msr->msc_reqbody_error_msg = *error_msg;
297
msr_log(msr, 2, "%s", *error_msg);
301
if (strcmp(msr->msc_reqbody_processor, "URLENCODED") == 0) {
302
/* Increase per-request data length counter. */
303
msr->msc_reqbody_no_files_length += length;
305
/* Do nothing else, URLENCODED processor does not support streaming. */
308
*error_msg = apr_psprintf(msr->mp, "Unknown request body processor: %s",
309
msr->msc_reqbody_processor);
314
/* Check that we are not over the request body no files limit. */
315
if (msr->msc_reqbody_no_files_length >= (unsigned long) msr->txcfg->reqbody_no_files_limit) {
320
if (msr->msc_reqbody_storage == MSC_REQBODY_MEMORY) {
321
return modsecurity_request_body_store_memory(msr, data, length, error_msg);
324
if (msr->msc_reqbody_storage == MSC_REQBODY_DISK) {
325
return modsecurity_request_body_store_disk(msr, data, length, error_msg);
328
/* Should never happen. */
329
*error_msg = apr_psprintf(msr->mp, "Internal error, unknown value for msc_reqbody_storage: %u",
330
msr->msc_reqbody_storage);
337
static apr_status_t modsecurity_request_body_end_urlencoded(modsec_rec *msr, char **error_msg) {
338
msc_data_chunk **chunks, *one_chunk;
341
int invalid_count = 0;
345
/* Allocate a buffer large enough to hold the request body. */
347
if (msr->msc_reqbody_length + 1 == 0) {
348
*error_msg = apr_psprintf(msr->mp, "Internal error, request body length will overflow: %u",
349
msr->msc_reqbody_length);
352
msr->msc_reqbody_buffer = malloc(msr->msc_reqbody_length + 1);
353
if (msr->msc_reqbody_buffer == NULL) {
354
*error_msg = apr_psprintf(msr->mp, "Unable to allocate memory to hold request body. Asked for %u bytes.",
355
msr->msc_reqbody_length + 1);
358
msr->msc_reqbody_buffer[msr->msc_reqbody_length] = '\0';
360
/* Copy the data we keep in chunks into the new buffer. */
363
d = msr->msc_reqbody_buffer;
364
chunks = (msc_data_chunk **)msr->msc_reqbody_chunks->elts;
365
for(i = 0; i < msr->msc_reqbody_chunks->nelts; i++) {
366
if (sofar + chunks[i]->length <= msr->msc_reqbody_length) {
367
memcpy(d, chunks[i]->data, chunks[i]->length);
368
d += chunks[i]->length;
369
sofar += chunks[i]->length;
371
*error_msg = apr_psprintf(msr->mp, "Internal error, request body buffer overflow.");
376
/* Now free the memory used by the chunks. */
378
chunks = (msc_data_chunk **)msr->msc_reqbody_chunks->elts;
379
for(i = 0; i < msr->msc_reqbody_chunks->nelts; i++) {
380
free(chunks[i]->data);
381
chunks[i]->data = NULL;
384
/* Create a new array with only one chunk in it. */
386
msr->msc_reqbody_chunks = apr_array_make(msr->msc_reqbody_mp, 2, sizeof(msc_data_chunk *));
387
if (msr->msc_reqbody_chunks == NULL) {
388
*error_msg = apr_pstrdup(msr->mp, "Failed to create structure to hold request body.");
391
one_chunk = (msc_data_chunk *)apr_pcalloc(msr->msc_reqbody_mp, sizeof(msc_data_chunk));
392
one_chunk->data = msr->msc_reqbody_buffer;
393
one_chunk->length = msr->msc_reqbody_length;
394
one_chunk->is_permanent = 1;
395
*(const msc_data_chunk **)apr_array_push(msr->msc_reqbody_chunks) = one_chunk;
397
/* Parse URL-encoded arguments in the request body. */
399
if (parse_arguments(msr, msr->msc_reqbody_buffer, msr->msc_reqbody_length,
400
msr->txcfg->argument_separator, "BODY", msr->arguments, &invalid_count) < 0)
402
*error_msg = apr_pstrdup(msr->mp, "Initialisation: Error occurred while parsing BODY arguments.");
410
* Stops receiving the request body.
412
apr_status_t modsecurity_request_body_end(modsec_rec *msr, char **error_msg) {
415
/* Close open file descriptors, if any. */
416
if (msr->msc_reqbody_storage == MSC_REQBODY_DISK) {
417
if (msr->msc_reqbody_fd > 0) {
418
close(msr->msc_reqbody_fd);
419
msr->msc_reqbody_fd = -1;
423
/* Note that we've read the body. */
424
msr->msc_reqbody_read = 1;
426
/* Finalise body processing. */
427
if ((msr->msc_reqbody_processor != NULL)&&(msr->msc_reqbody_error == 0)) {
428
char *my_error_msg = NULL;
430
if (strcmp(msr->msc_reqbody_processor, "MULTIPART") == 0) {
431
if (multipart_complete(msr, &my_error_msg) < 0) {
432
*error_msg = apr_psprintf(msr->mp, "Multipart parsing error: %s", my_error_msg);
433
msr->msc_reqbody_error = 1;
434
msr->msc_reqbody_error_msg = *error_msg;
435
msr_log(msr, 2, "%s", *error_msg);
439
if (multipart_get_arguments(msr, "BODY", msr->arguments) < 0) {
440
*error_msg = "Multipart parsing error: Failed to retrieve arguments.";
441
msr->msc_reqbody_error = 1;
442
msr->msc_reqbody_error_msg = *error_msg;
443
msr_log(msr, 2, "%s", *error_msg);
448
if (strcmp(msr->msc_reqbody_processor, "URLENCODED") == 0) {
449
return modsecurity_request_body_end_urlencoded(msr, error_msg);
452
if (strcmp(msr->msc_reqbody_processor, "XML") == 0) {
453
if (xml_complete(msr, &my_error_msg) < 0) {
454
*error_msg = apr_psprintf(msr->mp, "XML parser error: %s", my_error_msg);
455
msr->msc_reqbody_error = 1;
456
msr->msc_reqbody_error_msg = *error_msg;
457
msr_log(msr, 2, "%s", *error_msg);
463
/* Note the request body no files length. */
464
msr_log(msr, 4, "Reqest body no files length: %" APR_SIZE_T_FMT, msr->msc_reqbody_no_files_length);
470
* Prepares to forward the request body.
472
apr_status_t modsecurity_request_body_retrieve_start(modsec_rec *msr, char **error_msg) {
475
if (msr->msc_reqbody_storage == MSC_REQBODY_MEMORY) {
476
msr->msc_reqbody_chunk_position = 0;
477
msr->msc_reqbody_chunk_offset = 0;
479
msr->msc_reqbody_disk_chunk = apr_pcalloc(msr->msc_reqbody_mp, sizeof(msc_data_chunk));
480
if (msr->msc_reqbody_disk_chunk == NULL) {
481
*error_msg = apr_psprintf(msr->mp, "Failed to allocate %lu bytes for request body disk chunk.",
482
(unsigned long)sizeof(msc_data_chunk));
485
msr->msc_reqbody_disk_chunk->is_permanent = 1;
488
if (msr->msc_reqbody_storage == MSC_REQBODY_DISK) {
489
msr->msc_reqbody_disk_chunk = apr_pcalloc(msr->msc_reqbody_mp, sizeof(msc_data_chunk));
490
if (msr->msc_reqbody_disk_chunk == NULL) {
491
*error_msg = apr_psprintf(msr->mp, "Failed to allocate %lu bytes for request body disk chunk.",
492
(unsigned long)sizeof(msc_data_chunk));
496
msr->msc_reqbody_disk_chunk->is_permanent = 0;
497
msr->msc_reqbody_disk_chunk->data = apr_palloc(msr->msc_reqbody_mp, CHUNK_CAPACITY);
498
if (msr->msc_reqbody_disk_chunk->data == NULL) {
499
*error_msg = apr_psprintf(msr->mp, "Failed to allocate %d bytes for request body disk chunk data.",
504
msr->msc_reqbody_fd = open(msr->msc_reqbody_filename, O_RDONLY | O_BINARY);
505
if (msr->msc_reqbody_fd < 0) {
506
*error_msg = apr_psprintf(msr->mp, "Failed to open temporary file for reading: %s",
507
msr->msc_reqbody_filename);
518
apr_status_t modsecurity_request_body_retrieve_end(modsec_rec *msr) {
519
if (msr->msc_reqbody_storage == MSC_REQBODY_DISK) {
520
if (msr->msc_reqbody_fd > 0) {
521
close(msr->msc_reqbody_fd);
522
msr->msc_reqbody_fd = -1;
530
* Returns one chunk of request body data. It stores a NULL
531
* in the chunk pointer when there is no data to return. The
532
* return code is 1 if more calls can be made to retrieve more
533
* data, 0 if there is no more data to retrieve, or -1 on error.
535
* The caller can limit the amount of data returned by providing
536
* a non-negative value in nbytes.
538
apr_status_t modsecurity_request_body_retrieve(modsec_rec *msr,
539
msc_data_chunk **chunk, long int nbytes, char **error_msg)
541
msc_data_chunk **chunks;
546
*error_msg = apr_pstrdup(msr->mp, "Internal error, retrieving request body chunk.");
551
if (msr->msc_reqbody_storage == MSC_REQBODY_MEMORY) {
552
/* Are there any chunks left? */
553
if (msr->msc_reqbody_chunk_position >= msr->msc_reqbody_chunks->nelts) {
554
/* No more chunks. */
558
/* We always respond with the same chunk, just different information in it. */
559
*chunk = msr->msc_reqbody_disk_chunk;
561
/* Advance to the current chunk and position on the
562
* next byte we need to send.
564
chunks = (msc_data_chunk **)msr->msc_reqbody_chunks->elts;
565
msr->msc_reqbody_disk_chunk->data = chunks[msr->msc_reqbody_chunk_position]->data
566
+ msr->msc_reqbody_chunk_offset;
569
/* Send what's left in this chunk as there is no limit on the size. */
570
msr->msc_reqbody_disk_chunk->length = chunks[msr->msc_reqbody_chunk_position]->length;
571
msr->msc_reqbody_chunk_position++;
572
msr->msc_reqbody_chunk_offset = 0;
574
/* We have a limit we must obey. */
576
if (chunks[msr->msc_reqbody_chunk_position]->length -
577
msr->msc_reqbody_chunk_offset <= (unsigned int)nbytes)
579
/* If what's left in our chunk is less than the limit
580
* then send it all back.
582
msr->msc_reqbody_disk_chunk->length =
583
chunks[msr->msc_reqbody_chunk_position]->length -
584
msr->msc_reqbody_chunk_offset;
585
msr->msc_reqbody_chunk_position++;
586
msr->msc_reqbody_chunk_offset = 0;
588
/* If we have more data in our chunk, send the
589
* maximum bytes we can (nbytes).
591
msr->msc_reqbody_disk_chunk->length = nbytes;
592
msr->msc_reqbody_chunk_offset += nbytes;
596
/* If we've advanced beyond our last chunk then
597
* we have no more data to send.
599
if (msr->msc_reqbody_chunk_position >= msr->msc_reqbody_chunks->nelts) {
600
return 0; /* No more chunks. */
603
/* More data available. */
607
if (msr->msc_reqbody_storage == MSC_REQBODY_DISK) {
608
long int my_nbytes = CHUNK_CAPACITY;
611
/* Send CHUNK_CAPACITY bytes at a time unless a lower limit was requested. */
612
if ((nbytes != -1)&&(my_nbytes > nbytes)) {
616
i = read(msr->msc_reqbody_fd, msr->msc_reqbody_disk_chunk->data, my_nbytes);
618
*error_msg = apr_psprintf(msr->mp, "Input filter: Error reading from temporary file: %s",
623
*chunk = msr->msc_reqbody_disk_chunk;
624
msr->msc_reqbody_disk_chunk->length = i;
626
if (i == 0) return 0; /* No more data available. */
628
return 1; /* More data available. */
631
/* Should never happen. */
632
*error_msg = apr_psprintf(msr->mp, "Internal error, invalid msc_reqbody_storage value: %u",
633
msr->msc_reqbody_storage);
641
apr_status_t modsecurity_request_body_clear(modsec_rec *msr, char **error_msg) {
644
/* Release memory we used to store request body data. */
645
if (msr->msc_reqbody_chunks != NULL) {
646
msc_data_chunk **chunks = (msc_data_chunk **)msr->msc_reqbody_chunks->elts;
649
for(i = 0; i < msr->msc_reqbody_chunks->nelts; i++) {
650
if (chunks[i]->data != NULL) {
651
free(chunks[i]->data);
652
chunks[i]->data = NULL;
657
if (msr->msc_reqbody_storage == MSC_REQBODY_DISK) {
660
/* Should we keep the body? This normally
661
* happens when a PUT method was used, which
662
* means the body is actually a file.
664
if ((msr->upload_remove_files == 0)&&(strcasecmp(msr->request_method, "PUT") == 0)) {
665
if (msr->txcfg->upload_dir != NULL) {
668
*error_msg = apr_psprintf(msr->mp, "Input filter: SecUploadDir is undefined, "
669
"unable to store PUT file.");
673
/* Deal with a request body stored in a file. */
675
if (msr->msc_reqbody_filename != NULL) {
677
/* Move request body (which is a file) to the storage area. */
678
const char *put_filename = NULL;
679
const char *put_basename = NULL;
681
/* Construct the new filename. */
682
put_basename = file_basename(msr->msc_reqbody_mp, msr->msc_reqbody_filename);
683
if (put_basename == NULL) {
684
*error_msg = apr_psprintf(msr->mp, "Input filter: Failed to generate basename to PUT file \"%s\"", log_escape(msr->msc_reqbody_mp, msr->msc_reqbody_filename));
687
put_filename = apr_psprintf(msr->msc_reqbody_mp, "%s/%s",
688
msr->txcfg->upload_dir, put_basename);
689
if (put_filename == NULL) {
690
*error_msg = apr_psprintf(msr->mp, "Input filter: Failed to generate filename to PUT file \"%s\"", log_escape(msr->msc_reqbody_mp, msr->msc_reqbody_filename));
694
if (apr_file_rename(msr->msc_reqbody_filename, put_filename,
695
msr->msc_reqbody_mp) != APR_SUCCESS)
697
*error_msg = apr_psprintf(msr->mp, "Input filter: Failed to rename file from \"%s\" to \"%s\".",
698
log_escape(msr->msc_reqbody_mp, msr->msc_reqbody_filename),
699
log_escape(msr->msc_reqbody_mp, put_filename));
702
msr_log(msr, 4, "Input filter: Moved file from \"%s\" to \"%s\".",
703
log_escape(msr->msc_reqbody_mp, msr->msc_reqbody_filename),
704
log_escape(msr->msc_reqbody_mp, put_filename));
707
/* make sure it is closed first */
708
if (msr->msc_reqbody_fd > 0) {
709
close(msr->msc_reqbody_fd);
710
msr->msc_reqbody_fd = -1;
713
/* We do not want to keep the request body. */
714
if (apr_file_remove(msr->msc_reqbody_filename,
715
msr->msc_reqbody_mp) != APR_SUCCESS)
717
*error_msg = apr_psprintf(msr->mp, "Input filter: Failed to delete temporary file: %s",
718
log_escape(msr->mp, msr->msc_reqbody_filename));
722
msr_log(msr, 4, "Input filter: Removed temporary file: %s",
723
msr->msc_reqbody_filename);
726
msr->msc_reqbody_filename = NULL;
730
if (msr->msc_reqbody_mp != NULL) {
731
apr_pool_destroy(msr->msc_reqbody_mp);
732
msr->msc_reqbody_mp = NULL;