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 |