view_http_cache_job_factory.cc revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
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) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/net/view_http_cache_job_factory.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/url_constants.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_simple_job.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/view_cache_helper.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A job subclass that dumps an HTTP cache entry. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ViewHttpCacheJob : public net::URLRequestJob { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ViewHttpCacheJob(net::URLRequest* request, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate* network_delegate) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : net::URLRequestJob(request, network_delegate), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_(new Core), 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this), 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_(base::Bind(&ViewHttpCacheJob::OnStartCompleted, 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // net::URLRequestJob implementation. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Start() OVERRIDE; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Kill() OVERRIDE; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetMimeType(std::string* mime_type) const OVERRIDE{ 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return core_->GetMimeType(mime_type); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetCharset(std::string* charset) OVERRIDE{ 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return core_->GetCharset(charset); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool ReadRawData(net::IOBuffer* buf, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buf_size, int *bytes_read) OVERRIDE{ 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return core_->ReadRawData(buf, buf_size, bytes_read); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Core : public base::RefCounted<Core> { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Core() 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : data_offset_(0), 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_(base::Bind(&Core::OnIOComplete, this)) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Start(const net::URLRequest& request, const base::Closure& callback); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevents it from invoking its callback. It will self-delete. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Orphan() { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_callback_.Reset(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetMimeType(std::string* mime_type) const; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetCharset(std::string* charset); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<Core>; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Core() {} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when ViewCacheHelper completes the operation. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnIOComplete(int result); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string data_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data_offset_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::ViewCacheHelper cache_helper_; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback callback_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure user_callback_; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Core); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~ViewHttpCacheJob() {} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartAsync(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnStartCompleted(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Core> core_; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<ViewHttpCacheJob> weak_factory_; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure callback_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ViewHttpCacheJob); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewHttpCacheJob::Start() { 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ViewHttpCacheJob::StartAsync, weak_factory_.GetWeakPtr())); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewHttpCacheJob::Kill() { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (core_.get()) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_->Orphan(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_ = NULL; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestJob::Kill(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewHttpCacheJob::StartAsync() { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request()); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request()) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = core_->Start(*request(), callback_); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != net::ERR_IO_PENDING) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(net::OK, rv); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnStartCompleted(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewHttpCacheJob::OnStartCompleted() { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewHttpCacheJob::Core::Start(const net::URLRequest& request, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(user_callback_.is_null()); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); // Released on OnIOComplete(). 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string cache_key = 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.url().spec().substr(strlen(kChromeUINetworkViewCacheURL)); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cache_key.empty()) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = cache_helper_.GetContentsHTML(request.context(), 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kChromeUINetworkViewCacheURL, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &data_, callback_); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = cache_helper_.GetEntryInfoHTML(cache_key, request.context(), 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &data_, callback_); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == net::ERR_IO_PENDING) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_callback_ = callback; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ViewHttpCacheJob::Core::GetMimeType(std::string* mime_type) const { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mime_type->assign("text/html"); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ViewHttpCacheJob::Core::GetCharset(std::string* charset) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) charset->assign("UTF-8"); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ViewHttpCacheJob::Core::ReadRawData(net::IOBuffer* buf, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buf_size, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* bytes_read) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int remaining = static_cast<int>(data_.size()) - data_offset_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buf_size > remaining) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf_size = remaining; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buf->data(), data_.data() + data_offset_, buf_size); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_offset_ += buf_size; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_read = buf_size; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewHttpCacheJob::Core::OnIOComplete(int result) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(net::OK, result); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!user_callback_.is_null()) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_callback_.Run(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may be holding the last reference to this job. Do not access |this| 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // after Release(). 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Acquired on Start(). 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Static. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ViewHttpCacheJobFactory::IsSupportedURL(const GURL& url) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url.SchemeIs(chrome::kChromeUIScheme) && 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) url.host() == kChromeUINetworkViewCacheHost; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Static. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequestJob* ViewHttpCacheJobFactory::CreateJobForRequest( 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, net::NetworkDelegate* network_delegate) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ViewHttpCacheJob(request, network_delegate); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 204