OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "net/url_request/sdch_dictionary_fetcher.h" | 5 #include "net/url_request/sdch_dictionary_fetcher.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <queue> | 8 #include <queue> |
9 #include <set> | 9 #include <set> |
10 | 10 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 ever_network_queued_.clear(); | 109 ever_network_queued_.clear(); |
110 while (!queue_.empty()) | 110 while (!queue_.empty()) |
111 queue_.pop(); | 111 queue_.pop(); |
112 } | 112 } |
113 | 113 |
114 SdchDictionaryFetcher::SdchDictionaryFetcher(URLRequestContext* context) | 114 SdchDictionaryFetcher::SdchDictionaryFetcher(URLRequestContext* context) |
115 : next_state_(STATE_NONE), | 115 : next_state_(STATE_NONE), |
116 in_loop_(false), | 116 in_loop_(false), |
117 fetch_queue_(new UniqueFetchQueue()), | 117 fetch_queue_(new UniqueFetchQueue()), |
118 context_(context) { | 118 context_(context) { |
119 DCHECK(CalledOnValidThread()); | 119 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
120 DCHECK(context); | 120 DCHECK(context); |
121 } | 121 } |
122 | 122 |
123 SdchDictionaryFetcher::~SdchDictionaryFetcher() { | 123 SdchDictionaryFetcher::~SdchDictionaryFetcher() { |
| 124 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
124 } | 125 } |
125 | 126 |
126 bool SdchDictionaryFetcher::Schedule( | 127 bool SdchDictionaryFetcher::Schedule( |
127 const GURL& dictionary_url, | 128 const GURL& dictionary_url, |
128 const OnDictionaryFetchedCallback& callback) { | 129 const OnDictionaryFetchedCallback& callback) { |
129 return ScheduleInternal(dictionary_url, false, callback); | 130 return ScheduleInternal(dictionary_url, false, callback); |
130 } | 131 } |
131 | 132 |
132 bool SdchDictionaryFetcher::ScheduleReload( | 133 bool SdchDictionaryFetcher::ScheduleReload( |
133 const GURL& dictionary_url, | 134 const GURL& dictionary_url, |
134 const OnDictionaryFetchedCallback& callback) { | 135 const OnDictionaryFetchedCallback& callback) { |
135 return ScheduleInternal(dictionary_url, true, callback); | 136 return ScheduleInternal(dictionary_url, true, callback); |
136 } | 137 } |
137 | 138 |
138 void SdchDictionaryFetcher::Cancel() { | 139 void SdchDictionaryFetcher::Cancel() { |
139 DCHECK(CalledOnValidThread()); | 140 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
140 | 141 |
141 ResetRequest(); | 142 ResetRequest(); |
142 next_state_ = STATE_NONE; | 143 next_state_ = STATE_NONE; |
143 | 144 |
144 fetch_queue_->Clear(); | 145 fetch_queue_->Clear(); |
145 } | 146 } |
146 | 147 |
147 void SdchDictionaryFetcher::OnReceivedRedirect( | 148 void SdchDictionaryFetcher::OnReceivedRedirect( |
148 URLRequest* request, | 149 URLRequest* request, |
149 const RedirectInfo& redirect_info, | 150 const RedirectInfo& redirect_info, |
150 bool* defer_redirect) { | 151 bool* defer_redirect) { |
151 DCHECK_EQ(next_state_, STATE_SEND_REQUEST_PENDING); | 152 DCHECK_EQ(next_state_, STATE_SEND_REQUEST_PENDING); |
152 | 153 |
153 next_state_ = STATE_RECEIVED_REDIRECT; | 154 next_state_ = STATE_RECEIVED_REDIRECT; |
154 | 155 |
155 DoLoop(OK); | 156 DoLoop(OK); |
156 } | 157 } |
157 | 158 |
158 void SdchDictionaryFetcher::OnResponseStarted(URLRequest* request, | 159 void SdchDictionaryFetcher::OnResponseStarted(URLRequest* request, |
159 int net_error) { | 160 int net_error) { |
160 DCHECK(CalledOnValidThread()); | 161 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
161 DCHECK_EQ(request, current_request_.get()); | 162 DCHECK_EQ(request, current_request_.get()); |
162 DCHECK_EQ(next_state_, STATE_SEND_REQUEST_PENDING); | 163 DCHECK_EQ(next_state_, STATE_SEND_REQUEST_PENDING); |
163 DCHECK(!in_loop_); | 164 DCHECK(!in_loop_); |
164 DCHECK_NE(ERR_IO_PENDING, net_error); | 165 DCHECK_NE(ERR_IO_PENDING, net_error); |
165 | 166 |
166 // Confirm that the response isn't a stale read from the cache (as | 167 // Confirm that the response isn't a stale read from the cache (as |
167 // may happen in the reload case). If the response was not retrieved over | 168 // may happen in the reload case). If the response was not retrieved over |
168 // HTTP, it is presumed to be fresh. | 169 // HTTP, it is presumed to be fresh. |
169 HttpResponseHeaders* response_headers = request->response_headers(); | 170 HttpResponseHeaders* response_headers = request->response_headers(); |
170 if (net_error == OK && response_headers) { | 171 if (net_error == OK && response_headers) { |
171 bool requires_validation = response_headers->RequiresValidation( | 172 bool requires_validation = response_headers->RequiresValidation( |
172 request->response_info().request_time, | 173 request->response_info().request_time, |
173 request->response_info().response_time, base::Time::Now()); | 174 request->response_info().response_time, base::Time::Now()); |
174 if (requires_validation) | 175 if (requires_validation) |
175 net_error = ERR_FAILED; | 176 net_error = ERR_FAILED; |
176 } | 177 } |
177 | 178 |
178 DoLoop(net_error); | 179 DoLoop(net_error); |
179 } | 180 } |
180 | 181 |
181 void SdchDictionaryFetcher::OnReadCompleted(URLRequest* request, | 182 void SdchDictionaryFetcher::OnReadCompleted(URLRequest* request, |
182 int bytes_read) { | 183 int bytes_read) { |
183 DCHECK(CalledOnValidThread()); | 184 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
184 DCHECK_EQ(request, current_request_.get()); | 185 DCHECK_EQ(request, current_request_.get()); |
185 DCHECK_EQ(next_state_, STATE_READ_BODY_COMPLETE); | 186 DCHECK_EQ(next_state_, STATE_READ_BODY_COMPLETE); |
186 DCHECK(!in_loop_); | 187 DCHECK(!in_loop_); |
187 DCHECK_NE(ERR_IO_PENDING, bytes_read); | 188 DCHECK_NE(ERR_IO_PENDING, bytes_read); |
188 | 189 |
189 DoLoop(GetReadResult(bytes_read, current_request_.get())); | 190 DoLoop(GetReadResult(bytes_read, current_request_.get())); |
190 } | 191 } |
191 | 192 |
192 bool SdchDictionaryFetcher::ScheduleInternal( | 193 bool SdchDictionaryFetcher::ScheduleInternal( |
193 const GURL& dictionary_url, | 194 const GURL& dictionary_url, |
194 bool reload, | 195 bool reload, |
195 const OnDictionaryFetchedCallback& callback) { | 196 const OnDictionaryFetchedCallback& callback) { |
196 DCHECK(CalledOnValidThread()); | 197 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
197 | 198 |
198 // If Push() fails, |dictionary_url| has already been fetched or scheduled to | 199 // If Push() fails, |dictionary_url| has already been fetched or scheduled to |
199 // be fetched. | 200 // be fetched. |
200 if (!fetch_queue_->Push(FetchInfo(dictionary_url, reload, callback))) { | 201 if (!fetch_queue_->Push(FetchInfo(dictionary_url, reload, callback))) { |
201 // TODO(rdsmith): Log this error to the net log. In the case of a | 202 // TODO(rdsmith): Log this error to the net log. In the case of a |
202 // normal fetch, this can be through the URLRequest | 203 // normal fetch, this can be through the URLRequest |
203 // initiating this fetch (once the URLRequest is passed to the fetcher); | 204 // initiating this fetch (once the URLRequest is passed to the fetcher); |
204 // in the case of a reload, it's more complicated. | 205 // in the case of a reload, it's more complicated. |
205 SdchManager::SdchErrorRecovery( | 206 SdchManager::SdchErrorRecovery( |
206 SDCH_DICTIONARY_PREVIOUSLY_SCHEDULED_TO_DOWNLOAD); | 207 SDCH_DICTIONARY_PREVIOUSLY_SCHEDULED_TO_DOWNLOAD); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 break; | 258 break; |
258 case STATE_NONE: | 259 case STATE_NONE: |
259 NOTREACHED(); | 260 NOTREACHED(); |
260 } | 261 } |
261 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 262 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
262 | 263 |
263 return rv; | 264 return rv; |
264 } | 265 } |
265 | 266 |
266 int SdchDictionaryFetcher::DoSendRequest(int rv) { | 267 int SdchDictionaryFetcher::DoSendRequest(int rv) { |
267 DCHECK(CalledOnValidThread()); | 268 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
268 | 269 |
269 // |rv| is ignored, as the result from the previous request doesn't | 270 // |rv| is ignored, as the result from the previous request doesn't |
270 // affect the next request. | 271 // affect the next request. |
271 | 272 |
272 if (fetch_queue_->IsEmpty() || current_request_.get()) { | 273 if (fetch_queue_->IsEmpty() || current_request_.get()) { |
273 next_state_ = STATE_NONE; | 274 next_state_ = STATE_NONE; |
274 return OK; | 275 return OK; |
275 } | 276 } |
276 | 277 |
277 next_state_ = STATE_SEND_REQUEST_PENDING; | 278 next_state_ = STATE_SEND_REQUEST_PENDING; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 int SdchDictionaryFetcher::DoReceivedRedirect(int rv) { | 330 int SdchDictionaryFetcher::DoReceivedRedirect(int rv) { |
330 // Fetching SDCH through a redirect is forbidden; it raises possible | 331 // Fetching SDCH through a redirect is forbidden; it raises possible |
331 // security issues cross-origin, and isn't obviously useful within | 332 // security issues cross-origin, and isn't obviously useful within |
332 // an origin. | 333 // an origin. |
333 ResetRequest(); | 334 ResetRequest(); |
334 next_state_ = STATE_SEND_REQUEST; | 335 next_state_ = STATE_SEND_REQUEST; |
335 return ERR_UNSAFE_REDIRECT; | 336 return ERR_UNSAFE_REDIRECT; |
336 } | 337 } |
337 | 338 |
338 int SdchDictionaryFetcher::DoSendRequestPending(int rv) { | 339 int SdchDictionaryFetcher::DoSendRequestPending(int rv) { |
339 DCHECK(CalledOnValidThread()); | 340 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
340 | 341 |
341 // If there's been an error, abort the current request. | 342 // If there's been an error, abort the current request. |
342 if (rv != OK) { | 343 if (rv != OK) { |
343 ResetRequest(); | 344 ResetRequest(); |
344 next_state_ = STATE_SEND_REQUEST; | 345 next_state_ = STATE_SEND_REQUEST; |
345 return OK; | 346 return OK; |
346 } | 347 } |
347 | 348 |
348 next_state_ = STATE_READ_BODY; | 349 next_state_ = STATE_READ_BODY; |
349 return OK; | 350 return OK; |
350 } | 351 } |
351 | 352 |
352 int SdchDictionaryFetcher::DoReadBody(int rv) { | 353 int SdchDictionaryFetcher::DoReadBody(int rv) { |
353 DCHECK(CalledOnValidThread()); | 354 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
354 | 355 |
355 // If there's been an error, abort the current request. | 356 // If there's been an error, abort the current request. |
356 if (rv != OK) { | 357 if (rv != OK) { |
357 ResetRequest(); | 358 ResetRequest(); |
358 next_state_ = STATE_SEND_REQUEST; | 359 next_state_ = STATE_SEND_REQUEST; |
359 return OK; | 360 return OK; |
360 } | 361 } |
361 | 362 |
362 next_state_ = STATE_READ_BODY_COMPLETE; | 363 next_state_ = STATE_READ_BODY_COMPLETE; |
363 int bytes_read = current_request_->Read(buffer_.get(), kBufferSize); | 364 int bytes_read = current_request_->Read(buffer_.get(), kBufferSize); |
364 if (bytes_read == ERR_IO_PENDING) | 365 if (bytes_read == ERR_IO_PENDING) |
365 return ERR_IO_PENDING; | 366 return ERR_IO_PENDING; |
366 | 367 |
367 return GetReadResult(bytes_read, current_request_.get()); | 368 return GetReadResult(bytes_read, current_request_.get()); |
368 } | 369 } |
369 | 370 |
370 int SdchDictionaryFetcher::DoReadBodyComplete(int rv) { | 371 int SdchDictionaryFetcher::DoReadBodyComplete(int rv) { |
371 DCHECK(CalledOnValidThread()); | 372 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
372 | 373 |
373 // An error; abort the current request. | 374 // An error; abort the current request. |
374 if (rv < 0) { | 375 if (rv < 0) { |
375 ResetRequest(); | 376 ResetRequest(); |
376 next_state_ = STATE_SEND_REQUEST; | 377 next_state_ = STATE_SEND_REQUEST; |
377 return OK; | 378 return OK; |
378 } | 379 } |
379 | 380 |
380 DCHECK_GE(rv, 0); | 381 DCHECK_GE(rv, 0); |
381 | 382 |
382 // Data; append to the dictionary and look for more data. | 383 // Data; append to the dictionary and look for more data. |
383 if (rv > 0) { | 384 if (rv > 0) { |
384 dictionary_->append(buffer_->data(), rv); | 385 dictionary_->append(buffer_->data(), rv); |
385 next_state_ = STATE_READ_BODY; | 386 next_state_ = STATE_READ_BODY; |
386 return OK; | 387 return OK; |
387 } | 388 } |
388 | 389 |
389 // End of file; complete the request. | 390 // End of file; complete the request. |
390 next_state_ = STATE_REQUEST_COMPLETE; | 391 next_state_ = STATE_REQUEST_COMPLETE; |
391 return OK; | 392 return OK; |
392 } | 393 } |
393 | 394 |
394 int SdchDictionaryFetcher::DoCompleteRequest(int rv) { | 395 int SdchDictionaryFetcher::DoCompleteRequest(int rv) { |
395 DCHECK(CalledOnValidThread()); | 396 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
396 | 397 |
397 // If the dictionary was successfully fetched, add it to the manager. | 398 // If the dictionary was successfully fetched, add it to the manager. |
398 if (rv == OK) { | 399 if (rv == OK) { |
399 current_callback_.Run(*dictionary_, current_request_->url(), | 400 current_callback_.Run(*dictionary_, current_request_->url(), |
400 current_request_->net_log(), | 401 current_request_->net_log(), |
401 current_request_->was_cached()); | 402 current_request_->was_cached()); |
402 } | 403 } |
403 | 404 |
404 ResetRequest(); | 405 ResetRequest(); |
405 next_state_ = STATE_SEND_REQUEST; | 406 next_state_ = STATE_SEND_REQUEST; |
406 return OK; | 407 return OK; |
407 } | 408 } |
408 | 409 |
409 } // namespace net | 410 } // namespace net |
OLD | NEW |