void MTD_FLASHMEM MultipartFormDataProcessor::handle_GettingFile_GettingValue(char c) { static char const BOB[4] = {0x0D, 0x0A, '-', '-'}; // begin of boundary (just before every boundary) if (substate < 4 && c == BOB[substate]) { ++substate; } else if (substate >= 4 && c == boundary[substate - 4]) { ++substate; if (substate - 4 == boundarylen) { // found boundary, end file or value if (state == GettingFile) file.close(); else formfields->add(nameBegin, nameEnd, valueStorage->getIterator(), CharChunksIterator()); state = BoundaryFound; substate = 0; } } else { if (substate > 0) { // first "substate" bytes seemed the BOB or Boundary, but they were not! int32_t cnt = substate; substate = 0; if (state == GettingFile) file.write(BOB, 1); else valueStorage->append(BOB[0], FORM_CHUNK_SIZE); for (int32_t i = 1; i != cnt; ++i) push(i < 4 ? BOB[i] : boundary[i - 4]); push(c); } else { if (state == GettingFile) file.write(&c, 1); else valueStorage->append(c, FORM_CHUNK_SIZE); } } }
void MTD_FLASHMEM MultipartFormDataProcessor::handle_DecodingHeaders(char c) { static char const EOH[4] = {0x0D, 0x0A, 0x0D, 0x0A}; if (c == EOH[substate]) { ++substate; if (substate == 2) { // useful if this is not an EOH to separate headers headers->append(0x0D, 1); } else if (substate == 4) { // end of headers headers->append(0, 1); // add string terminating zero // look for "name" parameter CharChunksIterator keyBegin; extractParameter(FSTR(" name="), headers->getIterator(), &keyBegin, &nameBegin, &nameEnd); // look for "filename" parameter CharChunksIterator filenameBegin, filenameEnd; if (extractParameter(FSTR(" filename="), headers->getIterator(), &keyBegin, &filenameBegin, &filenameEnd)) { //// this is a file // add "filename" to form fields filenameBegin = getFilename(filenameBegin, filenameEnd); // some browsers send a full path instead of a simple file name (IE) formfields->add(keyBegin + 1, keyBegin + 9, filenameBegin, filenameEnd); // extract Content-Type parameter CharChunksIterator contentTypeBegin, contentTypeEnd; if (extractParameter(FSTR("Content-Type:"), filenameEnd, &keyBegin, &contentTypeBegin, &contentTypeEnd)) { // add "Content-Type" to form fields formfields->add(keyBegin, keyBegin + 12, contentTypeBegin, contentTypeEnd); // create file file.create(APtr<char>(t_strdup(filenameBegin, filenameEnd)).get(), APtr<char>(t_strdup(contentTypeBegin, contentTypeEnd)).get()); state = GettingFile; } else { // missing content-type, cannot get as file! state = GettingValue; } } else { //// this is a normal field valueStorage = chunksFactory.add(); state = GettingValue; } substate = 0; } } else { // add to headers buffer headers->append(c, HEADERS_CHUNK_SIZE); substate = 0; } }