Loading src/http.cpp +59 −77 Original line number Diff line number Diff line Loading @@ -2400,23 +2400,35 @@ void libhttppp::HttpForm::_parseMultiSection(netplus::condata<char> &data,size_t if((data[scl]!= ' ' && data[scl]!= '\r' && data[scl]!= '\n') && ctl==std::string::npos){ ctl=scl; }else if(data[scl]==':' && (ctl & ctlt) !=std::string::npos){ }else if(data[scl]==':' && ctl!=std::string::npos && ctlt==std::string::npos){ ctlt=scl; } if(ctl!=std::string::npos && ctlt!=std::string::npos){ MultipartForm::Data::Content content; // Key: lowercased header name std::transform(data.begin()+ctl, data.begin()+ctlt,std::back_inserter(content._Key), [](unsigned char c){ return static_cast<char>(std::tolower(c)); }); content._Key.push_back('\0'); while(data[++ctlt]==' '); std::copy(data.begin()+ctlt,data.begin()+findel, // Value: stop at end of current header line, not at findel size_t lineEnd = findel; for (size_t le = ctlt; le < findel; ++le) { if (data[le] == '\r' || data[le] == '\n') { lineEnd = le; break; } } std::copy(data.begin()+ctlt,data.begin()+lineEnd, std::inserter<std::vector<char>>(content._Value,content._Value.begin())); content._Value.push_back('\0'); MultipartFormData._lastData->addContent(content); scl = lineEnd; ctl=std::string::npos; ctlt=std::string::npos; } Loading @@ -2426,93 +2438,63 @@ void libhttppp::HttpForm::_parseMultiSection(netplus::condata<char> &data,size_t for (MultipartForm::Data::Content *curcontent = MultipartFormData._lastData->_firstContent.get(); curcontent; curcontent = curcontent->nextContent()) { std::string key(curcontent->getKey().begin(), curcontent->getKey().end()); for (auto &ch : key) ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch))); if (key == "content-disposition") { if (std::string(curcontent->getKey().data()) == "content-disposition") { cdispo = curcontent; break; } } auto searchLastElement=[](int startpos,size_t size,const char* word,std::vector<char> &sdata){ size_t wsize=strlen(word); for(size_t i=startpos; i<size; ++i){ for(size_t ii=0; ii<=wsize; ++ii){ if(ii==wsize){ return i; } if(sdata.at(i)==word[ii]){ ++i; continue; } break; } } return std::string::npos; }; if(cdispo){ size_t ifdp= searchLastElement(0,cdispo->_Value.size(),"form-data",cdispo->_Value); // Parse Content-Disposition value, e.g.: form-data; name="firstname"; filename="test.txt" std::string dval(cdispo->_Value.data()); size_t ifdp = dval.find("form-data"); if(ifdp!=std::string::npos){ size_t sc = ifdp + 9; // advance past "form-data" while (sc < dval.size()) { // Skip semicolons and whitespace between pairs while (sc < dval.size() && (dval[sc] == ';' || dval[sc] == ' ')) ++sc; if (sc >= dval.size()) break; size_t scss=std::string::npos,scse=std::string::npos; size_t scvts=std::string::npos; // Find key: ends at '=' or whitespace or ';' size_t keyStart = sc; while (sc < dval.size() && dval[sc] != '=' && dval[sc] != ' ' && dval[sc] != ';') ++sc; size_t keyEnd = sc; if (keyStart == keyEnd) break; size_t scvss=std::string::npos,scvse=std::string::npos; for(size_t sc=ifdp; sc<cdispo->_Value.size(); ++sc){ if(scss==std::string::npos){ if(cdispo->_Value[sc]!=';' && cdispo->_Value[sc]!=' '){ scss=sc; } MultipartForm::Data::ContentDisposition dispo; std::string keyStr = dval.substr(keyStart, keyEnd - keyStart); dispo._Key.assign(keyStr.begin(), keyStr.end()); dispo._Key.push_back('\0'); // Check for '=' and value if (sc < dval.size() && dval[sc] == '=') { ++sc; // skip '=' if (sc < dval.size() && dval[sc] == '"') { ++sc; // skip opening quote size_t valStart = sc; while (sc < dval.size() && dval[sc] != '"') ++sc; std::string valStr = dval.substr(valStart, sc - valStart); dispo._Value.assign(valStr.begin(), valStr.end()); dispo._Value.push_back('\0'); if (sc < dval.size()) ++sc; // skip closing quote } else { if( (cdispo->_Value[sc]==' ' || cdispo->_Value[sc]=='=' || sc+1==cdispo->_Value.size()) && scse==std::string::npos){ scse=sc; // Unquoted value: ends at ';' or whitespace size_t valStart = sc; while (sc < dval.size() && dval[sc] != ';' && dval[sc] != ' ') ++sc; std::string valStr = dval.substr(valStart, sc - valStart); dispo._Value.assign(valStr.begin(), valStr.end()); dispo._Value.push_back('\0'); } if( scse!=std::string::npos){ for(size_t scv=scss; scv<cdispo->_Value.size(); ++scv){ if(cdispo->_Value[scv]=='=' && scvts==std::string::npos){ scvts=scv; }else if(scvts!=std::string::npos){ if(cdispo->_Value[scv]=='"'){ if(scvss==std::string::npos) { scvss=++scv; }else if(scvse==std::string::npos){ scvse=scv; scv++; sc=scv; } } } } } } if(scss < scse && scss < cdispo->_Value.size() && scse <=cdispo->_Value.size()){ MultipartForm::Data::ContentDisposition dispo; std::copy(cdispo->_Value.begin()+scss,cdispo->_Value.begin()+scse, std::inserter<std::vector<char>>(dispo._Key,dispo._Key.begin())); if( scvss<scvse && scvss < cdispo->_Value.size() && scvse <= cdispo->_Value.size() ){ std::copy(cdispo->_Value.begin()+scvss,cdispo->_Value.begin()+scvse, std::inserter<std::vector<char>>(dispo._Value,dispo._Value.begin())); scvss=std::string::npos; scvse=std::string::npos; scvts=std::string::npos; } scss=std::string::npos; scse=std::string::npos; MultipartFormData._lastData->addDisposition(dispo); } } } if(MultipartFormData._lastData) Loading Loading
src/http.cpp +59 −77 Original line number Diff line number Diff line Loading @@ -2400,23 +2400,35 @@ void libhttppp::HttpForm::_parseMultiSection(netplus::condata<char> &data,size_t if((data[scl]!= ' ' && data[scl]!= '\r' && data[scl]!= '\n') && ctl==std::string::npos){ ctl=scl; }else if(data[scl]==':' && (ctl & ctlt) !=std::string::npos){ }else if(data[scl]==':' && ctl!=std::string::npos && ctlt==std::string::npos){ ctlt=scl; } if(ctl!=std::string::npos && ctlt!=std::string::npos){ MultipartForm::Data::Content content; // Key: lowercased header name std::transform(data.begin()+ctl, data.begin()+ctlt,std::back_inserter(content._Key), [](unsigned char c){ return static_cast<char>(std::tolower(c)); }); content._Key.push_back('\0'); while(data[++ctlt]==' '); std::copy(data.begin()+ctlt,data.begin()+findel, // Value: stop at end of current header line, not at findel size_t lineEnd = findel; for (size_t le = ctlt; le < findel; ++le) { if (data[le] == '\r' || data[le] == '\n') { lineEnd = le; break; } } std::copy(data.begin()+ctlt,data.begin()+lineEnd, std::inserter<std::vector<char>>(content._Value,content._Value.begin())); content._Value.push_back('\0'); MultipartFormData._lastData->addContent(content); scl = lineEnd; ctl=std::string::npos; ctlt=std::string::npos; } Loading @@ -2426,93 +2438,63 @@ void libhttppp::HttpForm::_parseMultiSection(netplus::condata<char> &data,size_t for (MultipartForm::Data::Content *curcontent = MultipartFormData._lastData->_firstContent.get(); curcontent; curcontent = curcontent->nextContent()) { std::string key(curcontent->getKey().begin(), curcontent->getKey().end()); for (auto &ch : key) ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch))); if (key == "content-disposition") { if (std::string(curcontent->getKey().data()) == "content-disposition") { cdispo = curcontent; break; } } auto searchLastElement=[](int startpos,size_t size,const char* word,std::vector<char> &sdata){ size_t wsize=strlen(word); for(size_t i=startpos; i<size; ++i){ for(size_t ii=0; ii<=wsize; ++ii){ if(ii==wsize){ return i; } if(sdata.at(i)==word[ii]){ ++i; continue; } break; } } return std::string::npos; }; if(cdispo){ size_t ifdp= searchLastElement(0,cdispo->_Value.size(),"form-data",cdispo->_Value); // Parse Content-Disposition value, e.g.: form-data; name="firstname"; filename="test.txt" std::string dval(cdispo->_Value.data()); size_t ifdp = dval.find("form-data"); if(ifdp!=std::string::npos){ size_t sc = ifdp + 9; // advance past "form-data" while (sc < dval.size()) { // Skip semicolons and whitespace between pairs while (sc < dval.size() && (dval[sc] == ';' || dval[sc] == ' ')) ++sc; if (sc >= dval.size()) break; size_t scss=std::string::npos,scse=std::string::npos; size_t scvts=std::string::npos; // Find key: ends at '=' or whitespace or ';' size_t keyStart = sc; while (sc < dval.size() && dval[sc] != '=' && dval[sc] != ' ' && dval[sc] != ';') ++sc; size_t keyEnd = sc; if (keyStart == keyEnd) break; size_t scvss=std::string::npos,scvse=std::string::npos; for(size_t sc=ifdp; sc<cdispo->_Value.size(); ++sc){ if(scss==std::string::npos){ if(cdispo->_Value[sc]!=';' && cdispo->_Value[sc]!=' '){ scss=sc; } MultipartForm::Data::ContentDisposition dispo; std::string keyStr = dval.substr(keyStart, keyEnd - keyStart); dispo._Key.assign(keyStr.begin(), keyStr.end()); dispo._Key.push_back('\0'); // Check for '=' and value if (sc < dval.size() && dval[sc] == '=') { ++sc; // skip '=' if (sc < dval.size() && dval[sc] == '"') { ++sc; // skip opening quote size_t valStart = sc; while (sc < dval.size() && dval[sc] != '"') ++sc; std::string valStr = dval.substr(valStart, sc - valStart); dispo._Value.assign(valStr.begin(), valStr.end()); dispo._Value.push_back('\0'); if (sc < dval.size()) ++sc; // skip closing quote } else { if( (cdispo->_Value[sc]==' ' || cdispo->_Value[sc]=='=' || sc+1==cdispo->_Value.size()) && scse==std::string::npos){ scse=sc; // Unquoted value: ends at ';' or whitespace size_t valStart = sc; while (sc < dval.size() && dval[sc] != ';' && dval[sc] != ' ') ++sc; std::string valStr = dval.substr(valStart, sc - valStart); dispo._Value.assign(valStr.begin(), valStr.end()); dispo._Value.push_back('\0'); } if( scse!=std::string::npos){ for(size_t scv=scss; scv<cdispo->_Value.size(); ++scv){ if(cdispo->_Value[scv]=='=' && scvts==std::string::npos){ scvts=scv; }else if(scvts!=std::string::npos){ if(cdispo->_Value[scv]=='"'){ if(scvss==std::string::npos) { scvss=++scv; }else if(scvse==std::string::npos){ scvse=scv; scv++; sc=scv; } } } } } } if(scss < scse && scss < cdispo->_Value.size() && scse <=cdispo->_Value.size()){ MultipartForm::Data::ContentDisposition dispo; std::copy(cdispo->_Value.begin()+scss,cdispo->_Value.begin()+scse, std::inserter<std::vector<char>>(dispo._Key,dispo._Key.begin())); if( scvss<scvse && scvss < cdispo->_Value.size() && scvse <= cdispo->_Value.size() ){ std::copy(cdispo->_Value.begin()+scvss,cdispo->_Value.begin()+scvse, std::inserter<std::vector<char>>(dispo._Value,dispo._Value.begin())); scvss=std::string::npos; scvse=std::string::npos; scvts=std::string::npos; } scss=std::string::npos; scse=std::string::npos; MultipartFormData._lastData->addDisposition(dispo); } } } if(MultipartFormData._lastData) Loading