177665bdaSNan Zhou #include "http_request.hpp"
2c33a039bSNan Zhou #include "multipart_parser.hpp"
3c33a039bSNan Zhou 
4c33a039bSNan Zhou #include <boost/beast/http/fields.hpp>
5c33a039bSNan Zhou 
6*f0b59af4SEd Tanous #include <iterator>
7c33a039bSNan Zhou #include <string_view>
8c33a039bSNan Zhou #include <system_error>
9c33a039bSNan Zhou #include <vector>
10c33a039bSNan Zhou 
11c33a039bSNan Zhou #include <gtest/gtest.h> // IWYU pragma: keep
12c33a039bSNan Zhou 
13c33a039bSNan Zhou // IWYU pragma: no_include <gtest/gtest-message.h>
14c33a039bSNan Zhou // IWYU pragma: no_include <gtest/gtest-test-part.h>
15c33a039bSNan Zhou // IWYU pragma: no_include "gtest/gtest_pred_impl.h"
16c33a039bSNan Zhou // IWYU pragma: no_include <boost/beast/http/impl/fields.hpp>
17c33a039bSNan Zhou // IWYU pragma: no_include <boost/intrusive/detail/list_iterator.hpp>
18c33a039bSNan Zhou // IWYU pragma: no_include <boost/intrusive/detail/tree_iterator.hpp>
19c33a039bSNan Zhou 
20c33a039bSNan Zhou namespace
21c33a039bSNan Zhou {
22c33a039bSNan Zhou using ::testing::Test;
23c33a039bSNan Zhou 
24c33a039bSNan Zhou class MultipartTest : public Test
25c33a039bSNan Zhou {
26c33a039bSNan Zhou   public:
27c33a039bSNan Zhou     MultipartParser parser;
28c33a039bSNan Zhou     std::error_code ec;
29c33a039bSNan Zhou };
30c33a039bSNan Zhou 
TEST_F(MultipartTest,TestGoodMultipartParser)31c33a039bSNan Zhou TEST_F(MultipartTest, TestGoodMultipartParser)
32c33a039bSNan Zhou {
336fb96ce3SEd Tanous     std::string_view body =
346fb96ce3SEd Tanous         "-----------------------------d74496d66958873e\r\n"
35c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
36c33a039bSNan Zhou         "111111111111111111111111112222222222222222222222222222222\r\n"
37c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r\n"
38c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
39c33a039bSNan Zhou         "{\r\n-----------------------------d74496d66958873e123456\r\n"
40c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r\n"
41c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test3\"\r\n\r\n"
42c33a039bSNan Zhou         "{\r\n--------d74496d6695887}\r\n"
43c33a039bSNan Zhou         "-----------------------------d74496d66958873e--\r\n";
44c33a039bSNan Zhou 
456fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
466fb96ce3SEd Tanous 
476fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
486fb96ce3SEd Tanous                     "multipart/form-data; "
496fb96ce3SEd Tanous                     "boundary=---------------------------d74496d66958873e");
506fb96ce3SEd Tanous 
51c33a039bSNan Zhou     ParserError rc = parser.parse(reqIn);
52c33a039bSNan Zhou     ASSERT_EQ(rc, ParserError::PARSER_SUCCESS);
53c33a039bSNan Zhou 
54c33a039bSNan Zhou     EXPECT_EQ(parser.boundary,
55c33a039bSNan Zhou               "\r\n-----------------------------d74496d66958873e");
56c33a039bSNan Zhou     EXPECT_EQ(parser.mime_fields.size(), 3);
57c33a039bSNan Zhou 
58c33a039bSNan Zhou     EXPECT_EQ(parser.mime_fields[0].fields.at("Content-Disposition"),
59c33a039bSNan Zhou               "form-data; name=\"Test1\"");
60c33a039bSNan Zhou     EXPECT_EQ(parser.mime_fields[0].content,
61c33a039bSNan Zhou               "111111111111111111111111112222222222222222222222222222222");
62c33a039bSNan Zhou 
63c33a039bSNan Zhou     EXPECT_EQ(parser.mime_fields[1].fields.at("Content-Disposition"),
64c33a039bSNan Zhou               "form-data; name=\"Test2\"");
65c33a039bSNan Zhou     EXPECT_EQ(parser.mime_fields[1].content,
66c33a039bSNan Zhou               "{\r\n-----------------------------d74496d66958873e123456");
67c33a039bSNan Zhou     EXPECT_EQ(parser.mime_fields[2].fields.at("Content-Disposition"),
68c33a039bSNan Zhou               "form-data; name=\"Test3\"");
69c33a039bSNan Zhou     EXPECT_EQ(parser.mime_fields[2].content, "{\r\n--------d74496d6695887}");
70c33a039bSNan Zhou }
71c33a039bSNan Zhou 
TEST_F(MultipartTest,TestBadMultipartParser1)72c33a039bSNan Zhou TEST_F(MultipartTest, TestBadMultipartParser1)
73c33a039bSNan Zhou {
746fb96ce3SEd Tanous     std::string_view body =
756fb96ce3SEd Tanous         "-----------------------------d74496d66958873e\r\n"
76c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
77c33a039bSNan Zhou         "1234567890\r\n"
78c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r-\r\n";
79c33a039bSNan Zhou 
806fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
816fb96ce3SEd Tanous 
826fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
836fb96ce3SEd Tanous                     "multipart/form-data; "
846fb96ce3SEd Tanous                     "boundary=---------------------------d74496d66958873e");
856fb96ce3SEd Tanous 
86c33a039bSNan Zhou     ParserError rc = parser.parse(reqIn);
87c33a039bSNan Zhou 
8818e3f7fbSKrzysztof Grobelny     EXPECT_EQ(rc, ParserError::ERROR_UNEXPECTED_END_OF_INPUT);
89c33a039bSNan Zhou }
90c33a039bSNan Zhou 
TEST_F(MultipartTest,TestBadMultipartParser2)91c33a039bSNan Zhou TEST_F(MultipartTest, TestBadMultipartParser2)
92c33a039bSNan Zhou {
936fb96ce3SEd Tanous     std::string_view body =
946fb96ce3SEd Tanous         "-----------------------------d74496d66958873e\r\n"
95c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
96c33a039bSNan Zhou         "abcd\r\n"
97c33a039bSNan Zhou         "-----------------------------d74496d66958873e-\r\n";
986fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
99c33a039bSNan Zhou 
1006fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
1016fb96ce3SEd Tanous                     "multipart/form-data; "
1026fb96ce3SEd Tanous                     "boundary=---------------------------d74496d66958873e");
1036fb96ce3SEd Tanous 
104c33a039bSNan Zhou     ParserError rc = parser.parse(reqIn);
105c33a039bSNan Zhou 
10618e3f7fbSKrzysztof Grobelny     EXPECT_EQ(rc, ParserError::ERROR_UNEXPECTED_END_OF_INPUT);
107c33a039bSNan Zhou }
108c33a039bSNan Zhou 
TEST_F(MultipartTest,TestErrorBoundaryFormat)109c33a039bSNan Zhou TEST_F(MultipartTest, TestErrorBoundaryFormat)
110c33a039bSNan Zhou {
1116fb96ce3SEd Tanous     std::string_view body =
1126fb96ce3SEd Tanous         "-----------------------------d74496d66958873e\r\n"
113c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
114c33a039bSNan Zhou         "{\"Key1\": 11223333333333333333333333333333333333333333}\r\n"
115c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r\n"
116c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
117c33a039bSNan Zhou         "123456\r\n"
118c33a039bSNan Zhou         "-----------------------------d74496d66958873e--\r\n";
119c33a039bSNan Zhou 
1206fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
1216fb96ce3SEd Tanous 
1226fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
1236fb96ce3SEd Tanous                     "multipart/form-data; "
1246fb96ce3SEd Tanous                     "boundary+=-----------------------------d74496d66958873e");
1256fb96ce3SEd Tanous 
126c33a039bSNan Zhou     EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_FORMAT);
127c33a039bSNan Zhou }
128c33a039bSNan Zhou 
TEST_F(MultipartTest,TestErrorBoundaryCR)129c33a039bSNan Zhou TEST_F(MultipartTest, TestErrorBoundaryCR)
130c33a039bSNan Zhou {
1316fb96ce3SEd Tanous     std::string_view body =
1326fb96ce3SEd Tanous         "-----------------------------d74496d66958873e"
133c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test1\"\r\n\r"
134c33a039bSNan Zhou         "{\"Key1\": 112233}\r\n"
135c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r\n"
136c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
137c33a039bSNan Zhou         "123456\r\n"
138c33a039bSNan Zhou         "-----------------------------d74496d66958873e--\r\n";
1396fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
140c33a039bSNan Zhou 
1416fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
1426fb96ce3SEd Tanous                     "multipart/form-data; "
1436fb96ce3SEd Tanous                     "boundary=---------------------------d74496d66958873e");
1446fb96ce3SEd Tanous 
145c33a039bSNan Zhou     EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_CR);
146c33a039bSNan Zhou }
147c33a039bSNan Zhou 
TEST_F(MultipartTest,TestErrorBoundaryLF)148c33a039bSNan Zhou TEST_F(MultipartTest, TestErrorBoundaryLF)
149c33a039bSNan Zhou {
1506fb96ce3SEd Tanous     std::string_view body =
1516fb96ce3SEd Tanous         "-----------------------------d74496d66958873e\r"
152c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
153c33a039bSNan Zhou         "{\"Key1\": 112233}\r\n"
154c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r\n"
155c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
156c33a039bSNan Zhou         "123456\r\n"
157c33a039bSNan Zhou         "-----------------------------d74496d66958873e--\r\n";
158c33a039bSNan Zhou 
1596fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
1606fb96ce3SEd Tanous 
1616fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
1626fb96ce3SEd Tanous                     "multipart/form-data; "
1636fb96ce3SEd Tanous                     "boundary=---------------------------d74496d66958873e");
1646fb96ce3SEd Tanous 
165c33a039bSNan Zhou     EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_LF);
166c33a039bSNan Zhou }
167c33a039bSNan Zhou 
TEST_F(MultipartTest,TestErrorBoundaryData)168c33a039bSNan Zhou TEST_F(MultipartTest, TestErrorBoundaryData)
169c33a039bSNan Zhou {
1706fb96ce3SEd Tanous     std::string_view body =
1716fb96ce3SEd Tanous         "-----------------------------d74496d66958873e\r\n"
172c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
173c33a039bSNan Zhou         "{\"Key1\": 112233}\r\n"
174c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r\n"
175c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
176c33a039bSNan Zhou         "123456\r\n"
177c33a039bSNan Zhou         "-----------------------------d74496d66958873e--\r\n";
178c33a039bSNan Zhou 
1796fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
1806fb96ce3SEd Tanous 
1816fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
1826fb96ce3SEd Tanous                     "multipart/form-data; "
1836fb96ce3SEd Tanous                     "boundary=---------------------------d7449sd6d66958873e");
1846fb96ce3SEd Tanous 
185c33a039bSNan Zhou     EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_DATA);
186c33a039bSNan Zhou }
187c33a039bSNan Zhou 
TEST_F(MultipartTest,TestErrorEmptyHeader)188c33a039bSNan Zhou TEST_F(MultipartTest, TestErrorEmptyHeader)
189c33a039bSNan Zhou {
1906fb96ce3SEd Tanous     std::string_view body =
1916fb96ce3SEd Tanous         "-----------------------------d74496d66958873e\r\n"
192c33a039bSNan Zhou         ": form-data; name=\"Test1\"\r\n"
193c33a039bSNan Zhou         "{\"Key1\": 112233}\r\n"
194c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r\n"
195c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test2\"\r\n"
196c33a039bSNan Zhou         "123456\r\n"
197c33a039bSNan Zhou         "-----------------------------d74496d66958873e--\r\n";
1986fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
199c33a039bSNan Zhou 
2006fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
2016fb96ce3SEd Tanous                     "multipart/form-data; "
2026fb96ce3SEd Tanous                     "boundary=---------------------------d74496d66958873e");
2036fb96ce3SEd Tanous 
204c33a039bSNan Zhou     EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_EMPTY_HEADER);
205c33a039bSNan Zhou }
206c33a039bSNan Zhou 
TEST_F(MultipartTest,TestErrorHeaderName)207c33a039bSNan Zhou TEST_F(MultipartTest, TestErrorHeaderName)
208c33a039bSNan Zhou {
2096fb96ce3SEd Tanous     std::string_view body =
2106fb96ce3SEd Tanous         "-----------------------------d74496d66958873e\r\n"
211c33a039bSNan Zhou         "Content-!!Disposition: form-data; name=\"Test1\"\r\n"
212c33a039bSNan Zhou         "{\"Key1\": 112233}\r\n"
213c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r\n"
214c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
215c33a039bSNan Zhou         "123456\r\n"
216c33a039bSNan Zhou         "-----------------------------d74496d66958873e--\r\n";
2176fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
218c33a039bSNan Zhou 
2196fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
2206fb96ce3SEd Tanous                     "multipart/form-data; "
2216fb96ce3SEd Tanous                     "boundary=---------------------------d74496d66958873e");
2226fb96ce3SEd Tanous 
223c33a039bSNan Zhou     EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_HEADER_NAME);
224c33a039bSNan Zhou }
225c33a039bSNan Zhou 
TEST_F(MultipartTest,TestErrorHeaderValue)226c33a039bSNan Zhou TEST_F(MultipartTest, TestErrorHeaderValue)
227c33a039bSNan Zhou {
2286fb96ce3SEd Tanous     std::string_view body =
2296fb96ce3SEd Tanous         "-----------------------------d74496d66958873e\r\n"
230c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test1\"\r"
231c33a039bSNan Zhou         "{\"Key1\": 112233}\r\n"
232c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r\n"
233c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
234c33a039bSNan Zhou         "123456\r\n"
235c33a039bSNan Zhou         "-----------------------------d74496d66958873e--\r\n";
236c33a039bSNan Zhou 
2376fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
2386fb96ce3SEd Tanous 
2396fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
2406fb96ce3SEd Tanous                     "multipart/form-data; "
2416fb96ce3SEd Tanous                     "boundary=---------------------------d74496d66958873e");
2426fb96ce3SEd Tanous 
243c33a039bSNan Zhou     EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_HEADER_VALUE);
244c33a039bSNan Zhou }
245c33a039bSNan Zhou 
TEST_F(MultipartTest,TestErrorHeaderEnding)246c33a039bSNan Zhou TEST_F(MultipartTest, TestErrorHeaderEnding)
247c33a039bSNan Zhou {
2486fb96ce3SEd Tanous     std::string_view body =
2496fb96ce3SEd Tanous         "-----------------------------d74496d66958873e\r\n"
250c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test1\"\r\n\r"
251c33a039bSNan Zhou         "{\"Key1\": 112233}\r\n"
252c33a039bSNan Zhou         "-----------------------------d74496d66958873e\r\n"
253c33a039bSNan Zhou         "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
254c33a039bSNan Zhou         "123456\r\n"
255c33a039bSNan Zhou         "-----------------------------d74496d66958873e--\r\n";
256c33a039bSNan Zhou 
2576fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
2586fb96ce3SEd Tanous 
2596fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
2606fb96ce3SEd Tanous                     "multipart/form-data; "
2616fb96ce3SEd Tanous                     "boundary=---------------------------d74496d66958873e");
2626fb96ce3SEd Tanous 
263c33a039bSNan Zhou     EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_HEADER_ENDING);
264c33a039bSNan Zhou }
26518e3f7fbSKrzysztof Grobelny 
TEST_F(MultipartTest,TestGoodMultipartParserMultipleHeaders)26618e3f7fbSKrzysztof Grobelny TEST_F(MultipartTest, TestGoodMultipartParserMultipleHeaders)
26718e3f7fbSKrzysztof Grobelny {
2686fb96ce3SEd Tanous     std::string_view body = "-----------------------------d74496d66958873e\r\n"
26918e3f7fbSKrzysztof Grobelny                             "Content-Disposition: form-data; name=\"Test1\"\r\n"
27018e3f7fbSKrzysztof Grobelny                             "Other-Header: value=\"v1\"\r\n"
27118e3f7fbSKrzysztof Grobelny                             "\r\n"
27218e3f7fbSKrzysztof Grobelny                             "Data1\r\n"
27318e3f7fbSKrzysztof Grobelny                             "-----------------------------d74496d66958873e--";
27418e3f7fbSKrzysztof Grobelny 
2756fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
2766fb96ce3SEd Tanous 
2776fb96ce3SEd Tanous     reqIn.addHeader("Content-Type",
2786fb96ce3SEd Tanous                     "multipart/form-data; "
2796fb96ce3SEd Tanous                     "boundary=---------------------------d74496d66958873e");
2806fb96ce3SEd Tanous 
28118e3f7fbSKrzysztof Grobelny     ParserError rc = parser.parse(reqIn);
28218e3f7fbSKrzysztof Grobelny     ASSERT_EQ(rc, ParserError::PARSER_SUCCESS);
28318e3f7fbSKrzysztof Grobelny 
28418e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.boundary,
28518e3f7fbSKrzysztof Grobelny               "\r\n-----------------------------d74496d66958873e");
28618e3f7fbSKrzysztof Grobelny     ASSERT_EQ(parser.mime_fields.size(), 1);
28718e3f7fbSKrzysztof Grobelny 
28818e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields[0].fields.at("Content-Disposition"),
28918e3f7fbSKrzysztof Grobelny               "form-data; name=\"Test1\"");
29018e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields[0].fields.at("Other-Header"), "value=\"v1\"");
29118e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields[0].content, "Data1");
29218e3f7fbSKrzysztof Grobelny }
29318e3f7fbSKrzysztof Grobelny 
TEST_F(MultipartTest,TestErrorHeaderWithoutColon)29418e3f7fbSKrzysztof Grobelny TEST_F(MultipartTest, TestErrorHeaderWithoutColon)
29518e3f7fbSKrzysztof Grobelny {
2966fb96ce3SEd Tanous     std::string_view body = "----end\r\n"
29718e3f7fbSKrzysztof Grobelny                             "abc\r\n"
29818e3f7fbSKrzysztof Grobelny                             "\r\n"
29918e3f7fbSKrzysztof Grobelny                             "Data1\r\n"
30018e3f7fbSKrzysztof Grobelny                             "----end--\r\n";
3016fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
30218e3f7fbSKrzysztof Grobelny 
3036fb96ce3SEd Tanous     reqIn.addHeader("Content-Type", "multipart/form-data; "
3046fb96ce3SEd Tanous                                     "boundary=--end");
3056fb96ce3SEd Tanous 
30618e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_UNEXPECTED_END_OF_HEADER);
30718e3f7fbSKrzysztof Grobelny }
30818e3f7fbSKrzysztof Grobelny 
TEST_F(MultipartTest,TestUnknownHeaderIsCorrectlyParsed)30918e3f7fbSKrzysztof Grobelny TEST_F(MultipartTest, TestUnknownHeaderIsCorrectlyParsed)
31018e3f7fbSKrzysztof Grobelny {
3116fb96ce3SEd Tanous     std::string_view body =
31218e3f7fbSKrzysztof Grobelny         "----end\r\n"
31318e3f7fbSKrzysztof Grobelny         "t-DiPpcccc:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccgcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaa\r\n"
31418e3f7fbSKrzysztof Grobelny         "\r\n"
31518e3f7fbSKrzysztof Grobelny         "Data1\r\n"
31618e3f7fbSKrzysztof Grobelny         "----end--\r\n";
31718e3f7fbSKrzysztof Grobelny 
3186fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
3196fb96ce3SEd Tanous 
3206fb96ce3SEd Tanous     reqIn.addHeader("Content-Type", "multipart/form-data; "
3216fb96ce3SEd Tanous                                     "boundary=--end");
32218e3f7fbSKrzysztof Grobelny     ParserError rc = parser.parse(reqIn);
32318e3f7fbSKrzysztof Grobelny 
32418e3f7fbSKrzysztof Grobelny     ASSERT_EQ(rc, ParserError::PARSER_SUCCESS);
32518e3f7fbSKrzysztof Grobelny 
32618e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.boundary, "\r\n----end");
32718e3f7fbSKrzysztof Grobelny     ASSERT_EQ(parser.mime_fields.size(), 1);
32818e3f7fbSKrzysztof Grobelny 
32918e3f7fbSKrzysztof Grobelny     EXPECT_EQ(
33018e3f7fbSKrzysztof Grobelny         parser.mime_fields[0].fields.at("t-DiPpcccc"),
33118e3f7fbSKrzysztof Grobelny         "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccgcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaa");
33218e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields[0].content, "Data1");
33318e3f7fbSKrzysztof Grobelny }
33418e3f7fbSKrzysztof Grobelny 
TEST_F(MultipartTest,TestErrorMissingSeparatorBetweenMimeFieldsAndData)33518e3f7fbSKrzysztof Grobelny TEST_F(MultipartTest, TestErrorMissingSeparatorBetweenMimeFieldsAndData)
33618e3f7fbSKrzysztof Grobelny {
3376fb96ce3SEd Tanous     std::string_view body =
33818e3f7fbSKrzysztof Grobelny         "-----------------------------d74496d66958873e\r\n"
33918e3f7fbSKrzysztof Grobelny         "t-DiPpcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccgcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaa\r\n"
34018e3f7fbSKrzysztof Grobelny         "Data1"
34118e3f7fbSKrzysztof Grobelny         "-----------------------------d74496d66958873e--";
34218e3f7fbSKrzysztof Grobelny 
3436fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
3446fb96ce3SEd Tanous 
3456fb96ce3SEd Tanous     reqIn.addHeader(
3466fb96ce3SEd Tanous         "Content-Type",
3476fb96ce3SEd Tanous         "multipart/form-data; boundary=---------------------------d74496d66958873e");
3486fb96ce3SEd Tanous 
34918e3f7fbSKrzysztof Grobelny     ParserError rc = parser.parse(reqIn);
35018e3f7fbSKrzysztof Grobelny 
35118e3f7fbSKrzysztof Grobelny     EXPECT_EQ(rc, ParserError::ERROR_UNEXPECTED_END_OF_HEADER);
35218e3f7fbSKrzysztof Grobelny }
35318e3f7fbSKrzysztof Grobelny 
TEST_F(MultipartTest,TestDataWithoutMimeFields)35418e3f7fbSKrzysztof Grobelny TEST_F(MultipartTest, TestDataWithoutMimeFields)
35518e3f7fbSKrzysztof Grobelny {
3566fb96ce3SEd Tanous     std::string_view body = "-----------------------------d74496d66958873e\r\n"
35718e3f7fbSKrzysztof Grobelny                             "\r\n"
35818e3f7fbSKrzysztof Grobelny                             "Data1\r\n"
35918e3f7fbSKrzysztof Grobelny                             "-----------------------------d74496d66958873e--";
36018e3f7fbSKrzysztof Grobelny 
3616fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
3626fb96ce3SEd Tanous 
3636fb96ce3SEd Tanous     reqIn.addHeader(
3646fb96ce3SEd Tanous         "Content-Type",
3656fb96ce3SEd Tanous         "multipart/form-data; boundary=---------------------------d74496d66958873e");
3666fb96ce3SEd Tanous 
36718e3f7fbSKrzysztof Grobelny     ParserError rc = parser.parse(reqIn);
36818e3f7fbSKrzysztof Grobelny 
36918e3f7fbSKrzysztof Grobelny     ASSERT_EQ(rc, ParserError::PARSER_SUCCESS);
37018e3f7fbSKrzysztof Grobelny 
37118e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.boundary,
37218e3f7fbSKrzysztof Grobelny               "\r\n-----------------------------d74496d66958873e");
37318e3f7fbSKrzysztof Grobelny     ASSERT_EQ(parser.mime_fields.size(), 1);
37418e3f7fbSKrzysztof Grobelny 
37518e3f7fbSKrzysztof Grobelny     EXPECT_EQ(std::distance(parser.mime_fields[0].fields.begin(),
37618e3f7fbSKrzysztof Grobelny                             parser.mime_fields[0].fields.end()),
37718e3f7fbSKrzysztof Grobelny               0);
37818e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields[0].content, "Data1");
37918e3f7fbSKrzysztof Grobelny }
38018e3f7fbSKrzysztof Grobelny 
TEST_F(MultipartTest,TestErrorMissingFinalBoundry)38118e3f7fbSKrzysztof Grobelny TEST_F(MultipartTest, TestErrorMissingFinalBoundry)
38218e3f7fbSKrzysztof Grobelny {
3836fb96ce3SEd Tanous     std::string_view body =
38418e3f7fbSKrzysztof Grobelny         "----XX\r\n"
38518e3f7fbSKrzysztof Grobelny         "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
38618e3f7fbSKrzysztof Grobelny         "t-DiPpccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccAAAAAAAAAAAAAAABCDz\r\n"
38718e3f7fbSKrzysztof Grobelny         "\335\r\n\r\n";
38818e3f7fbSKrzysztof Grobelny 
3896fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
3906fb96ce3SEd Tanous 
3916fb96ce3SEd Tanous     reqIn.addHeader("Content-Type", "multipart/form-data; boundary=--XX");
3926fb96ce3SEd Tanous 
39318e3f7fbSKrzysztof Grobelny     ParserError rc = parser.parse(reqIn);
39418e3f7fbSKrzysztof Grobelny 
39518e3f7fbSKrzysztof Grobelny     EXPECT_EQ(rc, ParserError::ERROR_UNEXPECTED_END_OF_INPUT);
39618e3f7fbSKrzysztof Grobelny }
39718e3f7fbSKrzysztof Grobelny 
TEST_F(MultipartTest,TestIgnoreDataAfterFinalBoundary)39818e3f7fbSKrzysztof Grobelny TEST_F(MultipartTest, TestIgnoreDataAfterFinalBoundary)
39918e3f7fbSKrzysztof Grobelny {
4006fb96ce3SEd Tanous     std::string_view body =
4016fb96ce3SEd Tanous         "----XX\r\n"
40218e3f7fbSKrzysztof Grobelny         "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
40318e3f7fbSKrzysztof Grobelny         "Data1\r\n"
40418e3f7fbSKrzysztof Grobelny         "----XX--\r\n"
40518e3f7fbSKrzysztof Grobelny         "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
40618e3f7fbSKrzysztof Grobelny         "Data2\r\n"
40718e3f7fbSKrzysztof Grobelny         "----XX--\r\n";
40818e3f7fbSKrzysztof Grobelny 
4096fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
4106fb96ce3SEd Tanous 
4116fb96ce3SEd Tanous     reqIn.addHeader("Content-Type", "multipart/form-data; boundary=--XX");
4126fb96ce3SEd Tanous 
41318e3f7fbSKrzysztof Grobelny     ParserError rc = parser.parse(reqIn);
41418e3f7fbSKrzysztof Grobelny 
41518e3f7fbSKrzysztof Grobelny     ASSERT_EQ(rc, ParserError::PARSER_SUCCESS);
41618e3f7fbSKrzysztof Grobelny 
41718e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.boundary, "\r\n----XX");
41818e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields.size(), 1);
41918e3f7fbSKrzysztof Grobelny 
42018e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields[0].fields.at("Content-Disposition"),
42118e3f7fbSKrzysztof Grobelny               "form-data; name=\"Test1\"");
42218e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields[0].content, "Data1");
42318e3f7fbSKrzysztof Grobelny }
42418e3f7fbSKrzysztof Grobelny 
TEST_F(MultipartTest,TestFinalBoundaryIsCorrectlyRecognized)42518e3f7fbSKrzysztof Grobelny TEST_F(MultipartTest, TestFinalBoundaryIsCorrectlyRecognized)
42618e3f7fbSKrzysztof Grobelny {
4276fb96ce3SEd Tanous     std::string_view body =
4286fb96ce3SEd Tanous         "----XX\r\n"
42918e3f7fbSKrzysztof Grobelny         "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
43018e3f7fbSKrzysztof Grobelny         "Data1\r\n"
43118e3f7fbSKrzysztof Grobelny         "----XX-abc-\r\n"
43218e3f7fbSKrzysztof Grobelny         "StillData1\r\n"
43318e3f7fbSKrzysztof Grobelny         "----XX--\r\n";
43418e3f7fbSKrzysztof Grobelny 
4356fb96ce3SEd Tanous     crow::Request reqIn(body, ec);
4366fb96ce3SEd Tanous 
4376fb96ce3SEd Tanous     reqIn.addHeader("Content-Type", "multipart/form-data; boundary=--XX");
4386fb96ce3SEd Tanous 
43918e3f7fbSKrzysztof Grobelny     ParserError rc = parser.parse(reqIn);
44018e3f7fbSKrzysztof Grobelny 
44118e3f7fbSKrzysztof Grobelny     ASSERT_EQ(rc, ParserError::PARSER_SUCCESS);
44218e3f7fbSKrzysztof Grobelny 
44318e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.boundary, "\r\n----XX");
44418e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields.size(), 1);
44518e3f7fbSKrzysztof Grobelny 
44618e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields[0].fields.at("Content-Disposition"),
44718e3f7fbSKrzysztof Grobelny               "form-data; name=\"Test1\"");
44818e3f7fbSKrzysztof Grobelny     EXPECT_EQ(parser.mime_fields[0].content, "Data1\r\n"
44918e3f7fbSKrzysztof Grobelny                                              "----XX-abc-\r\n"
45018e3f7fbSKrzysztof Grobelny                                              "StillData1");
45118e3f7fbSKrzysztof Grobelny }
45218e3f7fbSKrzysztof Grobelny 
453c33a039bSNan Zhou } // namespace
454