Home | History | Annotate | Download | only in child
      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