blob: 7ad7d98f89ab9d7e57f06bbafebc6665cb7668db [file] [log] [blame]
Nan Zhouca0cb4c2022-06-21 17:47:09 +00001#include "http/http_request.hpp"
2#include "multipart_parser.hpp"
3
Nan Zhoud5c80ad2022-07-11 01:16:31 +00004#include <boost/beast/http/fields.hpp>
Nan Zhouca0cb4c2022-06-21 17:47:09 +00005#include <boost/beast/http/message.hpp>
6#include <boost/beast/http/string_body.hpp>
Ed Tanousaf4edf62020-07-21 08:46:25 -07007
Nan Zhoud5c80ad2022-07-11 01:16:31 +00008#include <memory>
9#include <string_view>
Nan Zhouca0cb4c2022-06-21 17:47:09 +000010#include <system_error>
Nan Zhoud5c80ad2022-07-11 01:16:31 +000011#include <vector>
Ed Tanousaf4edf62020-07-21 08:46:25 -070012
Nan Zhoud5c80ad2022-07-11 01:16:31 +000013#include <gtest/gtest.h> // IWYU pragma: keep
14
15// IWYU pragma: no_include <gtest/gtest-message.h>
16// IWYU pragma: no_include <gtest/gtest-test-part.h>
17// IWYU pragma: no_include "gtest/gtest_pred_impl.h"
18// IWYU pragma: no_include <boost/beast/http/impl/fields.hpp>
19// IWYU pragma: no_include <boost/intrusive/detail/list_iterator.hpp>
20// IWYU pragma: no_include <boost/intrusive/detail/tree_iterator.hpp>
Ed Tanousaf4edf62020-07-21 08:46:25 -070021
Nan Zhoue52d1562022-06-21 17:47:15 +000022namespace
23{
24using ::testing::Test;
25
26class MultipartTest : public Test
Ed Tanousaf4edf62020-07-21 08:46:25 -070027{
28 public:
29 boost::beast::http::request<boost::beast::http::string_body> req{};
30 MultipartParser parser;
31 std::error_code ec;
32};
33
34TEST_F(MultipartTest, TestGoodMultipartParser)
35{
36 req.set("Content-Type",
37 "multipart/form-data; "
38 "boundary=---------------------------d74496d66958873e");
39
40 req.body() = "-----------------------------d74496d66958873e\r\n"
41 "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
42 "111111111111111111111111112222222222222222222222222222222\r\n"
43 "-----------------------------d74496d66958873e\r\n"
44 "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
45 "{\r\n-----------------------------d74496d66958873e123456\r\n"
46 "-----------------------------d74496d66958873e\r\n"
47 "Content-Disposition: form-data; name=\"Test3\"\r\n\r\n"
48 "{\r\n--------d74496d6695887}\r\n"
49 "-----------------------------d74496d66958873e--\r\n";
50
51 crow::Request reqIn(req, ec);
52 ParserError rc = parser.parse(reqIn);
53 ASSERT_EQ(rc, ParserError::PARSER_SUCCESS);
54
Nan Zhoucc606192022-06-21 17:47:19 +000055 EXPECT_EQ(parser.boundary,
Ed Tanousaf4edf62020-07-21 08:46:25 -070056 "\r\n-----------------------------d74496d66958873e");
Nan Zhoucc606192022-06-21 17:47:19 +000057 EXPECT_EQ(parser.mime_fields.size(), 3);
Ed Tanousaf4edf62020-07-21 08:46:25 -070058
Nan Zhoucc606192022-06-21 17:47:19 +000059 EXPECT_EQ(parser.mime_fields[0].fields.at("Content-Disposition"),
Ed Tanousaf4edf62020-07-21 08:46:25 -070060 "form-data; name=\"Test1\"");
Nan Zhoucc606192022-06-21 17:47:19 +000061 EXPECT_EQ(parser.mime_fields[0].content,
Ed Tanousaf4edf62020-07-21 08:46:25 -070062 "111111111111111111111111112222222222222222222222222222222");
63
Nan Zhoucc606192022-06-21 17:47:19 +000064 EXPECT_EQ(parser.mime_fields[1].fields.at("Content-Disposition"),
Ed Tanousaf4edf62020-07-21 08:46:25 -070065 "form-data; name=\"Test2\"");
Nan Zhoucc606192022-06-21 17:47:19 +000066 EXPECT_EQ(parser.mime_fields[1].content,
Ed Tanousaf4edf62020-07-21 08:46:25 -070067 "{\r\n-----------------------------d74496d66958873e123456");
Nan Zhoucc606192022-06-21 17:47:19 +000068 EXPECT_EQ(parser.mime_fields[2].fields.at("Content-Disposition"),
Ed Tanousaf4edf62020-07-21 08:46:25 -070069 "form-data; name=\"Test3\"");
Nan Zhoucc606192022-06-21 17:47:19 +000070 EXPECT_EQ(parser.mime_fields[2].content, "{\r\n--------d74496d6695887}");
Ed Tanousaf4edf62020-07-21 08:46:25 -070071}
72
73TEST_F(MultipartTest, TestBadMultipartParser1)
74{
75 req.set("Content-Type",
76 "multipart/form-data; "
77 "boundary=---------------------------d74496d66958873e");
78
79 req.body() = "-----------------------------d74496d66958873e\r\n"
80 "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
81 "1234567890\r\n"
82 "-----------------------------d74496d66958873e\r-\r\n";
83
84 crow::Request reqIn(req, ec);
85 ParserError rc = parser.parse(reqIn);
86 ASSERT_EQ(rc, ParserError::PARSER_SUCCESS);
87
Nan Zhoucc606192022-06-21 17:47:19 +000088 EXPECT_EQ(parser.boundary,
Ed Tanousaf4edf62020-07-21 08:46:25 -070089 "\r\n-----------------------------d74496d66958873e");
Nan Zhoucc606192022-06-21 17:47:19 +000090 EXPECT_EQ(parser.mime_fields.size(), 1);
Ed Tanousaf4edf62020-07-21 08:46:25 -070091}
92
93TEST_F(MultipartTest, TestBadMultipartParser2)
94{
95 req.set("Content-Type",
96 "multipart/form-data; "
97 "boundary=---------------------------d74496d66958873e");
98
99 req.body() = "-----------------------------d74496d66958873e\r\n"
100 "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
101 "abcd\r\n"
102 "-----------------------------d74496d66958873e-\r\n";
103
104 crow::Request reqIn(req, ec);
105 ParserError rc = parser.parse(reqIn);
106 ASSERT_EQ(rc, ParserError::PARSER_SUCCESS);
107
Nan Zhoucc606192022-06-21 17:47:19 +0000108 EXPECT_EQ(parser.boundary,
Ed Tanousaf4edf62020-07-21 08:46:25 -0700109 "\r\n-----------------------------d74496d66958873e");
Nan Zhoucc606192022-06-21 17:47:19 +0000110 EXPECT_EQ(parser.mime_fields.size(), 1);
Ed Tanousaf4edf62020-07-21 08:46:25 -0700111}
112
113TEST_F(MultipartTest, TestErrorBoundaryFormat)
114{
115 req.set("Content-Type",
116 "multipart/form-data; "
117 "boundary+=-----------------------------d74496d66958873e");
118
119 req.body() = "-----------------------------d74496d66958873e\r\n"
120 "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
121 "{\"Key1\": 11223333333333333333333333333333333333333333}\r\n"
122 "-----------------------------d74496d66958873e\r\n"
123 "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
124 "123456\r\n"
125 "-----------------------------d74496d66958873e--\r\n";
126
127 crow::Request reqIn(req, ec);
Nan Zhoucc606192022-06-21 17:47:19 +0000128 EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_FORMAT);
Ed Tanousaf4edf62020-07-21 08:46:25 -0700129}
130
131TEST_F(MultipartTest, TestErrorBoundaryCR)
132{
133 req.set("Content-Type",
134 "multipart/form-data; "
135 "boundary=---------------------------d74496d66958873e");
136
137 req.body() = "-----------------------------d74496d66958873e"
138 "Content-Disposition: form-data; name=\"Test1\"\r\n\r"
139 "{\"Key1\": 112233}\r\n"
140 "-----------------------------d74496d66958873e\r\n"
141 "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
142 "123456\r\n"
143 "-----------------------------d74496d66958873e--\r\n";
144
145 crow::Request reqIn(req, ec);
Nan Zhoucc606192022-06-21 17:47:19 +0000146 EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_CR);
Ed Tanousaf4edf62020-07-21 08:46:25 -0700147}
148
149TEST_F(MultipartTest, TestErrorBoundaryLF)
150{
151 req.set("Content-Type",
152 "multipart/form-data; "
153 "boundary=---------------------------d74496d66958873e");
154
155 req.body() = "-----------------------------d74496d66958873e\r"
156 "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
157 "{\"Key1\": 112233}\r\n"
158 "-----------------------------d74496d66958873e\r\n"
159 "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
160 "123456\r\n"
161 "-----------------------------d74496d66958873e--\r\n";
162
163 crow::Request reqIn(req, ec);
Nan Zhoucc606192022-06-21 17:47:19 +0000164 EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_LF);
Ed Tanousaf4edf62020-07-21 08:46:25 -0700165}
166
167TEST_F(MultipartTest, TestErrorBoundaryData)
168{
169 req.set("Content-Type",
170 "multipart/form-data; "
171 "boundary=---------------------------d7449sd6d66958873e");
172
173 req.body() = "-----------------------------d74496d66958873e\r\n"
174 "Content-Disposition: form-data; name=\"Test1\"\r\n\r\n"
175 "{\"Key1\": 112233}\r\n"
176 "-----------------------------d74496d66958873e\r\n"
177 "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
178 "123456\r\n"
179 "-----------------------------d74496d66958873e--\r\n";
180
181 crow::Request reqIn(req, ec);
Nan Zhoucc606192022-06-21 17:47:19 +0000182 EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_BOUNDARY_DATA);
Ed Tanousaf4edf62020-07-21 08:46:25 -0700183}
184
185TEST_F(MultipartTest, TestErrorEmptyHeader)
186{
187 req.set("Content-Type",
188 "multipart/form-data; "
189 "boundary=---------------------------d74496d66958873e");
190
191 req.body() = "-----------------------------d74496d66958873e\r\n"
192 ": form-data; name=\"Test1\"\r\n"
193 "{\"Key1\": 112233}\r\n"
194 "-----------------------------d74496d66958873e\r\n"
195 "Content-Disposition: form-data; name=\"Test2\"\r\n"
196 "123456\r\n"
197 "-----------------------------d74496d66958873e--\r\n";
198
199 crow::Request reqIn(req, ec);
Nan Zhoucc606192022-06-21 17:47:19 +0000200 EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_EMPTY_HEADER);
Ed Tanousaf4edf62020-07-21 08:46:25 -0700201}
202
203TEST_F(MultipartTest, TestErrorHeaderName)
204{
205 req.set("Content-Type",
206 "multipart/form-data; "
207 "boundary=---------------------------d74496d66958873e");
208
209 req.body() = "-----------------------------d74496d66958873e\r\n"
210 "Content-!!Disposition: form-data; name=\"Test1\"\r\n"
211 "{\"Key1\": 112233}\r\n"
212 "-----------------------------d74496d66958873e\r\n"
213 "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
214 "123456\r\n"
215 "-----------------------------d74496d66958873e--\r\n";
216
217 crow::Request reqIn(req, ec);
Nan Zhoucc606192022-06-21 17:47:19 +0000218 EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_HEADER_NAME);
Ed Tanousaf4edf62020-07-21 08:46:25 -0700219}
220
221TEST_F(MultipartTest, TestErrorHeaderValue)
222{
223 req.set("Content-Type",
224 "multipart/form-data; "
225 "boundary=---------------------------d74496d66958873e");
226
227 req.body() = "-----------------------------d74496d66958873e\r\n"
228 "Content-Disposition: form-data; name=\"Test1\"\r"
229 "{\"Key1\": 112233}\r\n"
230 "-----------------------------d74496d66958873e\r\n"
231 "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
232 "123456\r\n"
233 "-----------------------------d74496d66958873e--\r\n";
234
235 crow::Request reqIn(req, ec);
Nan Zhoucc606192022-06-21 17:47:19 +0000236 EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_HEADER_VALUE);
Ed Tanousaf4edf62020-07-21 08:46:25 -0700237}
238
239TEST_F(MultipartTest, TestErrorHeaderEnding)
240{
241 req.set("Content-Type",
242 "multipart/form-data; "
243 "boundary=---------------------------d74496d66958873e");
244
245 req.body() = "-----------------------------d74496d66958873e\r\n"
246 "Content-Disposition: form-data; name=\"Test1\"\r\n\r"
247 "{\"Key1\": 112233}\r\n"
248 "-----------------------------d74496d66958873e\r\n"
249 "Content-Disposition: form-data; name=\"Test2\"\r\n\r\n"
250 "123456\r\n"
251 "-----------------------------d74496d66958873e--\r\n";
252
253 crow::Request reqIn(req, ec);
Nan Zhoucc606192022-06-21 17:47:19 +0000254 EXPECT_EQ(parser.parse(reqIn), ParserError::ERROR_HEADER_ENDING);
Ed Tanousaf4edf62020-07-21 08:46:25 -0700255}
Nan Zhoue52d1562022-06-21 17:47:15 +0000256} // namespace