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/browser/appcache/appcache_url_request_job.h" | 5 #include "content/browser/appcache/appcache_url_request_job.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "net/http/http_request_headers.h" | 25 #include "net/http/http_request_headers.h" |
26 #include "net/http/http_response_headers.h" | 26 #include "net/http/http_response_headers.h" |
27 #include "net/http/http_util.h" | 27 #include "net/http/http_util.h" |
28 #include "net/log/net_log_event_type.h" | 28 #include "net/log/net_log_event_type.h" |
29 #include "net/log/net_log_with_source.h" | 29 #include "net/log/net_log_with_source.h" |
30 #include "net/url_request/url_request.h" | 30 #include "net/url_request/url_request.h" |
31 #include "net/url_request/url_request_status.h" | 31 #include "net/url_request/url_request_status.h" |
32 | 32 |
33 namespace content { | 33 namespace content { |
34 | 34 |
35 AppCacheURLRequestJob::AppCacheURLRequestJob( | |
36 net::URLRequest* request, | |
37 net::NetworkDelegate* network_delegate, | |
38 AppCacheStorage* storage, | |
39 AppCacheHost* host, | |
40 bool is_main_resource, | |
41 const OnPrepareToRestartCallback& restart_callback) | |
42 : net::URLRequestJob(request, network_delegate), | |
43 host_(host), | |
44 storage_(storage), | |
45 has_been_started_(false), | |
46 has_been_killed_(false), | |
47 delivery_type_(AWAITING_DELIVERY_ORDERS), | |
48 cache_id_(kAppCacheNoCacheId), | |
49 is_fallback_(false), | |
50 is_main_resource_(is_main_resource), | |
51 cache_entry_not_found_(false), | |
52 on_prepare_to_restart_callback_(restart_callback), | |
53 weak_factory_(this) { | |
54 DCHECK(storage_); | |
55 } | |
56 | |
57 AppCacheURLRequestJob::~AppCacheURLRequestJob() { | 35 AppCacheURLRequestJob::~AppCacheURLRequestJob() { |
58 if (storage_) | 36 if (storage_) |
59 storage_->CancelDelegateCallbacks(this); | 37 storage_->CancelDelegateCallbacks(this); |
60 } | 38 } |
61 | 39 |
| 40 void AppCacheURLRequestJob::Kill() { |
| 41 if (!has_been_killed_) { |
| 42 has_been_killed_ = true; |
| 43 reader_.reset(); |
| 44 handler_source_reader_.reset(); |
| 45 if (storage_) { |
| 46 storage_->CancelDelegateCallbacks(this); |
| 47 storage_ = NULL; |
| 48 } |
| 49 host_ = NULL; |
| 50 info_ = NULL; |
| 51 cache_ = NULL; |
| 52 group_ = NULL; |
| 53 range_response_info_.reset(); |
| 54 net::URLRequestJob::Kill(); |
| 55 AppCacheJob::weak_factory_.InvalidateWeakPtrs(); |
| 56 } |
| 57 } |
| 58 |
| 59 bool AppCacheURLRequestJob::IsStarted() const { |
| 60 return has_been_started_; |
| 61 } |
| 62 |
| 63 bool AppCacheURLRequestJob::IsWaiting() const { |
| 64 return delivery_type_ == AWAITING_DELIVERY_ORDERS; |
| 65 } |
| 66 |
| 67 bool AppCacheURLRequestJob::IsDeliveringAppCacheResponse() const { |
| 68 return delivery_type_ == APPCACHED_DELIVERY; |
| 69 } |
| 70 |
| 71 bool AppCacheURLRequestJob::IsDeliveringNetworkResponse() const { |
| 72 return delivery_type_ == NETWORK_DELIVERY; |
| 73 } |
| 74 |
| 75 bool AppCacheURLRequestJob::IsDeliveringErrorResponse() const { |
| 76 return delivery_type_ == ERROR_DELIVERY; |
| 77 } |
| 78 |
| 79 bool AppCacheURLRequestJob::IsCacheEntryNotFound() const { |
| 80 return cache_entry_not_found_; |
| 81 } |
| 82 |
62 void AppCacheURLRequestJob::DeliverAppCachedResponse(const GURL& manifest_url, | 83 void AppCacheURLRequestJob::DeliverAppCachedResponse(const GURL& manifest_url, |
63 int64_t cache_id, | 84 int64_t cache_id, |
64 const AppCacheEntry& entry, | 85 const AppCacheEntry& entry, |
65 bool is_fallback) { | 86 bool is_fallback) { |
66 DCHECK(!has_delivery_orders()); | 87 DCHECK(!has_delivery_orders()); |
67 DCHECK(entry.has_response_id()); | 88 DCHECK(entry.has_response_id()); |
68 delivery_type_ = APPCACHED_DELIVERY; | 89 delivery_type_ = APPCACHED_DELIVERY; |
69 manifest_url_ = manifest_url; | 90 manifest_url_ = manifest_url; |
70 cache_id_ = cache_id; | 91 cache_id_ = cache_id; |
71 entry_ = entry; | 92 entry_ = entry; |
72 is_fallback_ = is_fallback; | 93 is_fallback_ = is_fallback; |
73 MaybeBeginDelivery(); | 94 MaybeBeginDelivery(); |
74 } | 95 } |
75 | 96 |
76 void AppCacheURLRequestJob::DeliverNetworkResponse() { | 97 void AppCacheURLRequestJob::DeliverNetworkResponse() { |
77 DCHECK(!has_delivery_orders()); | 98 DCHECK(!has_delivery_orders()); |
78 delivery_type_ = NETWORK_DELIVERY; | 99 delivery_type_ = NETWORK_DELIVERY; |
79 storage_ = NULL; // not needed | 100 storage_ = NULL; // not needed |
80 MaybeBeginDelivery(); | 101 MaybeBeginDelivery(); |
81 } | 102 } |
82 | 103 |
83 void AppCacheURLRequestJob::DeliverErrorResponse() { | 104 void AppCacheURLRequestJob::DeliverErrorResponse() { |
84 DCHECK(!has_delivery_orders()); | 105 DCHECK(!has_delivery_orders()); |
85 delivery_type_ = ERROR_DELIVERY; | 106 delivery_type_ = ERROR_DELIVERY; |
86 storage_ = NULL; // not needed | 107 storage_ = NULL; // not needed |
87 MaybeBeginDelivery(); | 108 MaybeBeginDelivery(); |
88 } | 109 } |
89 | 110 |
90 base::WeakPtr<AppCacheURLRequestJob> AppCacheURLRequestJob::GetWeakPtr() { | 111 const GURL& AppCacheURLRequestJob::GetURL() const { |
91 return weak_factory_.GetWeakPtr(); | 112 return request()->url(); |
| 113 } |
| 114 |
| 115 net::URLRequestJob* AppCacheURLRequestJob::AsURLRequestJob() { |
| 116 return this; |
| 117 } |
| 118 |
| 119 AppCacheURLRequestJob::AppCacheURLRequestJob( |
| 120 net::URLRequest* request, |
| 121 net::NetworkDelegate* network_delegate, |
| 122 AppCacheStorage* storage, |
| 123 AppCacheHost* host, |
| 124 bool is_main_resource, |
| 125 const OnPrepareToRestartCallback& restart_callback) |
| 126 : net::URLRequestJob(request, network_delegate), |
| 127 host_(host), |
| 128 storage_(storage), |
| 129 has_been_started_(false), |
| 130 has_been_killed_(false), |
| 131 delivery_type_(AWAITING_DELIVERY_ORDERS), |
| 132 cache_id_(kAppCacheNoCacheId), |
| 133 is_fallback_(false), |
| 134 is_main_resource_(is_main_resource), |
| 135 cache_entry_not_found_(false), |
| 136 on_prepare_to_restart_callback_(restart_callback) { |
| 137 DCHECK(storage_); |
92 } | 138 } |
93 | 139 |
94 void AppCacheURLRequestJob::MaybeBeginDelivery() { | 140 void AppCacheURLRequestJob::MaybeBeginDelivery() { |
95 if (has_been_started() && has_delivery_orders()) { | 141 if (IsStarted() && has_delivery_orders()) { |
96 // Start asynchronously so that all error reporting and data | 142 // Start asynchronously so that all error reporting and data |
97 // callbacks happen as they would for network requests. | 143 // callbacks happen as they would for network requests. |
98 base::ThreadTaskRunnerHandle::Get()->PostTask( | 144 base::ThreadTaskRunnerHandle::Get()->PostTask( |
99 FROM_HERE, base::Bind(&AppCacheURLRequestJob::BeginDelivery, | 145 FROM_HERE, base::Bind(&AppCacheURLRequestJob::BeginDelivery, |
100 weak_factory_.GetWeakPtr())); | 146 StaticAsWeakPtr(this))); |
101 } | 147 } |
102 } | 148 } |
103 | 149 |
104 void AppCacheURLRequestJob::BeginDelivery() { | 150 void AppCacheURLRequestJob::BeginDelivery() { |
105 DCHECK(has_delivery_orders() && has_been_started()); | 151 DCHECK(has_delivery_orders() && IsStarted()); |
106 | 152 |
107 if (has_been_killed()) | 153 if (has_been_killed()) |
108 return; | 154 return; |
109 | 155 |
110 switch (delivery_type_) { | 156 switch (delivery_type_) { |
111 case NETWORK_DELIVERY: | 157 case NETWORK_DELIVERY: |
112 AppCacheHistograms::AddNetworkJobStartDelaySample( | 158 AppCacheHistograms::AddNetworkJobStartDelaySample( |
113 base::TimeTicks::Now() - start_time_tick_); | 159 base::TimeTicks::Now() - start_time_tick_); |
114 // To fallthru to the network, we restart the request which will | 160 // To fallthru to the network, we restart the request which will |
115 // cause a new job to be created to retrieve the resource from the | 161 // cause a new job to be created to retrieve the resource from the |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } | 275 } |
230 | 276 |
231 BeginErrorDelivery("factory failed to produce a handler"); | 277 BeginErrorDelivery("factory failed to produce a handler"); |
232 } | 278 } |
233 | 279 |
234 void AppCacheURLRequestJob::InvokeExecutableHandler( | 280 void AppCacheURLRequestJob::InvokeExecutableHandler( |
235 AppCacheExecutableHandler* handler) { | 281 AppCacheExecutableHandler* handler) { |
236 handler->HandleRequest( | 282 handler->HandleRequest( |
237 request(), | 283 request(), |
238 base::Bind(&AppCacheURLRequestJob::OnExecutableResponseCallback, | 284 base::Bind(&AppCacheURLRequestJob::OnExecutableResponseCallback, |
239 weak_factory_.GetWeakPtr())); | 285 StaticAsWeakPtr(this))); |
240 } | 286 } |
241 | 287 |
242 void AppCacheURLRequestJob::OnExecutableResponseCallback( | 288 void AppCacheURLRequestJob::OnExecutableResponseCallback( |
243 const AppCacheExecutableHandler::Response& response) { | 289 const AppCacheExecutableHandler::Response& response) { |
244 DCHECK(!has_been_killed()); | 290 DCHECK(!has_been_killed()); |
245 if (response.use_network) { | 291 if (response.use_network) { |
246 delivery_type_ = NETWORK_DELIVERY; | 292 delivery_type_ = NETWORK_DELIVERY; |
247 storage_ = NULL; | 293 storage_ = NULL; |
248 BeginDelivery(); | 294 BeginDelivery(); |
249 return; | 295 return; |
(...skipping 23 matching lines...) Expand all Loading... |
273 host_->frontend()->OnLogMessage(host_->host_id(), APPCACHE_LOG_ERROR, | 319 host_->frontend()->OnLogMessage(host_->host_id(), APPCACHE_LOG_ERROR, |
274 message); | 320 message); |
275 delivery_type_ = ERROR_DELIVERY; | 321 delivery_type_ = ERROR_DELIVERY; |
276 storage_ = NULL; | 322 storage_ = NULL; |
277 BeginDelivery(); | 323 BeginDelivery(); |
278 } | 324 } |
279 | 325 |
280 void AppCacheURLRequestJob::OnResponseInfoLoaded( | 326 void AppCacheURLRequestJob::OnResponseInfoLoaded( |
281 AppCacheResponseInfo* response_info, | 327 AppCacheResponseInfo* response_info, |
282 int64_t response_id) { | 328 int64_t response_id) { |
283 DCHECK(is_delivering_appcache_response()); | 329 DCHECK(IsDeliveringAppCacheResponse()); |
284 if (response_info) { | 330 if (response_info) { |
285 info_ = response_info; | 331 info_ = response_info; |
286 reader_.reset( | 332 reader_.reset( |
287 storage_->CreateResponseReader(manifest_url_, entry_.response_id())); | 333 storage_->CreateResponseReader(manifest_url_, entry_.response_id())); |
288 | 334 |
289 if (is_range_request()) | 335 if (is_range_request()) |
290 SetupRangeResponse(); | 336 SetupRangeResponse(); |
291 | 337 |
292 NotifyHeadersComplete(); | 338 NotifyHeadersComplete(); |
293 } else { | 339 } else { |
(...skipping 16 matching lines...) Expand all Loading... |
310 const net::HttpResponseInfo* AppCacheURLRequestJob::http_info() const { | 356 const net::HttpResponseInfo* AppCacheURLRequestJob::http_info() const { |
311 if (!info_.get()) | 357 if (!info_.get()) |
312 return NULL; | 358 return NULL; |
313 if (range_response_info_) | 359 if (range_response_info_) |
314 return range_response_info_.get(); | 360 return range_response_info_.get(); |
315 return info_->http_response_info(); | 361 return info_->http_response_info(); |
316 } | 362 } |
317 | 363 |
318 void AppCacheURLRequestJob::SetupRangeResponse() { | 364 void AppCacheURLRequestJob::SetupRangeResponse() { |
319 DCHECK(is_range_request() && info_.get() && reader_.get() && | 365 DCHECK(is_range_request() && info_.get() && reader_.get() && |
320 is_delivering_appcache_response()); | 366 IsDeliveringAppCacheResponse()); |
321 int resource_size = static_cast<int>(info_->response_data_size()); | 367 int resource_size = static_cast<int>(info_->response_data_size()); |
322 if (resource_size < 0 || !range_requested_.ComputeBounds(resource_size)) { | 368 if (resource_size < 0 || !range_requested_.ComputeBounds(resource_size)) { |
323 range_requested_ = net::HttpByteRange(); | 369 range_requested_ = net::HttpByteRange(); |
324 return; | 370 return; |
325 } | 371 } |
326 | 372 |
327 DCHECK(range_requested_.IsValid()); | 373 DCHECK(range_requested_.IsValid()); |
328 int offset = static_cast<int>(range_requested_.first_byte_position()); | 374 int offset = static_cast<int>(range_requested_.first_byte_position()); |
329 int length = static_cast<int>(range_requested_.last_byte_position() - | 375 int length = static_cast<int>(range_requested_.last_byte_position() - |
330 range_requested_.first_byte_position() + 1); | 376 range_requested_.first_byte_position() + 1); |
331 | 377 |
332 // Tell the reader about the range to read. | 378 // Tell the reader about the range to read. |
333 reader_->SetReadRange(offset, length); | 379 reader_->SetReadRange(offset, length); |
334 | 380 |
335 // Make a copy of the full response headers and fix them up | 381 // Make a copy of the full response headers and fix them up |
336 // for the range we'll be returning. | 382 // for the range we'll be returning. |
337 range_response_info_.reset( | 383 range_response_info_.reset( |
338 new net::HttpResponseInfo(*info_->http_response_info())); | 384 new net::HttpResponseInfo(*info_->http_response_info())); |
339 net::HttpResponseHeaders* headers = range_response_info_->headers.get(); | 385 net::HttpResponseHeaders* headers = range_response_info_->headers.get(); |
340 headers->UpdateWithNewRange( | 386 headers->UpdateWithNewRange( |
341 range_requested_, resource_size, true /* replace status line */); | 387 range_requested_, resource_size, true /* replace status line */); |
342 } | 388 } |
343 | 389 |
344 void AppCacheURLRequestJob::OnReadComplete(int result) { | 390 void AppCacheURLRequestJob::OnReadComplete(int result) { |
345 DCHECK(is_delivering_appcache_response()); | 391 DCHECK(IsDeliveringAppCacheResponse()); |
346 if (result == 0) { | 392 if (result == 0) { |
347 AppCacheHistograms::CountResponseRetrieval( | 393 AppCacheHistograms::CountResponseRetrieval( |
348 true, is_main_resource_, manifest_url_.GetOrigin()); | 394 true, is_main_resource_, manifest_url_.GetOrigin()); |
349 } else if (result < 0) { | 395 } else if (result < 0) { |
350 if (storage_->service()->storage() == storage_) { | 396 if (storage_->service()->storage() == storage_) { |
351 storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_, | 397 storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_, |
352 entry_.response_id()); | 398 entry_.response_id()); |
353 } | 399 } |
354 AppCacheHistograms::CountResponseRetrieval( | 400 AppCacheHistograms::CountResponseRetrieval( |
355 false, is_main_resource_, manifest_url_.GetOrigin()); | 401 false, is_main_resource_, manifest_url_.GetOrigin()); |
356 } | 402 } |
357 ReadRawDataComplete(result); | 403 ReadRawDataComplete(result); |
358 } | 404 } |
359 | 405 |
360 // net::URLRequestJob overrides ------------------------------------------------ | 406 // net::URLRequestJob overrides ------------------------------------------------ |
361 | 407 |
362 void AppCacheURLRequestJob::Start() { | 408 void AppCacheURLRequestJob::Start() { |
363 DCHECK(!has_been_started()); | 409 DCHECK(!IsStarted()); |
364 has_been_started_ = true; | 410 has_been_started_ = true; |
365 start_time_tick_ = base::TimeTicks::Now(); | 411 start_time_tick_ = base::TimeTicks::Now(); |
366 MaybeBeginDelivery(); | 412 MaybeBeginDelivery(); |
367 } | 413 } |
368 | 414 |
369 void AppCacheURLRequestJob::Kill() { | |
370 if (!has_been_killed_) { | |
371 has_been_killed_ = true; | |
372 reader_.reset(); | |
373 handler_source_reader_.reset(); | |
374 if (storage_) { | |
375 storage_->CancelDelegateCallbacks(this); | |
376 storage_ = NULL; | |
377 } | |
378 host_ = NULL; | |
379 info_ = NULL; | |
380 cache_ = NULL; | |
381 group_ = NULL; | |
382 range_response_info_.reset(); | |
383 net::URLRequestJob::Kill(); | |
384 weak_factory_.InvalidateWeakPtrs(); | |
385 } | |
386 } | |
387 | |
388 net::LoadState AppCacheURLRequestJob::GetLoadState() const { | 415 net::LoadState AppCacheURLRequestJob::GetLoadState() const { |
389 if (!has_been_started()) | 416 if (!IsStarted()) |
390 return net::LOAD_STATE_IDLE; | 417 return net::LOAD_STATE_IDLE; |
391 if (!has_delivery_orders()) | 418 if (!has_delivery_orders()) |
392 return net::LOAD_STATE_WAITING_FOR_APPCACHE; | 419 return net::LOAD_STATE_WAITING_FOR_APPCACHE; |
393 if (delivery_type_ != APPCACHED_DELIVERY) | 420 if (delivery_type_ != APPCACHED_DELIVERY) |
394 return net::LOAD_STATE_IDLE; | 421 return net::LOAD_STATE_IDLE; |
395 if (!info_.get()) | 422 if (!info_.get()) |
396 return net::LOAD_STATE_WAITING_FOR_APPCACHE; | 423 return net::LOAD_STATE_WAITING_FOR_APPCACHE; |
397 if (reader_.get() && reader_->IsReadPending()) | 424 if (reader_.get() && reader_->IsReadPending()) |
398 return net::LOAD_STATE_READING_RESPONSE; | 425 return net::LOAD_STATE_READING_RESPONSE; |
399 return net::LOAD_STATE_IDLE; | 426 return net::LOAD_STATE_IDLE; |
(...skipping 11 matching lines...) Expand all Loading... |
411 return http_info()->headers->GetCharset(charset); | 438 return http_info()->headers->GetCharset(charset); |
412 } | 439 } |
413 | 440 |
414 void AppCacheURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { | 441 void AppCacheURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { |
415 if (!http_info()) | 442 if (!http_info()) |
416 return; | 443 return; |
417 *info = *http_info(); | 444 *info = *http_info(); |
418 } | 445 } |
419 | 446 |
420 int AppCacheURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) { | 447 int AppCacheURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) { |
421 DCHECK(is_delivering_appcache_response()); | 448 DCHECK(IsDeliveringAppCacheResponse()); |
422 DCHECK_NE(buf_size, 0); | 449 DCHECK_NE(buf_size, 0); |
423 DCHECK(!reader_->IsReadPending()); | 450 DCHECK(!reader_->IsReadPending()); |
424 reader_->ReadData(buf, buf_size, | 451 reader_->ReadData(buf, buf_size, |
425 base::Bind(&AppCacheURLRequestJob::OnReadComplete, | 452 base::Bind(&AppCacheURLRequestJob::OnReadComplete, |
426 base::Unretained(this))); | 453 base::Unretained(this))); |
427 return net::ERR_IO_PENDING; | 454 return net::ERR_IO_PENDING; |
428 } | 455 } |
429 | 456 |
430 net::HostPortPair AppCacheURLRequestJob::GetSocketAddress() const { | 457 net::HostPortPair AppCacheURLRequestJob::GetSocketAddress() const { |
431 if (!http_info()) | 458 if (!http_info()) |
(...skipping 15 matching lines...) Expand all Loading... |
447 if (ranges.size() == 1U) | 474 if (ranges.size() == 1U) |
448 range_requested_ = ranges[0]; | 475 range_requested_ = ranges[0]; |
449 } | 476 } |
450 | 477 |
451 void AppCacheURLRequestJob::NotifyRestartRequired() { | 478 void AppCacheURLRequestJob::NotifyRestartRequired() { |
452 on_prepare_to_restart_callback_.Run(); | 479 on_prepare_to_restart_callback_.Run(); |
453 URLRequestJob::NotifyRestartRequired(); | 480 URLRequestJob::NotifyRestartRequired(); |
454 } | 481 } |
455 | 482 |
456 } // namespace content | 483 } // namespace content |
OLD | NEW |