void Parser::parseMultipart(RequestImpl *req, DataBuffer data, const std::string &boundary) { DataBuffer head, tail; while (!data.empty()) { if (data.split(boundary, head, tail) && !head.empty()) { if (head.endsWith(RETURN_RN_STRING)) { head = head.trimn(0, 2); } else if (head.endsWith(RETURN_N_STRING)) { head = head.trimn(0, 1); } else { throw std::runtime_error("malformed multipart message"); } if (head.startsWith(RETURN_RN_STRING)) { head = head.trimn(2, 0); } else if (head.startsWith(RETURN_N_STRING)) { head = head.trimn(1, 0); } else { throw std::runtime_error("malformed multipart message"); } } if (!head.empty()) { parsePart(req, head); } if (tail.startsWith(MINUS_PREFIX_STRING)) { break; } data = tail; } }
TEST(DataBuffer, GetMax) { DataBuffer db; db.append((uint8_t*) "1234", 4); DataBufferData data1 = db.get(8); ASSERT_EQ(4, data1.length); data1.free(); ASSERT_TRUE(db.empty()); }
void Parser::parsePart(RequestImpl *req, DataBuffer part) { DataBuffer headers, content; DataBuffer name, filename, type; if (!part.split(EMPTY_LINE_RNRN_STRING, headers, content)) { part.split(EMPTY_LINE_NN_STRING, headers, content); } while (!headers.empty()) { DataBuffer line; DataBuffer tail = headers; bool lineFound = false; while (!tail.empty()) { DataBuffer subline, subtail; if (!tail.split(RETURN_RN_STRING, subline, subtail)) { tail.split('\n', subline, subtail); } if (subline.startsWith(ONE_SPACE_STRING) || subline.startsWith(ONE_TAB_STRING)) { line = DataBuffer(part, line.beginIndex(), subline.endIndex()); } else { if (lineFound) { break; } line = subline; } tail = subtail; lineFound = true; } parseLine(line, name, filename, type); headers = tail; } if (name.empty()) { return; } std::string name_str; name.toString(name_str); if (!filename.empty()) { req->files_.insert(std::make_pair(name_str, File(filename, type, content))); } else { std::string arg; content.toString(arg); req->args_.push_back(std::make_pair(name_str, arg)); } }
void Parser::parseLine(DataBuffer line, DataBuffer &name, DataBuffer &filename, DataBuffer &type) { while (!line.empty()) { DataBuffer head, tail, key, value; line.split(';', head, tail); head.split('=', key, value); if (NAME_STRING.size() == key.size() && key.startsWith(NAME_STRING)) { name = value.trimn(1, 1); } else if (FILENAME_STRING.size() == key.size() && key.startsWith(FILENAME_STRING)) { filename = value.trimn(1, 1); } else if (CONTENT_TYPE_STRING.size() == key.size() && key.startsWithCI(CONTENT_TYPE_STRING)) { type = value.trim(); } line = tail.trim(); } }
TEST(DataBuffer, Delete) { DataBuffer db; const char* str = "123"; db.append((uint8_t*)str, 3); DataBufferData d0 = db.get(1); ASSERT_DATA_EQ("1", d0.data, 1); ASSERT_EQ(3, db.bytesUsed()); d0.free(); ASSERT_EQ(2, db.bytesUsed()); DataBufferData d1 = db.get(1); ASSERT_DATA_EQ("2", d1.data, 1); d1.free(); ASSERT_EQ(1, db.bytesUsed()); DataBufferData d2 = db.get(1); ASSERT_DATA_EQ("3", d2.data, 1); ASSERT_EQ(1, db.bytesUsed()); d2.free(); ASSERT_EQ(0, db.bytesUsed()); ASSERT_TRUE(db.empty()); ASSERT_EQ(0, d2.data); ASSERT_EQ(0, d2.length); }