OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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/bind.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "base/callback.h" | |
10 #include "base/compiler_specific.h" | |
11 #include "base/memory/weak_ptr.h" | |
12 #include "base/message_loop.h" | |
13 #include "base/string_util.h" | |
14 #include "chrome/common/url_constants.h" | |
15 #include "net/base/completion_callback.h" | |
16 #include "net/base/net_errors.h" | |
17 #include "net/url_request/url_request.h" | |
18 #include "net/url_request/url_request_context.h" | |
19 #include "net/url_request/url_request_simple_job.h" | |
20 #include "net/url_request/view_cache_helper.h" | |
21 | |
22 namespace { | |
23 | |
24 // A job subclass that dumps an HTTP cache entry. | |
25 class ViewHttpCacheJob : public net::URLRequestJob { | |
26 public: | |
27 explicit ViewHttpCacheJob(net::URLRequest* request) | |
28 : net::URLRequestJob(request), | |
29 core_(new Core), | |
30 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | |
31 ALLOW_THIS_IN_INITIALIZER_LIST( | |
32 callback_(base::Bind(&ViewHttpCacheJob::OnStartCompleted, | |
33 base::Unretained(this)))) { | |
34 } | |
35 | |
36 // net::URLRequestJob implementation. | |
37 virtual void Start() OVERRIDE; | |
38 virtual void Kill() OVERRIDE; | |
39 virtual bool GetMimeType(std::string* mime_type) const OVERRIDE{ | |
40 return core_->GetMimeType(mime_type); | |
41 } | |
42 virtual bool GetCharset(std::string* charset) OVERRIDE{ | |
43 return core_->GetCharset(charset); | |
44 } | |
45 virtual bool ReadRawData(net::IOBuffer* buf, | |
46 int buf_size, int *bytes_read) OVERRIDE{ | |
47 return core_->ReadRawData(buf, buf_size, bytes_read); | |
48 } | |
49 | |
50 private: | |
51 class Core : public base::RefCounted<Core> { | |
52 public: | |
53 Core() | |
54 : data_offset_(0), | |
55 ALLOW_THIS_IN_INITIALIZER_LIST(callback_( | |
56 base::Bind(&Core::OnIOComplete, this))) { | |
57 } | |
58 | |
59 int Start(const net::URLRequest& request, const base::Closure& callback); | |
60 | |
61 // Prevents it from invoking its callback. It will self-delete. | |
62 void Orphan() { | |
63 user_callback_.Reset(); | |
64 } | |
65 | |
66 bool GetMimeType(std::string* mime_type) const; | |
67 bool GetCharset(std::string* charset); | |
68 bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); | |
69 | |
70 private: | |
71 friend class base::RefCounted<Core>; | |
72 | |
73 ~Core() {} | |
74 | |
75 // Called when ViewCacheHelper completes the operation. | |
76 void OnIOComplete(int result); | |
77 | |
78 std::string data_; | |
79 int data_offset_; | |
80 net::ViewCacheHelper cache_helper_; | |
81 net::CompletionCallback callback_; | |
82 base::Closure user_callback_; | |
83 | |
84 DISALLOW_COPY_AND_ASSIGN(Core); | |
85 }; | |
86 | |
87 ~ViewHttpCacheJob() {} | |
88 | |
89 void StartAsync(); | |
90 void OnStartCompleted(); | |
91 | |
92 scoped_refptr<Core> core_; | |
93 base::WeakPtrFactory<ViewHttpCacheJob> weak_factory_; | |
94 base::Closure callback_; | |
95 | |
96 DISALLOW_COPY_AND_ASSIGN(ViewHttpCacheJob); | |
97 }; | |
98 | |
99 void ViewHttpCacheJob::Start() { | |
100 MessageLoop::current()->PostTask( | |
101 FROM_HERE, | |
102 base::Bind(&ViewHttpCacheJob::StartAsync, weak_factory_.GetWeakPtr())); | |
103 } | |
104 | |
105 void ViewHttpCacheJob::Kill() { | |
106 weak_factory_.InvalidateWeakPtrs(); | |
107 if (core_) { | |
108 core_->Orphan(); | |
109 core_ = NULL; | |
110 } | |
111 net::URLRequestJob::Kill(); | |
112 } | |
113 | |
114 void ViewHttpCacheJob::StartAsync() { | |
115 DCHECK(request()); | |
116 | |
117 if (!request()) | |
118 return; | |
119 | |
120 int rv = core_->Start(*request(), callback_); | |
121 if (rv != net::ERR_IO_PENDING) { | |
122 DCHECK_EQ(net::OK, rv); | |
123 OnStartCompleted(); | |
124 } | |
125 } | |
126 | |
127 void ViewHttpCacheJob::OnStartCompleted() { | |
128 NotifyHeadersComplete(); | |
129 } | |
130 | |
131 int ViewHttpCacheJob::Core::Start(const net::URLRequest& request, | |
132 const base::Closure& callback) { | |
133 DCHECK(!callback.is_null()); | |
134 DCHECK(user_callback_.is_null()); | |
135 | |
136 AddRef(); // Released on OnIOComplete(). | |
137 std::string cache_key = | |
138 request.url().spec().substr(strlen(chrome::kChromeUINetworkViewCacheURL)); | |
139 | |
140 int rv; | |
141 if (cache_key.empty()) { | |
142 rv = cache_helper_.GetContentsHTML(request.context(), | |
143 chrome::kChromeUINetworkViewCacheURL, | |
144 &data_, callback_); | |
145 } else { | |
146 rv = cache_helper_.GetEntryInfoHTML(cache_key, request.context(), | |
147 &data_, callback_); | |
148 } | |
149 | |
150 if (rv == net::ERR_IO_PENDING) | |
151 user_callback_ = callback; | |
152 | |
153 return rv; | |
154 } | |
155 | |
156 bool ViewHttpCacheJob::Core::GetMimeType(std::string* mime_type) const { | |
157 mime_type->assign("text/html"); | |
158 return true; | |
159 } | |
160 | |
161 bool ViewHttpCacheJob::Core::GetCharset(std::string* charset) { | |
162 charset->assign("UTF-8"); | |
163 return true; | |
164 } | |
165 | |
166 bool ViewHttpCacheJob::Core::ReadRawData(net::IOBuffer* buf, | |
167 int buf_size, | |
168 int* bytes_read) { | |
169 DCHECK(bytes_read); | |
170 int remaining = static_cast<int>(data_.size()) - data_offset_; | |
171 if (buf_size > remaining) | |
172 buf_size = remaining; | |
173 memcpy(buf->data(), data_.data() + data_offset_, buf_size); | |
174 data_offset_ += buf_size; | |
175 *bytes_read = buf_size; | |
176 return true; | |
177 } | |
178 | |
179 void ViewHttpCacheJob::Core::OnIOComplete(int result) { | |
180 DCHECK_EQ(net::OK, result); | |
181 | |
182 if (!user_callback_.is_null()) | |
183 user_callback_.Run(); | |
184 | |
185 // We may be holding the last reference to this job. Do not access |this| | |
186 // after Release(). | |
187 Release(); // Acquired on Start(). | |
188 } | |
189 | |
190 } // namespace. | |
191 | |
192 // Static. | |
193 bool ViewHttpCacheJobFactory::IsSupportedURL(const GURL& url) { | |
194 return url.SchemeIs(chrome::kChromeUIScheme) && | |
195 url.host() == chrome::kChromeUINetworkViewCacheHost; | |
196 } | |
197 | |
198 // Static. | |
199 net::URLRequestJob* ViewHttpCacheJobFactory::CreateJobForRequest( | |
200 net::URLRequest* request) { | |
201 return new ViewHttpCacheJob(request); | |
202 } | |
OLD | NEW |