appcache_url_request_job.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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) 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/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" 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_group.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_histograms.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_host.h" 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_service_impl.h" 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/base/io_buffer.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_headers.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace content { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheURLRequestJob::AppCacheURLRequestJob( 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate* network_delegate, 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AppCacheStorage* storage, 36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AppCacheHost* host, 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool is_main_resource) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : net::URLRequestJob(request, network_delegate), 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) host_(host), 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_(storage), 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_been_started_(false), has_been_killed_(false), 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_(AWAITING_DELIVERY_ORDERS), 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) group_id_(0), cache_id_(kAppCacheNoCacheId), is_fallback_(false), 44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch is_main_resource_(is_main_resource), 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_entry_not_found_(false), 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(storage_); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::DeliverAppCachedResponse( 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, int64 group_id, int64 cache_id, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AppCacheEntry& entry, bool is_fallback) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_delivery_orders()); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(entry.has_response_id()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_ = APPCACHED_DELIVERY; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest_url_ = manifest_url; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_id_ = group_id; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_id_ = cache_id; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_ = entry; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_fallback_ = is_fallback; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::DeliverNetworkResponse() { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_delivery_orders()); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_ = NETWORK_DELIVERY; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = NULL; // not needed 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::DeliverErrorResponse() { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_delivery_orders()); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_ = ERROR_DELIVERY; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = NULL; // not needed 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::MaybeBeginDelivery() { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_been_started() && has_delivery_orders()) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start asynchronously so that all error reporting and data 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callbacks happen as they would for network requests. 82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppCacheURLRequestJob::BeginDelivery, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::BeginDelivery() { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(has_delivery_orders() && has_been_started()); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_been_killed()) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (delivery_type_) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NETWORK_DELIVERY: 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppCacheHistograms::AddNetworkJobStartDelaySample( 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - start_time_tick_); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To fallthru to the network, we restart the request which will 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cause a new job to be created to retrieve the resource from the 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // network. Our caller is responsible for arranging to not re-intercept 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the same request. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyRestartRequired(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERROR_DELIVERY: 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppCacheHistograms::AddErrorJobStartDelaySample( 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - start_time_tick_); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request()->net_log().AddEvent( 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_ERROR_RESPONSE); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::ERR_FAILED)); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case APPCACHED_DELIVERY: 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry_.IsExecutable()) { 1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginExecutableHandlerDelivery(); 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppCacheHistograms::AddAppCacheJobStartDelaySample( 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - start_time_tick_); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request()->net_log().AddEvent( 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_fallback_ ? 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_FALLBACK_RESPONSE : 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_CACHED_RESPONSE); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->LoadResponseInfo( 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest_url_, group_id_, entry_.response_id(), this); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::BeginExecutableHandlerDelivery() { 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(CommandLine::ForCurrentProcess()-> 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) HasSwitch(kEnableExecutableHandlers)); 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!storage_->service()->handler_factory()) { 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginErrorDelivery("missing handler factory"); 1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request()->net_log().AddEvent( 1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_EXECUTABLE_RESPONSE); 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // We defer job delivery until the executable handler is spun up and 1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // provides a response. The sequence goes like this... 1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // 1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // 1. First we load the cache. 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // 2. Then if the handler is not spun up, we load the script resource which 1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // is needed to spin it up. 1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // 3. Then we ask then we ask the handler to compute a response. 1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // 4. Finally we deilver that response to the caller. 1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) storage_->LoadCache(cache_id_, this); 1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::OnCacheLoaded(AppCache* cache, int64 cache_id) { 1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK_EQ(cache_id_, cache_id); 1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(!has_been_killed()); 1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!cache) { 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginErrorDelivery("cache load failed"); 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Keep references to ensure they don't go out of scope until job completion. 1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cache_ = cache; 1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) group_ = cache->owning_group(); 1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // If the handler is spun up, ask it to compute a response. 1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AppCacheExecutableHandler* handler = 1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cache->GetExecutableHandler(entry_.response_id()); 1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (handler) { 1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) InvokeExecutableHandler(handler); 1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Handler is not spun up yet, load the script resource to do that. 1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // NOTE: This is not ideal since multiple jobs may be doing this, 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // concurrently but close enough for now, the first to load the script 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // will win. 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Read the script data, truncating if its too large. 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // NOTE: we just issue one read and don't bother chaining if the resource 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // is very (very) large, close enough for now. 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const int64 kLimit = 500 * 1000; 1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_buffer_ = new net::GrowableIOBuffer(); 1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_buffer_->SetCapacity(kLimit); 1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_reader_.reset(storage_->CreateResponseReader( 1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) manifest_url_, group_id_, entry_.response_id())); 1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_reader_->ReadData( 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch handler_source_buffer_.get(), 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kLimit, 1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&AppCacheURLRequestJob::OnExecutableSourceLoaded, 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Unretained(this))); 1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::OnExecutableSourceLoaded(int result) { 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(!has_been_killed()); 2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_reader_.reset(); 2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (result < 0) { 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginErrorDelivery("script source load failed"); 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_buffer_->SetCapacity(result); // Free up some memory. 2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AppCacheExecutableHandler* handler = cache_->GetOrCreateExecutableHandler( 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry_.response_id(), handler_source_buffer_.get()); 2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_buffer_ = NULL; // not needed anymore 2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (handler) { 2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) InvokeExecutableHandler(handler); 2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginErrorDelivery("factory failed to produce a handler"); 2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::InvokeExecutableHandler( 2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AppCacheExecutableHandler* handler) { 2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler->HandleRequest( 2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request(), 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&AppCacheURLRequestJob::OnExecutableResponseCallback, 2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_factory_.GetWeakPtr())); 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::OnExecutableResponseCallback( 2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const AppCacheExecutableHandler::Response& response) { 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(!has_been_killed()); 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (response.use_network) { 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) delivery_type_ = NETWORK_DELIVERY; 2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) storage_ = NULL; 2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginDelivery(); 2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!response.cached_resource_url.is_empty()) { 2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AppCacheEntry* entry_ptr = cache_->GetEntry(response.cached_resource_url); 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (entry_ptr && !entry_ptr->IsExecutable()) { 2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) entry_ = *entry_ptr; 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginDelivery(); 2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!response.redirect_url.is_empty()) { 2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // TODO(michaeln): playback a redirect 2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // response_headers_(new HttpResponseHeaders(response_headers)), 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // fallthru for now to deliver an error 2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Otherwise, return an error. 2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginErrorDelivery("handler returned an invalid response"); 2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::BeginErrorDelivery(const char* message) { 2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (host_) 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) host_->frontend()->OnLogMessage(host_->host_id(), APPCACHE_LOG_ERROR, 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) message); 2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) delivery_type_ = ERROR_DELIVERY; 2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) storage_ = NULL; 2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginDelivery(); 2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheURLRequestJob::~AppCacheURLRequestJob() { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (storage_) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->CancelDelegateCallbacks(this); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::OnResponseInfoLoaded( 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheResponseInfo* response_info, int64 response_id) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_delivering_appcache_response()); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AppCacheURLRequestJob> protect(this); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_info) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ = response_info; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_.reset(storage_->CreateResponseReader( 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest_url_, group_id_, entry_.response_id())); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_range_request()) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetupRangeResponse(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (storage_->service()->storage() == storage_) { 2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // A resource that is expected to be in the appcache is missing. 2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // See http://code.google.com/p/chromium/issues/detail?id=50657 2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Instead of failing the request, we restart the request. The retry 2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // attempt will fallthru to the network instead of trying to load 2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // from the appcache. 2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_, 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) entry_.response_id()); 293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AppCacheHistograms::CountResponseRetrieval( 294effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch false, is_main_resource_, manifest_url_.GetOrigin()); 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_entry_not_found_ = true; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyRestartRequired(); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const net::HttpResponseInfo* AppCacheURLRequestJob::http_info() const { 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!info_.get()) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (range_response_info_) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return range_response_info_.get(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return info_->http_response_info(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::SetupRangeResponse() { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_range_request() && info_.get() && reader_.get() && 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_delivering_appcache_response()); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resource_size = static_cast<int>(info_->response_data_size()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resource_size < 0 || !range_requested_.ComputeBounds(resource_size)) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_ = net::HttpByteRange(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(range_requested_.IsValid()); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int offset = static_cast<int>(range_requested_.first_byte_position()); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int length = static_cast<int>(range_requested_.last_byte_position() - 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_.first_byte_position() + 1); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the reader about the range to read. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_->SetReadRange(offset, length); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a copy of the full response headers and fix them up 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for the range we'll be returning. 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_response_info_.reset( 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new net::HttpResponseInfo(*info_->http_response_info())); 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::HttpResponseHeaders* headers = range_response_info_->headers.get(); 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) headers->UpdateWithNewRange( 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) range_requested_, resource_size, true /* replace status line */); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::OnReadComplete(int result) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_delivering_appcache_response()); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == 0) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(net::URLRequestStatus()); 339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AppCacheHistograms::CountResponseRetrieval( 340effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch true, is_main_resource_, manifest_url_.GetOrigin()); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result < 0) { 3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (storage_->service()->storage() == storage_) { 3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_, 3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) entry_.response_id()); 3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); 347effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AppCacheHistograms::CountResponseRetrieval( 348effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch false, is_main_resource_, manifest_url_.GetOrigin()); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyReadComplete(result); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// net::URLRequestJob overrides ------------------------------------------------ 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::Start() { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_been_started()); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_been_started_ = true; 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_time_tick_ = base::TimeTicks::Now(); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::Kill() { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_been_killed_) { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_been_killed_ = true; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_.reset(); 3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_reader_.reset(); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (storage_) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->CancelDelegateCallbacks(this); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = NULL; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) host_ = NULL; 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) info_ = NULL; 3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) cache_ = NULL; 3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) group_ = NULL; 3771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) range_response_info_.reset(); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestJob::Kill(); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::LoadState AppCacheURLRequestJob::GetLoadState() const { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_been_started()) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_IDLE; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_delivery_orders()) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_WAITING_FOR_APPCACHE; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delivery_type_ != APPCACHED_DELIVERY) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_IDLE; 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!info_.get()) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_WAITING_FOR_APPCACHE; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reader_.get() && reader_->IsReadPending()) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_READING_RESPONSE; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_IDLE; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCacheURLRequestJob::GetMimeType(std::string* mime_type) const { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_info()->headers->GetMimeType(mime_type); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCacheURLRequestJob::GetCharset(std::string* charset) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_info()->headers->GetCharset(charset); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *info = *http_info(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int AppCacheURLRequestJob::GetResponseCode() const { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_info()->headers->response_code(); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCacheURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size, 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *bytes_read) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_delivering_appcache_response()); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(buf_size, 0); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!reader_->IsReadPending()); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_->ReadData( 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf, buf_size, base::Bind(&AppCacheURLRequestJob::OnReadComplete, 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::SetExtraRequestHeaders( 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpRequestHeaders& headers) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<net::HttpByteRange> ranges; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &value) || 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !net::HttpUtil::ParseRangeHeader(value, &ranges)) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If multiple ranges are requested, we play dumb and 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return the entire response with 200 OK. 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ranges.size() == 1U) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_ = ranges[0]; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace content 450