#include "http/http_request.hpp" #include "multipart_parser.hpp" #include #include #include #include #include #include #include #include // IWYU pragma: keep // IWYU pragma: no_include // IWYU pragma: no_include // IWYU pragma: no_include "gtest/gtest_pred_impl.h" // IWYU pragma: no_include // IWYU pragma: no_include // IWYU pragma: no_include namespace { using ::testing::Test; class MultipartTest : public Test { public: boost::beast::http::request req{}; MultipartParser parser; std::error_code ec; }; TEST_F(MultipartTest, TestGoodMultipartParser) { req.set("Content-Type", "multipart/form-data; " "boundary=---------------------------d74496d66958873e"); req.body() = "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n" "111111111111111111111111112222222222222222222222222222222\r\n" "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n" "{\r\n-----------------------------d74496d66958873e123456\r\n" "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test3\"\r\n\r\n" "{\r\n--------d74496d6695887}\r\n" "-----------------------------d74496d66958873e--\r\n"; crow::Request reqIn(req, ec); ParserError rc = parser.parse(reqIn); ASSERT_EQ(rc, ParserError::PARSER_SUCCESS); EXPECT_EQ(parser.boundary, "\r\n-----------------------------d74496d66958873e"); EXPECT_EQ(parser.mime_fields.size(), 3); EXPECT_EQ(parser.mime_fields[0].fields.at("Content-Disposition"), "form-data; name=\"Test1\""); EXPECT_EQ(parser.mime_fields[0].content, "111111111111111111111111112222222222222222222222222222222"); EXPECT_EQ(parser.mime_fields[1].fields.at("Content-Disposition"), "form-data; name=\"Test2\""); EXPECT_EQ(parser.mime_fields[1].content, "{\r\n-----------------------------d74496d66958873e123456"); EXPECT_EQ(parser.mime_fields[2].fields.at("Content-Disposition"), "form-data; name=\"Test3\""); EXPECT_EQ(parser.mime_fields[2].content, "{\r\n--------d74496d6695887}"); } TEST_F(MultipartTest, TestBadMultipartParser1) { req.set("Content-Type", "multipart/form-data; " "boundary=---------------------------d74496d66958873e"); req.body() = "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n" "1234567890\r\n" "-----------------------------d74496d66958873e\r-\r\n"; crow::Request reqIn(req, ec); ParserError rc = parser.parse(reqIn); ASSERT_EQ(rc, ParserError::PARSER_SUCCESS); EXPECT_EQ(parser.boundary, "\r\n-----------------------------d74496d66958873e"); EXPECT_EQ(parser.mime_fields.size(), 1); } TEST_F(MultipartTest, TestBadMultipartParser2) { req.set("Content-Type", "multipart/form-data; " "boundary=---------------------------d74496d66958873e"); req.body() = "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n" "abcd\r\n" "-----------------------------d74496d66958873e-\r\n"; crow::Request reqIn(req, ec); ParserError rc = parser.parse(reqIn); ASSERT_EQ(rc, ParserError::PARSER_SUCCESS); EXPECT_EQ(parser.boundary, "\r\n-----------------------------d74496d66958873e"); EXPECT_EQ(parser.mime_fields.size(), 1); } TEST_F(MultipartTest, TestErrorBoundaryFormat) { req.set("Content-Type", "multipart/form-data; " "boundary+=-----------------------------d74496d66958873e"); req.body() = "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n" "{\"Key1\": 11223333333333333333333333333333333333333333}\r\n" "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n" "123456\r\n" "-----------------------------d74496d66958873e--\r\n"; crow::Request reqIn(req, ec); EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_FORMAT); } TEST_F(MultipartTest, TestErrorBoundaryCR) { req.set("Content-Type", "multipart/form-data; " "boundary=---------------------------d74496d66958873e"); req.body() = "-----------------------------d74496d66958873e" "Content-Disposition: form-data; name=\"Test1\"\r\n\r" "{\"Key1\": 112233}\r\n" "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n" "123456\r\n" "-----------------------------d74496d66958873e--\r\n"; crow::Request reqIn(req, ec); EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_CR); } TEST_F(MultipartTest, TestErrorBoundaryLF) { req.set("Content-Type", "multipart/form-data; " "boundary=---------------------------d74496d66958873e"); req.body() = "-----------------------------d74496d66958873e\r" "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n" "{\"Key1\": 112233}\r\n" "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n" "123456\r\n" "-----------------------------d74496d66958873e--\r\n"; crow::Request reqIn(req, ec); EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_LF); } TEST_F(MultipartTest, TestErrorBoundaryData) { req.set("Content-Type", "multipart/form-data; " "boundary=---------------------------d7449sd6d66958873e"); req.body() = "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n" "{\"Key1\": 112233}\r\n" "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n" "123456\r\n" "-----------------------------d74496d66958873e--\r\n"; crow::Request reqIn(req, ec); EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_DATA); } TEST_F(MultipartTest, TestErrorEmptyHeader) { req.set("Content-Type", "multipart/form-data; " "boundary=---------------------------d74496d66958873e"); req.body() = "-----------------------------d74496d66958873e\r\n" ": form-data; name=\"Test1\"\r\n" "{\"Key1\": 112233}\r\n" "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test2\"\r\n" "123456\r\n" "-----------------------------d74496d66958873e--\r\n"; crow::Request reqIn(req, ec); EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_EMPTY_HEADER); } TEST_F(MultipartTest, TestErrorHeaderName) { req.set("Content-Type", "multipart/form-data; " "boundary=---------------------------d74496d66958873e"); req.body() = "-----------------------------d74496d66958873e\r\n" "Content-!!Disposition: form-data; name=\"Test1\"\r\n" "{\"Key1\": 112233}\r\n" "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n" "123456\r\n" "-----------------------------d74496d66958873e--\r\n"; crow::Request reqIn(req, ec); EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_HEADER_NAME); } TEST_F(MultipartTest, TestErrorHeaderValue) { req.set("Content-Type", "multipart/form-data; " "boundary=---------------------------d74496d66958873e"); req.body() = "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test1\"\r" "{\"Key1\": 112233}\r\n" "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n" "123456\r\n" "-----------------------------d74496d66958873e--\r\n"; crow::Request reqIn(req, ec); EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_HEADER_VALUE); } TEST_F(MultipartTest, TestErrorHeaderEnding) { req.set("Content-Type", "multipart/form-data; " "boundary=---------------------------d74496d66958873e"); req.body() = "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test1\"\r\n\r" "{\"Key1\": 112233}\r\n" "-----------------------------d74496d66958873e\r\n" "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n" "123456\r\n" "-----------------------------d74496d66958873e--\r\n"; crow::Request reqIn(req, ec); EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_HEADER_ENDING); } } // namespace