| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "modules/fetch/FormDataBytesConsumer.h" | 5 #include "modules/fetch/FormDataBytesConsumer.h" |
| 6 | 6 |
| 7 #include "core/dom/DOMArrayBuffer.h" | 7 #include "core/dom/DOMArrayBuffer.h" |
| 8 #include "core/dom/DOMTypedArray.h" | 8 #include "core/dom/DOMTypedArray.h" |
| 9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
| 10 #include "core/html/FormData.h" | 10 #include "core/html/FormData.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 namespace blink { | 21 namespace blink { |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 using Result = BytesConsumer::Result; | 24 using Result = BytesConsumer::Result; |
| 25 using ::testing::_; | 25 using ::testing::_; |
| 26 using ::testing::DoAll; | 26 using ::testing::DoAll; |
| 27 using ::testing::InSequence; | 27 using ::testing::InSequence; |
| 28 using ::testing::Return; | 28 using ::testing::Return; |
| 29 using Checkpoint = ::testing::StrictMock<::testing::MockFunction<void(int)>>; | 29 using Checkpoint = ::testing::StrictMock<::testing::MockFunction<void(int)>>; |
| 30 using MockBytesConsumer = BytesConsumerTestUtil::MockBytesConsumer; | 30 using MockBytesConsumer = BytesConsumerTestUtil::MockBytesConsumer; |
| 31 using ReplayingBytesConsumer = BytesConsumerTestUtil::ReplayingBytesConsumer; |
| 32 using Command = BytesConsumerTestUtil::Command; |
| 33 |
| 34 BytesConsumer* createStubBytesConsumer(ExecutionContext* executionContext, |
| 35 PassRefPtr<BlobDataHandle> handle) { |
| 36 auto* consumer = new ReplayingBytesConsumer(executionContext); |
| 37 consumer->add(Command(Command::Data, "type = ")); |
| 38 consumer->add(Command(Command::Data, handle->type().utf8().data())); |
| 39 consumer->add(Command(Command::Done)); |
| 40 return consumer; |
| 41 } |
| 42 |
| 43 BytesConsumer* returnMockBytesConsumer(MockBytesConsumer* bytesConsumer, |
| 44 ExecutionContext*, |
| 45 PassRefPtr<BlobDataHandle>) { |
| 46 return bytesConsumer; |
| 47 } |
| 31 | 48 |
| 32 String toString(const Vector<char>& v) { | 49 String toString(const Vector<char>& v) { |
| 33 return String(v.data(), v.size()); | 50 return String(v.data(), v.size()); |
| 34 } | 51 } |
| 35 | 52 |
| 36 PassRefPtr<EncodedFormData> complexFormData() { | 53 PassRefPtr<EncodedFormData> complexFormData() { |
| 37 RefPtr<EncodedFormData> data = EncodedFormData::create(); | 54 RefPtr<EncodedFormData> data = EncodedFormData::create(); |
| 38 | 55 |
| 39 data->appendData("foo", 3); | 56 data->appendData("foo", 3); |
| 40 data->appendFileRange("/foo/bar/baz", 3, 4, 5); | 57 data->appendFileRange("/foo/bar/baz", 3, 4, 5); |
| 41 data->appendFileSystemURLRange(KURL(KURL(), "file:///foo/bar/baz"), 6, 7, 8); | 58 data->appendFileSystemURLRange(KURL(KURL(), "file:///foo/bar/baz"), 6, 7, 8); |
| 42 std::unique_ptr<BlobData> blobData = BlobData::create(); | 59 std::unique_ptr<BlobData> blobData = BlobData::create(); |
| 43 blobData->appendText("hello", false); | 60 blobData->appendText("hello", false); |
| 61 blobData->setContentType("text/plain"); |
| 44 auto size = blobData->length(); | 62 auto size = blobData->length(); |
| 45 RefPtr<BlobDataHandle> blobDataHandle = | 63 RefPtr<BlobDataHandle> blobDataHandle = |
| 46 BlobDataHandle::create(std::move(blobData), size); | 64 BlobDataHandle::create(std::move(blobData), size); |
| 47 data->appendBlob(blobDataHandle->uuid(), blobDataHandle); | 65 data->appendBlob(blobDataHandle->uuid(), blobDataHandle); |
| 48 Vector<char> boundary; | 66 Vector<char> boundary; |
| 49 boundary.append("\0", 1); | 67 boundary.append("\0", 1); |
| 50 data->setBoundary(boundary); | 68 data->setBoundary(boundary); |
| 51 return data.release(); | 69 return data.release(); |
| 52 } | 70 } |
| 53 | 71 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 | 141 |
| 124 auto result = (new BytesConsumerTestUtil::TwoPhaseReader( | 142 auto result = (new BytesConsumerTestUtil::TwoPhaseReader( |
| 125 new FormDataBytesConsumer(getDocument(), data))) | 143 new FormDataBytesConsumer(getDocument(), data))) |
| 126 ->run(); | 144 ->run(); |
| 127 EXPECT_EQ(Result::Done, result.first); | 145 EXPECT_EQ(Result::Done, result.first); |
| 128 EXPECT_EQ("foohoge", toString(result.second)); | 146 EXPECT_EQ("foohoge", toString(result.second)); |
| 129 } | 147 } |
| 130 | 148 |
| 131 TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromComplexFormData) { | 149 TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromComplexFormData) { |
| 132 RefPtr<EncodedFormData> data = complexFormData(); | 150 RefPtr<EncodedFormData> data = complexFormData(); |
| 133 MockBytesConsumer* underlying = MockBytesConsumer::create(); | 151 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting( |
| 134 BytesConsumer* consumer = | 152 getDocument(), data, WTF::bind(createStubBytesConsumer)); |
| 135 FormDataBytesConsumer::createForTesting(getDocument(), data, underlying); | |
| 136 Checkpoint checkpoint; | |
| 137 | 153 |
| 138 const char* buffer = nullptr; | 154 auto result = (new BytesConsumerTestUtil::TwoPhaseReader(consumer))->run(); |
| 139 size_t available = 0; | |
| 140 | 155 |
| 141 InSequence s; | 156 ASSERT_EQ(Result::Done, result.first); |
| 142 EXPECT_CALL(checkpoint, Call(1)); | 157 String expected = |
| 143 EXPECT_CALL(*underlying, beginRead(&buffer, &available)) | 158 "foo" |
| 144 .WillOnce(Return(Result::Ok)); | 159 "type = application/octet-stream" |
| 145 EXPECT_CALL(checkpoint, Call(2)); | 160 "type = application/octet-stream" |
| 146 EXPECT_CALL(*underlying, endRead(0)).WillOnce(Return(Result::Ok)); | 161 "type = text/plain"; |
| 147 EXPECT_CALL(checkpoint, Call(3)); | |
| 148 | 162 |
| 149 checkpoint.Call(1); | 163 EXPECT_EQ(expected, toString(result.second)); |
| 150 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); | |
| 151 checkpoint.Call(2); | |
| 152 EXPECT_EQ(Result::Ok, consumer->endRead(0)); | |
| 153 checkpoint.Call(3); | |
| 154 } | 164 } |
| 155 | 165 |
| 156 TEST_F(FormDataBytesConsumerTest, EndReadCanReturnDone) { | 166 TEST_F(FormDataBytesConsumerTest, EndReadCanReturnDone) { |
| 157 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | 167 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); |
| 158 const char* buffer = nullptr; | 168 const char* buffer = nullptr; |
| 159 size_t available = 0; | 169 size_t available = 0; |
| 160 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); | 170 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); |
| 161 ASSERT_EQ(12u, available); | 171 ASSERT_EQ(12u, available); |
| 162 EXPECT_EQ("hello, world", String(buffer, available)); | 172 EXPECT_EQ("hello, world", String(buffer, available)); |
| 163 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, | 173 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 size_t available = 0; | 224 size_t available = 0; |
| 215 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available)); | 225 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available)); |
| 216 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | 226 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); |
| 217 } | 227 } |
| 218 | 228 |
| 219 TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromComplexFormData) { | 229 TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromComplexFormData) { |
| 220 RefPtr<EncodedFormData> inputFormData = complexFormData(); | 230 RefPtr<EncodedFormData> inputFormData = complexFormData(); |
| 221 | 231 |
| 222 BytesConsumer* consumer = | 232 BytesConsumer* consumer = |
| 223 new FormDataBytesConsumer(getDocument(), inputFormData); | 233 new FormDataBytesConsumer(getDocument(), inputFormData); |
| 224 RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); | 234 EXPECT_EQ(nullptr, consumer->drainAsBlobDataHandle()); |
| 225 ASSERT_TRUE(blobDataHandle); | 235 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, |
| 236 consumer->getPublicState()); |
| 226 | 237 |
| 227 EXPECT_FALSE(consumer->drainAsFormData()); | 238 EXPECT_TRUE(consumer->drainAsFormData()); |
| 239 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); |
| 228 const char* buffer = nullptr; | 240 const char* buffer = nullptr; |
| 229 size_t available = 0; | 241 size_t available = 0; |
| 230 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available)); | 242 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available)); |
| 231 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | 243 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); |
| 232 } | 244 } |
| 233 | 245 |
| 234 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromString) { | 246 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromString) { |
| 235 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | 247 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); |
| 236 RefPtr<EncodedFormData> formData = consumer->drainAsFormData(); | 248 RefPtr<EncodedFormData> formData = consumer->drainAsFormData(); |
| 237 ASSERT_TRUE(formData); | 249 ASSERT_TRUE(formData); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available)); | 286 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available)); |
| 275 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | 287 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); |
| 276 } | 288 } |
| 277 | 289 |
| 278 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromComplexFormData) { | 290 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromComplexFormData) { |
| 279 RefPtr<EncodedFormData> inputFormData = complexFormData(); | 291 RefPtr<EncodedFormData> inputFormData = complexFormData(); |
| 280 | 292 |
| 281 BytesConsumer* consumer = | 293 BytesConsumer* consumer = |
| 282 new FormDataBytesConsumer(getDocument(), inputFormData); | 294 new FormDataBytesConsumer(getDocument(), inputFormData); |
| 283 EXPECT_EQ(inputFormData, consumer->drainAsFormData()); | 295 EXPECT_EQ(inputFormData, consumer->drainAsFormData()); |
| 296 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); |
| 284 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | 297 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); |
| 298 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); |
| 285 const char* buffer = nullptr; | 299 const char* buffer = nullptr; |
| 286 size_t available = 0; | 300 size_t available = 0; |
| 287 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available)); | 301 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available)); |
| 288 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | 302 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); |
| 289 } | 303 } |
| 290 | 304 |
| 291 TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDraining) { | 305 TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDraining) { |
| 292 const char* buffer = nullptr; | 306 const char* buffer = nullptr; |
| 293 size_t available = 0; | 307 size_t available = 0; |
| 294 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | 308 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); |
| 295 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); | 309 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); |
| 296 EXPECT_EQ("hello, world", String(buffer, available)); | 310 EXPECT_EQ("hello, world", String(buffer, available)); |
| 297 | 311 |
| 298 ASSERT_EQ(Result::Ok, consumer->endRead(0)); | 312 ASSERT_EQ(Result::Ok, consumer->endRead(0)); |
| 299 EXPECT_FALSE(consumer->drainAsFormData()); | 313 EXPECT_FALSE(consumer->drainAsFormData()); |
| 300 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | 314 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); |
| 301 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, | 315 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, |
| 302 consumer->getPublicState()); | 316 consumer->getPublicState()); |
| 303 } | 317 } |
| 304 | 318 |
| 305 TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDrainingWithComplexFormData) { | 319 TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDrainingWithComplexFormData) { |
| 306 MockBytesConsumer* underlying = MockBytesConsumer::create(); | |
| 307 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting( | 320 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting( |
| 308 getDocument(), complexFormData(), underlying); | 321 getDocument(), complexFormData(), WTF::bind(createStubBytesConsumer)); |
| 309 | 322 |
| 310 const char* buffer = nullptr; | 323 const char* buffer = nullptr; |
| 311 size_t available = 0; | 324 size_t available = 0; |
| 325 |
| 326 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); |
| 327 ASSERT_EQ(Result::Ok, consumer->endRead(0)); |
| 328 EXPECT_FALSE(consumer->drainAsFormData()); |
| 329 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); |
| 330 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, |
| 331 consumer->getPublicState()); |
| 332 } |
| 333 |
| 334 // The consumer is cancelled before creating a ByteConsumer for a blob. |
| 335 TEST_F(FormDataBytesConsumerTest, CancelWithComplexFormData1) { |
| 336 RefPtr<EncodedFormData> inputFormData = complexFormData(); |
| 337 |
| 338 MockBytesConsumer* underlying = MockBytesConsumer::create(); |
| 339 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting( |
| 340 getDocument(), inputFormData, |
| 341 WTF::bind(returnMockBytesConsumer, wrapPersistent(underlying))); |
| 312 Checkpoint checkpoint; | 342 Checkpoint checkpoint; |
| 313 | 343 |
| 314 InSequence s; | 344 InSequence s; |
| 315 EXPECT_CALL(checkpoint, Call(1)); | 345 EXPECT_CALL(checkpoint, Call(1)); |
| 316 EXPECT_CALL(*underlying, beginRead(&buffer, &available)) | |
| 317 .WillOnce(Return(Result::Ok)); | |
| 318 EXPECT_CALL(*underlying, endRead(0)).WillOnce(Return(Result::Ok)); | |
| 319 EXPECT_CALL(checkpoint, Call(2)); | |
| 320 // drainAsFormData should not be called here. | |
| 321 EXPECT_CALL(checkpoint, Call(3)); | |
| 322 EXPECT_CALL(*underlying, drainAsBlobDataHandle(_)); | |
| 323 EXPECT_CALL(checkpoint, Call(4)); | |
| 324 // |consumer| delegates the getPublicState call to |underlying|. | |
| 325 EXPECT_CALL(*underlying, getPublicState()) | |
| 326 .WillOnce(Return(BytesConsumer::PublicState::ReadableOrWaiting)); | |
| 327 EXPECT_CALL(checkpoint, Call(5)); | |
| 328 | |
| 329 checkpoint.Call(1); | |
| 330 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); | |
| 331 ASSERT_EQ(Result::Ok, consumer->endRead(0)); | |
| 332 checkpoint.Call(2); | |
| 333 EXPECT_FALSE(consumer->drainAsFormData()); | |
| 334 checkpoint.Call(3); | |
| 335 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | |
| 336 checkpoint.Call(4); | |
| 337 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, | |
| 338 consumer->getPublicState()); | |
| 339 checkpoint.Call(5); | |
| 340 } | |
| 341 | |
| 342 TEST_F(FormDataBytesConsumerTest, SetClientWithComplexFormData) { | |
| 343 RefPtr<EncodedFormData> inputFormData = complexFormData(); | |
| 344 | |
| 345 MockBytesConsumer* underlying = MockBytesConsumer::create(); | |
| 346 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting( | |
| 347 getDocument(), inputFormData, underlying); | |
| 348 Checkpoint checkpoint; | |
| 349 | |
| 350 InSequence s; | |
| 351 EXPECT_CALL(checkpoint, Call(1)); | |
| 352 EXPECT_CALL(*underlying, setClient(_)); | |
| 353 EXPECT_CALL(checkpoint, Call(2)); | |
| 354 EXPECT_CALL(*underlying, clearClient()); | |
| 355 EXPECT_CALL(checkpoint, Call(3)); | |
| 356 | |
| 357 checkpoint.Call(1); | |
| 358 consumer->setClient(new NoopClient()); | |
| 359 checkpoint.Call(2); | |
| 360 consumer->clearClient(); | |
| 361 checkpoint.Call(3); | |
| 362 } | |
| 363 | |
| 364 TEST_F(FormDataBytesConsumerTest, CancelWithComplexFormData) { | |
| 365 RefPtr<EncodedFormData> inputFormData = complexFormData(); | |
| 366 | |
| 367 MockBytesConsumer* underlying = MockBytesConsumer::create(); | |
| 368 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting( | |
| 369 getDocument(), inputFormData, underlying); | |
| 370 Checkpoint checkpoint; | |
| 371 | |
| 372 InSequence s; | |
| 373 EXPECT_CALL(checkpoint, Call(1)); | |
| 374 EXPECT_CALL(*underlying, cancel()); | |
| 375 EXPECT_CALL(checkpoint, Call(2)); | 346 EXPECT_CALL(checkpoint, Call(2)); |
| 376 | 347 |
| 377 checkpoint.Call(1); | 348 checkpoint.Call(1); |
| 378 consumer->cancel(); | 349 consumer->cancel(); |
| 379 checkpoint.Call(2); | 350 checkpoint.Call(2); |
| 380 } | 351 } |
| 381 | 352 |
| 353 // The consumer is cancelled after creating a ByteConsumer for a blob. |
| 354 TEST_F(FormDataBytesConsumerTest, CancelWithComplexFormData2) { |
| 355 RefPtr<EncodedFormData> inputFormData = complexFormData(); |
| 356 |
| 357 MockBytesConsumer* underlying = MockBytesConsumer::create(); |
| 358 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting( |
| 359 getDocument(), inputFormData, |
| 360 WTF::bind(returnMockBytesConsumer, wrapPersistent(underlying))); |
| 361 Checkpoint checkpoint; |
| 362 |
| 363 const char* buffer = nullptr; |
| 364 size_t available = 0; |
| 365 |
| 366 InSequence s; |
| 367 EXPECT_CALL(checkpoint, Call(1)); |
| 368 EXPECT_CALL(checkpoint, Call(2)); |
| 369 EXPECT_CALL(*underlying, beginRead(&buffer, &available)) |
| 370 .WillOnce(Return(Result::ShouldWait)); |
| 371 EXPECT_CALL(checkpoint, Call(3)); |
| 372 EXPECT_CALL(*underlying, cancel()); |
| 373 EXPECT_CALL(checkpoint, Call(4)); |
| 374 |
| 375 checkpoint.Call(1); |
| 376 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); |
| 377 ASSERT_EQ(3u, available); |
| 378 ASSERT_EQ(Result::Ok, consumer->endRead(available)); |
| 379 |
| 380 checkpoint.Call(2); |
| 381 ASSERT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available)); |
| 382 |
| 383 checkpoint.Call(3); |
| 384 consumer->cancel(); |
| 385 checkpoint.Call(4); |
| 386 } |
| 387 |
| 382 } // namespace | 388 } // namespace |
| 383 } // namespace blink | 389 } // namespace blink |
| OLD | NEW |