appcache_url_request_job.cc revision 5e3f23d412006dc4db4e659864679f29341e113f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_url_request_job.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <vector> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/command_line.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h" 145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_headers.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_histograms.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_service.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace appcache { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheURLRequestJob::AppCacheURLRequestJob( 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate* network_delegate, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheStorage* storage) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : net::URLRequestJob(request, network_delegate), 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_(storage), 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_been_started_(false), has_been_killed_(false), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_(AWAITING_DELIVERY_ORDERS), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_id_(0), cache_id_(kNoCacheId), is_fallback_(false), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_entry_not_found_(false), 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(storage_); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::DeliverAppCachedResponse( 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, int64 group_id, int64 cache_id, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AppCacheEntry& entry, bool is_fallback) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_delivery_orders()); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(entry.has_response_id()); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_ = APPCACHED_DELIVERY; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest_url_ = manifest_url; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_id_ = group_id; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_id_ = cache_id; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_ = entry; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_fallback_ = is_fallback; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::DeliverNetworkResponse() { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_delivery_orders()); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_ = NETWORK_DELIVERY; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = NULL; // not needed 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::DeliverErrorResponse() { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_delivery_orders()); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_ = ERROR_DELIVERY; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = NULL; // not needed 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::MaybeBeginDelivery() { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_been_started() && has_delivery_orders()) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start asynchronously so that all error reporting and data 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callbacks happen as they would for network requests. 74b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppCacheURLRequestJob::BeginDelivery, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::BeginDelivery() { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(has_delivery_orders() && has_been_started()); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_been_killed()) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (delivery_type_) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NETWORK_DELIVERY: 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppCacheHistograms::AddNetworkJobStartDelaySample( 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - start_time_tick_); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To fallthru to the network, we restart the request which will 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cause a new job to be created to retrieve the resource from the 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // network. Our caller is responsible for arranging to not re-intercept 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the same request. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyRestartRequired(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERROR_DELIVERY: 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppCacheHistograms::AddErrorJobStartDelaySample( 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - start_time_tick_); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request()->net_log().AddEvent( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_ERROR_RESPONSE); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::ERR_FAILED)); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case APPCACHED_DELIVERY: 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry_.IsExecutable()) { 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(CommandLine::ForCurrentProcess()->HasSwitch( 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kEnableExecutableHandlers)); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(michaeln): do something different here with 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // an AppCacheExecutableHandler. 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppCacheHistograms::AddAppCacheJobStartDelaySample( 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - start_time_tick_); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request()->net_log().AddEvent( 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_fallback_ ? 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_FALLBACK_RESPONSE : 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_CACHED_RESPONSE); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->LoadResponseInfo( 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest_url_, group_id_, entry_.response_id(), this); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheURLRequestJob::~AppCacheURLRequestJob() { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (storage_) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->CancelDelegateCallbacks(this); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::OnResponseInfoLoaded( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheResponseInfo* response_info, int64 response_id) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_delivering_appcache_response()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AppCacheURLRequestJob> protect(this); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_info) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ = response_info; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_.reset(storage_->CreateResponseReader( 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest_url_, group_id_, entry_.response_id())); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_range_request()) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetupRangeResponse(); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A resource that is expected to be in the appcache is missing. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://code.google.com/p/chromium/issues/detail?id=50657 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Instead of failing the request, we restart the request. The retry 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // attempt will fallthru to the network instead of trying to load 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the appcache. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_.response_id()); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_entry_not_found_ = true; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyRestartRequired(); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const net::HttpResponseInfo* AppCacheURLRequestJob::http_info() const { 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!info_.get()) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 164b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (range_response_info_) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return range_response_info_.get(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return info_->http_response_info(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::SetupRangeResponse() { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_range_request() && info_.get() && reader_.get() && 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_delivering_appcache_response()); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resource_size = static_cast<int>(info_->response_data_size()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resource_size < 0 || !range_requested_.ComputeBounds(resource_size)) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_ = net::HttpByteRange(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(range_requested_.HasFirstBytePosition() && 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_.HasLastBytePosition()); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int offset = static_cast<int>(range_requested_.first_byte_position()); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int length = static_cast<int>(range_requested_.last_byte_position() - 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_.first_byte_position() + 1); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the reader about the range to read. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_->SetReadRange(offset, length); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a copy of the full response headers and fix them up 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for the range we'll be returning. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kLengthHeader[] = "Content-Length"; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kRangeHeader[] = "Content-Range"; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kPartialStatusLine[] = "HTTP/1.1 206 Partial Content"; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_response_info_.reset( 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new net::HttpResponseInfo(*info_->http_response_info())); 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::HttpResponseHeaders* headers = range_response_info_->headers.get(); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->RemoveHeader(kLengthHeader); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->RemoveHeader(kRangeHeader); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->ReplaceStatusLine(kPartialStatusLine); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->AddHeader( 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf("%s: %d", kLengthHeader, length)); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->AddHeader( 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf("%s: bytes %d-%d/%d", 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kRangeHeader, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset + length - 1, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_size)); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::OnReadComplete(int result) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_delivering_appcache_response()); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == 0) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(net::URLRequestStatus()); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result < 0) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_.response_id()); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyReadComplete(result); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// net::URLRequestJob overrides ------------------------------------------------ 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::Start() { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_been_started()); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_been_started_ = true; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_time_tick_ = base::TimeTicks::Now(); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::Kill() { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_been_killed_) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_been_killed_ = true; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_.reset(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (storage_) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->CancelDelegateCallbacks(this); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = NULL; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestJob::Kill(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::LoadState AppCacheURLRequestJob::GetLoadState() const { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_been_started()) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_IDLE; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_delivery_orders()) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_WAITING_FOR_APPCACHE; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delivery_type_ != APPCACHED_DELIVERY) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_IDLE; 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!info_.get()) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_WAITING_FOR_APPCACHE; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reader_.get() && reader_->IsReadPending()) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_READING_RESPONSE; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_IDLE; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCacheURLRequestJob::GetMimeType(std::string* mime_type) const { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_info()->headers->GetMimeType(mime_type); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCacheURLRequestJob::GetCharset(std::string* charset) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_info()->headers->GetCharset(charset); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *info = *http_info(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int AppCacheURLRequestJob::GetResponseCode() const { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_info()->headers->response_code(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCacheURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size, 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *bytes_read) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_delivering_appcache_response()); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(buf_size, 0); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!reader_->IsReadPending()); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_->ReadData( 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf, buf_size, base::Bind(&AppCacheURLRequestJob::OnReadComplete, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::SetExtraRequestHeaders( 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpRequestHeaders& headers) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<net::HttpByteRange> ranges; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &value) || 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !net::HttpUtil::ParseRangeHeader(value, &ranges)) { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If multiple ranges are requested, we play dumb and 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return the entire response with 200 OK. 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ranges.size() == 1U) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_ = ranges[0]; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace appcache 311