1 // Copyright 2014 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 "content/child/web_url_loader_impl.h" 6 7 #include <string.h> 8 9 #include "base/macros.h" 10 #include "base/memory/weak_ptr.h" 11 #include "base/message_loop/message_loop.h" 12 #include "base/time/time.h" 13 #include "content/child/resource_dispatcher.h" 14 #include "content/child/resource_loader_bridge.h" 15 #include "content/public/child/request_peer.h" 16 #include "content/public/common/resource_response_info.h" 17 #include "net/base/net_errors.h" 18 #include "net/http/http_response_headers.h" 19 #include "net/http/http_util.h" 20 #include "net/url_request/redirect_info.h" 21 #include "testing/gtest/include/gtest/gtest.h" 22 #include "third_party/WebKit/public/platform/WebString.h" 23 #include "third_party/WebKit/public/platform/WebURLError.h" 24 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h" 25 #include "third_party/WebKit/public/platform/WebURLRequest.h" 26 #include "url/gurl.h" 27 28 namespace content { 29 namespace { 30 31 const char kTestURL[] = "http://foo"; 32 const char kTestData[] = "blah!"; 33 34 const char kFtpDirMimeType[] = "text/vnd.chromium.ftp-dir"; 35 // Simple FTP directory listing. Tests are not concerned with correct parsing, 36 // but rather correct cleanup when deleted while parsing. Important details of 37 // this list are that it contains more than one entry that are not "." or "..". 38 const char kFtpDirListing[] = 39 "drwxr-xr-x 3 ftp ftp 4096 May 15 18:11 goat\n" 40 "drwxr-xr-x 3 ftp ftp 4096 May 15 18:11 hat"; 41 42 const char kMultipartResponseMimeType[] = "multipart/x-mixed-replace"; 43 const char kMultipartResponseHeaders[] = 44 "HTTP/1.0 200 Peachy\r\n" 45 "Content-Type: multipart/x-mixed-replace; boundary=boundary\r\n\r\n"; 46 // Simple multipart response. Imporant details for the tests are that it 47 // contains multiple chunks, and that it doesn't end with a boundary, so will 48 // send data in OnResponseComplete. Also, it will resolve to kTestData. 49 const char kMultipartResponse[] = 50 "--boundary\n" 51 "Content-type: text/html\n\n" 52 "bl" 53 "--boundary\n" 54 "Content-type: text/html\n\n" 55 "ah!"; 56 57 class TestBridge : public ResourceLoaderBridge, 58 public base::SupportsWeakPtr<TestBridge> { 59 public: 60 TestBridge() : peer_(NULL), canceled_(false) {} 61 virtual ~TestBridge() {} 62 63 // ResourceLoaderBridge implementation: 64 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE {} 65 66 virtual bool Start(RequestPeer* peer) OVERRIDE { 67 EXPECT_FALSE(peer_); 68 peer_ = peer; 69 return true; 70 } 71 72 virtual void Cancel() OVERRIDE { 73 EXPECT_FALSE(canceled_); 74 canceled_ = true; 75 } 76 77 virtual void SetDefersLoading(bool value) OVERRIDE {} 78 79 virtual void DidChangePriority(net::RequestPriority new_priority, 80 int intra_priority_value) OVERRIDE {} 81 82 virtual bool AttachThreadedDataReceiver( 83 blink::WebThreadedDataReceiver* threaded_data_receiver) OVERRIDE { 84 NOTREACHED(); 85 return false; 86 } 87 88 virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE {} 89 90 RequestPeer* peer() { return peer_; } 91 92 bool canceled() { return canceled_; } 93 94 private: 95 RequestPeer* peer_; 96 bool canceled_; 97 98 DISALLOW_COPY_AND_ASSIGN(TestBridge); 99 }; 100 101 class TestResourceDispatcher : public ResourceDispatcher { 102 public: 103 TestResourceDispatcher() : ResourceDispatcher(NULL) {} 104 virtual ~TestResourceDispatcher() {} 105 106 // ResourceDispatcher implementation: 107 virtual ResourceLoaderBridge* CreateBridge( 108 const RequestInfo& request_info) OVERRIDE { 109 EXPECT_FALSE(bridge_.get()); 110 TestBridge* bridge = new TestBridge(); 111 bridge_ = bridge->AsWeakPtr(); 112 return bridge; 113 } 114 115 TestBridge* bridge() { return bridge_.get(); } 116 117 private: 118 base::WeakPtr<TestBridge> bridge_; 119 120 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcher); 121 }; 122 123 class TestWebURLLoaderClient : public blink::WebURLLoaderClient { 124 public: 125 TestWebURLLoaderClient(ResourceDispatcher* dispatcher) 126 : loader_(new WebURLLoaderImpl(dispatcher)), 127 expect_multipart_response_(false), 128 delete_on_receive_redirect_(false), 129 delete_on_receive_response_(false), 130 delete_on_receive_data_(false), 131 delete_on_finish_(false), 132 delete_on_fail_(false), 133 did_receive_redirect_(false), 134 did_receive_response_(false), 135 did_finish_(false) { 136 } 137 138 virtual ~TestWebURLLoaderClient() {} 139 140 // blink::WebURLLoaderClient implementation: 141 virtual void willSendRequest( 142 blink::WebURLLoader* loader, 143 blink::WebURLRequest& newRequest, 144 const blink::WebURLResponse& redirectResponse) OVERRIDE { 145 EXPECT_TRUE(loader_); 146 EXPECT_EQ(loader_.get(), loader); 147 // No test currently simulates mutiple redirects. 148 EXPECT_FALSE(did_receive_redirect_); 149 did_receive_redirect_ = true; 150 151 if (delete_on_receive_redirect_) 152 loader_.reset(); 153 } 154 155 virtual void didSendData(blink::WebURLLoader* loader, 156 unsigned long long bytesSent, 157 unsigned long long totalBytesToBeSent) OVERRIDE { 158 EXPECT_TRUE(loader_); 159 EXPECT_EQ(loader_.get(), loader); 160 } 161 162 virtual void didReceiveResponse( 163 blink::WebURLLoader* loader, 164 const blink::WebURLResponse& response) OVERRIDE { 165 EXPECT_TRUE(loader_); 166 EXPECT_EQ(loader_.get(), loader); 167 168 // Only multipart requests may receive multiple response headers. 169 EXPECT_TRUE(expect_multipart_response_ || !did_receive_response_); 170 171 did_receive_response_ = true; 172 if (delete_on_receive_response_) 173 loader_.reset(); 174 } 175 176 virtual void didDownloadData(blink::WebURLLoader* loader, 177 int dataLength, 178 int encodedDataLength) OVERRIDE { 179 EXPECT_TRUE(loader_); 180 EXPECT_EQ(loader_.get(), loader); 181 } 182 183 virtual void didReceiveData(blink::WebURLLoader* loader, 184 const char* data, 185 int dataLength, 186 int encodedDataLength) OVERRIDE { 187 EXPECT_TRUE(loader_); 188 EXPECT_EQ(loader_.get(), loader); 189 // The response should have started, but must not have finished, or failed. 190 EXPECT_TRUE(did_receive_response_); 191 EXPECT_FALSE(did_finish_); 192 EXPECT_EQ(net::OK, error_.reason); 193 EXPECT_EQ("", error_.domain.utf8()); 194 195 received_data_.append(data, dataLength); 196 197 if (delete_on_receive_data_) 198 loader_.reset(); 199 } 200 201 virtual void didReceiveCachedMetadata(blink::WebURLLoader* loader, 202 const char* data, 203 int dataLength) OVERRIDE { 204 EXPECT_EQ(loader_.get(), loader); 205 } 206 207 virtual void didFinishLoading(blink::WebURLLoader* loader, 208 double finishTime, 209 int64_t totalEncodedDataLength) OVERRIDE { 210 EXPECT_TRUE(loader_); 211 EXPECT_EQ(loader_.get(), loader); 212 EXPECT_TRUE(did_receive_response_); 213 EXPECT_FALSE(did_finish_); 214 did_finish_ = true; 215 216 if (delete_on_finish_) 217 loader_.reset(); 218 } 219 220 virtual void didFail(blink::WebURLLoader* loader, 221 const blink::WebURLError& error) OVERRIDE { 222 EXPECT_TRUE(loader_); 223 EXPECT_EQ(loader_.get(), loader); 224 EXPECT_FALSE(did_finish_); 225 error_ = error; 226 227 if (delete_on_fail_) 228 loader_.reset(); 229 } 230 231 WebURLLoaderImpl* loader() { return loader_.get(); } 232 void DeleteLoader() { 233 loader_.reset(); 234 } 235 236 void set_expect_multipart_response() { expect_multipart_response_ = true; } 237 238 void set_delete_on_receive_redirect() { delete_on_receive_redirect_ = true; } 239 void set_delete_on_receive_response() { delete_on_receive_response_ = true; } 240 void set_delete_on_receive_data() { delete_on_receive_data_ = true; } 241 void set_delete_on_finish() { delete_on_finish_ = true; } 242 void set_delete_on_fail() { delete_on_fail_ = true; } 243 244 bool did_receive_redirect() const { return did_receive_redirect_; } 245 bool did_receive_response() const { return did_receive_response_; } 246 const std::string& received_data() const { return received_data_; } 247 bool did_finish() const { return did_finish_; } 248 const blink::WebURLError& error() const { return error_; } 249 250 private: 251 scoped_ptr<WebURLLoaderImpl> loader_; 252 253 bool expect_multipart_response_; 254 255 bool delete_on_receive_redirect_; 256 bool delete_on_receive_response_; 257 bool delete_on_receive_data_; 258 bool delete_on_finish_; 259 bool delete_on_fail_; 260 261 bool did_receive_redirect_; 262 bool did_receive_response_; 263 std::string received_data_; 264 bool did_finish_; 265 blink::WebURLError error_; 266 267 DISALLOW_COPY_AND_ASSIGN(TestWebURLLoaderClient); 268 }; 269 270 class WebURLLoaderImplTest : public testing::Test { 271 public: 272 explicit WebURLLoaderImplTest() : client_(&dispatcher_) {} 273 virtual ~WebURLLoaderImplTest() {} 274 275 void DoStartAsyncRequest() { 276 blink::WebURLRequest request; 277 request.initialize(); 278 request.setURL(GURL(kTestURL)); 279 client()->loader()->loadAsynchronously(request, client()); 280 ASSERT_TRUE(bridge()); 281 ASSERT_TRUE(peer()); 282 } 283 284 void DoReceiveRedirect() { 285 EXPECT_FALSE(client()->did_receive_redirect()); 286 net::RedirectInfo redirect_info; 287 redirect_info.status_code = 302; 288 redirect_info.new_method = "GET"; 289 redirect_info.new_url = GURL(kTestURL); 290 redirect_info.new_first_party_for_cookies = GURL(kTestURL); 291 peer()->OnReceivedRedirect(redirect_info, 292 content::ResourceResponseInfo()); 293 EXPECT_TRUE(client()->did_receive_redirect()); 294 } 295 296 void DoReceiveResponse() { 297 EXPECT_FALSE(client()->did_receive_response()); 298 peer()->OnReceivedResponse(content::ResourceResponseInfo()); 299 EXPECT_TRUE(client()->did_receive_response()); 300 } 301 302 // Assumes it is called only once for a request. 303 void DoReceiveData() { 304 EXPECT_EQ("", client()->received_data()); 305 peer()->OnReceivedData(kTestData, strlen(kTestData), strlen(kTestData)); 306 EXPECT_EQ(kTestData, client()->received_data()); 307 } 308 309 void DoCompleteRequest() { 310 EXPECT_FALSE(client()->did_finish()); 311 peer()->OnCompletedRequest(net::OK, false, false, "", base::TimeTicks(), 312 strlen(kTestData)); 313 EXPECT_TRUE(client()->did_finish()); 314 // There should be no error. 315 EXPECT_EQ(net::OK, client()->error().reason); 316 EXPECT_EQ("", client()->error().domain.utf8()); 317 } 318 319 void DoFailRequest() { 320 EXPECT_FALSE(client()->did_finish()); 321 peer()->OnCompletedRequest(net::ERR_FAILED, false, false, "", 322 base::TimeTicks(), strlen(kTestData)); 323 EXPECT_FALSE(client()->did_finish()); 324 EXPECT_EQ(net::ERR_FAILED, client()->error().reason); 325 EXPECT_EQ(net::kErrorDomain, client()->error().domain.utf8()); 326 } 327 328 void DoReceiveResponseFtp() { 329 EXPECT_FALSE(client()->did_receive_response()); 330 content::ResourceResponseInfo response_info; 331 response_info.mime_type = kFtpDirMimeType; 332 peer()->OnReceivedResponse(response_info); 333 EXPECT_TRUE(client()->did_receive_response()); 334 } 335 336 void DoReceiveDataFtp() { 337 peer()->OnReceivedData(kFtpDirListing, strlen(kFtpDirListing), 338 strlen(kFtpDirListing)); 339 // The FTP delegate should modify the data the client sees. 340 EXPECT_NE(kFtpDirListing, client()->received_data()); 341 } 342 343 void DoReceiveResponseMultipart() { 344 EXPECT_FALSE(client()->did_receive_response()); 345 content::ResourceResponseInfo response_info; 346 response_info.headers = new net::HttpResponseHeaders( 347 net::HttpUtil::AssembleRawHeaders(kMultipartResponseHeaders, 348 strlen(kMultipartResponseHeaders))); 349 response_info.mime_type = kMultipartResponseMimeType; 350 peer()->OnReceivedResponse(response_info); 351 EXPECT_TRUE(client()->did_receive_response()); 352 } 353 354 void DoReceiveDataMultipart() { 355 peer()->OnReceivedData(kMultipartResponse, strlen(kMultipartResponse), 356 strlen(kMultipartResponse)); 357 // Multipart delegate should modify the data the client sees. 358 EXPECT_NE(kMultipartResponse, client()->received_data()); 359 } 360 361 TestWebURLLoaderClient* client() { return &client_; } 362 TestBridge* bridge() { return dispatcher_.bridge(); } 363 RequestPeer* peer() { return bridge()->peer(); } 364 base::MessageLoop* message_loop() { return &message_loop_; } 365 366 private: 367 TestResourceDispatcher dispatcher_; 368 TestWebURLLoaderClient client_; 369 370 base::MessageLoop message_loop_; 371 }; 372 373 TEST_F(WebURLLoaderImplTest, Success) { 374 DoStartAsyncRequest(); 375 DoReceiveResponse(); 376 DoReceiveData(); 377 DoCompleteRequest(); 378 EXPECT_FALSE(bridge()->canceled()); 379 EXPECT_EQ(kTestData, client()->received_data()); 380 } 381 382 TEST_F(WebURLLoaderImplTest, Redirect) { 383 DoStartAsyncRequest(); 384 DoReceiveRedirect(); 385 DoReceiveResponse(); 386 DoReceiveData(); 387 DoCompleteRequest(); 388 EXPECT_FALSE(bridge()->canceled()); 389 EXPECT_EQ(kTestData, client()->received_data()); 390 } 391 392 TEST_F(WebURLLoaderImplTest, Failure) { 393 DoStartAsyncRequest(); 394 DoReceiveResponse(); 395 DoReceiveData(); 396 DoFailRequest(); 397 EXPECT_FALSE(bridge()->canceled()); 398 } 399 400 // The client may delete the WebURLLoader during any callback from the loader. 401 // These tests make sure that doesn't result in a crash. 402 TEST_F(WebURLLoaderImplTest, DeleteOnReceiveRedirect) { 403 client()->set_delete_on_receive_redirect(); 404 DoStartAsyncRequest(); 405 DoReceiveRedirect(); 406 EXPECT_FALSE(bridge()); 407 } 408 409 TEST_F(WebURLLoaderImplTest, DeleteOnReceiveResponse) { 410 client()->set_delete_on_receive_response(); 411 DoStartAsyncRequest(); 412 DoReceiveResponse(); 413 EXPECT_FALSE(bridge()); 414 } 415 416 TEST_F(WebURLLoaderImplTest, DeleteOnReceiveData) { 417 client()->set_delete_on_receive_data(); 418 DoStartAsyncRequest(); 419 DoReceiveResponse(); 420 DoReceiveData(); 421 EXPECT_FALSE(bridge()); 422 } 423 424 TEST_F(WebURLLoaderImplTest, DeleteOnFinish) { 425 client()->set_delete_on_finish(); 426 DoStartAsyncRequest(); 427 DoReceiveResponse(); 428 DoReceiveData(); 429 DoCompleteRequest(); 430 EXPECT_FALSE(bridge()); 431 } 432 433 TEST_F(WebURLLoaderImplTest, DeleteOnFail) { 434 client()->set_delete_on_fail(); 435 DoStartAsyncRequest(); 436 DoReceiveResponse(); 437 DoReceiveData(); 438 DoFailRequest(); 439 EXPECT_FALSE(bridge()); 440 } 441 442 TEST_F(WebURLLoaderImplTest, DeleteBeforeResponseDataURL) { 443 blink::WebURLRequest request; 444 request.initialize(); 445 request.setURL(GURL("data:text/html;charset=utf-8,blah!")); 446 client()->loader()->loadAsynchronously(request, client()); 447 client()->DeleteLoader(); 448 message_loop()->RunUntilIdle(); 449 EXPECT_FALSE(client()->did_receive_response()); 450 EXPECT_FALSE(bridge()); 451 } 452 453 // Data URL tests. 454 455 TEST_F(WebURLLoaderImplTest, DataURL) { 456 blink::WebURLRequest request; 457 request.initialize(); 458 request.setURL(GURL("data:text/html;charset=utf-8,blah!")); 459 client()->loader()->loadAsynchronously(request, client()); 460 message_loop()->RunUntilIdle(); 461 EXPECT_EQ("blah!", client()->received_data()); 462 EXPECT_TRUE(client()->did_finish()); 463 EXPECT_EQ(net::OK, client()->error().reason); 464 EXPECT_EQ("", client()->error().domain.utf8()); 465 } 466 467 TEST_F(WebURLLoaderImplTest, DataURLDeleteOnReceiveResponse) { 468 blink::WebURLRequest request; 469 request.initialize(); 470 request.setURL(GURL("data:text/html;charset=utf-8,blah!")); 471 client()->set_delete_on_receive_response(); 472 client()->loader()->loadAsynchronously(request, client()); 473 message_loop()->RunUntilIdle(); 474 EXPECT_TRUE(client()->did_receive_response()); 475 EXPECT_EQ("", client()->received_data()); 476 EXPECT_FALSE(client()->did_finish()); 477 EXPECT_FALSE(bridge()); 478 } 479 480 TEST_F(WebURLLoaderImplTest, DataURLDeleteOnReceiveData) { 481 blink::WebURLRequest request; 482 request.initialize(); 483 request.setURL(GURL("data:text/html;charset=utf-8,blah!")); 484 client()->set_delete_on_receive_data(); 485 client()->loader()->loadAsynchronously(request, client()); 486 message_loop()->RunUntilIdle(); 487 EXPECT_TRUE(client()->did_receive_response()); 488 EXPECT_EQ("blah!", client()->received_data()); 489 EXPECT_FALSE(client()->did_finish()); 490 EXPECT_FALSE(bridge()); 491 } 492 493 TEST_F(WebURLLoaderImplTest, DataURLDeleteOnFinisha) { 494 blink::WebURLRequest request; 495 request.initialize(); 496 request.setURL(GURL("data:text/html;charset=utf-8,blah!")); 497 client()->set_delete_on_finish(); 498 client()->loader()->loadAsynchronously(request, client()); 499 message_loop()->RunUntilIdle(); 500 EXPECT_TRUE(client()->did_receive_response()); 501 EXPECT_EQ("blah!", client()->received_data()); 502 EXPECT_TRUE(client()->did_finish()); 503 EXPECT_FALSE(bridge()); 504 } 505 506 // FTP integration tests. These are focused more on safe deletion than correct 507 // parsing of FTP responses. 508 509 TEST_F(WebURLLoaderImplTest, Ftp) { 510 DoStartAsyncRequest(); 511 DoReceiveResponseFtp(); 512 DoReceiveDataFtp(); 513 DoCompleteRequest(); 514 EXPECT_FALSE(bridge()->canceled()); 515 } 516 517 TEST_F(WebURLLoaderImplTest, FtpDeleteOnReceiveResponse) { 518 client()->set_delete_on_receive_response(); 519 DoStartAsyncRequest(); 520 DoReceiveResponseFtp(); 521 522 // No data should have been received. 523 EXPECT_EQ("", client()->received_data()); 524 EXPECT_FALSE(bridge()); 525 } 526 527 TEST_F(WebURLLoaderImplTest, FtpDeleteOnReceiveFirstData) { 528 client()->set_delete_on_receive_data(); 529 DoStartAsyncRequest(); 530 // Some data is sent in ReceiveResponse for FTP requests, so the bridge should 531 // be deleted here. 532 DoReceiveResponseFtp(); 533 534 EXPECT_NE("", client()->received_data()); 535 EXPECT_FALSE(bridge()); 536 } 537 538 TEST_F(WebURLLoaderImplTest, FtpDeleteOnReceiveMoreData) { 539 DoStartAsyncRequest(); 540 DoReceiveResponseFtp(); 541 DoReceiveDataFtp(); 542 543 // Directory listings are only parsed once the request completes, so this will 544 // cancel in DoReceiveDataFtp, before the request finishes. 545 client()->set_delete_on_receive_data(); 546 peer()->OnCompletedRequest(net::OK, false, false, "", base::TimeTicks(), 547 strlen(kTestData)); 548 EXPECT_FALSE(client()->did_finish()); 549 550 EXPECT_FALSE(bridge()); 551 } 552 553 TEST_F(WebURLLoaderImplTest, FtpDeleteOnFinish) { 554 client()->set_delete_on_finish(); 555 DoStartAsyncRequest(); 556 DoReceiveResponseFtp(); 557 DoReceiveDataFtp(); 558 DoCompleteRequest(); 559 EXPECT_FALSE(bridge()); 560 } 561 562 TEST_F(WebURLLoaderImplTest, FtpDeleteOnFail) { 563 client()->set_delete_on_fail(); 564 DoStartAsyncRequest(); 565 DoReceiveResponseFtp(); 566 DoReceiveDataFtp(); 567 DoFailRequest(); 568 EXPECT_FALSE(bridge()); 569 } 570 571 // Multipart integration tests. These are focused more on safe deletion than 572 // correct parsing of Multipart responses. 573 574 TEST_F(WebURLLoaderImplTest, Multipart) { 575 client()->set_expect_multipart_response(); 576 DoStartAsyncRequest(); 577 DoReceiveResponseMultipart(); 578 DoReceiveDataMultipart(); 579 DoCompleteRequest(); 580 EXPECT_EQ(kTestData, client()->received_data()); 581 EXPECT_FALSE(bridge()->canceled()); 582 } 583 584 TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveFirstResponse) { 585 client()->set_expect_multipart_response(); 586 client()->set_delete_on_receive_response(); 587 DoStartAsyncRequest(); 588 DoReceiveResponseMultipart(); 589 EXPECT_EQ("", client()->received_data()); 590 EXPECT_FALSE(bridge()); 591 } 592 593 TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveSecondResponse) { 594 client()->set_expect_multipart_response(); 595 DoStartAsyncRequest(); 596 DoReceiveResponseMultipart(); 597 client()->set_delete_on_receive_response(); 598 DoReceiveDataMultipart(); 599 EXPECT_EQ("", client()->received_data()); 600 EXPECT_FALSE(bridge()); 601 } 602 603 TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveFirstData) { 604 client()->set_expect_multipart_response(); 605 client()->set_delete_on_receive_data(); 606 DoStartAsyncRequest(); 607 DoReceiveResponseMultipart(); 608 DoReceiveDataMultipart(); 609 EXPECT_EQ("bl", client()->received_data()); 610 EXPECT_FALSE(bridge()); 611 } 612 613 TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveMoreData) { 614 client()->set_expect_multipart_response(); 615 DoStartAsyncRequest(); 616 DoReceiveResponseMultipart(); 617 DoReceiveDataMultipart(); 618 // For multipart responses, the delegate may send some data when notified 619 // of a request completing. 620 client()->set_delete_on_receive_data(); 621 peer()->OnCompletedRequest(net::OK, false, false, "", base::TimeTicks(), 622 strlen(kTestData)); 623 EXPECT_FALSE(client()->did_finish()); 624 EXPECT_EQ(kTestData, client()->received_data()); 625 EXPECT_FALSE(bridge()); 626 } 627 628 TEST_F(WebURLLoaderImplTest, MultipartDeleteFinish) { 629 client()->set_expect_multipart_response(); 630 client()->set_delete_on_finish(); 631 DoStartAsyncRequest(); 632 DoReceiveResponseMultipart(); 633 DoReceiveDataMultipart(); 634 DoCompleteRequest(); 635 EXPECT_EQ(kTestData, client()->received_data()); 636 EXPECT_FALSE(bridge()); 637 } 638 639 TEST_F(WebURLLoaderImplTest, MultipartDeleteFail) { 640 client()->set_expect_multipart_response(); 641 client()->set_delete_on_fail(); 642 DoStartAsyncRequest(); 643 DoReceiveResponseMultipart(); 644 DoReceiveDataMultipart(); 645 DoFailRequest(); 646 EXPECT_FALSE(bridge()); 647 } 648 649 } // namespace 650 } // namespace content 651