• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TestBridge()60   TestBridge() : peer_(NULL), canceled_(false) {}
~TestBridge()61   virtual ~TestBridge() {}
62 
63   // ResourceLoaderBridge implementation:
SetRequestBody(ResourceRequestBody * request_body)64   virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE {}
65 
Start(RequestPeer * peer)66   virtual bool Start(RequestPeer* peer) OVERRIDE {
67     EXPECT_FALSE(peer_);
68     peer_ = peer;
69     return true;
70   }
71 
Cancel()72   virtual void Cancel() OVERRIDE {
73     EXPECT_FALSE(canceled_);
74     canceled_ = true;
75   }
76 
SetDefersLoading(bool value)77   virtual void SetDefersLoading(bool value) OVERRIDE {}
78 
DidChangePriority(net::RequestPriority new_priority,int intra_priority_value)79   virtual void DidChangePriority(net::RequestPriority new_priority,
80                                  int intra_priority_value) OVERRIDE {}
81 
AttachThreadedDataReceiver(blink::WebThreadedDataReceiver * threaded_data_receiver)82   virtual bool AttachThreadedDataReceiver(
83       blink::WebThreadedDataReceiver* threaded_data_receiver) OVERRIDE {
84     NOTREACHED();
85     return false;
86   }
87 
SyncLoad(SyncLoadResponse * response)88   virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE {}
89 
peer()90   RequestPeer* peer() { return peer_; }
91 
canceled()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:
TestResourceDispatcher()103   TestResourceDispatcher() : ResourceDispatcher(NULL) {}
~TestResourceDispatcher()104   virtual ~TestResourceDispatcher() {}
105 
106   // ResourceDispatcher implementation:
CreateBridge(const RequestInfo & request_info)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 
bridge()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:
TestWebURLLoaderClient(ResourceDispatcher * dispatcher)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 
~TestWebURLLoaderClient()138   virtual ~TestWebURLLoaderClient() {}
139 
140   // blink::WebURLLoaderClient implementation:
willSendRequest(blink::WebURLLoader * loader,blink::WebURLRequest & newRequest,const blink::WebURLResponse & redirectResponse)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 
didSendData(blink::WebURLLoader * loader,unsigned long long bytesSent,unsigned long long totalBytesToBeSent)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 
didReceiveResponse(blink::WebURLLoader * loader,const blink::WebURLResponse & response)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 
didDownloadData(blink::WebURLLoader * loader,int dataLength,int encodedDataLength)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 
didReceiveData(blink::WebURLLoader * loader,const char * data,int dataLength,int encodedDataLength)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 
didReceiveCachedMetadata(blink::WebURLLoader * loader,const char * data,int dataLength)201   virtual void didReceiveCachedMetadata(blink::WebURLLoader* loader,
202                                         const char* data,
203                                         int dataLength) OVERRIDE {
204     EXPECT_EQ(loader_.get(), loader);
205   }
206 
didFinishLoading(blink::WebURLLoader * loader,double finishTime,int64_t totalEncodedDataLength)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 
didFail(blink::WebURLLoader * loader,const blink::WebURLError & error)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 
loader()231   WebURLLoaderImpl* loader() { return loader_.get(); }
DeleteLoader()232   void DeleteLoader() {
233     loader_.reset();
234   }
235 
set_expect_multipart_response()236   void set_expect_multipart_response() { expect_multipart_response_ = true; }
237 
set_delete_on_receive_redirect()238   void set_delete_on_receive_redirect() { delete_on_receive_redirect_ = true; }
set_delete_on_receive_response()239   void set_delete_on_receive_response() { delete_on_receive_response_ = true; }
set_delete_on_receive_data()240   void set_delete_on_receive_data() { delete_on_receive_data_ = true; }
set_delete_on_finish()241   void set_delete_on_finish() { delete_on_finish_ = true; }
set_delete_on_fail()242   void set_delete_on_fail() { delete_on_fail_ = true; }
243 
did_receive_redirect() const244   bool did_receive_redirect() const { return did_receive_redirect_; }
did_receive_response() const245   bool did_receive_response() const { return did_receive_response_; }
received_data() const246   const std::string& received_data() const { return received_data_; }
did_finish() const247   bool did_finish() const { return did_finish_; }
error() const248   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:
WebURLLoaderImplTest()272   explicit WebURLLoaderImplTest() : client_(&dispatcher_) {}
~WebURLLoaderImplTest()273   virtual ~WebURLLoaderImplTest() {}
274 
DoStartAsyncRequest()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 
DoReceiveRedirect()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 
DoReceiveResponse()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.
DoReceiveData()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 
DoCompleteRequest()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 
DoFailRequest()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 
DoReceiveResponseFtp()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 
DoReceiveDataFtp()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 
DoReceiveResponseMultipart()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 
DoReceiveDataMultipart()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 
client()361   TestWebURLLoaderClient* client() { return &client_; }
bridge()362   TestBridge* bridge() { return dispatcher_.bridge(); }
peer()363   RequestPeer* peer() { return bridge()->peer(); }
message_loop()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 
TEST_F(WebURLLoaderImplTest,Success)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 
TEST_F(WebURLLoaderImplTest,Redirect)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 
TEST_F(WebURLLoaderImplTest,Failure)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.
TEST_F(WebURLLoaderImplTest,DeleteOnReceiveRedirect)402 TEST_F(WebURLLoaderImplTest, DeleteOnReceiveRedirect) {
403   client()->set_delete_on_receive_redirect();
404   DoStartAsyncRequest();
405   DoReceiveRedirect();
406   EXPECT_FALSE(bridge());
407 }
408 
TEST_F(WebURLLoaderImplTest,DeleteOnReceiveResponse)409 TEST_F(WebURLLoaderImplTest, DeleteOnReceiveResponse) {
410   client()->set_delete_on_receive_response();
411   DoStartAsyncRequest();
412   DoReceiveResponse();
413   EXPECT_FALSE(bridge());
414 }
415 
TEST_F(WebURLLoaderImplTest,DeleteOnReceiveData)416 TEST_F(WebURLLoaderImplTest, DeleteOnReceiveData) {
417   client()->set_delete_on_receive_data();
418   DoStartAsyncRequest();
419   DoReceiveResponse();
420   DoReceiveData();
421   EXPECT_FALSE(bridge());
422 }
423 
TEST_F(WebURLLoaderImplTest,DeleteOnFinish)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 
TEST_F(WebURLLoaderImplTest,DeleteOnFail)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 
TEST_F(WebURLLoaderImplTest,DeleteBeforeResponseDataURL)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 
TEST_F(WebURLLoaderImplTest,DataURL)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 
TEST_F(WebURLLoaderImplTest,DataURLDeleteOnReceiveResponse)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 
TEST_F(WebURLLoaderImplTest,DataURLDeleteOnReceiveData)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 
TEST_F(WebURLLoaderImplTest,DataURLDeleteOnFinisha)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 
TEST_F(WebURLLoaderImplTest,Ftp)509 TEST_F(WebURLLoaderImplTest, Ftp) {
510   DoStartAsyncRequest();
511   DoReceiveResponseFtp();
512   DoReceiveDataFtp();
513   DoCompleteRequest();
514   EXPECT_FALSE(bridge()->canceled());
515 }
516 
TEST_F(WebURLLoaderImplTest,FtpDeleteOnReceiveResponse)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 
TEST_F(WebURLLoaderImplTest,FtpDeleteOnReceiveFirstData)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 
TEST_F(WebURLLoaderImplTest,FtpDeleteOnReceiveMoreData)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 
TEST_F(WebURLLoaderImplTest,FtpDeleteOnFinish)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 
TEST_F(WebURLLoaderImplTest,FtpDeleteOnFail)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 
TEST_F(WebURLLoaderImplTest,Multipart)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 
TEST_F(WebURLLoaderImplTest,MultipartDeleteOnReceiveFirstResponse)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 
TEST_F(WebURLLoaderImplTest,MultipartDeleteOnReceiveSecondResponse)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 
TEST_F(WebURLLoaderImplTest,MultipartDeleteOnReceiveFirstData)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 
TEST_F(WebURLLoaderImplTest,MultipartDeleteOnReceiveMoreData)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 
TEST_F(WebURLLoaderImplTest,MultipartDeleteFinish)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 
TEST_F(WebURLLoaderImplTest,MultipartDeleteFail)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