Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: chrome/browser/net/url_fetcher.cc

Issue 1702016: Changed UrlFetcher to use a MessageLoopProxy instead of directly relying on C... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/net/url_fetcher.h" 5 #include "chrome/browser/net/url_fetcher.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/message_loop_proxy.h"
8 #include "base/string_util.h" 9 #include "base/string_util.h"
9 #include "base/thread.h" 10 #include "base/thread.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chrome_thread.h"
12 #include "chrome/browser/net/url_fetcher_protect.h" 11 #include "chrome/browser/net/url_fetcher_protect.h"
13 #include "chrome/browser/net/url_request_context_getter.h" 12 #include "chrome/browser/net/url_request_context_getter.h"
14 #include "googleurl/src/gurl.h" 13 #include "googleurl/src/gurl.h"
15 #include "net/base/load_flags.h" 14 #include "net/base/load_flags.h"
16 #include "net/base/io_buffer.h" 15 #include "net/base/io_buffer.h"
17 #include "net/http/http_response_headers.h" 16 #include "net/http/http_response_headers.h"
18 #include "net/url_request/url_request.h" 17 #include "net/url_request/url_request.h"
19 #include "net/url_request/url_request_context.h" 18 #include "net/url_request/url_request_context.h"
20 19
21 static const int kBufferSize = 4096; 20 static const int kBufferSize = 4096;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 void StartURLRequest(); 62 void StartURLRequest();
64 void CancelURLRequest(); 63 void CancelURLRequest();
65 void OnCompletedURLRequest(const URLRequestStatus& status); 64 void OnCompletedURLRequest(const URLRequestStatus& status);
66 65
67 URLFetcher* fetcher_; // Corresponding fetcher object 66 URLFetcher* fetcher_; // Corresponding fetcher object
68 GURL original_url_; // The URL we were asked to fetch 67 GURL original_url_; // The URL we were asked to fetch
69 GURL url_; // The URL we eventually wound up at 68 GURL url_; // The URL we eventually wound up at
70 RequestType request_type_; // What type of request is this? 69 RequestType request_type_; // What type of request is this?
71 URLFetcher::Delegate* delegate_; // Object to notify on completion 70 URLFetcher::Delegate* delegate_; // Object to notify on completion
72 MessageLoop* delegate_loop_; // Message loop of the creating thread 71 MessageLoop* delegate_loop_; // Message loop of the creating thread
72 scoped_refptr<MessageLoopProxy> io_message_loop_proxy_;
73 // The message loop proxy for the thread
74 // on which the request IO happens.
73 URLRequest* request_; // The actual request this wraps 75 URLRequest* request_; // The actual request this wraps
74 int load_flags_; // Flags for the load operation 76 int load_flags_; // Flags for the load operation
75 int response_code_; // HTTP status code for the request 77 int response_code_; // HTTP status code for the request
76 std::string data_; // Results of the request 78 std::string data_; // Results of the request
77 scoped_refptr<net::IOBuffer> buffer_; 79 scoped_refptr<net::IOBuffer> buffer_;
78 // Read buffer 80 // Read buffer
79 scoped_refptr<URLRequestContextGetter> request_context_getter_; 81 scoped_refptr<URLRequestContextGetter> request_context_getter_;
80 // Cookie/cache info for the request 82 // Cookie/cache info for the request
81 ResponseCookies cookies_; // Response cookies 83 ResponseCookies cookies_; // Response cookies
82 std::string extra_request_headers_;// Extra headers for the request, if any 84 std::string extra_request_headers_;// Extra headers for the request, if any
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 buffer_(new net::IOBuffer(kBufferSize)), 142 buffer_(new net::IOBuffer(kBufferSize)),
141 protect_entry_(URLFetcherProtectManager::GetInstance()->Register( 143 protect_entry_(URLFetcherProtectManager::GetInstance()->Register(
142 original_url_.host())), 144 original_url_.host())),
143 num_retries_(0), 145 num_retries_(0),
144 was_cancelled_(false) { 146 was_cancelled_(false) {
145 } 147 }
146 148
147 void URLFetcher::Core::Start() { 149 void URLFetcher::Core::Start() {
148 DCHECK(delegate_loop_); 150 DCHECK(delegate_loop_);
149 CHECK(request_context_getter_) << "We need an URLRequestContext!"; 151 CHECK(request_context_getter_) << "We need an URLRequestContext!";
150 ChromeThread::PostDelayedTask( 152 io_message_loop_proxy_ = request_context_getter_->GetIOMessageLoopProxy();
151 ChromeThread::IO, FROM_HERE, 153 CHECK(io_message_loop_proxy_.get()) << "We need an IO message loop proxy";
154 io_message_loop_proxy_->PostDelayedTask(
155 FROM_HERE,
152 NewRunnableMethod(this, &Core::StartURLRequest), 156 NewRunnableMethod(this, &Core::StartURLRequest),
153 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SEND)); 157 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SEND));
154 } 158 }
155 159
156 void URLFetcher::Core::Stop() { 160 void URLFetcher::Core::Stop() {
157 DCHECK_EQ(MessageLoop::current(), delegate_loop_); 161 DCHECK_EQ(MessageLoop::current(), delegate_loop_);
158 delegate_ = NULL; 162 delegate_ = NULL;
159 fetcher_ = NULL; 163 fetcher_ = NULL;
160 ChromeThread::PostTask( 164 if (io_message_loop_proxy_.get()) {
161 ChromeThread::IO, FROM_HERE, 165 io_message_loop_proxy_->PostTask(
162 NewRunnableMethod(this, &Core::CancelURLRequest)); 166 FROM_HERE, NewRunnableMethod(this, &Core::CancelURLRequest));
167 }
163 } 168 }
164 169
165 void URLFetcher::Core::OnResponseStarted(URLRequest* request) { 170 void URLFetcher::Core::OnResponseStarted(URLRequest* request) {
166 DCHECK(request == request_); 171 DCHECK(request == request_);
167 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 172 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
168 if (request_->status().is_success()) { 173 if (request_->status().is_success()) {
169 response_code_ = request_->GetResponseCode(); 174 response_code_ = request_->GetResponseCode();
170 response_headers_ = request_->response_headers(); 175 response_headers_ = request_->response_headers();
171 } 176 }
172 177
173 int bytes_read = 0; 178 int bytes_read = 0;
174 // Some servers may treat HEAD requests as GET requests. To free up the 179 // Some servers may treat HEAD requests as GET requests. To free up the
175 // network connection as soon as possible, signal that the request has 180 // network connection as soon as possible, signal that the request has
176 // completed immediately, without trying to read any data back (all we care 181 // completed immediately, without trying to read any data back (all we care
177 // about is the response code and headers, which we already have). 182 // about is the response code and headers, which we already have).
178 if (request_->status().is_success() && (request_type_ != HEAD)) 183 if (request_->status().is_success() && (request_type_ != HEAD))
179 request_->Read(buffer_, kBufferSize, &bytes_read); 184 request_->Read(buffer_, kBufferSize, &bytes_read);
180 OnReadCompleted(request_, bytes_read); 185 OnReadCompleted(request_, bytes_read);
181 } 186 }
182 187
183 void URLFetcher::Core::OnReadCompleted(URLRequest* request, int bytes_read) { 188 void URLFetcher::Core::OnReadCompleted(URLRequest* request, int bytes_read) {
184 DCHECK(request == request_); 189 DCHECK(request == request_);
185 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 190 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
186 191
187 url_ = request->url(); 192 url_ = request->url();
188 193
189 do { 194 do {
190 if (!request_->status().is_success() || bytes_read <= 0) 195 if (!request_->status().is_success() || bytes_read <= 0)
191 break; 196 break;
192 data_.append(buffer_->data(), bytes_read); 197 data_.append(buffer_->data(), bytes_read);
193 } while (request_->Read(buffer_, kBufferSize, &bytes_read)); 198 } while (request_->Read(buffer_, kBufferSize, &bytes_read));
194 199
195 if (request_->status().is_success()) 200 if (request_->status().is_success())
196 request_->GetResponseCookies(&cookies_); 201 request_->GetResponseCookies(&cookies_);
197 202
198 // See comments re: HEAD requests in OnResponseStarted(). 203 // See comments re: HEAD requests in OnResponseStarted().
199 if (!request_->status().is_io_pending() || (request_type_ == HEAD)) { 204 if (!request_->status().is_io_pending() || (request_type_ == HEAD)) {
200 delegate_loop_->PostTask(FROM_HERE, NewRunnableMethod( 205 delegate_loop_->PostTask(FROM_HERE, NewRunnableMethod(
201 this, &Core::OnCompletedURLRequest, request_->status())); 206 this, &Core::OnCompletedURLRequest, request_->status()));
202 delete request_; 207 delete request_;
203 request_ = NULL; 208 request_ = NULL;
204 } 209 }
205 } 210 }
206 211
207 void URLFetcher::Core::StartURLRequest() { 212 void URLFetcher::Core::StartURLRequest() {
208 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 213 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
209 214
210 if (was_cancelled_) { 215 if (was_cancelled_) {
211 // Since StartURLRequest() is posted as a *delayed* task, it may 216 // Since StartURLRequest() is posted as a *delayed* task, it may
212 // run after the URLFetcher was already stopped. 217 // run after the URLFetcher was already stopped.
213 return; 218 return;
214 } 219 }
215 220
216 CHECK(request_context_getter_); 221 CHECK(request_context_getter_);
217 DCHECK(!request_); 222 DCHECK(!request_);
218 223
(...skipping 30 matching lines...) Expand all
249 NOTREACHED(); 254 NOTREACHED();
250 } 255 }
251 256
252 if (!extra_request_headers_.empty()) 257 if (!extra_request_headers_.empty())
253 request_->SetExtraRequestHeaders(extra_request_headers_); 258 request_->SetExtraRequestHeaders(extra_request_headers_);
254 259
255 request_->Start(); 260 request_->Start();
256 } 261 }
257 262
258 void URLFetcher::Core::CancelURLRequest() { 263 void URLFetcher::Core::CancelURLRequest() {
259 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 264 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
265
260 if (request_) { 266 if (request_) {
261 request_->Cancel(); 267 request_->Cancel();
262 delete request_; 268 delete request_;
263 request_ = NULL; 269 request_ = NULL;
264 } 270 }
265 // Release the reference to the request context. There could be multiple 271 // Release the reference to the request context. There could be multiple
266 // references to URLFetcher::Core at this point so it may take a while to 272 // references to URLFetcher::Core at this point so it may take a while to
267 // delete the object, but we cannot delay the destruction of the request 273 // delete the object, but we cannot delay the destruction of the request
268 // context. 274 // context.
269 request_context_getter_ = NULL; 275 request_context_getter_ = NULL;
(...skipping 11 matching lines...) Expand all
281 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::FAILURE); 287 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::FAILURE);
282 if (delegate_) { 288 if (delegate_) {
283 fetcher_->backoff_delay_ = 289 fetcher_->backoff_delay_ =
284 base::TimeDelta::FromMilliseconds(back_off_time); 290 base::TimeDelta::FromMilliseconds(back_off_time);
285 } 291 }
286 ++num_retries_; 292 ++num_retries_;
287 // Restarts the request if we still need to notify the delegate. 293 // Restarts the request if we still need to notify the delegate.
288 if (delegate_) { 294 if (delegate_) {
289 if (fetcher_->automatically_retry_on_5xx_ && 295 if (fetcher_->automatically_retry_on_5xx_ &&
290 num_retries_ <= protect_entry_->max_retries()) { 296 num_retries_ <= protect_entry_->max_retries()) {
291 ChromeThread::PostDelayedTask( 297 io_message_loop_proxy_->PostDelayedTask(
292 ChromeThread::IO, FROM_HERE, 298 FROM_HERE,
293 NewRunnableMethod(this, &Core::StartURLRequest), back_off_time); 299 NewRunnableMethod(this, &Core::StartURLRequest), back_off_time);
294 } else { 300 } else {
295 delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_, 301 delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_,
296 cookies_, data_); 302 cookies_, data_);
297 } 303 }
298 } 304 }
299 } else { 305 } else {
300 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SUCCESS); 306 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SUCCESS);
301 if (delegate_) { 307 if (delegate_) {
302 fetcher_->backoff_delay_ = base::TimeDelta(); 308 fetcher_->backoff_delay_ = base::TimeDelta();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 core_->Start(); 352 core_->Start();
347 } 353 }
348 354
349 const GURL& URLFetcher::url() const { 355 const GURL& URLFetcher::url() const {
350 return core_->url_; 356 return core_->url_;
351 } 357 }
352 358
353 URLFetcher::Delegate* URLFetcher::delegate() const { 359 URLFetcher::Delegate* URLFetcher::delegate() const {
354 return core_->delegate(); 360 return core_->delegate();
355 } 361 }
OLDNEW
« no previous file with comments | « chrome/browser/net/chrome_url_request_context.cc ('k') | chrome/browser/net/url_fetcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698