| 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 |