Commit ef92c6e1 authored by jan.koester's avatar jan.koester
Browse files

test

parent 563eadca
Loading
Loading
Loading
Loading
+59 −77
Original line number Diff line number Diff line
@@ -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;
    }
@@ -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)