Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: third_party/WebKit/Source/modules/fetch/MultipartParserTest.cpp

Issue 2292763002: [Fetch API] Implement Request.formData and Response.formData. (Closed)
Patch Set: Parse functions etc Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "modules/fetch/MultipartParser.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 #include <algorithm>
10
11 namespace blink {
12
13 namespace {
14
15 class MockClient final : public GarbageCollectedFinalized<MockClient>, public Mu ltipartParser::Client {
16 USING_GARBAGE_COLLECTED_MIXIN(MockClient);
17 public:
18 struct Part {
19 Part() = default;
20 explicit Part(const ResourceResponse& response) : response(response), da taFullyReceived(false) {}
21 ResourceResponse response;
22 Vector<char> data;
23 bool dataFullyReceived;
24 };
25 void partHeaderFieldsInMultipartReceived(const ResourceResponse& response) o verride
26 {
27 m_parts.append(response);
28 }
29 void partDataInMultipartReceived(const char* bytes, size_t size) override
30 {
31 m_parts.last().data.append(bytes, size);
32 }
33 void partDataInMultipartFullyReceived() override
34 {
35 m_parts.last().dataFullyReceived = true;
36 }
37 size_t numberOfParts() const
38 {
39 return m_parts.size();
40 }
41 const Part& part(size_t partIndex) const
42 {
43 EXPECT_LT(partIndex, numberOfParts());
44 return partIndex < numberOfParts() ? m_parts[partIndex] : m_emptyPart;
45 }
46 private:
47 Part m_emptyPart;
48 Vector<Part> m_parts;
49 };
50
51 const char* kBytes =
yhirano 2016/09/21 09:02:58 [optional] How about using |constexpr char kBytes[
e_hakkinen 2016/09/22 22:27:16 Done.
52 "preamble"
53 "\r\n--boundary\r\n\r\n"
54 "\r\n--boundary\r\ncontent-type: application/xhtml+xml\r\n\r\n1"
55 "\r\n--boundary\t\r\ncontent-type: text/html\r\n\r\n2\r\n--\r\n--bound--\r\n --\r\n2\r\n"
56 "\r\n--boundary \r\ncontent-type: text/plain\r\n\r\n333"
57 "\r\n--boundary--\t \r\n"
58 "epilogue";
59
60 TEST(MultipartParserTest, AppendDataInChunks)
61 {
62 const size_t sizes[] = {1u, 2u, strlen(kBytes)};
63
64 Vector<char> boundary;
65 boundary.append("boundary", 8u);
66 for (size_t size : sizes) {
67 MockClient* client = new MockClient;
68 MultipartParser* parser = new MultipartParser(boundary, client);
69
70 for (size_t i = 0u; kBytes[i]; i += size)
yhirano 2016/09/21 09:02:58 |i| can be greater than or equal to sizeof(kBytes)
e_hakkinen 2016/09/22 22:27:17 Done.
71 EXPECT_TRUE(parser->appendData(kBytes + i, std::min(size, strlen(kBy tes + i))));
72 EXPECT_TRUE(parser->finish()) << " size=" << size;
73 EXPECT_EQ(4u, client->numberOfParts()) << " size=" << size;
74 EXPECT_EQ(0u, client->part(0).data.size());
75 EXPECT_TRUE(client->part(0).dataFullyReceived);
76 EXPECT_EQ(String("1"), client->part(1).data);
yhirano 2016/09/21 09:02:58 Can you verify the content type for each part?
e_hakkinen 2016/09/22 22:27:16 Sure.
77 EXPECT_TRUE(client->part(1).dataFullyReceived);
78 EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2\r\n"), client->part(2) .data);
79 EXPECT_TRUE(client->part(2).dataFullyReceived);
80 EXPECT_EQ(String("333"), client->part(3).data);
81 EXPECT_TRUE(client->part(3).dataFullyReceived);
82 }
83 }
84
85 TEST(MultipartParserTest, Epilogue)
86 {
87 const size_t ends[] = {
yhirano 2016/09/21 09:02:58 constexpr
e_hakkinen 2016/09/22 22:27:16 Done.
88 0u, // Non-empty epilogue in the end.
89 8u, // Empty epilogue in the end.
90 9u, // Partial CRLF after close delimiter in the end.
91 10u, // No CRLF after close delimiter in the end.
92 12u, // No transport padding nor CRLF after close delimiter in the end.
93 13u, // Partial close delimiter in the end.
94 14u, // No close delimiter but a delimiter in the end.
95 15u // Partial delimiter in the end.
96 };
97
98 Vector<char> boundary;
99 boundary.append("boundary", 8u);
100 for (size_t end : ends) {
101 MockClient* client = new MockClient;
102 MultipartParser* parser = new MultipartParser(boundary, client);
103
104 EXPECT_TRUE(parser->appendData(kBytes, strlen(kBytes) - end));
105 EXPECT_EQ(end <= 12u, parser->finish()) << " end=" << end;
106 EXPECT_EQ(4u, client->numberOfParts()) << " end=" << end;
107 EXPECT_EQ(0u, client->part(0).data.size());
108 EXPECT_TRUE(client->part(0).dataFullyReceived);
109 EXPECT_EQ(String("1"), client->part(1).data);
110 EXPECT_TRUE(client->part(1).dataFullyReceived);
111 EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2\r\n"), client->part(2) .data);
112 EXPECT_TRUE(client->part(2).dataFullyReceived);
113 switch (end) {
114 case 14u:
115 EXPECT_EQ(String("333"), client->part(3).data);
116 EXPECT_TRUE(client->part(3).dataFullyReceived);
117 break;
118 case 15u:
119 EXPECT_EQ(String("333\r\n--boundar"), client->part(3).data);
120 EXPECT_FALSE(client->part(3).dataFullyReceived);
121 break;
122 default:
123 EXPECT_EQ(String("333"), client->part(3).data);
yhirano 2016/09/21 09:02:58 Are this case and the |14| case same?
e_hakkinen 2016/09/22 22:27:16 Yep, they are now. When I tested parser->finish()
124 EXPECT_TRUE(client->part(3).dataFullyReceived);
125 }
126 }
127 }
128
129 TEST(MultipartParserTest, NoEndBoundary)
130 {
131 const char* bytes = "--boundary\r\ncontent-type: application/xhtml+xml\r\n\r \n1";
yhirano 2016/09/21 09:02:58 How about using constexpr char[]?
e_hakkinen 2016/09/22 22:27:16 Done.
132
133 Vector<char> boundary;
134 boundary.append("boundary", 8u);
135 MockClient* client = new MockClient;
136 MultipartParser* parser = new MultipartParser(boundary, client);
137
138 EXPECT_TRUE(parser->appendData(bytes, strlen(bytes)));
139 EXPECT_FALSE(parser->finish()); // No close delimiter.
140 EXPECT_EQ(1u, client->numberOfParts());
141 EXPECT_EQ(String("1"), client->part(0).data);
142 EXPECT_FALSE(client->part(0).dataFullyReceived);
143 }
144
145 TEST(MultipartParserTest, NoStartBoundary)
146 {
147 const char* bytes = "content-type: application/xhtml+xml\r\n\r\n1\r\n--bound ary--\r\n";
148
149 Vector<char> boundary;
150 boundary.append("boundary", 8u);
151 MockClient* client = new MockClient;
152 MultipartParser* parser = new MultipartParser(boundary, client);
153
154 EXPECT_FALSE(parser->appendData(bytes, strlen(bytes))); // Close delimiter b efore delimiter.
155 EXPECT_FALSE(parser->finish()); // No parts.
156 EXPECT_EQ(0u, client->numberOfParts());
157 }
158
159 TEST(MultipartParserTest, NoStartNorEndBoundary)
160 {
161 const char* bytes = "content-type: application/xhtml+xml\r\n\r\n1";
yhirano 2016/09/21 09:02:58 ditto
e_hakkinen 2016/09/22 22:27:17 Done.
162
163 Vector<char> boundary;
164 boundary.append("boundary", 8u);
165 MockClient* client = new MockClient;
166 MultipartParser* parser = new MultipartParser(boundary, client);
167
168 EXPECT_TRUE(parser->appendData(bytes, strlen(bytes))); // Valid preamble.
169 EXPECT_FALSE(parser->finish()); // No parts.
170 EXPECT_EQ(0u, client->numberOfParts());
171 }
172
173 const size_t kStarts[] = {
yhirano 2016/09/21 09:02:58 constexpr
e_hakkinen 2016/09/22 22:27:16 Done.
174 0u, // Non-empty preamble in the beginning.
175 8u, // Empty preamble in the beginning.
176 9u, // Truncated delimiter in the beginning.
177 10u, // No preamble in the beginning.
178 11u // Truncated dash boundary in the beginning.
179 };
180
181 TEST(MultipartParserTest, Preamble)
182 {
183 Vector<char> boundary;
184 boundary.append("boundary", 8u);
185 for (size_t start : kStarts) {
186 MockClient* client = new MockClient;
187 MultipartParser* parser = new MultipartParser(boundary, client);
188
189 EXPECT_TRUE(parser->appendData(kBytes + start, strlen(kBytes + start)));
190 EXPECT_TRUE(parser->finish());
191 switch (start) {
192 case 9u:
193 case 11u:
194 EXPECT_EQ(3u, client->numberOfParts()) << " start=" << start;
195 EXPECT_EQ(String("1"), client->part(0).data);
196 EXPECT_TRUE(client->part(0).dataFullyReceived);
197 EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2\r\n"), client->par t(1).data);
198 EXPECT_TRUE(client->part(1).dataFullyReceived);
199 EXPECT_EQ(String("333"), client->part(2).data);
200 EXPECT_TRUE(client->part(2).dataFullyReceived);
201 break;
202 default:
203 EXPECT_EQ(4u, client->numberOfParts()) << " start=" << start;
204 EXPECT_EQ(0u, client->part(0).data.size());
205 EXPECT_TRUE(client->part(0).dataFullyReceived);
206 EXPECT_EQ(String("1"), client->part(1).data);
207 EXPECT_TRUE(client->part(1).dataFullyReceived);
208 EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2\r\n"), client->par t(2).data);
209 EXPECT_TRUE(client->part(2).dataFullyReceived);
210 EXPECT_EQ(String("333"), client->part(3).data);
211 EXPECT_TRUE(client->part(3).dataFullyReceived);
212 }
213 }
214 }
215
216 TEST(MultipartParserTest, PreambleWithMalformedBoundary)
217 {
218 Vector<char> boundary;
219 boundary.append("--boundary", 10u);
220 for (size_t start : kStarts) {
221 MockClient* client = new MockClient;
222 MultipartParser* parser = new MultipartParser(boundary, client);
223
224 EXPECT_TRUE(parser->appendData(kBytes + start, strlen(kBytes + start))); // Valid preamble.
225 EXPECT_FALSE(parser->finish()); // No parts.
226 EXPECT_EQ(0u, client->numberOfParts());
227 }
228 }
229
230 } // namespace
231
232 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698