view_http_cache_job_factory.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/net/view_http_cache_job_factory.h" 6 7#include "base/message_loop.h" 8#include "base/string_util.h" 9#include "chrome/common/url_constants.h" 10#include "net/base/net_errors.h" 11#include "net/url_request/url_request.h" 12#include "net/url_request/url_request_context.h" 13#include "net/url_request/url_request_simple_job.h" 14#include "net/url_request/view_cache_helper.h" 15 16namespace { 17 18// A job subclass that dumps an HTTP cache entry. 19class ViewHttpCacheJob : public URLRequestJob { 20 public: 21 explicit ViewHttpCacheJob(URLRequest* request) 22 : URLRequestJob(request), data_offset_(0), cancel_(false), busy_(false), 23 ALLOW_THIS_IN_INITIALIZER_LIST( 24 callback_(this, &ViewHttpCacheJob::OnIOComplete)) {} 25 26 virtual void Start(); 27 virtual void Kill(); 28 virtual bool GetMimeType(std::string* mime_type) const; 29 virtual bool GetCharset(std::string* charset); 30 virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); 31 32 private: 33 ~ViewHttpCacheJob() {} 34 35 // Called when ViewCacheHelper completes the operation. 36 void OnIOComplete(int result); 37 38 std::string data_; 39 int data_offset_; 40 bool cancel_; 41 bool busy_; 42 net::ViewCacheHelper cache_helper_; 43 net::CompletionCallbackImpl<ViewHttpCacheJob> callback_; 44}; 45 46void ViewHttpCacheJob::Start() { 47 if (!request_ || cancel_) 48 return; 49 50 busy_ = true; 51 AddRef(); // Released on OnIOComplete(). 52 std::string cache_key = 53 request_->url().spec().substr(strlen(chrome::kNetworkViewCacheURL)); 54 55 int rv; 56 if (cache_key.empty()) { 57 rv = cache_helper_.GetContentsHTML(request_->context(), 58 chrome::kNetworkViewCacheURL, &data_, 59 &callback_); 60 } else { 61 rv = cache_helper_.GetEntryInfoHTML(cache_key, request_->context(), 62 &data_, &callback_); 63 } 64 65 if (rv != net::ERR_IO_PENDING) { 66 // Start reading asynchronously so that all error reporting and data 67 // callbacks happen as they would for network requests. 68 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 69 this, &ViewHttpCacheJob::OnIOComplete, rv)); 70 } 71} 72 73void ViewHttpCacheJob::Kill() { 74 // We don't want to delete this object while we are busy; we'll do it when it 75 // is safe. 76 cancel_ = true; 77 if (!busy_) 78 URLRequestJob::Kill(); 79} 80 81bool ViewHttpCacheJob::GetMimeType(std::string* mime_type) const { 82 mime_type->assign("text/html"); 83 return true; 84} 85 86bool ViewHttpCacheJob::GetCharset(std::string* charset) { 87 charset->assign("UTF-8"); 88 return true; 89} 90 91bool ViewHttpCacheJob::ReadRawData(net::IOBuffer* buf, int buf_size, 92 int* bytes_read) { 93 DCHECK(bytes_read); 94 int remaining = static_cast<int>(data_.size()) - data_offset_; 95 if (buf_size > remaining) 96 buf_size = remaining; 97 memcpy(buf->data(), data_.data() + data_offset_, buf_size); 98 data_offset_ += buf_size; 99 *bytes_read = buf_size; 100 return true; 101} 102 103void ViewHttpCacheJob::OnIOComplete(int result) { 104 // We may be holding the last reference to this job. 105 scoped_refptr<ViewHttpCacheJob> self(this); 106 DCHECK_EQ(net::OK, result); 107 busy_ = false; 108 Release(); // Acquired on Start(). 109 110 if (cancel_) 111 return URLRequestJob::Kill(); 112 113 // Notify that the headers are complete. 114 NotifyHeadersComplete(); 115} 116 117} // namespace. 118 119// Static. 120bool ViewHttpCacheJobFactory::IsSupportedURL(const GURL& url) { 121 return StartsWithASCII(url.spec(), chrome::kNetworkViewCacheURL, 122 true /*case_sensitive*/); 123} 124 125// Static. 126URLRequestJob* ViewHttpCacheJobFactory::CreateJobForRequest( 127 URLRequest* request) { 128 return new ViewHttpCacheJob(request); 129} 130