| 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 |