OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/renderer/fetchers/resource_fetcher_impl.h" | 5 #include "content/renderer/fetchers/resource_fetcher_impl.h" |
6 | 6 |
7 #include <stdint.h> | |
8 | |
7 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/macros.h" | |
8 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
9 #include "base/time/time.h" | 12 #include "base/time/time.h" |
10 #include "third_party/WebKit/public/platform/Platform.h" | 13 #include "third_party/WebKit/public/platform/Platform.h" |
11 #include "third_party/WebKit/public/platform/WebHTTPBody.h" | 14 #include "third_party/WebKit/public/platform/WebHTTPBody.h" |
12 #include "third_party/WebKit/public/platform/WebString.h" | 15 #include "third_party/WebKit/public/platform/WebString.h" |
13 #include "third_party/WebKit/public/platform/WebURL.h" | 16 #include "third_party/WebKit/public/platform/WebURL.h" |
17 #include "third_party/WebKit/public/platform/WebURLError.h" | |
14 #include "third_party/WebKit/public/platform/WebURLLoader.h" | 18 #include "third_party/WebKit/public/platform/WebURLLoader.h" |
15 #include "third_party/WebKit/public/platform/WebURLRequest.h" | 19 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h" |
20 #include "third_party/WebKit/public/platform/WebURLResponse.h" | |
16 #include "third_party/WebKit/public/web/WebDocument.h" | 21 #include "third_party/WebKit/public/web/WebDocument.h" |
17 #include "third_party/WebKit/public/web/WebFrame.h" | 22 #include "third_party/WebKit/public/web/WebFrame.h" |
18 #include "third_party/WebKit/public/web/WebKit.h" | 23 #include "third_party/WebKit/public/web/WebKit.h" |
19 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" | 24 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" |
20 | 25 |
21 namespace content { | 26 namespace content { |
22 | 27 |
23 // static | 28 // static |
24 ResourceFetcher* ResourceFetcher::Create(const GURL& url) { | 29 ResourceFetcher* ResourceFetcher::Create(const GURL& url) { |
25 return new ResourceFetcherImpl(url); | 30 return new ResourceFetcherImpl(url); |
26 } | 31 } |
27 | 32 |
33 class ResourceFetcherImpl::ClientImpl : public blink::WebURLLoaderClient { | |
34 public: | |
35 ClientImpl(ResourceFetcherImpl* parent, const Callback& callback) | |
36 : parent_(parent), | |
37 completed_(false), | |
38 status_(LOADING), | |
39 callback_(callback) {} | |
40 | |
41 ~ClientImpl() override {} | |
42 | |
43 virtual void Cancel() { OnLoadCompleteInternal(LOAD_FAILED); } | |
44 | |
45 bool completed() const { return completed_; } | |
46 | |
47 private: | |
48 enum LoadStatus { | |
49 LOADING, | |
50 LOAD_FAILED, | |
51 LOAD_SUCCEEDED, | |
52 }; | |
53 | |
54 void OnLoadCompleteInternal(LoadStatus status) { | |
55 DCHECK(!completed_); | |
56 DCHECK(status_ == LOADING); | |
57 | |
58 completed_ = true; | |
59 status_ = status; | |
60 | |
61 parent_->OnLoadComplete(); | |
62 | |
63 if (callback_.is_null()) | |
64 return; | |
65 | |
66 // Take a reference to the callback as running the callback may lead to our | |
67 // destruction. | |
68 Callback callback = callback_; | |
69 callback.Run(status_ == LOAD_FAILED ? blink::WebURLResponse() : response_, | |
70 status_ == LOAD_FAILED ? std::string() : data_); | |
71 } | |
72 | |
73 // WebURLLoaderClient methods: | |
74 void didReceiveResponse(blink::WebURLLoader* loader, | |
75 const blink::WebURLResponse& response) override { | |
76 DCHECK(!completed_); | |
77 response_ = response; | |
78 } | |
79 void didReceiveCachedMetadata(blink::WebURLLoader* loader, | |
80 const char* data, | |
81 int data_length) override { | |
82 DCHECK(!completed_); | |
83 DCHECK(data_length > 0); | |
84 } | |
85 void didReceiveData(blink::WebURLLoader* loader, | |
86 const char* data, | |
87 int data_length, | |
88 int encoded_data_length, | |
89 int encoded_body_length) override { | |
90 // The AssociatedURLLoader will continue after a load failure. | |
kinuko
2016/10/14 03:15:20
Do we still need these behaviors in this class?
tyoshino (SeeGerritForStatus)
2016/10/14 06:12:06
Good catch! Replaced this and one in didFinishLoad
| |
91 // For example, for an Access Control error. | |
92 if (completed_) | |
93 return; | |
94 DCHECK(data_length > 0); | |
95 | |
96 data_.append(data, data_length); | |
97 } | |
98 void didFinishLoading(blink::WebURLLoader* loader, | |
99 double finishTime, | |
100 int64_t total_encoded_data_length) override { | |
101 // The AssociatedURLLoader will continue after a load failure. | |
102 // For example, for an Access Control error. | |
103 if (completed_) | |
104 return; | |
105 OnLoadCompleteInternal(LOAD_SUCCEEDED); | |
106 } | |
107 void didFail(blink::WebURLLoader* loader, | |
108 const blink::WebURLError& error) override { | |
109 OnLoadCompleteInternal(LOAD_FAILED); | |
110 } | |
111 | |
112 private: | |
113 ResourceFetcherImpl* parent_; | |
114 | |
115 // Set to true once the request is complete. | |
116 bool completed_; | |
117 | |
118 // Buffer to hold the content from the server. | |
119 std::string data_; | |
120 | |
121 // A copy of the original resource response. | |
122 blink::WebURLResponse response_; | |
123 | |
124 LoadStatus status_; | |
125 | |
126 // Callback when we're done. | |
127 Callback callback_; | |
128 | |
129 DISALLOW_COPY_AND_ASSIGN(ClientImpl); | |
130 }; | |
131 | |
28 ResourceFetcherImpl::ResourceFetcherImpl(const GURL& url) | 132 ResourceFetcherImpl::ResourceFetcherImpl(const GURL& url) |
29 : request_(url) { | 133 : request_(url) { |
30 } | 134 } |
31 | 135 |
32 ResourceFetcherImpl::~ResourceFetcherImpl() { | 136 ResourceFetcherImpl::~ResourceFetcherImpl() { |
33 if (!completed() && loader_) | 137 if (!loader_) |
138 return; | |
139 | |
140 DCHECK(client_); | |
141 | |
142 if (!client_->completed()) | |
34 loader_->cancel(); | 143 loader_->cancel(); |
35 } | 144 } |
36 | 145 |
37 void ResourceFetcherImpl::SetMethod(const std::string& method) { | 146 void ResourceFetcherImpl::SetMethod(const std::string& method) { |
38 DCHECK(!request_.isNull()); | 147 DCHECK(!request_.isNull()); |
39 DCHECK(!loader_); | 148 DCHECK(!loader_); |
40 | 149 |
41 request_.setHTTPMethod(blink::WebString::fromUTF8(method)); | 150 request_.setHTTPMethod(blink::WebString::fromUTF8(method)); |
42 } | 151 } |
43 | 152 |
(...skipping 18 matching lines...) Expand all Loading... | |
62 blink::WebReferrerPolicyDefault, | 171 blink::WebReferrerPolicyDefault, |
63 request_.url(), | 172 request_.url(), |
64 blink::WebString::fromUTF8(value)); | 173 blink::WebString::fromUTF8(value)); |
65 request_.setHTTPReferrer(referrer, blink::WebReferrerPolicyDefault); | 174 request_.setHTTPReferrer(referrer, blink::WebReferrerPolicyDefault); |
66 } else { | 175 } else { |
67 request_.setHTTPHeaderField(blink::WebString::fromUTF8(header), | 176 request_.setHTTPHeaderField(blink::WebString::fromUTF8(header), |
68 blink::WebString::fromUTF8(value)); | 177 blink::WebString::fromUTF8(value)); |
69 } | 178 } |
70 } | 179 } |
71 | 180 |
72 void ResourceFetcherImpl::SetSkipServiceWorker( | |
73 blink::WebURLRequest::SkipServiceWorker skip_service_worker) { | |
74 DCHECK(!request_.isNull()); | |
75 DCHECK(!loader_); | |
76 | |
77 request_.setSkipServiceWorker(skip_service_worker); | |
78 } | |
79 | |
80 void ResourceFetcherImpl::SetCachePolicy(blink::WebCachePolicy policy) { | |
81 DCHECK(!request_.isNull()); | |
82 DCHECK(!loader_); | |
83 | |
84 request_.setCachePolicy(policy); | |
85 } | |
86 | |
87 void ResourceFetcherImpl::SetLoaderOptions( | |
88 const blink::WebURLLoaderOptions& options) { | |
89 DCHECK(!request_.isNull()); | |
90 DCHECK(!loader_); | |
91 | |
92 options_ = options; | |
93 } | |
94 | |
95 void ResourceFetcherImpl::Start( | 181 void ResourceFetcherImpl::Start( |
96 blink::WebFrame* frame, | 182 blink::WebFrame* frame, |
97 blink::WebURLRequest::RequestContext request_context, | 183 blink::WebURLRequest::RequestContext request_context, |
98 blink::WebURLRequest::FrameType frame_type, | 184 blink::WebURLRequest::FrameType frame_type, |
99 LoaderType loader_type, | |
100 const Callback& callback) { | 185 const Callback& callback) { |
101 DCHECK(!loader_); | 186 DCHECK(!loader_); |
187 DCHECK(!client_); | |
102 DCHECK(!request_.isNull()); | 188 DCHECK(!request_.isNull()); |
103 DCHECK(callback_.is_null()); | |
104 DCHECK(!completed()); | |
105 if (!request_.httpBody().isNull()) | 189 if (!request_.httpBody().isNull()) |
106 DCHECK_NE("GET", request_.httpMethod().utf8()) << "GETs can't have bodies."; | 190 DCHECK_NE("GET", request_.httpMethod().utf8()) << "GETs can't have bodies."; |
107 | 191 |
108 callback_ = callback; | |
109 | |
110 request_.setRequestContext(request_context); | 192 request_.setRequestContext(request_context); |
111 request_.setFrameType(frame_type); | 193 request_.setFrameType(frame_type); |
112 request_.setFirstPartyForCookies(frame->document().firstPartyForCookies()); | 194 request_.setFirstPartyForCookies(frame->document().firstPartyForCookies()); |
113 frame->dispatchWillSendRequest(request_); | 195 frame->dispatchWillSendRequest(request_); |
114 | 196 |
115 switch (loader_type) { | 197 client_.reset(new ClientImpl(this, callback)); |
116 case PLATFORM_LOADER: | 198 |
117 loader_.reset(blink::Platform::current()->createURLLoader()); | 199 loader_.reset(blink::Platform::current()->createURLLoader()); |
118 break; | 200 loader_->loadAsynchronously(request_, client_.get()); |
119 case FRAME_ASSOCIATED_LOADER: | |
120 loader_.reset(frame->createAssociatedURLLoader(options_)); | |
121 break; | |
122 } | |
123 loader_->loadAsynchronously(request_, this); | |
124 | 201 |
125 // No need to hold on to the request; reset it now. | 202 // No need to hold on to the request; reset it now. |
126 request_ = blink::WebURLRequest(); | 203 request_ = blink::WebURLRequest(); |
127 } | 204 } |
128 | 205 |
129 void ResourceFetcherImpl::SetTimeout(const base::TimeDelta& timeout) { | 206 void ResourceFetcherImpl::SetTimeout(const base::TimeDelta& timeout) { |
130 DCHECK(loader_); | 207 DCHECK(loader_); |
131 DCHECK(!completed()); | 208 DCHECK(client_); |
209 DCHECK(!client_->completed()); | |
132 | 210 |
133 timeout_timer_.Start(FROM_HERE, timeout, this, &ResourceFetcherImpl::Cancel); | 211 timeout_timer_.Start(FROM_HERE, timeout, this, &ResourceFetcherImpl::Cancel); |
134 } | 212 } |
135 | 213 |
136 void ResourceFetcherImpl::OnLoadComplete() { | 214 void ResourceFetcherImpl::OnLoadComplete() { |
137 timeout_timer_.Stop(); | 215 timeout_timer_.Stop(); |
138 if (callback_.is_null()) | |
139 return; | |
140 | |
141 // Take a reference to the callback as running the callback may lead to our | |
142 // destruction. | |
143 Callback callback = callback_; | |
144 callback.Run(status() == LOAD_FAILED ? blink::WebURLResponse() : response(), | |
145 status() == LOAD_FAILED ? std::string() : data()); | |
146 } | 216 } |
147 | 217 |
148 void ResourceFetcherImpl::Cancel() { | 218 void ResourceFetcherImpl::Cancel() { |
149 loader_->cancel(); | 219 loader_->cancel(); |
150 WebURLLoaderClientImpl::Cancel(); | 220 client_->Cancel(); |
151 } | 221 } |
152 | 222 |
153 } // namespace content | 223 } // namespace content |
OLD | NEW |