@@ -38,6 +38,61 @@ namespace RequestBodyProcessor {
38
38
static const char * mime_charset_special = " !#$%&+-^_`{}~" ;
39
39
static const char * attr_char_special = " !#$&+-.^_`~" ;
40
40
41
+ MultipartPartTmpFile::~MultipartPartTmpFile () {
42
+ if (!m_tmp_file_name.empty () && m_delete) {
43
+ /* make sure it is closed first */
44
+ if (m_tmp_file_fd > 0 ) {
45
+ Close ();
46
+ }
47
+
48
+ const int unlink_rc = unlink (m_tmp_file_name.c_str ());
49
+ if (unlink_rc < 0 ) {
50
+ ms_dbg_a (m_transaction, 1 , " Multipart: Failed to delete file (part) \" " \
51
+ + m_tmp_file_name + " \" because " \
52
+ + std::to_string (errno) + " (" \
53
+ + strerror (errno) + " )" );
54
+ } else {
55
+ ms_dbg_a (m_transaction, 4 , " Multipart: file deleted successfully (part) \" " \
56
+ + m_tmp_file_name + " \" " );
57
+ }
58
+
59
+ }
60
+ }
61
+
62
+ void MultipartPartTmpFile::Open () {
63
+ struct tm timeinfo;
64
+ char tstr[300 ];
65
+ time_t tt = time (NULL );
66
+
67
+ localtime_r (&tt, &timeinfo);
68
+
69
+ memset (tstr, ' \0 ' , 300 );
70
+ strftime (tstr, 299 , " /%Y%m%d-%H%M%S" , &timeinfo);
71
+
72
+ std::string path = m_transaction->m_rules ->m_uploadDirectory .m_value ;
73
+ path = path + tstr + " -" + *m_transaction->m_id .get ();
74
+ path += " -file-XXXXXX" ;
75
+
76
+ char * tmp = strdup (path.c_str ());
77
+ m_tmp_file_fd = mkstemp (tmp);
78
+ m_tmp_file_name.assign (tmp);
79
+ free (tmp);
80
+ ms_dbg_a (m_transaction, 4 , " MultipartPartTmpFile: Create filename= " + m_tmp_file_name);
81
+
82
+ int mode = m_transaction->m_rules ->m_uploadFileMode .m_value ;
83
+ if ((m_tmp_file_fd != -1 ) && (mode != 0 )) {
84
+ if (fchmod (m_tmp_file_fd, mode) == -1 ) {
85
+ m_tmp_file_fd = -1 ;
86
+ }
87
+ }
88
+ }
89
+
90
+ void MultipartPartTmpFile::Close () {
91
+ close (m_tmp_file_fd);
92
+ m_tmp_file_fd = -1 ;
93
+ }
94
+
95
+
41
96
Multipart::Multipart (const std::string &header, Transaction *transaction)
42
97
: m_reqbody_no_files_length(0 ),
43
98
m_nfiles (0 ),
@@ -80,30 +135,14 @@ Multipart::~Multipart() {
80
135
if (m_transaction->m_rules ->m_uploadKeepFiles
81
136
!= RulesSetProperties::TrueConfigBoolean) {
82
137
for (MultipartPart *m : m_parts) {
83
- if (m->m_type == MULTIPART_FILE) {
84
- if (!m->m_tmp_file_name .empty ()) {
85
- /* make sure it is closed first */
86
- if (m->m_tmp_file_fd > 0 ) {
87
- close (m->m_tmp_file_fd );
88
- m->m_tmp_file_fd = -1 ;
89
- }
90
- const int unlink_rc =
91
- unlink (m->m_tmp_file_name .c_str ());
92
-
93
- if (unlink_rc < 0 ) {
94
- ms_dbg_a (m_transaction, 1 ,
95
- " Multipart: Failed to delete file (part) \" " \
96
- + m->m_tmp_file_name + " \" because " \
97
- + std::to_string (errno) + " (" \
98
- + strerror (errno) + " )" );
99
- } else {
100
- ms_dbg_a (m_transaction, 4 ,
101
- " Multipart: file deleted successfully (part) \" " \
102
- + m->m_tmp_file_name + " \" " );
103
- }
104
-
105
- }
138
+ if ((m->m_type == MULTIPART_FILE) && (m->m_tmp_file )) {
139
+ // only mark for deletion for now; the file should stay on disk until
140
+ // the transaction is complete
141
+ ms_dbg_a (m_transaction, 9 , " Multipart: Marking temporary file for deletion: " \
142
+ + m->m_tmp_file ->getFilename ());
143
+ m->m_tmp_file ->setDelete ();
106
144
}
145
+
107
146
}
108
147
}
109
148
@@ -432,7 +471,7 @@ int Multipart::parse_content_disposition(const char *c_d_value, int offset) {
432
471
+ std::to_string (strlen (p)) + " bytes" );
433
472
m_flag_invalid_quoting = 1 ;
434
473
}
435
- p++;
474
+ /* p++; */
436
475
return -12 ;
437
476
}
438
477
p++; /* move over the semi-colon */
@@ -453,40 +492,6 @@ int Multipart::parse_content_disposition(const char *c_d_value, int offset) {
453
492
}
454
493
455
494
456
- int Multipart::tmp_file_name (std::string *filename) const {
457
- std::string path;
458
- struct tm timeinfo;
459
- char tstr[300 ];
460
- char *tmp;
461
- int fd;
462
- int mode;
463
- time_t tt = time (NULL );
464
-
465
- localtime_r (&tt, &timeinfo);
466
-
467
- path = m_transaction->m_rules ->m_uploadDirectory .m_value ;
468
- mode = m_transaction->m_rules ->m_uploadFileMode .m_value ;
469
-
470
- memset (tstr, ' \0 ' , 300 );
471
- strftime (tstr, 299 , " /%Y%m%d-%H%M%S" , &timeinfo);
472
- path = path + tstr + " -" + *m_transaction->m_id .get ();
473
- path = path + " -file-XXXXXX" ;
474
-
475
- tmp = strdup (path.c_str ());
476
-
477
- fd = mkstemp (tmp);
478
- filename->assign (tmp);
479
- free (tmp);
480
- if ((fd != -1 ) && (mode != 0 )) {
481
- if (fchmod (fd, mode) == -1 ) {
482
- return -1 ;
483
- }
484
- }
485
-
486
- return fd;
487
- }
488
-
489
-
490
495
int Multipart::process_part_data (std::string *error, size_t offset) {
491
496
char *p = m_buf + (MULTIPART_BUF_SIZE - m_bufleft);
492
497
char localreserve[2 ] = { ' \0 ' , ' \0 ' }; /* initialized to quiet warning */
@@ -546,20 +551,18 @@ int Multipart::process_part_data(std::string *error, size_t offset) {
546
551
*/
547
552
if (extract) {
548
553
/* first create a temporary file if we don't have it already */
549
- if (m_mpp->m_tmp_file_fd == 0 ) {
550
- std::string path;
551
- m_mpp->m_tmp_file_fd = tmp_file_name (&path);
552
-
553
- /* construct temporary file name */
554
- m_mpp->m_tmp_file_name = path;
554
+ if (!m_mpp->m_tmp_file || !m_mpp->m_tmp_file ->isValid ()) {
555
+ m_mpp->m_tmp_file = std::make_shared<RequestBodyProcessor::MultipartPartTmpFile>(m_transaction);
556
+ m_transaction->m_multipartPartTmpFiles .push_back (m_mpp->m_tmp_file );
557
+ m_mpp->m_tmp_file ->Open ();
555
558
556
559
/* do we have an opened file? */
557
- if (m_mpp->m_tmp_file_fd < 0 ) {
560
+ if (! m_mpp->m_tmp_file || m_mpp-> m_tmp_file -> getFd () < 0 ) {
558
561
ms_dbg_a (m_transaction, 1 ,
559
562
" Multipart: Failed to create file: " \
560
- + m_mpp->m_tmp_file_name );
563
+ + m_mpp->m_tmp_file -> getFilename () );
561
564
error->assign (" Multipart: Failed to create file: " \
562
- + m_mpp->m_tmp_file_name );
565
+ + m_mpp->m_tmp_file -> getFilename () );
563
566
return -1 ;
564
567
}
565
568
/* keep track of the files count */
@@ -569,18 +572,18 @@ int Multipart::process_part_data(std::string *error, size_t offset) {
569
572
ms_dbg_a (m_transaction, 4 ,
570
573
" Multipart: Created temporary file " \
571
574
+ std::to_string (m_nfiles) + " (mode o" + std::to_string (m_transaction->m_rules ->m_uploadFileMode .m_value ) + " ): " \
572
- + m_mpp->m_tmp_file_name );
575
+ + m_mpp->m_tmp_file -> getFilename () );
573
576
}
574
577
575
578
/* write the reserve first */
576
579
if (m_reserve[0 ] != 0 ) {
577
- if (write (m_mpp->m_tmp_file_fd , &m_reserve[1 ], m_reserve[0 ])
580
+ if (write (m_mpp->m_tmp_file -> getFd () , &m_reserve[1 ], m_reserve[0 ])
578
581
!= m_reserve[0 ]) {
579
582
ms_dbg_a (m_transaction, 1 ,
580
583
" Multipart: writing to \" " \
581
- + m_mpp->m_tmp_file_name + " \" failed" );
584
+ + m_mpp->m_tmp_file -> getFilename () + " \" failed" );
582
585
error->assign (" Multipart: writing to \" " \
583
- + m_mpp->m_tmp_file_name + " \" failed" );
586
+ + m_mpp->m_tmp_file -> getFilename () + " \" failed" );
584
587
return -1 ;
585
588
}
586
589
@@ -594,14 +597,14 @@ int Multipart::process_part_data(std::string *error, size_t offset) {
594
597
595
598
/* write data to the file */
596
599
597
- if (write (m_mpp->m_tmp_file_fd , m_buf,
600
+ if (write (m_mpp->m_tmp_file -> getFd () , m_buf,
598
601
MULTIPART_BUF_SIZE - m_bufleft)
599
602
!= (MULTIPART_BUF_SIZE - m_bufleft)) {
600
603
ms_dbg_a (m_transaction, 1 ,
601
604
" Multipart: writing to \" " \
602
- + m_mpp->m_tmp_file_name + " \" failed" );
605
+ + m_mpp->m_tmp_file -> getFilename () + " \" failed" );
603
606
error->assign (" Multipart: writing to \" " \
604
- + m_mpp->m_tmp_file_name + " \" failed" );
607
+ + m_mpp->m_tmp_file -> getFilename () + " \" failed" );
605
608
return -1 ;
606
609
}
607
610
@@ -911,11 +914,9 @@ int Multipart::process_boundary(int last_part) {
911
914
/* if there was a part being built finish it */
912
915
if (m_mpp != NULL ) {
913
916
/* close the temp file */
914
- if ((m_mpp->m_type == MULTIPART_FILE)
915
- && (!m_mpp->m_tmp_file_name .empty ())
916
- && (m_mpp->m_tmp_file_fd != 0 )) {
917
- close (m_mpp->m_tmp_file_fd );
918
- m_mpp->m_tmp_file_fd = -1 ;
917
+ if ((m_mpp->m_type == MULTIPART_FILE) && (m_mpp->m_tmp_file )
918
+ && (m_mpp->m_tmp_file ->isValid ())) {
919
+ m_mpp->m_tmp_file ->Close ();
919
920
}
920
921
921
922
if (m_mpp->m_type != MULTIPART_FILE) {
@@ -1128,8 +1129,10 @@ int Multipart::multipart_complete(std::string *error) {
1128
1129
if (m->m_type == MULTIPART_FILE) {
1129
1130
std::string tmp_name;
1130
1131
std::string name;
1131
- if (!m->m_tmp_file_name .empty ()) {
1132
- tmp_name.assign (m->m_tmp_file_name );
1132
+ if (m->m_tmp_file && !m->m_tmp_file ->getFilename ().empty ()) {
1133
+ tmp_name.assign (m->m_tmp_file ->getFilename ());
1134
+ m_transaction->m_variableFilesTmpNames .set (m->m_tmp_file ->getFilename (),
1135
+ m->m_tmp_file ->getFilename (), m->m_filenameOffset );
1133
1136
}
1134
1137
if (!m->m_filename .empty ()) {
1135
1138
name.assign (m->m_filename );
@@ -1149,9 +1152,6 @@ int Multipart::multipart_complete(std::string *error) {
1149
1152
m_transaction->m_variableFilesTmpContent .set (m->m_filename ,
1150
1153
m->m_value , m->m_valueOffset );
1151
1154
1152
- m_transaction->m_variableFilesTmpNames .set (m->m_tmp_file_name ,
1153
- m->m_tmp_file_name , m->m_filenameOffset );
1154
-
1155
1155
file_combined_size = file_combined_size + m->m_tmp_file_size .first ;
1156
1156
1157
1157
m_transaction->m_variableFilesCombinedSize .set (
0 commit comments