}
}
+ustring CGIFormFile::typeAt (int i) {
+ if (i >= 0) {
+ tary_t::iterator it = typemap.find (i);
+ if (it == typemap.end ()) {
+ return uEmpty;
+ } else {
+ return it->second;
+ }
+ } else {
+ return uEmpty;
+ }
+}
+
void CGIFormFile::read_multipart (MotorEnv* env) {
#ifdef DEBUG2
std::cerr << "boundary:" << boundary << "\n";
}
bool CGIFormFile::saveData (MotorEnv* env) {
- static const int bsize = 65536 * 4;
+ static const size_t bsize = 65536 * 4;
size_t size = postSize ();
ustring b;
size_t s;
s = std::cin.read (&b[0], s).gcount ();
if (s <= 0)
break;
- s = ::write (fp.fd, &b[0], s);
+ ::write (fp.fd, &b[0], s);
size -= s;
mapsize += s;
- if (size > 0) {
- std::cerr << "post-file[" << mypid << ":" << env->scriptName << "]: reading " << mapsize << "Bytes...\n"; // cerrはバッファリングされない
- }
}
-// fp.close ();
- std::cerr << "post-file[" << mypid << ":" << env->scriptName << "]: done " << mapsize << "Bytes\n";
+// fp.close (); mmapした後にクローズする。
+// std::cerr << "post-file[" << mypid << ":" << env->scriptName << "]: done " << mapsize << "Bytes\n"; // 出力サイズが大きいと、デッドロックする。
mapdata = (char*)mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE, fp.fd, 0);
#ifdef DEBUG2
std::cerr << (void*) mapdata << ": " << mapsize << "\n";
}
void CGIFormFile::unlinkTmpFile () {
- if (mapdata > 0) {
+ if (mapdata != NULL) {
munmap (mapdata, mapsize);
mapdata = NULL;
}
fix (name);
parts.push_back (part (b, x));
fix (filename);
+ fix (type);
k1 = insert (iarg, name, filePart_osSafe (filename));
datamap.insert (sary_t::value_type (k1, k2));
+ typemap.insert (tary_t::value_type (k2, type));
#ifdef DEBUG2
std::cerr << "insert(" << k1 << "," << k2 << ")\n";
#endif /* DEBUG */
reN.assign (a);
}
+class ChSplitterNL {
+ public:
+ char* b; // 先頭
+ char* t; // 区切り文字列先頭
+ char* u; // 区切り文字列末尾
+ char* e; // 末尾
+
+ ChSplitterNL (char* _begin, char* _end) {
+ b = t = u = _begin;
+ e = _end;
+ };
+ ~ChSplitterNL () {};
+
+ bool isEnd () {
+ return b == e;
+ };
+ ustring pre () {
+ return ustring (b, t);
+ };
+ bool next () {
+ b = t = u;
+ if (b < e) {
+ if (findNL ()) {
+ } else {
+ t = u = e;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ };
+ bool nextSep () {
+ b = t = u;
+ if (b < e) {
+ if (findNL ()) {
+ return true;
+ } else {
+ t = u = e;
+ return false;
+ }
+ } else {
+ t = u = e;
+ return false;
+ }
+ };
+ bool findNL () {
+ for (; t < e; ++ t) {
+ if (*t == '\n') {
+ u = t + 1;
+ return true;
+ } else if (*t == '\r') {
+ u = t + 1;
+ if (u < e && *u == '\n')
+ ++ u;
+ return true;
+ }
+ }
+ return false;
+ };
+};
+
void CGIFormFile::readMimeHead (char*& b, char* e, ustring& disp, ustring& name, ustring& filename, ustring& type) {
- boost::match_results<char*> m;
+ ChSplitterNL sp (b, e);
boost::match_results<char*> m2;
- char* x;
static uregex re_disp1 ("^Content-Disposition:\\s*(.*);\\s*name=\"(.*)\";\\s*filename=\"(.*)\"$");
static uregex re_disp2 ("^Content-Disposition:\\s*(.*);\\s*name=\"(.*)\"$");
static uregex re_type ("^Content-Type:\\s*([a-zA-Z_0-9/.+-]*)(;\\s*(.*))?$");
name.resize (0);
filename.resize (0);
type.resize (0);
- while (b != e && regex_search (b, e, m, re_nl, boost::regex_constants::match_single_line)) {
- x = m[0].first;
+ while (sp.next ()) {
#ifdef DEBUG2
- std::cerr << "line:" << ustring (b, x) << "\n";
+ std::cerr << "line:" << sp.pre () << "\n";
#endif /* DEBUG */
- if (b == x) { // empty line
- b = m[0].second;
+ if (sp.b == sp.t) {
+ b = sp.u;
break;
}
- if (regex_search (b, x, m2, re_disp1, boost::regex_constants::match_single_line)) {
+ if (regex_search (sp.b, sp.t, m2, re_disp1, boost::regex_constants::match_single_line)) {
disp.assign (m2[1].first, m2[1].second - m2[1].first);
name.assign (m2[2].first, m2[2].second - m2[2].first);
filename.assign (m2[3].first, m2[3].second - m2[3].first);
- } else if (regex_search (b, x, m2, re_disp2, boost::regex_constants::match_single_line)) {
+ } else if (regex_search (sp.b, sp.t, m2, re_disp2, boost::regex_constants::match_single_line)) {
disp.assign (m2[1].first, m2[1].second - m2[1].first);
name.assign (m2[2].first, m2[2].second - m2[2].first);
- } else if (regex_search (b, x, m2, re_type, boost::regex_constants::match_single_line)) {
+ } else if (regex_search (sp.b, sp.t, m2, re_type, boost::regex_constants::match_single_line)) {
type.assign (m2[1].first, m2[1].second - m2[1].first);
} else {
#ifdef DEBUG2
- std::cerr << "not match:" << ustring (b, x) << "\n";
+ std::cerr << "not match:" << sp.pre () << "\n";
#endif /* DEBUG */
}
- b = m[0].second;
- }
-}
-
-#if 0
-bool CGIFormFile::readFilename (int i, ustring& filename) {
- if (0 <= i && i < parts.size ()) {
- filename = filenames[i];
- return true;
}
- return false;
}
-#endif
bool CGIFormFile::saveFile (int i, const ustring& path, size_t max) {
static size_t bsize = 65536;