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

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: Handle partial delimiter prefixes correctly and really test them 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 =
52 "preamble"
53 "\r\n--boundary\r\ncontent-type: application/xhtml+xml\r\n\r\n1"
54 "\r\n--boundary\t\r\ncontent-type: text/html\r\n\r\n2\r\n--\r\n--bound--\r\n --\r\n2"
55 "\r\n--boundary \r\ncontent-type: text/plain\r\n\r\n333"
56 "\r\n--boundary--\t \r\n"
57 "epilogue";
58
59 TEST(MultipartParserTest, AppendDataInChunks)
60 {
61 const size_t sizes[] = {1u, 2u, strlen(kBytes)};
62
63 Vector<char> boundary;
64 boundary.append("boundary", 8u);
65 for (size_t size : sizes) {
66 MockClient* client = new MockClient;
67 MultipartParser* parser = new MultipartParser(boundary, client);
68
69 for (size_t i = 0u; kBytes[i]; i += size)
70 EXPECT_TRUE(parser->appendData(kBytes + i, std::min(size, strlen(kBy tes + i))));
71 EXPECT_TRUE(parser->finish()) << " size=" << size;
72 EXPECT_EQ(3u, client->numberOfParts()) << " size=" << size;
73 EXPECT_EQ(String("1"), client->part(0).data);
74 EXPECT_TRUE(client->part(0).dataFullyReceived);
75 EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2"), client->part(1).dat a);
76 EXPECT_TRUE(client->part(1).dataFullyReceived);
77 EXPECT_EQ(String("333"), client->part(2).data);
78 EXPECT_TRUE(client->part(2).dataFullyReceived);
79 }
80 }
81
82 TEST(MultipartParserTest, Epilogue)
83 {
84 const size_t ends[] = {
85 0u, // Non-empty epilogue in the end.
86 8u, // Empty epilogue in the end.
87 9u, // Partial CRLF after close delimiter in the end.
88 10u, // No CRLF after close delimiter in the end.
89 12u, // No transport padding nor CRLF after close delimiter in the end.
90 13u, // Partial close delimiter in the end.
91 14u, // No close delimiter but a delimiter in the end.
92 15u // Partial delimiter in the end.
93 };
94
95 Vector<char> boundary;
96 boundary.append("boundary", 8u);
97 for (size_t end : ends) {
98 MockClient* client = new MockClient;
99 MultipartParser* parser = new MultipartParser(boundary, client);
100
101 EXPECT_TRUE(parser->appendData(kBytes, strlen(kBytes) - end));
102 EXPECT_EQ(end <= 12u, parser->finish()) << " end=" << end;
103 EXPECT_EQ(3u, client->numberOfParts()) << " end=" << end;
104 EXPECT_EQ(String("1"), client->part(0).data);
105 EXPECT_TRUE(client->part(0).dataFullyReceived);
106 EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2"), client->part(1).dat a);
107 EXPECT_TRUE(client->part(1).dataFullyReceived);
108 switch (end) {
109 case 14u:
110 EXPECT_EQ(String("333"), client->part(2).data);
111 EXPECT_TRUE(client->part(2).dataFullyReceived);
112 break;
113 case 15u:
114 EXPECT_EQ(String("333\r\n--boundar"), client->part(2).data);
115 EXPECT_FALSE(client->part(2).dataFullyReceived);
116 break;
117 default:
118 EXPECT_EQ(String("333"), client->part(2).data);
119 EXPECT_TRUE(client->part(2).dataFullyReceived);
120 }
121 }
122 }
123
124 TEST(MultipartParserTest, NoEndBoundary)
125 {
126 const char* bytes = "--boundary\r\ncontent-type: application/xhtml+xml\r\n\r \n1";
127
128 Vector<char> boundary;
129 boundary.append("boundary", 8u);
130 MockClient* client = new MockClient;
131 MultipartParser* parser = new MultipartParser(boundary, client);
132
133 EXPECT_TRUE(parser->appendData(bytes, strlen(bytes)));
134 EXPECT_FALSE(parser->finish()); // No close delimiter.
135 EXPECT_EQ(1u, client->numberOfParts());
136 EXPECT_EQ(String("1"), client->part(0).data);
137 EXPECT_FALSE(client->part(0).dataFullyReceived);
138 }
139
140 TEST(MultipartParserTest, NoStartBoundary)
141 {
142 const char* bytes = "content-type: application/xhtml+xml\r\n\r\n1\r\n--bound ary--\r\n";
143
144 Vector<char> boundary;
145 boundary.append("boundary", 8u);
146 MockClient* client = new MockClient;
147 MultipartParser* parser = new MultipartParser(boundary, client);
148
149 EXPECT_FALSE(parser->appendData(bytes, strlen(bytes))); // Close delimiter b efore delimiter.
150 EXPECT_FALSE(parser->finish()); // No parts.
151 EXPECT_EQ(0u, client->numberOfParts());
152 }
153
154 TEST(MultipartParserTest, NoStartNorEndBoundary)
155 {
156 const char* bytes = "content-type: application/xhtml+xml\r\n\r\n1";
157
158 Vector<char> boundary;
159 boundary.append("boundary", 8u);
160 MockClient* client = new MockClient;
161 MultipartParser* parser = new MultipartParser(boundary, client);
162
163 EXPECT_TRUE(parser->appendData(bytes, strlen(bytes))); // Valid preamble.
164 EXPECT_FALSE(parser->finish()); // No parts.
165 EXPECT_EQ(0u, client->numberOfParts());
166 }
167
168 const size_t kStarts[] = {
169 0u, // Non-empty preamble in the beginning.
170 8u, // Empty preamble in the beginning.
171 9u, // Truncated delimiter in the beginning.
172 10u, // No preamble in the beginning.
173 11u // Truncated dash delimiter in the beginning.
174 };
175
176 void runPreambleTests(const char* boundaryString)
177 {
178 Vector<char> boundary;
179 boundary.append(boundaryString, strlen(boundaryString));
180 for (size_t start : kStarts) {
181 MockClient* client = new MockClient;
182 MultipartParser* parser = new MultipartParser(boundary, client);
183
184 EXPECT_TRUE(parser->appendData(kBytes + start, strlen(kBytes + start)));
185 EXPECT_TRUE(parser->finish());
186 switch (start) {
187 case 9u:
188 case 11u:
189 EXPECT_EQ(2u, client->numberOfParts()) << " start=" << start;
190 EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2"), client->part(0) .data);
191 EXPECT_TRUE(client->part(0).dataFullyReceived);
192 EXPECT_EQ(String("333"), client->part(1).data);
193 EXPECT_TRUE(client->part(1).dataFullyReceived);
194 break;
195 default:
196 EXPECT_EQ(3u, client->numberOfParts()) << " start=" << start;
197 EXPECT_EQ(String("1"), client->part(0).data);
198 EXPECT_TRUE(client->part(0).dataFullyReceived);
199 EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2"), client->part(1) .data);
200 EXPECT_TRUE(client->part(1).dataFullyReceived);
201 EXPECT_EQ(String("333"), client->part(2).data);
202 EXPECT_TRUE(client->part(2).dataFullyReceived);
203 }
204 }
205 }
206
207 TEST(MultipartParserTest, Preamble)
208 {
209 runPreambleTests("boundary");
210 }
211
212 TEST(MultipartParserTest, PreambleWithMalformedBoundary)
213 {
214 runPreambleTests("--boundary");
215 }
216
217 TEST(MultipartParserTest, PreambleWithVeryMalformedBoundary)
218 {
219 Vector<char> boundary;
220 boundary.append("----boundary", 12u);
221 for (size_t start : kStarts) {
222 MockClient* client = new MockClient;
223 MultipartParser* parser = new MultipartParser(boundary, client);
224
225 EXPECT_TRUE(parser->appendData(kBytes + start, strlen(kBytes + start))); // Valid preamble.
226 EXPECT_FALSE(parser->finish()); // No parts.
227 EXPECT_EQ(0u, client->numberOfParts());
228 }
229 }
230
231 } // namespace
232
233 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698