| OLD | NEW |
| 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/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "base/thread.h" | 9 #include "base/thread.h" |
| 10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 void StartURLRequest(); | 58 void StartURLRequest(); |
| 59 void CancelURLRequest(); | 59 void CancelURLRequest(); |
| 60 void OnCompletedURLRequest(const URLRequestStatus& status); | 60 void OnCompletedURLRequest(const URLRequestStatus& status); |
| 61 | 61 |
| 62 URLFetcher* fetcher_; // Corresponding fetcher object | 62 URLFetcher* fetcher_; // Corresponding fetcher object |
| 63 GURL original_url_; // The URL we were asked to fetch | 63 GURL original_url_; // The URL we were asked to fetch |
| 64 GURL url_; // The URL we eventually wound up at | 64 GURL url_; // The URL we eventually wound up at |
| 65 RequestType request_type_; // What type of request is this? | 65 RequestType request_type_; // What type of request is this? |
| 66 URLFetcher::Delegate* delegate_; // Object to notify on completion | 66 URLFetcher::Delegate* delegate_; // Object to notify on completion |
| 67 MessageLoop* delegate_loop_; // Message loop of the creating thread | 67 MessageLoop* delegate_loop_; // Message loop of the creating thread |
| 68 MessageLoop* io_loop_; // Message loop of the IO thread | |
| 69 URLRequest* request_; // The actual request this wraps | 68 URLRequest* request_; // The actual request this wraps |
| 70 int load_flags_; // Flags for the load operation | 69 int load_flags_; // Flags for the load operation |
| 71 int response_code_; // HTTP status code for the request | 70 int response_code_; // HTTP status code for the request |
| 72 std::string data_; // Results of the request | 71 std::string data_; // Results of the request |
| 73 scoped_refptr<net::IOBuffer> buffer_; | 72 scoped_refptr<net::IOBuffer> buffer_; |
| 74 // Read buffer | 73 // Read buffer |
| 75 scoped_refptr<URLRequestContextGetter> request_context_getter_; | 74 scoped_refptr<URLRequestContextGetter> request_context_getter_; |
| 76 // Cookie/cache info for the request | 75 // Cookie/cache info for the request |
| 77 ResponseCookies cookies_; // Response cookies | 76 ResponseCookies cookies_; // Response cookies |
| 78 std::string extra_request_headers_;// Extra headers for the request, if any | 77 std::string extra_request_headers_;// Extra headers for the request, if any |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 | 118 |
| 120 URLFetcher::Core::Core(URLFetcher* fetcher, | 119 URLFetcher::Core::Core(URLFetcher* fetcher, |
| 121 const GURL& original_url, | 120 const GURL& original_url, |
| 122 RequestType request_type, | 121 RequestType request_type, |
| 123 URLFetcher::Delegate* d) | 122 URLFetcher::Delegate* d) |
| 124 : fetcher_(fetcher), | 123 : fetcher_(fetcher), |
| 125 original_url_(original_url), | 124 original_url_(original_url), |
| 126 request_type_(request_type), | 125 request_type_(request_type), |
| 127 delegate_(d), | 126 delegate_(d), |
| 128 delegate_loop_(MessageLoop::current()), | 127 delegate_loop_(MessageLoop::current()), |
| 129 io_loop_(ChromeThread::GetMessageLoop(ChromeThread::IO)), | |
| 130 request_(NULL), | 128 request_(NULL), |
| 131 load_flags_(net::LOAD_NORMAL), | 129 load_flags_(net::LOAD_NORMAL), |
| 132 response_code_(-1), | 130 response_code_(-1), |
| 133 buffer_(new net::IOBuffer(kBufferSize)), | 131 buffer_(new net::IOBuffer(kBufferSize)), |
| 134 protect_entry_(URLFetcherProtectManager::GetInstance()->Register( | 132 protect_entry_(URLFetcherProtectManager::GetInstance()->Register( |
| 135 original_url_.host())), | 133 original_url_.host())), |
| 136 num_retries_(0) { | 134 num_retries_(0) { |
| 137 } | 135 } |
| 138 | 136 |
| 139 void URLFetcher::Core::Start() { | 137 void URLFetcher::Core::Start() { |
| 140 DCHECK(delegate_loop_); | 138 DCHECK(delegate_loop_); |
| 141 DCHECK(io_loop_); | 139 DCHECK(request_context_getter_) << "We need an URLRequestContext!"; |
| 142 DCHECK(request_context_getter_) << "We need an URLRequestContextGetter!"; | 140 ChromeThread::PostDelayedTask( |
| 143 io_loop_->PostDelayedTask(FROM_HERE, NewRunnableMethod( | 141 ChromeThread::IO, FROM_HERE, |
| 144 this, &Core::StartURLRequest), | 142 NewRunnableMethod(this, &Core::StartURLRequest), |
| 145 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SEND)); | 143 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SEND)); |
| 146 } | 144 } |
| 147 | 145 |
| 148 void URLFetcher::Core::Stop() { | 146 void URLFetcher::Core::Stop() { |
| 149 DCHECK_EQ(MessageLoop::current(), delegate_loop_); | 147 DCHECK_EQ(MessageLoop::current(), delegate_loop_); |
| 150 delegate_ = NULL; | 148 delegate_ = NULL; |
| 151 io_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 149 ChromeThread::PostTask( |
| 152 this, &Core::CancelURLRequest)); | 150 ChromeThread::IO, FROM_HERE, |
| 151 NewRunnableMethod(this, &Core::CancelURLRequest)); |
| 153 } | 152 } |
| 154 | 153 |
| 155 void URLFetcher::Core::OnResponseStarted(URLRequest* request) { | 154 void URLFetcher::Core::OnResponseStarted(URLRequest* request) { |
| 156 DCHECK(request == request_); | 155 DCHECK(request == request_); |
| 157 DCHECK(MessageLoop::current() == io_loop_); | 156 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 158 if (request_->status().is_success()) { | 157 if (request_->status().is_success()) { |
| 159 response_code_ = request_->GetResponseCode(); | 158 response_code_ = request_->GetResponseCode(); |
| 160 response_headers_ = request_->response_headers(); | 159 response_headers_ = request_->response_headers(); |
| 161 } | 160 } |
| 162 | 161 |
| 163 int bytes_read = 0; | 162 int bytes_read = 0; |
| 164 // Some servers may treat HEAD requests as GET requests. To free up the | 163 // Some servers may treat HEAD requests as GET requests. To free up the |
| 165 // network connection as soon as possible, signal that the request has | 164 // network connection as soon as possible, signal that the request has |
| 166 // completed immediately, without trying to read any data back (all we care | 165 // completed immediately, without trying to read any data back (all we care |
| 167 // about is the response code and headers, which we already have). | 166 // about is the response code and headers, which we already have). |
| 168 if (request_->status().is_success() && (request_type_ != HEAD)) | 167 if (request_->status().is_success() && (request_type_ != HEAD)) |
| 169 request_->Read(buffer_, kBufferSize, &bytes_read); | 168 request_->Read(buffer_, kBufferSize, &bytes_read); |
| 170 OnReadCompleted(request_, bytes_read); | 169 OnReadCompleted(request_, bytes_read); |
| 171 } | 170 } |
| 172 | 171 |
| 173 void URLFetcher::Core::OnReadCompleted(URLRequest* request, int bytes_read) { | 172 void URLFetcher::Core::OnReadCompleted(URLRequest* request, int bytes_read) { |
| 174 DCHECK(request == request_); | 173 DCHECK(request == request_); |
| 175 DCHECK(MessageLoop::current() == io_loop_); | 174 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 176 | 175 |
| 177 url_ = request->url(); | 176 url_ = request->url(); |
| 178 | 177 |
| 179 do { | 178 do { |
| 180 if (!request_->status().is_success() || bytes_read <= 0) | 179 if (!request_->status().is_success() || bytes_read <= 0) |
| 181 break; | 180 break; |
| 182 data_.append(buffer_->data(), bytes_read); | 181 data_.append(buffer_->data(), bytes_read); |
| 183 } while (request_->Read(buffer_, kBufferSize, &bytes_read)); | 182 } while (request_->Read(buffer_, kBufferSize, &bytes_read)); |
| 184 | 183 |
| 185 if (request_->status().is_success()) | 184 if (request_->status().is_success()) |
| 186 request_->GetResponseCookies(&cookies_); | 185 request_->GetResponseCookies(&cookies_); |
| 187 | 186 |
| 188 // See comments re: HEAD requests in OnResponseStarted(). | 187 // See comments re: HEAD requests in OnResponseStarted(). |
| 189 if (!request_->status().is_io_pending() || (request_type_ == HEAD)) { | 188 if (!request_->status().is_io_pending() || (request_type_ == HEAD)) { |
| 190 delegate_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 189 delegate_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 191 this, &Core::OnCompletedURLRequest, request_->status())); | 190 this, &Core::OnCompletedURLRequest, request_->status())); |
| 192 delete request_; | 191 delete request_; |
| 193 request_ = NULL; | 192 request_ = NULL; |
| 194 } | 193 } |
| 195 } | 194 } |
| 196 | 195 |
| 197 void URLFetcher::Core::StartURLRequest() { | 196 void URLFetcher::Core::StartURLRequest() { |
| 198 DCHECK(MessageLoop::current() == io_loop_); | 197 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 199 DCHECK(!request_); | 198 DCHECK(!request_); |
| 200 | 199 |
| 201 request_ = new URLRequest(original_url_, this); | 200 request_ = new URLRequest(original_url_, this); |
| 202 int flags = request_->load_flags() | load_flags_; | 201 int flags = request_->load_flags() | load_flags_; |
| 203 if (!g_interception_enabled) { | 202 if (!g_interception_enabled) { |
| 204 flags = flags | net::LOAD_DISABLE_INTERCEPT; | 203 flags = flags | net::LOAD_DISABLE_INTERCEPT; |
| 205 } | 204 } |
| 206 request_->set_load_flags(flags); | 205 request_->set_load_flags(flags); |
| 207 request_->set_context(request_context_getter_->GetURLRequestContext()); | 206 request_->set_context(request_context_getter_->GetURLRequestContext()); |
| 208 | 207 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 231 NOTREACHED(); | 230 NOTREACHED(); |
| 232 } | 231 } |
| 233 | 232 |
| 234 if (!extra_request_headers_.empty()) | 233 if (!extra_request_headers_.empty()) |
| 235 request_->SetExtraRequestHeaders(extra_request_headers_); | 234 request_->SetExtraRequestHeaders(extra_request_headers_); |
| 236 | 235 |
| 237 request_->Start(); | 236 request_->Start(); |
| 238 } | 237 } |
| 239 | 238 |
| 240 void URLFetcher::Core::CancelURLRequest() { | 239 void URLFetcher::Core::CancelURLRequest() { |
| 241 DCHECK(MessageLoop::current() == io_loop_); | 240 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 242 if (request_) { | 241 if (request_) { |
| 243 request_->Cancel(); | 242 request_->Cancel(); |
| 244 delete request_; | 243 delete request_; |
| 245 request_ = NULL; | 244 request_ = NULL; |
| 246 } | 245 } |
| 247 // Release the reference to the request context. There could be multiple | 246 // Release the reference to the request context. There could be multiple |
| 248 // references to URLFetcher::Core at this point so it may take a while to | 247 // references to URLFetcher::Core at this point so it may take a while to |
| 249 // delete the object, but we cannot delay the destruction of the request | 248 // delete the object, but we cannot delay the destruction of the request |
| 250 // context. | 249 // context. |
| 251 request_context_getter_ = NULL; | 250 request_context_getter_ = NULL; |
| 252 } | 251 } |
| 253 | 252 |
| 254 void URLFetcher::Core::OnCompletedURLRequest(const URLRequestStatus& status) { | 253 void URLFetcher::Core::OnCompletedURLRequest(const URLRequestStatus& status) { |
| 255 DCHECK(MessageLoop::current() == delegate_loop_); | 254 DCHECK(MessageLoop::current() == delegate_loop_); |
| 256 | 255 |
| 257 // Checks the response from server. | 256 // Checks the response from server. |
| 258 if (response_code_ >= 500) { | 257 if (response_code_ >= 500) { |
| 259 // When encountering a server error, we will send the request again | 258 // When encountering a server error, we will send the request again |
| 260 // after backoff time. | 259 // after backoff time. |
| 261 const int64 wait = | 260 const int64 wait = |
| 262 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::FAILURE); | 261 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::FAILURE); |
| 263 ++num_retries_; | 262 ++num_retries_; |
| 264 // Restarts the request if we still need to notify the delegate. | 263 // Restarts the request if we still need to notify the delegate. |
| 265 if (delegate_) { | 264 if (delegate_) { |
| 266 if (num_retries_ <= protect_entry_->max_retries()) { | 265 if (num_retries_ <= protect_entry_->max_retries()) { |
| 267 io_loop_->PostDelayedTask(FROM_HERE, NewRunnableMethod( | 266 ChromeThread::PostDelayedTask( |
| 268 this, &Core::StartURLRequest), wait); | 267 ChromeThread::IO, FROM_HERE, |
| 268 NewRunnableMethod(this, &Core::StartURLRequest), wait); |
| 269 } else { | 269 } else { |
| 270 delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_, | 270 delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_, |
| 271 cookies_, data_); | 271 cookies_, data_); |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 } else { | 274 } else { |
| 275 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SUCCESS); | 275 protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SUCCESS); |
| 276 if (delegate_) | 276 if (delegate_) |
| 277 delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_, | 277 delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_, |
| 278 cookies_, data_); | 278 cookies_, data_); |
| 279 } | 279 } |
| 280 } | 280 } |
| 281 | 281 |
| 282 void URLFetcher::set_io_loop(MessageLoop* io_loop) { | |
| 283 core_->io_loop_ = io_loop; | |
| 284 } | |
| 285 | |
| 286 void URLFetcher::set_upload_data(const std::string& upload_content_type, | 282 void URLFetcher::set_upload_data(const std::string& upload_content_type, |
| 287 const std::string& upload_content) { | 283 const std::string& upload_content) { |
| 288 core_->upload_content_type_ = upload_content_type; | 284 core_->upload_content_type_ = upload_content_type; |
| 289 core_->upload_content_ = upload_content; | 285 core_->upload_content_ = upload_content; |
| 290 } | 286 } |
| 291 | 287 |
| 292 void URLFetcher::set_load_flags(int load_flags) { | 288 void URLFetcher::set_load_flags(int load_flags) { |
| 293 core_->load_flags_ = load_flags; | 289 core_->load_flags_ = load_flags; |
| 294 } | 290 } |
| 295 | 291 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 315 core_->Start(); | 311 core_->Start(); |
| 316 } | 312 } |
| 317 | 313 |
| 318 const GURL& URLFetcher::url() const { | 314 const GURL& URLFetcher::url() const { |
| 319 return core_->url_; | 315 return core_->url_; |
| 320 } | 316 } |
| 321 | 317 |
| 322 URLFetcher::Delegate* URLFetcher::delegate() const { | 318 URLFetcher::Delegate* URLFetcher::delegate() const { |
| 323 return core_->delegate(); | 319 return core_->delegate(); |
| 324 } | 320 } |
| OLD | NEW |