OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 "config.h" | |
6 #include "modules/fetch/FetchFormDataConsumerHandle.h" | |
7 | |
8 #include "core/dom/DOMTypedArray.h" | |
9 #include "core/html/DOMFormData.h" | |
10 #include "core/html/FormDataList.h" | |
11 #include "core/loader/ThreadableLoader.h" | |
12 #include "core/loader/ThreadableLoaderClient.h" | |
13 #include "core/testing/DummyPageHolder.h" | |
14 #include "modules/fetch/DataConsumerHandleTestUtil.h" | |
15 #include "platform/network/ResourceResponse.h" | |
16 #include "platform/testing/UnitTestHelpers.h" | |
17 #include "platform/weborigin/KURL.h" | |
18 #include "wtf/PassRefPtr.h" | |
19 #include "wtf/RefPtr.h" | |
20 #include "wtf/Vector.h" | |
21 #include "wtf/text/TextEncoding.h" | |
22 #include "wtf/text/WTFString.h" | |
23 | |
24 #include <gtest/gtest.h> | |
25 #include <string.h> | |
26 | |
27 namespace blink { | |
28 namespace { | |
29 | |
30 using Result = WebDataConsumerHandle::Result; | |
31 const Result kOk = WebDataConsumerHandle::Ok; | |
32 const Result kDone = WebDataConsumerHandle::Done; | |
33 const Result kShouldWait = WebDataConsumerHandle::ShouldWait; | |
34 const WebDataConsumerHandle::Flags kNone = WebDataConsumerHandle::FlagNone; | |
35 using HandleReader = DataConsumerHandleTestUtil::HandleReader; | |
36 using HandleTwoPhaseReader = DataConsumerHandleTestUtil::HandleTwoPhaseReader; | |
37 using HandleReadResult = DataConsumerHandleTestUtil::HandleReadResult; | |
38 template <typename T> | |
39 using HandleReaderRunner = DataConsumerHandleTestUtil::HandleReaderRunner<T>; | |
40 using ReplayingHandle = DataConsumerHandleTestUtil::ReplayingHandle; | |
41 using Command = DataConsumerHandleTestUtil::Command; | |
42 | |
43 String toString(const Vector<char>& data) | |
44 { | |
45 return String(data.data(), data.size()); | |
46 } | |
47 | |
48 class NoopLoader final : public ThreadableLoader { | |
49 public: | |
50 static PassRefPtr<ThreadableLoader> create() { return adoptRef(new NoopLoade r); } | |
51 void overrideTimeout(unsigned long) override {} | |
52 void cancel() override {} | |
53 }; | |
54 | |
55 class LoaderFactory : public FetchBlobDataConsumerHandle::LoaderFactory { | |
56 public: | |
57 explicit LoaderFactory(PassOwnPtr<WebDataConsumerHandle> handle) : m_handle( handle) {} | |
58 PassRefPtr<ThreadableLoader> create(ExecutionContext&, ThreadableLoaderClien t* client, const ResourceRequest&, const ThreadableLoaderOptions&, const Resourc eLoaderOptions&) override | |
59 { | |
60 RefPtr<ThreadableLoader> loader = NoopLoader::create(); | |
61 client->didReceiveResponse(0, ResourceResponse(), m_handle.release()); | |
62 return loader.release(); | |
63 } | |
64 | |
65 private: | |
66 OwnPtr<WebDataConsumerHandle> m_handle; | |
67 }; | |
68 | |
69 class FetchFormDataConsumerHandleTest : public ::testing::Test { | |
70 public: | |
71 FetchFormDataConsumerHandleTest() : m_page(DummyPageHolder::create(IntSize(1 , 1))) {} | |
72 | |
73 protected: | |
74 Document* document() { return &m_page->document(); } | |
75 | |
76 OwnPtr<DummyPageHolder> m_page; | |
77 }; | |
78 | |
79 PassRefPtr<FormData> complexFormData() | |
80 { | |
81 RefPtr<FormData> data = FormData::create(); | |
82 | |
83 data->appendData("foo", 3); | |
84 data->appendFileRange("/foo/bar/baz", 3, 4, 5); | |
85 data->appendFileSystemURLRange(KURL(KURL(), "file:///foo/bar/baz"), 6, 7, 8) ; | |
86 OwnPtr<BlobData> blobData = BlobData::create(); | |
87 blobData->appendText("hello", false); | |
88 auto size = blobData->length(); | |
89 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(blobData.rele ase(), size); | |
90 data->appendBlob(blobDataHandle->uuid(), blobDataHandle); | |
91 Vector<char> boundary; | |
92 boundary.append("\0", 1); | |
93 data->setBoundary(boundary); | |
94 return data.release(); | |
95 } | |
96 | |
97 void verifyFormData(FormData* data) | |
98 { | |
99 const auto& elements = data->elements(); | |
100 if (4 != elements.size()) { | |
101 FAIL() << "data->elements().size() should be 4, but is " << data->elemen ts().size() << "."; | |
102 } | |
103 EXPECT_EQ(FormDataElement::data, elements[0].m_type); | |
104 EXPECT_EQ("foo", String(elements[0].m_data.data(), elements[0].m_data.size() )); | |
105 | |
106 EXPECT_EQ(FormDataElement::encodedFile, elements[1].m_type); | |
107 EXPECT_EQ("/foo/bar/baz", elements[1].m_filename); | |
108 EXPECT_EQ(3, elements[1].m_fileStart); | |
109 EXPECT_EQ(4, elements[1].m_fileLength); | |
110 EXPECT_EQ(5, elements[1].m_expectedFileModificationTime); | |
111 | |
112 EXPECT_EQ(FormDataElement::encodedFileSystemURL, elements[2].m_type); | |
113 EXPECT_EQ(KURL(KURL(), "file:///foo/bar/baz"), elements[2].m_fileSystemURL); | |
114 EXPECT_EQ(6, elements[2].m_fileStart); | |
115 EXPECT_EQ(7, elements[2].m_fileLength); | |
116 EXPECT_EQ(8, elements[2].m_expectedFileModificationTime); | |
117 | |
118 EXPECT_EQ(FormDataElement::encodedBlob, elements[3].m_type); | |
119 if (!elements[3].m_optionalBlobDataHandle) { | |
120 FAIL() << "optional BlobDataHandle must be set."; | |
121 } | |
122 EXPECT_EQ(elements[3].m_blobUUID, elements[3].m_optionalBlobDataHandle->uuid ()); | |
123 EXPECT_EQ(5u, elements[3].m_optionalBlobDataHandle->size()); | |
124 } | |
125 | |
126 TEST_F(FetchFormDataConsumerHandleTest, ReadFromString) | |
127 { | |
128 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (String("hello, world")); | |
129 HandleReaderRunner<HandleReader> runner(handle.release()); | |
130 OwnPtr<HandleReadResult> r = runner.wait(); | |
131 EXPECT_EQ(kDone, r->result()); | |
132 EXPECT_EQ("hello, world", toString(r->data())); | |
133 } | |
134 | |
135 TEST_F(FetchFormDataConsumerHandleTest, TwoPhaseReadFromString) | |
136 { | |
137 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (String("hello, world")); | |
138 HandleReaderRunner<HandleTwoPhaseReader> runner(handle.release()); | |
139 OwnPtr<HandleReadResult> r = runner.wait(); | |
140 EXPECT_EQ(kDone, r->result()); | |
141 EXPECT_EQ("hello, world", toString(r->data())); | |
142 } | |
143 | |
144 TEST_F(FetchFormDataConsumerHandleTest, ReadFromStringNonLatain) | |
145 { | |
146 UChar cs[] = {0x3042, 0}; | |
147 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (String(cs)); | |
148 HandleReaderRunner<HandleReader> runner(handle.release()); | |
149 OwnPtr<HandleReadResult> r = runner.wait(); | |
150 EXPECT_EQ(kDone, r->result()); | |
151 EXPECT_EQ("\xe3\x81\x82", toString(r->data())); | |
152 } | |
153 | |
154 TEST_F(FetchFormDataConsumerHandleTest, ReadFromArrayBuffer) | |
155 { | |
156 const unsigned char data[] = { 0x21, 0xfe, 0x00, 0x00, 0xff, 0xa3, 0x42, 0x3 0, 0x42, 0x99, 0x88 }; | |
157 RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(data, WTF_ARRAY_LENGT H(data)); | |
158 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (buffer); | |
159 HandleReaderRunner<HandleReader> runner(handle.release()); | |
160 OwnPtr<HandleReadResult> r = runner.wait(); | |
161 EXPECT_EQ(kDone, r->result()); | |
162 Vector<char> expected; | |
163 expected.append(data, WTF_ARRAY_LENGTH(data)); | |
164 EXPECT_EQ(expected, r->data()); | |
165 } | |
166 | |
167 TEST_F(FetchFormDataConsumerHandleTest, ReadFromArrayBufferView) | |
168 { | |
169 const unsigned char data[] = { 0x21, 0xfe, 0x00, 0x00, 0xff, 0xa3, 0x42, 0x3 0, 0x42, 0x99, 0x88 }; | |
170 const size_t offset = 1, size = 4; | |
171 RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(data, WTF_ARRAY_LENGT H(data)); | |
172 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (DOMUint8Array::create(buffer, offset, size)); | |
173 HandleReaderRunner<HandleReader> runner(handle.release()); | |
174 OwnPtr<HandleReadResult> r = runner.wait(); | |
175 EXPECT_EQ(kDone, r->result()); | |
176 Vector<char> expected; | |
177 expected.append(data + offset, size); | |
178 EXPECT_EQ(expected, r->data()); | |
179 } | |
180 | |
181 TEST_F(FetchFormDataConsumerHandleTest, ReadFromSimplFormData) | |
182 { | |
183 RefPtr<FormData> data = FormData::create(); | |
184 data->appendData("foo", 3); | |
185 data->appendData("hoge", 4); | |
186 | |
187 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (document(), data); | |
188 HandleReaderRunner<HandleReader> runner(handle.release()); | |
189 testing::runPendingTasks(); | |
190 OwnPtr<HandleReadResult> r = runner.wait(); | |
191 EXPECT_EQ(kDone, r->result()); | |
192 EXPECT_EQ("foohoge", toString(r->data())); | |
193 } | |
194 | |
195 TEST_F(FetchFormDataConsumerHandleTest, ReadFromComplexFormData) | |
196 { | |
197 RefPtr<FormData> data = complexFormData(); | |
198 OwnPtr<ReplayingHandle> src = ReplayingHandle::create(); | |
199 src->add(Command(Command::Data, "bar")); | |
200 src->add(Command(Command::Done)); | |
201 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create ForTest(document(), data, new LoaderFactory(src.release())); | |
202 char c; | |
203 size_t readSize; | |
204 EXPECT_EQ(kShouldWait, handle->obtainReader(nullptr)->read(&c, 1, kNone, &re adSize)); | |
205 | |
206 HandleReaderRunner<HandleReader> runner(handle.release()); | |
207 testing::runPendingTasks(); | |
208 OwnPtr<HandleReadResult> r = runner.wait(); | |
209 EXPECT_EQ(kDone, r->result()); | |
210 EXPECT_EQ("bar", toString(r->data())); | |
211 } | |
212 | |
213 TEST_F(FetchFormDataConsumerHandleTest, TwoPhaseReadFromComplexFormData) | |
214 { | |
215 RefPtr<FormData> data = complexFormData(); | |
216 OwnPtr<ReplayingHandle> src = ReplayingHandle::create(); | |
217 src->add(Command(Command::Data, "bar")); | |
218 src->add(Command(Command::Done)); | |
219 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create ForTest(document(), data, new LoaderFactory(src.release())); | |
220 char c; | |
221 size_t readSize; | |
222 EXPECT_EQ(kShouldWait, handle->obtainReader(nullptr)->read(&c, 1, kNone, &re adSize)); | |
223 | |
224 HandleReaderRunner<HandleTwoPhaseReader> runner(handle.release()); | |
225 testing::runPendingTasks(); | |
226 OwnPtr<HandleReadResult> r = runner.wait(); | |
227 EXPECT_EQ(kDone, r->result()); | |
228 EXPECT_EQ("bar", toString(r->data())); | |
229 } | |
230 | |
231 TEST_F(FetchFormDataConsumerHandleTest, DrainAsBlobDataHandle) | |
232 { | |
233 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (String("hello, world")); | |
234 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
235 EXPECT_FALSE(reader->drainAsBlobDataHandle(FetchDataConsumerHandle::Reader:: AllowBlobWithInvalidSize)); | |
236 } | |
237 | |
238 TEST_F(FetchFormDataConsumerHandleTest, DrainAsFormDataFromString) | |
239 { | |
240 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (String("hello, world")); | |
241 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
242 RefPtr<FormData> formData = reader->drainAsFormData(); | |
243 ASSERT_TRUE(formData); | |
244 EXPECT_TRUE(formData->hasOneRef()); | |
hiroshige
2015/08/12 06:44:48
isSafeToSendToAnotherThread() would be better.
yhirano
2015/08/12 07:43:43
Done.
| |
245 EXPECT_EQ("hello, world", formData->flattenToString()); | |
246 | |
247 const void* buffer = nullptr; | |
248 size_t size; | |
249 EXPECT_EQ(kDone, reader->read(nullptr, 0, kNone, &size)); | |
250 EXPECT_EQ(kDone, reader->beginRead(&buffer, kNone, &size)); | |
251 } | |
252 | |
253 TEST_F(FetchFormDataConsumerHandleTest, DrainAsFormDataFromArrayBuffer) | |
254 { | |
255 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (DOMArrayBuffer::create("foo", 3)); | |
256 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
257 RefPtr<FormData> formData = reader->drainAsFormData(); | |
258 ASSERT_TRUE(formData); | |
259 EXPECT_TRUE(formData->hasOneRef()); | |
hiroshige
2015/08/12 06:44:48
ditto.
yhirano
2015/08/12 07:43:43
Done.
| |
260 EXPECT_EQ("foo", formData->flattenToString()); | |
261 } | |
262 | |
263 TEST_F(FetchFormDataConsumerHandleTest, DrainAsFormDataFromSimpleFormData) | |
264 { | |
265 DOMFormData* data = DOMFormData::create(UTF8Encoding()); | |
266 data->append("name1", "value1"); | |
267 data->append("name2", "value2"); | |
268 RefPtr<FormData> inputFormData = data->createMultiPartFormData(); | |
269 | |
270 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (document(), inputFormData); | |
271 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
272 RefPtr<FormData> outputFormData = reader->drainAsFormData(); | |
273 ASSERT_TRUE(outputFormData); | |
274 EXPECT_TRUE(outputFormData->hasOneRef()); | |
hiroshige
2015/08/12 06:44:48
ditto.
yhirano
2015/08/12 07:43:43
Done.
| |
275 EXPECT_NE(outputFormData.get(), inputFormData.get()); | |
276 EXPECT_EQ(inputFormData->flattenToString(), outputFormData->flattenToString( )); | |
277 } | |
278 | |
279 TEST_F(FetchFormDataConsumerHandleTest, DrainAsFormDataFromComplexFormData) | |
280 { | |
281 RefPtr<FormData> inputFormData = complexFormData(); | |
282 | |
283 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (document(), inputFormData); | |
284 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
285 RefPtr<FormData> outputFormData = reader->drainAsFormData(); | |
286 ASSERT_TRUE(outputFormData); | |
287 EXPECT_TRUE(outputFormData->hasOneRef()); | |
hiroshige
2015/08/12 06:44:48
ditto.
yhirano
2015/08/12 07:43:43
Done.
| |
288 EXPECT_NE(outputFormData.get(), inputFormData.get()); | |
289 verifyFormData(outputFormData.get()); | |
290 } | |
291 | |
292 TEST_F(FetchFormDataConsumerHandleTest, ZeroByteReadDoesNotAffectDraining) | |
293 { | |
294 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (String("hello, world")); | |
295 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
296 size_t readSize; | |
297 EXPECT_EQ(kOk, reader->read(nullptr, 0, kNone, &readSize)); | |
298 RefPtr<FormData> formData = reader->drainAsFormData(); | |
299 ASSERT_TRUE(formData); | |
300 EXPECT_TRUE(formData->hasOneRef()); | |
hiroshige
2015/08/12 06:44:48
ditto.
yhirano
2015/08/12 07:43:42
Done.
| |
301 EXPECT_EQ("hello, world", formData->flattenToString()); | |
302 } | |
303 | |
304 TEST_F(FetchFormDataConsumerHandleTest, OneByteReadAffectsDraining) | |
305 { | |
306 char c; | |
307 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (String("hello, world")); | |
308 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
309 size_t readSize; | |
310 EXPECT_EQ(kOk, reader->read(&c, 1, kNone, &readSize)); | |
311 EXPECT_EQ(1u, readSize); | |
312 EXPECT_EQ('h', c); | |
313 EXPECT_FALSE(reader->drainAsFormData()); | |
314 } | |
315 | |
316 TEST_F(FetchFormDataConsumerHandleTest, BeginReadAffectsDraining) | |
317 { | |
318 const void* buffer = nullptr; | |
319 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create (String("hello, world")); | |
320 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
321 size_t available; | |
322 EXPECT_EQ(kOk, reader->beginRead(&buffer, kNone, &available)); | |
323 ASSERT_TRUE(buffer); | |
324 EXPECT_EQ("hello, world", String(static_cast<const char*>(buffer), available )); | |
325 EXPECT_FALSE(reader->drainAsFormData()); | |
326 reader->endRead(available); | |
327 } | |
328 | |
329 TEST_F(FetchFormDataConsumerHandleTest, ZeroByteReadDoesNotAffectDrainingForComp lexFormData) | |
330 { | |
331 OwnPtr<ReplayingHandle> src = ReplayingHandle::create(); | |
332 src->add(Command(Command::Data, "bar")); | |
333 src->add(Command(Command::Done)); | |
334 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create ForTest(document(), complexFormData(), new LoaderFactory(src.release())); | |
335 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
336 size_t readSize; | |
337 EXPECT_EQ(kShouldWait, reader->read(nullptr, 0, kNone, &readSize)); | |
338 testing::runPendingTasks(); | |
339 EXPECT_EQ(kOk, reader->read(nullptr, 0, kNone, &readSize)); | |
340 RefPtr<FormData> formData = reader->drainAsFormData(); | |
341 ASSERT_TRUE(formData); | |
342 EXPECT_TRUE(formData->hasOneRef()); | |
hiroshige
2015/08/12 06:44:48
ditto.
yhirano
2015/08/12 07:43:43
Done.
| |
343 verifyFormData(formData.get()); | |
344 } | |
345 | |
346 TEST_F(FetchFormDataConsumerHandleTest, OneByteReadAffectsDrainingForComplexForm Data) | |
347 { | |
348 OwnPtr<ReplayingHandle> src = ReplayingHandle::create(); | |
349 src->add(Command(Command::Data, "bar")); | |
350 src->add(Command(Command::Done)); | |
351 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create ForTest(document(), complexFormData(), new LoaderFactory(src.release())); | |
352 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
353 char c; | |
354 size_t readSize; | |
355 EXPECT_EQ(kShouldWait, reader->read(&c, 1, kNone, &readSize)); | |
356 testing::runPendingTasks(); | |
357 EXPECT_EQ(kOk, reader->read(&c, 1, kNone, &readSize)); | |
358 EXPECT_EQ(1u, readSize); | |
359 EXPECT_EQ('b', c); | |
360 EXPECT_FALSE(reader->drainAsFormData()); | |
361 } | |
362 | |
363 TEST_F(FetchFormDataConsumerHandleTest, BeginReadAffectsDrainingForComplexFormDa ta) | |
364 { | |
365 OwnPtr<ReplayingHandle> src = ReplayingHandle::create(); | |
366 src->add(Command(Command::Data, "bar")); | |
367 src->add(Command(Command::Done)); | |
368 const void* buffer = nullptr; | |
369 OwnPtr<FetchDataConsumerHandle> handle = FetchFormDataConsumerHandle::create ForTest(document(), complexFormData(), new LoaderFactory(src.release())); | |
370 OwnPtr<FetchDataConsumerHandle::Reader> reader = handle->obtainReader(nullpt r); | |
371 size_t available; | |
372 EXPECT_EQ(kShouldWait, reader->beginRead(&buffer, kNone, &available)); | |
373 testing::runPendingTasks(); | |
374 EXPECT_EQ(kOk, reader->beginRead(&buffer, kNone, &available)); | |
375 EXPECT_FALSE(reader->drainAsFormData()); | |
376 reader->endRead(0); | |
377 EXPECT_FALSE(reader->drainAsFormData()); | |
378 } | |
379 | |
380 } // namespace | |
381 } // namespace blink | |
OLD | NEW |