Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(462)

Side by Side Diff: content/browser/appcache/appcache_url_loader_job.cc

Issue 2902653002: Get main frame and subframe AppCache loads to work. (Closed)
Patch Set: Use weak ptr in the url loader job through out. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2017 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/browser/appcache/appcache_url_loader_job.h" 5 #include "content/browser/appcache/appcache_url_loader_job.h"
6 #include "content/browser/appcache/appcache_entry.h" 6 #include "content/browser/appcache/appcache_histograms.h"
7 #include "content/browser/url_loader_factory_getter.h"
8 #include "content/common/net_adapters.h"
9 #include "content/public/common/resource_type.h"
7 10
8 namespace content { 11 namespace content {
9 12
10 AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {} 13 AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {}
11 14
12 void AppCacheURLLoaderJob::Kill() {} 15 void AppCacheURLLoaderJob::Kill() {}
13 16
14 bool AppCacheURLLoaderJob::IsStarted() const { 17 bool AppCacheURLLoaderJob::IsStarted() const {
15 return false; 18 return delivery_type_ != AWAITING_DELIVERY_ORDERS;
16 }
17
18 bool AppCacheURLLoaderJob::IsWaiting() const {
19 return false;
20 }
21
22 bool AppCacheURLLoaderJob::IsDeliveringAppCacheResponse() const {
23 return false;
24 }
25
26 bool AppCacheURLLoaderJob::IsDeliveringNetworkResponse() const {
27 return false;
28 }
29
30 bool AppCacheURLLoaderJob::IsDeliveringErrorResponse() const {
31 return false;
32 }
33
34 bool AppCacheURLLoaderJob::IsCacheEntryNotFound() const {
35 return false;
36 } 19 }
37 20
38 void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url, 21 void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
39 int64_t cache_id, 22 int64_t cache_id,
40 const AppCacheEntry& entry, 23 const AppCacheEntry& entry,
41 bool is_fallback) {} 24 bool is_fallback) {
42 25 delivery_type_ = APPCACHED_DELIVERY;
43 void AppCacheURLLoaderJob::DeliverNetworkResponse() {} 26
44 27 AppCacheHistograms::AddAppCacheJobStartDelaySample(base::TimeTicks::Now() -
45 void AppCacheURLLoaderJob::DeliverErrorResponse() {} 28 start_time_tick_);
29
30 manifest_url_ = manifest_url;
31 cache_id_ = cache_id;
32 entry_ = entry;
33 is_fallback_ = is_fallback;
34
35 storage_->LoadResponseInfo(manifest_url_, entry_.response_id(), this);
michaeln 2017/06/09 02:06:18 Unfortunately, the rawptr is a problem We're goin
ananta 2017/06/09 04:48:19 I added a call to CancelDelegateCallbacks in the d
michaeln 2017/06/09 19:59:53 The other class is actually safe but its not at al
36 }
37
38 void AppCacheURLLoaderJob::DeliverNetworkResponse() {
39 delivery_type_ = NETWORK_DELIVERY;
40
41 AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() -
42 start_time_tick_);
43
44 // In network service land, if we are processing a navigation request, we
45 // need to inform the loader callback that we are not going to handle this
46 // request. The loader callback is valid only for navigation requests.
47 if (!loader_callback_.is_null()) {
48 std::move(loader_callback_).Run(StartLoaderCallback());
49 return;
50 }
51
52 url_loader_factory_getter_->GetNetworkFactory()->get()->CreateLoaderAndStart(
michaeln 2017/06/09 01:48:29 We don't yet know if there will be a chain of hand
ananta 2017/06/09 04:48:19 Removed
53 mojo::MakeRequest(&url_loader_network_), routing_id_, request_id_,
54 mojom::kURLLoadOptionSendSSLInfo, request_, std::move(client_info_));
55 }
56
57 void AppCacheURLLoaderJob::DeliverErrorResponse() {
58 delivery_type_ = ERROR_DELIVERY;
59
60 // TODO(ananta)
61 // Fill up the correct error code here and add support in NotifyError() to
62 // generate a proper error response.
63 NotifyCompleted(net::ERR_UNEXPECTED);
64
65 AppCacheHistograms::AddErrorJobStartDelaySample(base::TimeTicks::Now() -
66 start_time_tick_);
67 }
46 68
47 const GURL& AppCacheURLLoaderJob::GetURL() const { 69 const GURL& AppCacheURLLoaderJob::GetURL() const {
48 return url_; 70 return request_.url;
49 } 71 }
50 72
51 AppCacheURLLoaderJob::AppCacheURLLoaderJob() {} 73 AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() {
74 return this;
75 }
76
77 void AppCacheURLLoaderJob::FollowRedirect() {
78 if (url_loader_network_)
79 url_loader_network_->FollowRedirect();
80 }
81
82 void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority,
83 int32_t intra_priority_value) {
84 NOTREACHED() << "We don't support SetPriority()";
85 }
86
87 void AppCacheURLLoaderJob::Start(int routing_id,
88 int request_id,
89 mojom::URLLoaderRequest request,
90 mojom::URLLoaderClientPtr client) {
91 DCHECK(!binding_.is_bound());
92 binding_.Bind(std::move(request));
93
94 binding_.set_connection_error_handler(base::Bind(
95 &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this)));
96
97 routing_id_ = routing_id;
98 request_id_ = request_id;
99
100 client_info_ = std::move(client);
101
102 // Send the cached AppCacheResponse if any.
103 if (info_.get())
104 SendResponseInfo();
105 }
106
107 void AppCacheURLLoaderJob::SetURLLoaderFactoryGetter(
108 URLLoaderFactoryGetter* url_loader_factory_getter) {
109 url_loader_factory_getter_ = url_loader_factory_getter;
110 }
111
112 AppCacheURLLoaderJob::AppCacheURLLoaderJob(const ResourceRequest& request,
113 AppCacheStorage* storage)
114 : request_(request),
115 storage_(storage),
116 start_time_tick_(base::TimeTicks::Now()),
117 cache_id_(kAppCacheNoCacheId),
118 is_fallback_(false),
119 buffer_(nullptr),
120 binding_(this),
121 routing_id_(-1),
122 request_id_(-1),
123 writable_handle_watcher_(FROM_HERE,
124 mojo::SimpleWatcher::ArmingPolicy::MANUAL) {}
125
126 void AppCacheURLLoaderJob::OnResponseInfoLoaded(
127 AppCacheResponseInfo* response_info,
128 int64_t response_id) {
129 DCHECK(IsDeliveringAppCacheResponse());
130
131 if (response_info) {
132 info_ = response_info;
133 reader_.reset(
134 storage_->CreateResponseReader(manifest_url_, entry_.response_id()));
135
136 if (!loader_callback_.is_null()) {
michaeln 2017/06/09 01:48:30 in our current use case, navigation, this is never
ananta 2017/06/09 04:48:19 Replaced with a DCHECK
137 std::move(loader_callback_)
138 .Run(base::Bind(&AppCacheURLLoaderJob::Start, StaticAsWeakPtr(this),
139 0, 0));
140 }
141
142 // TODO(ananta)
143 // Handle range requests.
144
145 response_body_stream_ = std::move(data_pipe_.producer_handle);
146
147 // Wait for the data pipe to be ready to accept data.
148 writable_handle_watcher_.Watch(
149 response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
150 base::Bind(&AppCacheURLLoaderJob::OnResponseBodyStreamReady,
michaeln 2017/06/09 01:48:29 is it possible/expected for OnResponseBodyStreamRe
ananta 2017/06/09 04:48:19 It is on the same thread?. Unless I am missing som
151 StaticAsWeakPtr(this)));
152
153 if (client_info_)
154 SendResponseInfo();
155
156 ReadMore();
157 } else {
158 // Error case here. We fallback to the network.
159 // TODO(ananta)
160 // Should we be invoking the loader callback here to give control to the
161 // next handler in the chain?.
michaeln 2017/06/09 01:48:29 The TODO comment seems stale or misplaced, for nav
ananta 2017/06/09 04:48:19 Thanks. Removed the comment.
162 DeliverNetworkResponse();
163 AppCacheHistograms::CountResponseRetrieval(
164 false, IsResourceTypeFrame(request_.resource_type),
165 manifest_url_.GetOrigin());
166
167 cache_entry_not_found_ = true;
168 }
169 }
170
171 void AppCacheURLLoaderJob::OnCacheLoaded(AppCache* cache, int64_t cache_id) {
172 NOTREACHED() << "Unhandled at the moment.";
173 }
174
175 void AppCacheURLLoaderJob::OnReadComplete(int result) {
176 DLOG(WARNING) << "AppCache read completed with result: " << result;
177
178 bool is_main_resource = IsResourceTypeFrame(request_.resource_type);
179
180 if (result == 0) {
181 NotifyCompleted(result);
182 AppCacheHistograms::CountResponseRetrieval(true, is_main_resource,
183 manifest_url_.GetOrigin());
michaeln 2017/06/09 01:48:30 you could early return here and avoid the if (resu
ananta 2017/06/09 04:48:19 Done.
184 } else if (result < 0) {
185 // TODO(ananta)
186 // Populate the relevant fields of the ResourceRequestCompletionStatus
187 // structure.
188 NotifyCompleted(result);
189 AppCacheHistograms::CountResponseRetrieval(false, is_main_resource,
190 manifest_url_.GetOrigin());
191 return;
192 }
193
194 if (result > 0) {
195 uint32_t bytes_written = static_cast<uint32_t>(result);
196 response_body_stream_ = pending_write_->Complete(bytes_written);
197 pending_write_ = nullptr;
198 ReadMore();
199 }
200 }
201
202 void AppCacheURLLoaderJob::OnConnectionError() {
203 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
204 }
205
206 void AppCacheURLLoaderJob::SendResponseInfo() {
207 DCHECK(client_info_);
208
209 // If this is null it means the response information was sent to the client.
210 if (!data_pipe_.consumer_handle.is_valid())
211 return;
212
213 const net::HttpResponseInfo* http_info = info_->http_response_info();
214
215 ResourceResponseHead response_head;
216 response_head.headers = http_info->headers;
217
218 // TODO(ananta)
219 // Copy more fields.
220 http_info->headers->GetMimeType(&response_head.mime_type);
221 http_info->headers->GetCharset(&response_head.charset);
222
223 response_head.request_time = http_info->request_time;
224 response_head.response_time = http_info->response_time;
225 response_head.content_length = info_->response_data_size();
226
227 client_info_->OnReceiveResponse(response_head, http_info->ssl_info,
228 mojom::DownloadedTempFilePtr());
229
230 client_info_->OnStartLoadingResponseBody(
231 std::move(data_pipe_.consumer_handle));
232 }
233
234 void AppCacheURLLoaderJob::ReadMore() {
235 DCHECK(!pending_write_.get());
236
237 uint32_t num_bytes;
238 // TODO: we should use the abstractions in MojoAsyncResourceHandler.
239 MojoResult result = NetToMojoPendingBuffer::BeginWrite(
240 &response_body_stream_, &pending_write_, &num_bytes);
241 if (result == MOJO_RESULT_SHOULD_WAIT) {
242 // The pipe is full. We need to wait for it to have more space.
243 writable_handle_watcher_.ArmOrNotify();
244 return;
245 } else if (result != MOJO_RESULT_OK) {
246 // The response body stream is in a bad state. Bail.
247 // TODO: How should this be communicated to our client?
michaeln 2017/06/09 01:48:29 Probably NotifyComplete(ERR)? As coded will progre
ananta 2017/06/09 04:48:19 Added a call to NotifyCompleted here.
248 writable_handle_watcher_.Cancel();
249 response_body_stream_.reset();
250 return;
251 }
252
253 CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes);
254 buffer_ = nullptr;
255 buffer_ = new NetToMojoIOBuffer(pending_write_.get());
michaeln 2017/06/09 01:48:29 Is the buffer_ data member is needed? It's only ac
ananta 2017/06/09 04:48:19 The buffer_ member should not be needed I think. R
256
257 reader_->ReadData(
258 buffer_.get(), info_->response_data_size(),
259 base::Bind(&AppCacheURLLoaderJob::OnReadComplete, StaticAsWeakPtr(this)));
260 }
261
262 void AppCacheURLLoaderJob::OnResponseBodyStreamReady(MojoResult result) {
263 // TODO: Handle a bad |result| value.
michaeln 2017/06/09 01:48:30 ditto probably NotifyComplete(ERR)
ananta 2017/06/09 04:48:19 Done.
264 DCHECK_EQ(result, MOJO_RESULT_OK);
265 ReadMore();
266 }
267
268 void AppCacheURLLoaderJob::NotifyCompleted(int error_code) {
269 // TODO(ananta)
270 // Fill other details in the ResourceRequestCompletionStatus structure.
271 // In case of an error we may need to call OnReceiveResponse on the client.
272 // That requires HTTP header generation etc.
michaeln 2017/06/09 01:48:29 I think we only need http header generation and a
ananta 2017/06/09 04:48:19 Thanks. moved this comment to the DeliverErrorResp
273 ResourceRequestCompletionStatus request_complete_data;
274 request_complete_data.error_code = error_code;
275 client_info_->OnComplete(request_complete_data);
276 }
52 277
53 } // namespace content 278 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698