3 #include "util_const.h"
4 #include "util_string.h"
12 int CGIFormFile::partAt (int i) {
14 sary_t::iterator it = datamap.find (i);
15 if (it == datamap.end ()) {
25 ustring CGIFormFile::typeAt (int i) {
27 tary_t::iterator it = typemap.find (i);
28 if (it == typemap.end ()) {
38 void CGIFormFile::read_multipart (MotorEnv* env) {
40 std::cerr << "boundary:" << boundary << "\n";
47 for (int i = 0; i < parts.size (); i ++) {
48 std::cerr << "file:" << i << " (" << (void*)parts[i].first << ", " << (void*)parts[i].second << ") filename:" << filenames[i] << "\n";
54 bool CGIFormFile::saveData (MotorEnv* env) {
55 static const int bsize = 65536 * 4;
56 size_t size = postSize ();
59 pid_t mypid = getpid ();
62 if (size == 0 || size > env->appenv->postfilelimit)
64 tmpfile = env->path_to_posttemp ();
66 if (fp.openReadWrite (tmpfile.c_str ())) {
67 unlink (tmpfile.c_str ());
69 s = (size < bsize) ? size : bsize;
70 s = std::cin.read (&b[0], s).gcount ();
73 s = ::write (fp.fd, &b[0], s);
77 std::cerr << "post-file[" << mypid << ":" << env->scriptName << "]: reading " << mapsize << "Bytes...\n"; // cerrはバッファリングされない
81 std::cerr << "post-file[" << mypid << ":" << env->scriptName << "]: done " << mapsize << "Bytes\n";
82 mapdata = (char*)mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE, fp.fd, 0);
84 std::cerr << (void*) mapdata << ": " << mapsize << "\n";
87 throw (ustring (CharConst ("configuration error: can't open temporary file.")));
92 void CGIFormFile::unlinkTmpFile () {
94 munmap (mapdata, mapsize);
97 if (tmpfile.size () > 0) {
98 // unlink (tmpfile.c_str ());
103 void CGIFormFile::searchPart (MotorEnv* env) {
105 char* e = mapdata + mapsize;
107 boost::match_results<char*> m;
116 std::cerr << "b:" << (void*)b << " e:" << (void*)e << "\n";
117 std::cerr << "mapdata:" << ustring (b, b + 40) << "\n";
119 if (b != e && regex_search (b, e, m, re1, boost::regex_constants::match_single_line)) {
121 std::cerr << "match:" << ustring (m[0].first, m[0].second) << "\n";
124 while (b != e && regex_search (b, e, m, reN, boost::regex_constants::match_single_line)) {
127 std::cerr << "match:" << ustring (m[0].first, m[0].second) << "\n";
129 readMimeHead (b, x, disp, name, filename, type);
131 std::cerr << "disp:" << disp << " name:" << name << " filename:" << filename << " type:" << type << "\n";
133 if (filename.size () > 0) {
137 parts.push_back (part (b, x));
140 k1 = insert (iarg, name, filePart_osSafe (filename));
141 datamap.insert (sary_t::value_type (k1, k2));
142 typemap.insert (tary_t::value_type (k2, type));
144 std::cerr << "insert(" << k1 << "," << k2 << ")\n";
149 if (size < env->appenv->postlimit) {
151 name = omitNul (name);
155 insert (iarg, name, v);
157 *env->log << "form variable '" << name << "': size limit.\n";
164 } else if (b[0] == '-' && b[1] == '-') {
166 std::cerr << "break\n";
169 } else if (b[0] == '\r' && b[1] == '\n') {
172 break; // format error;
178 void CGIFormFile::compileReg () {
180 ustring t = escape_re (boundary);
182 a.append (CharConst ("^--"));
186 std::cerr << "re1:" << a << "\n";
190 a.append (CharConst ("--"));
193 std::cerr << "reN:" << a << "\n";
205 ChSplitterNL (char* _begin, char* _end) {
215 return ustring (b, t);
244 for (; t < e; ++ t) {
248 } else if (*t == '\r') {
250 if (u < e && *u == '\n')
259 void CGIFormFile::readMimeHead (char*& b, char* e, ustring& disp, ustring& name, ustring& filename, ustring& type) {
260 // boost::match_results<char*> m;
261 ChSplitterNL sp (b, e);
262 boost::match_results<char*> m2;
264 static uregex re_disp1 ("^Content-Disposition:\\s*(.*);\\s*name=\"(.*)\";\\s*filename=\"(.*)\"$");
265 static uregex re_disp2 ("^Content-Disposition:\\s*(.*);\\s*name=\"(.*)\"$");
266 static uregex re_type ("^Content-Type:\\s*([a-zA-Z_0-9/.+-]*)(;\\s*(.*))?$");
272 // while (b != e && regex_search (b, e, m, re_nl, boost::regex_constants::match_single_line)) {
276 // std::cerr << "line:" << ustring (b, x) << "\n";
277 std::cerr << "line:" << sp.pre () << "\n";
279 // if (b == x) { // empty line
285 // if (regex_search (b, x, m2, re_disp1, boost::regex_constants::match_single_line)) {
286 if (regex_search (sp.b, sp.t, m2, re_disp1, boost::regex_constants::match_single_line)) {
287 disp.assign (m2[1].first, m2[1].second - m2[1].first);
288 name.assign (m2[2].first, m2[2].second - m2[2].first);
289 filename.assign (m2[3].first, m2[3].second - m2[3].first);
290 // } else if (regex_search (b, x, m2, re_disp2, boost::regex_constants::match_single_line)) {
291 } else if (regex_search (sp.b, sp.t, m2, re_disp2, boost::regex_constants::match_single_line)) {
292 disp.assign (m2[1].first, m2[1].second - m2[1].first);
293 name.assign (m2[2].first, m2[2].second - m2[2].first);
294 // } else if (regex_search (b, x, m2, re_type, boost::regex_constants::match_single_line)) {
295 } else if (regex_search (sp.b, sp.t, m2, re_type, boost::regex_constants::match_single_line)) {
296 type.assign (m2[1].first, m2[1].second - m2[1].first);
299 // std::cerr << "not match:" << ustring (b, x) << "\n";
300 std::cerr << "not match:" << sp.pre () << "\n";
307 bool CGIFormFile::saveFile (int i, const ustring& path, size_t max) {
308 static size_t bsize = 65536;
314 if (0 <= i && i < parts.size ()) {
316 assert (mapdata <= p.first && p.first <= p.second && p.second < mapdata + mapsize);
318 size = p.second - p.first;
319 if (max > 0 && size > max)
323 std::cerr << "saveFile(" << i << "," << path << "): " << (void*)p.first << "--" << (p.second - p.first) << "\n";
325 f.openWrite (path.c_str ());
327 std::cerr << "write:" << path << "\n";
330 s = (size < bsize) ? size : bsize;
331 s = ::write (f.fd, b, s);