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
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/renderer/platform/testing/weburl_loader_mock.h"
6 
7 #include <utility>
8 
9 #include "net/cookies/site_for_cookies.h"
10 #include "services/network/public/cpp/resource_request.h"
11 #include "third_party/blink/public/platform/resource_load_info_notifier_wrapper.h"
12 #include "third_party/blink/public/platform/url_conversion.h"
13 #include "third_party/blink/public/platform/web_data.h"
14 #include "third_party/blink/public/platform/web_security_origin.h"
15 #include "third_party/blink/public/platform/web_url_error.h"
16 #include "third_party/blink/public/platform/web_url_loader_client.h"
17 #include "third_party/blink/public/platform/web_url_request_extra_data.h"
18 #include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h"
19 #include "third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h"
20 #include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
21 
22 namespace blink {
23 
WebURLLoaderMock(WebURLLoaderMockFactoryImpl * factory)24 WebURLLoaderMock::WebURLLoaderMock(WebURLLoaderMockFactoryImpl* factory)
25     : factory_(factory) {}
26 
~WebURLLoaderMock()27 WebURLLoaderMock::~WebURLLoaderMock() {
28   Cancel();
29 }
30 
ServeAsynchronousRequest(WebURLLoaderTestDelegate * delegate,const WebURLResponse & response,const WebData & data,const base::Optional<WebURLError> & error)31 void WebURLLoaderMock::ServeAsynchronousRequest(
32     WebURLLoaderTestDelegate* delegate,
33     const WebURLResponse& response,
34     const WebData& data,
35     const base::Optional<WebURLError>& error) {
36   if (!client_)
37     return;
38 
39   // If no delegate is provided then create an empty one. The default behavior
40   // will just proxy to the client.
41   std::unique_ptr<WebURLLoaderTestDelegate> default_delegate;
42   if (!delegate) {
43     default_delegate = std::make_unique<WebURLLoaderTestDelegate>();
44     delegate = default_delegate.get();
45   }
46 
47   if (error) {
48     delegate->DidFail(client_, *error, data.size(), 0, 0);
49     return;
50   }
51 
52   // didReceiveResponse() and didReceiveData() might end up getting ::cancel()
53   // to be called which will make the ResourceLoader to delete |this|.
54   base::WeakPtr<WebURLLoaderMock> self = weak_factory_.GetWeakPtr();
55 
56   delegate->DidReceiveResponse(client_, response);
57   if (!self)
58     return;
59 
60   data.ForEachSegment([this, &delegate, &self](const char* segment,
61                                                size_t segment_size,
62                                                size_t segment_offset) {
63     delegate->DidReceiveData(client_, segment, segment_size);
64     // DidReceiveData() may clear the |self| weak ptr.  We stop iterating
65     // when that happens.
66     return self;
67   });
68 
69   if (!self)
70     return;
71 
72   delegate->DidFinishLoading(client_, base::TimeTicks(), data.size(),
73                              data.size(), data.size());
74 }
75 
ServeRedirect(const WebString & method,const WebURLResponse & redirect_response)76 WebURL WebURLLoaderMock::ServeRedirect(
77     const WebString& method,
78     const WebURLResponse& redirect_response) {
79   KURL redirect_url(redirect_response.HttpHeaderField("Location"));
80 
81   base::WeakPtr<WebURLLoaderMock> self = weak_factory_.GetWeakPtr();
82 
83   bool report_raw_headers = false;
84   bool follow = client_->WillFollowRedirect(
85       redirect_url, net::SiteForCookies::FromUrl(redirect_url), WebString(),
86       network::mojom::ReferrerPolicy::kDefault, method, redirect_response,
87       report_raw_headers, nullptr /* removed_headers */);
88   // |this| might be deleted in willFollowRedirect().
89   if (!self)
90     return redirect_url;
91 
92   if (!follow)
93     Cancel();
94 
95   return redirect_url;
96 }
97 
LoadSynchronously(std::unique_ptr<network::ResourceRequest> request,scoped_refptr<WebURLRequestExtraData> url_request_extra_data,int requestor_id,bool pass_response_pipe_to_client,bool no_mime_sniffing,base::TimeDelta timeout_interval,WebURLLoaderClient * client,WebURLResponse & response,base::Optional<WebURLError> & error,WebData & data,int64_t & encoded_data_length,int64_t & encoded_body_length,blink::WebBlobInfo & downloaded_blob,std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper> resource_load_info_notifier_wrapper)98 void WebURLLoaderMock::LoadSynchronously(
99     std::unique_ptr<network::ResourceRequest> request,
100     scoped_refptr<WebURLRequestExtraData> url_request_extra_data,
101     int requestor_id,
102     bool pass_response_pipe_to_client,
103     bool no_mime_sniffing,
104     base::TimeDelta timeout_interval,
105     WebURLLoaderClient* client,
106     WebURLResponse& response,
107     base::Optional<WebURLError>& error,
108     WebData& data,
109     int64_t& encoded_data_length,
110     int64_t& encoded_body_length,
111     blink::WebBlobInfo& downloaded_blob,
112     std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
113         resource_load_info_notifier_wrapper) {
114   DCHECK(factory_->IsMockedURL(WebURL(KURL(request->url)))) << request->url;
115   factory_->LoadSynchronously(std::move(request), &response, &error, &data,
116                               &encoded_data_length);
117 }
118 
LoadAsynchronously(std::unique_ptr<network::ResourceRequest> request,scoped_refptr<WebURLRequestExtraData> url_request_extra_data,int requestor_id,bool no_mime_sniffing,std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper> resource_load_info_notifier_wrapper,WebURLLoaderClient * client)119 void WebURLLoaderMock::LoadAsynchronously(
120     std::unique_ptr<network::ResourceRequest> request,
121     scoped_refptr<WebURLRequestExtraData> url_request_extra_data,
122     int requestor_id,
123     bool no_mime_sniffing,
124     std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
125         resource_load_info_notifier_wrapper,
126     WebURLLoaderClient* client) {
127   DCHECK(client);
128   DCHECK(factory_->IsMockedURL(WebURL(KURL(request->url)))) << request->url;
129   client_ = client;
130   factory_->LoadAsynchronouly(std::move(request), this);
131 }
132 
Cancel()133 void WebURLLoaderMock::Cancel() {
134   client_ = nullptr;
135   factory_->CancelLoad(this);
136 }
137 
SetDefersLoading(DeferType deferred)138 void WebURLLoaderMock::SetDefersLoading(DeferType deferred) {
139   is_deferred_ = (deferred != DeferType::kNotDeferred);
140   // Ignores setDefersLoading(false) safely.
141   if (!is_deferred_)
142     return;
143 
144   // setDefersLoading(true) is not implemented.
145   NOTIMPLEMENTED();
146 }
147 
DidChangePriority(WebURLRequest::Priority new_priority,int intra_priority_value)148 void WebURLLoaderMock::DidChangePriority(WebURLRequest::Priority new_priority,
149                                          int intra_priority_value) {}
150 
151 scoped_refptr<base::SingleThreadTaskRunner>
GetTaskRunnerForBodyLoader()152 WebURLLoaderMock::GetTaskRunnerForBodyLoader() {
153   return base::MakeRefCounted<scheduler::FakeTaskRunner>();
154 }
155 
GetWeakPtr()156 base::WeakPtr<WebURLLoaderMock> WebURLLoaderMock::GetWeakPtr() {
157   return weak_factory_.GetWeakPtr();
158 }
159 
160 } // namespace blink
161