| 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_SEQUENCE(sequence_checker_); | 
| 120   DCHECK(context); | 120   DCHECK(context); | 
| 121 } | 121 } | 
| 122 | 122 | 
| 123 SdchDictionaryFetcher::~SdchDictionaryFetcher() { | 123 SdchDictionaryFetcher::~SdchDictionaryFetcher() { | 
|  | 124   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_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_SEQUENCE(sequence_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_SEQUENCE(sequence_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_SEQUENCE(sequence_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_SEQUENCE(sequence_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_SEQUENCE(sequence_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_SEQUENCE(sequence_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_SEQUENCE(sequence_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_SEQUENCE(sequence_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_SEQUENCE(sequence_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 | 
|---|