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" 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" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/base/io_buffer.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_headers.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h" 247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "webkit/browser/appcache/appcache.h" 257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "webkit/browser/appcache/appcache_group.h" 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_histograms.h" 277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "webkit/browser/appcache/appcache_host.h" 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_service.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace appcache { 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, 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AppCacheHost* host) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : net::URLRequestJob(request, network_delegate), 387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) host_(host), 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_(storage), 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_been_started_(false), has_been_killed_(false), 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_(AWAITING_DELIVERY_ORDERS), 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_id_(0), cache_id_(kNoCacheId), is_fallback_(false), 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_entry_not_found_(false), 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(storage_); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::DeliverAppCachedResponse( 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, int64 group_id, int64 cache_id, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AppCacheEntry& entry, bool is_fallback) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_delivery_orders()); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(entry.has_response_id()); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_ = APPCACHED_DELIVERY; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest_url_ = manifest_url; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_id_ = group_id; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_id_ = cache_id; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_ = entry; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_fallback_ = is_fallback; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::DeliverNetworkResponse() { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_delivery_orders()); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_ = NETWORK_DELIVERY; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = NULL; // not needed 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::DeliverErrorResponse() { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!has_delivery_orders()); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delivery_type_ = ERROR_DELIVERY; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_ = NULL; // not needed 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeBeginDelivery(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::MaybeBeginDelivery() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_been_started() && has_delivery_orders()) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start asynchronously so that all error reporting and data 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callbacks happen as they would for network requests. 80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppCacheURLRequestJob::BeginDelivery, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::BeginDelivery() { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(has_delivery_orders() && has_been_started()); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_been_killed()) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (delivery_type_) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NETWORK_DELIVERY: 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppCacheHistograms::AddNetworkJobStartDelaySample( 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - start_time_tick_); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To fallthru to the network, we restart the request which will 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cause a new job to be created to retrieve the resource from the 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // network. Our caller is responsible for arranging to not re-intercept 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the same request. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyRestartRequired(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ERROR_DELIVERY: 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppCacheHistograms::AddErrorJobStartDelaySample( 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - start_time_tick_); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request()->net_log().AddEvent( 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_ERROR_RESPONSE); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::ERR_FAILED)); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case APPCACHED_DELIVERY: 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (entry_.IsExecutable()) { 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginExecutableHandlerDelivery(); 1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppCacheHistograms::AddAppCacheJobStartDelaySample( 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - start_time_tick_); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request()->net_log().AddEvent( 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_fallback_ ? 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_FALLBACK_RESPONSE : 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_CACHED_RESPONSE); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->LoadResponseInfo( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest_url_, group_id_, entry_.response_id(), this); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::BeginExecutableHandlerDelivery() { 1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(CommandLine::ForCurrentProcess()-> 1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) HasSwitch(kEnableExecutableHandlers)); 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!storage_->service()->handler_factory()) { 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginErrorDelivery("missing handler factory"); 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request()->net_log().AddEvent( 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) net::NetLog::TYPE_APPCACHE_DELIVERING_EXECUTABLE_RESPONSE); 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // We defer job delivery until the executable handler is spun up and 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // provides a response. The sequence goes like this... 1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // 1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // 1. First we load the cache. 1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // 2. Then if the handler is not spun up, we load the script resource which 1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // is needed to spin it up. 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // 3. Then we ask then we ask the handler to compute a response. 1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // 4. Finally we deilver that response to the caller. 1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) storage_->LoadCache(cache_id_, this); 1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::OnCacheLoaded(AppCache* cache, int64 cache_id) { 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK_EQ(cache_id_, cache_id); 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(!has_been_killed()); 1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!cache) { 1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginErrorDelivery("cache load failed"); 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Keep references to ensure they don't go out of scope until job completion. 1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cache_ = cache; 1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) group_ = cache->owning_group(); 1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // If the handler is spun up, ask it to compute a response. 1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AppCacheExecutableHandler* handler = 1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cache->GetExecutableHandler(entry_.response_id()); 1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (handler) { 1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) InvokeExecutableHandler(handler); 1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Handler is not spun up yet, load the script resource to do that. 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // NOTE: This is not ideal since multiple jobs may be doing this, 1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // concurrently but close enough for now, the first to load the script 1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // will win. 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Read the script data, truncating if its too large. 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // NOTE: we just issue one read and don't bother chaining if the resource 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // is very (very) large, close enough for now. 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const int64 kLimit = 500 * 1000; 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_buffer_ = new net::GrowableIOBuffer(); 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_buffer_->SetCapacity(kLimit); 1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_reader_.reset(storage_->CreateResponseReader( 1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) manifest_url_, group_id_, entry_.response_id())); 1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_reader_->ReadData( 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch handler_source_buffer_.get(), 192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kLimit, 1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&AppCacheURLRequestJob::OnExecutableSourceLoaded, 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Unretained(this))); 1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::OnExecutableSourceLoaded(int result) { 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(!has_been_killed()); 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_reader_.reset(); 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (result < 0) { 2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginErrorDelivery("script source load failed"); 2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_buffer_->SetCapacity(result); // Free up some memory. 2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AppCacheExecutableHandler* handler = cache_->GetOrCreateExecutableHandler( 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry_.response_id(), handler_source_buffer_.get()); 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler_source_buffer_ = NULL; // not needed anymore 2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (handler) { 2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) InvokeExecutableHandler(handler); 2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginErrorDelivery("factory failed to produce a handler"); 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::InvokeExecutableHandler( 2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AppCacheExecutableHandler* handler) { 2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) handler->HandleRequest( 2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request(), 2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&AppCacheURLRequestJob::OnExecutableResponseCallback, 2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_factory_.GetWeakPtr())); 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::OnExecutableResponseCallback( 2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const AppCacheExecutableHandler::Response& response) { 2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(!has_been_killed()); 2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (response.use_network) { 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) delivery_type_ = NETWORK_DELIVERY; 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) storage_ = NULL; 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginDelivery(); 2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!response.cached_resource_url.is_empty()) { 2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AppCacheEntry* entry_ptr = cache_->GetEntry(response.cached_resource_url); 2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (entry_ptr && !entry_ptr->IsExecutable()) { 2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) entry_ = *entry_ptr; 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginDelivery(); 2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!response.redirect_url.is_empty()) { 2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // TODO(michaeln): playback a redirect 2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // response_headers_(new HttpResponseHeaders(response_headers)), 2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // fallthru for now to deliver an error 2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Otherwise, return an error. 2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginErrorDelivery("handler returned an invalid response"); 2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AppCacheURLRequestJob::BeginErrorDelivery(const char* message) { 2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (host_) 2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) host_->frontend()->OnLogMessage(host_->host_id(), LOG_ERROR, message); 2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) delivery_type_ = ERROR_DELIVERY; 2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) storage_ = NULL; 2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BeginDelivery(); 2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheURLRequestJob::~AppCacheURLRequestJob() { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (storage_) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->CancelDelegateCallbacks(this); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::OnResponseInfoLoaded( 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheResponseInfo* response_info, int64 response_id) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_delivering_appcache_response()); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AppCacheURLRequestJob> protect(this); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_info) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ = response_info; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_.reset(storage_->CreateResponseReader( 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest_url_, group_id_, entry_.response_id())); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_range_request()) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetupRangeResponse(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A resource that is expected to be in the appcache is missing. 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://code.google.com/p/chromium/issues/detail?id=50657 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Instead of failing the request, we restart the request. The retry 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // attempt will fallthru to the network instead of trying to load 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the appcache. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_, 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_.response_id()); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_entry_not_found_ = true; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyRestartRequired(); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const net::HttpResponseInfo* AppCacheURLRequestJob::http_info() const { 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!info_.get()) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (range_response_info_) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return range_response_info_.get(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return info_->http_response_info(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::SetupRangeResponse() { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_range_request() && info_.get() && reader_.get() && 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_delivering_appcache_response()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resource_size = static_cast<int>(info_->response_data_size()); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resource_size < 0 || !range_requested_.ComputeBounds(resource_size)) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_ = net::HttpByteRange(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(range_requested_.HasFirstBytePosition() && 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_.HasLastBytePosition()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int offset = static_cast<int>(range_requested_.first_byte_position()); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int length = static_cast<int>(range_requested_.last_byte_position() - 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_.first_byte_position() + 1); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the reader about the range to read. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_->SetReadRange(offset, length); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a copy of the full response headers and fix them up 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for the range we'll be returning. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kLengthHeader[] = "Content-Length"; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kRangeHeader[] = "Content-Range"; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kPartialStatusLine[] = "HTTP/1.1 206 Partial Content"; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_response_info_.reset( 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new net::HttpResponseInfo(*info_->http_response_info())); 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::HttpResponseHeaders* headers = range_response_info_->headers.get(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->RemoveHeader(kLengthHeader); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->RemoveHeader(kRangeHeader); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->ReplaceStatusLine(kPartialStatusLine); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->AddHeader( 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf("%s: %d", kLengthHeader, length)); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->AddHeader( 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf("%s: bytes %d-%d/%d", 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kRangeHeader, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset + length - 1, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_size)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::OnReadComplete(int result) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_delivering_appcache_response()); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == 0) { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(net::URLRequestStatus()); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result < 0) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_, 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_.response_id()); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); 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; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestJob::Kill(); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::LoadState AppCacheURLRequestJob::GetLoadState() const { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_been_started()) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_IDLE; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_delivery_orders()) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_WAITING_FOR_APPCACHE; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delivery_type_ != APPCACHED_DELIVERY) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_IDLE; 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!info_.get()) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_WAITING_FOR_APPCACHE; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reader_.get() && reader_->IsReadPending()) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_READING_RESPONSE; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::LOAD_STATE_IDLE; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCacheURLRequestJob::GetMimeType(std::string* mime_type) const { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_info()->headers->GetMimeType(mime_type); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCacheURLRequestJob::GetCharset(std::string* charset) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_info()->headers->GetCharset(charset); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *info = *http_info(); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int AppCacheURLRequestJob::GetResponseCode() const { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!http_info()) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return http_info()->headers->response_code(); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCacheURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size, 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *bytes_read) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_delivering_appcache_response()); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(buf_size, 0); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!reader_->IsReadPending()); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_->ReadData( 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf, buf_size, base::Bind(&AppCacheURLRequestJob::OnReadComplete, 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheURLRequestJob::SetExtraRequestHeaders( 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpRequestHeaders& headers) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<net::HttpByteRange> ranges; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &value) || 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !net::HttpUtil::ParseRangeHeader(value, &ranges)) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If multiple ranges are requested, we play dumb and 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return the entire response with 200 OK. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ranges.size() == 1U) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_requested_ = ranges[0]; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace appcache 446