Changeset 12513
- Timestamp:
- 2006-08-24T11:10:07+12:00 (18 years ago)
- Location:
- trunk/gsdl/src/recpt
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gsdl/src/recpt/cgiutils.cpp
r11998 r12513 25 25 26 26 #include "cgiutils.h" 27 #include "md5.h" 28 #include "fileutil.h" 27 29 #include "gsdlunicode.h" 28 30 #include "fileutil.h" 29 31 #include "unitool.h" // in mg, for output_utf8_char 32 33 #if defined(GSDL_USE_OBJECTSPACE) 34 # include <ospace\std\iostream> 35 # include <ospace\std\fstream> 36 #elif defined(GSDL_USE_IOS_H) 37 # include <iostream.h> 38 # include <fstream.h> 39 #else 40 # include <iostream> 41 # include <fstream> 42 #endif 30 43 31 44 … … 57 70 t.push_back(o1); 58 71 t.push_back(o2); 72 } 73 74 static text_t::iterator getline (text_t::iterator first, 75 text_t::iterator last, 76 bool include_crlf) { 77 while (first != last) { 78 if (((first+1) != last) && (*first == 13) && (*(first+1) == 10)) { 79 // found <CRLF> 80 if (include_crlf) first += 2; 81 break; 82 } 83 first++; 84 } 85 return first; 86 } 87 88 static void process_post_section (text_t &argname, text_t &argdata, text_t &filename, text_t &filedata, 89 text_t &filetype, bool &isfile, text_t &argstr, 90 fileupload_tmap &fileuploads, const text_t &gsdlhome) { 91 92 if (!argname.empty()) { 93 94 if (!isfile) { 95 // argdata includes a trailing <CRLF> that we must remove 96 if ((argdata.size() > 1) && (*(argdata.end()-2) == 13) && (*(argdata.end()-1) == 10)) { 97 argdata.erase(argdata.end()-2, argdata.end()); 98 } 99 if (!argstr.empty()) argstr += "&"; 100 argstr += argname + "=" + argdata; 101 102 } else if (!filename.empty()) { 103 // filedata includes a trailing <CRLF> that we must remove 104 if ((filedata.size() > 1) && (*(filedata.end()-2) == 13) && (*(filedata.end()-1) == 10)) { 105 filedata.erase(filedata.end()-2, filedata.end()); 106 } 107 108 // create tmp_name for storing the file on disk 109 text_t tmp_name = md5data(filedata); 110 tmp_name = filename_cat(gsdlhome, "tmp", tmp_name); 111 char *tmp_name_c = tmp_name.getcstr(); 112 113 // write the file data to disk 114 outconvertclass out; 115 ofstream filestream(tmp_name_c, ios::out | ios::binary); 116 filestream << out << filedata; 117 filestream.close(); 118 delete tmp_name_c; 119 120 // populate the fields of a fileupload_t and put it in the 121 // fileuploads map 122 fileupload_t fu; 123 // note that filename currently may or may not include the path since 124 // some browsers (e.g. IE) include the path while others 125 // (e.g. mozilla) do not. we should probably remove the path from 126 // this field here to get a consistent value across all browsers. 127 text_t::iterator slash = findlastchar(filename.begin(), filename.end(), '\\'); 128 if (slash != filename.end()) { 129 filename = substr(slash+1, filename.end()); 130 } 131 fu.name = filename; 132 fu.type = filetype; 133 // size has yet to be implemented 134 fu.size = 0; 135 fu.tmp_name = tmp_name; 136 fileuploads[argname] = fu; 137 } 138 } 139 isfile = false; 140 argname.clear(); 141 argdata.clear(); 142 filename.clear(); 143 filedata.clear(); 144 filetype.clear(); 145 } 146 147 // parse data obtained through a CGI POST request 148 text_t parse_post_data (text_t &content_type, text_t &raw_post_data, 149 fileupload_tmap &fileuploads, const text_t &gsdlhome) { 150 151 text_t argstr; 152 153 text_t::iterator content_type_begin = content_type.begin(); 154 text_t::iterator content_type_end = content_type.end(); 155 if (findword(content_type_begin, content_type_end, "multipart/form-data") == content_type_end) { 156 // a simple post request 157 return raw_post_data; 158 159 } else { 160 // multipart/form data - may contain one or more uploaded files 161 162 /* 163 content_type should look something like the following 164 multipart/form-data; boundary=---------------------------7d411e1a50330 165 166 while raw_post_data will be as follows 167 -----------------------------7d43e73450330CRLF 168 Content-Disposition: form-data; name="e"<CRLF> 169 <CRLF> 170 d-0testss--1-0-00---4----0--0-110--1en-Zz-1---10-about-0--00031-001utfZz-8-0<CRLF> 171 -----------------------------7d43e73450330<CRLF> 172 Content-Disposition: form-data; name="afile"; filename="C:\somedoc.doc"<CRLF> 173 Content-Type: application/msword<CRLF> 174 <CRLF> 175 <Content of file><CRLF> 176 177 */ 178 179 // first get the boundary from content-type 180 text_t::iterator boundary_begin = findword(content_type_begin, content_type_end, "boundary="); 181 if (boundary_begin+9 < content_type_end) boundary_begin += 9; 182 else { 183 // error 184 return ""; 185 } 186 text_t boundary = substr(boundary_begin, getline(boundary_begin, content_type_end, false)); 187 int boundary_len = boundary.size(); 188 189 text_t argname, argdata, filename, filedata, filetype; 190 bool isfile = false; 191 text_t::iterator data_here = raw_post_data.begin(); 192 text_t::iterator data_end = raw_post_data.end(); 193 while (data_here != data_end) { 194 195 // get the next available line (including the trailing <CRLF> 196 text_t line = substr(data_here, getline(data_here, data_end, true)); 197 data_here += line.size(); 198 text_t::iterator line_begin = line.begin(); 199 text_t::iterator line_end = line.end(); 200 if (findword(line_begin, line_end, boundary) != line_end) { 201 // we've found a boundary 202 process_post_section(argname, argdata, filename, filedata, filetype, 203 isfile, argstr, fileuploads, gsdlhome); 204 205 } else if (findword(line_begin, line_end, "Content-Disposition: form-data") != line_end) { 206 // we've found the the beginning of a new section 207 argname.clear(); 208 argdata.clear(); 209 210 // get the name of this piece of form data 211 text_t::iterator it = findword(line_begin, line_end, "name=\""); 212 if (it == line_end) break; // error - this shouldn't happen 213 it = findchar(it, line_end, '"'); 214 if ((it != line_end) && (it+1 != line_end)) { 215 argname = substr(it+1, findchar(it+1, line_end, '"')); 216 } 217 218 // if this piece of form data contains filename="" it's a file 219 // upload and needs to be treated special 220 it = (findword(line_begin, line_end, "filename=\"")); 221 if (it != line_end) { 222 // we've found a file upload 223 isfile = true; 224 it = findchar(it, line_end, '"'); 225 if ((it != line_end) && (it+1 != line_end)) { 226 filename = substr(it+1, findchar(it+1, line_end, '"')); 227 } 228 229 // the next line is the content-type of this section 230 line = substr(data_here, getline(data_here, data_end, true)); 231 data_here += line.size(); 232 line_begin = line.begin(); 233 line_end = line.end(); 234 it = (findword(line_begin, line_end, "Content-Type: ")); 235 if (it != line_end) { 236 filetype = substr(it+14, getline(it, line_end, false)); 237 } 238 } 239 240 // eat up the next line as it's just a <CRLF> on it's own 241 data_here += 2; 242 243 } else { 244 if (isfile) filedata += line; 245 else argdata += line; 246 } 247 } 248 249 // process last section 250 process_post_section(argname, argdata, filename, filedata, filetype, 251 isfile, argstr, fileuploads, gsdlhome); 252 253 return argstr; 254 } 59 255 } 60 256 … … 465 661 } 466 662 663 void add_fileupload_args (const cgiargsinfoclass &argsinfo, 664 cgiargsclass &args, 665 fileupload_tmap &fileuploads, 666 ostream &logout) { 667 668 const cgiarginfo *info = argsinfo.getarginfo("a"); 669 fileupload_tmap::const_iterator this_file = fileuploads.begin(); 670 fileupload_tmap::const_iterator end_file = fileuploads.end(); 671 while (this_file != end_file) { 672 const cgiarginfo *info = argsinfo.getarginfo((*this_file).first); 673 if (info != NULL) { 674 if ((*info).fileupload && (file_exists((*this_file).second.tmp_name))) { 675 args.setargfile((*this_file).first, (*this_file).second); 676 } 677 } 678 this_file++; 679 } 680 } 467 681 468 682 // compress_save_args will compress the arguments and return -
trunk/gsdl/src/recpt/cgiutils.h
r2426 r12513 32 32 #include "cgiargs.h" 33 33 34 // parse data obtained through a CGI POST request 35 text_t parse_post_data (text_t &content_type, text_t &raw_post_data, 36 fileupload_tmap &fileuploads, const text_t &gsdlhome); 34 37 35 38 // convert %xx and + to their appropriate equivalents … … 82 85 ostream &logout); 83 86 87 void add_fileupload_args (const cgiargsinfoclass &argsinfo, 88 cgiargsclass &args, 89 fileupload_tmap &fileuploads, 90 ostream &logout); 91 84 92 // compress_save_args will compress the arguments and return 85 93 // them in compressed_args. If an error was encountered
Note:
See TracChangeset
for help on using the changeset viewer.