| 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 13 matching lines...) Expand all Loading... |
| 24 #include "net/url_request/url_request_throttler_manager.h" | 24 #include "net/url_request/url_request_throttler_manager.h" |
| 25 | 25 |
| 26 namespace net { | 26 namespace net { |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 const int kBufferSize = 4096; | 30 const int kBufferSize = 4096; |
| 31 | 31 |
| 32 // Map the bytes_read result from a read attempt and a URLRequest's | 32 // Map the bytes_read result from a read attempt and a URLRequest's |
| 33 // status into a single net return value. | 33 // status into a single net return value. |
| 34 int GetReadResult(int bytes_read, const URLRequest* request) { | 34 int GetReadResult(int rv, const URLRequest* request) { |
| 35 int rv = request->status().error(); | 35 DCHECK_NE(ERR_IO_PENDING, rv); |
| 36 if (request->status().is_success() && bytes_read < 0) { | 36 |
| 37 if (rv < 0) { |
| 37 rv = ERR_FAILED; | 38 rv = ERR_FAILED; |
| 38 request->net_log().AddEventWithNetErrorCode( | 39 request->net_log().AddEventWithNetErrorCode( |
| 39 NetLog::TYPE_SDCH_DICTIONARY_FETCH_IMPLIED_ERROR, rv); | 40 NetLog::TYPE_SDCH_DICTIONARY_FETCH_IMPLIED_ERROR, rv); |
| 40 } | 41 } |
| 41 | 42 |
| 42 if (rv == OK) | |
| 43 rv = bytes_read; | |
| 44 | |
| 45 return rv; | 43 return rv; |
| 46 } | 44 } |
| 47 | 45 |
| 48 struct FetchInfo { | 46 struct FetchInfo { |
| 49 FetchInfo(const GURL& url, | 47 FetchInfo(const GURL& url, |
| 50 bool cache_only, | 48 bool cache_only, |
| 51 const SdchDictionaryFetcher::OnDictionaryFetchedCallback& callback) | 49 const SdchDictionaryFetcher::OnDictionaryFetchedCallback& callback) |
| 52 : url(url), cache_only(cache_only), callback(callback) {} | 50 : url(url), cache_only(cache_only), callback(callback) {} |
| 53 FetchInfo() {} | 51 FetchInfo() {} |
| 54 | 52 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 URLRequest* request, | 146 URLRequest* request, |
| 149 const RedirectInfo& redirect_info, | 147 const RedirectInfo& redirect_info, |
| 150 bool* defer_redirect) { | 148 bool* defer_redirect) { |
| 151 DCHECK_EQ(next_state_, STATE_SEND_REQUEST_PENDING); | 149 DCHECK_EQ(next_state_, STATE_SEND_REQUEST_PENDING); |
| 152 | 150 |
| 153 next_state_ = STATE_RECEIVED_REDIRECT; | 151 next_state_ = STATE_RECEIVED_REDIRECT; |
| 154 | 152 |
| 155 DoLoop(OK); | 153 DoLoop(OK); |
| 156 } | 154 } |
| 157 | 155 |
| 158 void SdchDictionaryFetcher::OnResponseStarted(URLRequest* request) { | 156 void SdchDictionaryFetcher::OnResponseStarted(URLRequest* request, |
| 157 int net_error) { |
| 159 DCHECK(CalledOnValidThread()); | 158 DCHECK(CalledOnValidThread()); |
| 160 DCHECK_EQ(request, current_request_.get()); | 159 DCHECK_EQ(request, current_request_.get()); |
| 161 DCHECK_EQ(next_state_, STATE_SEND_REQUEST_PENDING); | 160 DCHECK_EQ(next_state_, STATE_SEND_REQUEST_PENDING); |
| 162 DCHECK(!in_loop_); | 161 DCHECK(!in_loop_); |
| 162 DCHECK_NE(ERR_IO_PENDING, net_error); |
| 163 | 163 |
| 164 // Confirm that the response isn't a stale read from the cache (as | 164 // Confirm that the response isn't a stale read from the cache (as |
| 165 // may happen in the reload case). If the response was not retrieved over | 165 // may happen in the reload case). If the response was not retrieved over |
| 166 // HTTP, it is presumed to be fresh. | 166 // HTTP, it is presumed to be fresh. |
| 167 HttpResponseHeaders* response_headers = request->response_headers(); | 167 HttpResponseHeaders* response_headers = request->response_headers(); |
| 168 int result = request->status().error(); | 168 if (net_error == OK && response_headers) { |
| 169 if (result == OK && response_headers) { | |
| 170 ValidationType validation_type = response_headers->RequiresValidation( | 169 ValidationType validation_type = response_headers->RequiresValidation( |
| 171 request->response_info().request_time, | 170 request->response_info().request_time, |
| 172 request->response_info().response_time, base::Time::Now()); | 171 request->response_info().response_time, base::Time::Now()); |
| 173 // TODO(rdsmith): Maybe handle VALIDATION_ASYNCHRONOUS by queueing | 172 // TODO(rdsmith): Maybe handle VALIDATION_ASYNCHRONOUS by queueing |
| 174 // a non-reload request for the dictionary. | 173 // a non-reload request for the dictionary. |
| 175 if (validation_type != VALIDATION_NONE) | 174 if (validation_type != VALIDATION_NONE) |
| 176 result = ERR_FAILED; | 175 net_error = ERR_FAILED; |
| 177 } | 176 } |
| 178 | 177 |
| 179 DoLoop(result); | 178 DoLoop(net_error); |
| 180 } | 179 } |
| 181 | 180 |
| 182 void SdchDictionaryFetcher::OnReadCompleted(URLRequest* request, | 181 void SdchDictionaryFetcher::OnReadCompleted(URLRequest* request, |
| 183 int bytes_read) { | 182 int bytes_read) { |
| 184 DCHECK(CalledOnValidThread()); | 183 DCHECK(CalledOnValidThread()); |
| 185 DCHECK_EQ(request, current_request_.get()); | 184 DCHECK_EQ(request, current_request_.get()); |
| 186 DCHECK_EQ(next_state_, STATE_READ_BODY_COMPLETE); | 185 DCHECK_EQ(next_state_, STATE_READ_BODY_COMPLETE); |
| 187 DCHECK(!in_loop_); | 186 DCHECK(!in_loop_); |
| 187 DCHECK_NE(ERR_IO_PENDING, bytes_read); |
| 188 | 188 |
| 189 DoLoop(GetReadResult(bytes_read, current_request_.get())); | 189 DoLoop(GetReadResult(bytes_read, current_request_.get())); |
| 190 } | 190 } |
| 191 | 191 |
| 192 bool SdchDictionaryFetcher::ScheduleInternal( | 192 bool SdchDictionaryFetcher::ScheduleInternal( |
| 193 const GURL& dictionary_url, | 193 const GURL& dictionary_url, |
| 194 bool reload, | 194 bool reload, |
| 195 const OnDictionaryFetchedCallback& callback) { | 195 const OnDictionaryFetchedCallback& callback) { |
| 196 DCHECK(CalledOnValidThread()); | 196 DCHECK(CalledOnValidThread()); |
| 197 | 197 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 DCHECK(CalledOnValidThread()); | 322 DCHECK(CalledOnValidThread()); |
| 323 | 323 |
| 324 // If there's been an error, abort the current request. | 324 // If there's been an error, abort the current request. |
| 325 if (rv != OK) { | 325 if (rv != OK) { |
| 326 ResetRequest(); | 326 ResetRequest(); |
| 327 next_state_ = STATE_SEND_REQUEST; | 327 next_state_ = STATE_SEND_REQUEST; |
| 328 return OK; | 328 return OK; |
| 329 } | 329 } |
| 330 | 330 |
| 331 next_state_ = STATE_READ_BODY_COMPLETE; | 331 next_state_ = STATE_READ_BODY_COMPLETE; |
| 332 int bytes_read = 0; | 332 int bytes_read = current_request_->Read(buffer_.get(), kBufferSize); |
| 333 current_request_->Read(buffer_.get(), kBufferSize, &bytes_read); | 333 if (bytes_read == ERR_IO_PENDING) |
| 334 if (current_request_->status().is_io_pending()) | |
| 335 return ERR_IO_PENDING; | 334 return ERR_IO_PENDING; |
| 336 | 335 |
| 337 return GetReadResult(bytes_read, current_request_.get()); | 336 return GetReadResult(bytes_read, current_request_.get()); |
| 338 } | 337 } |
| 339 | 338 |
| 340 int SdchDictionaryFetcher::DoReadBodyComplete(int rv) { | 339 int SdchDictionaryFetcher::DoReadBodyComplete(int rv) { |
| 341 DCHECK(CalledOnValidThread()); | 340 DCHECK(CalledOnValidThread()); |
| 342 | 341 |
| 343 // An error; abort the current request. | 342 // An error; abort the current request. |
| 344 if (rv < 0) { | 343 if (rv < 0) { |
| 345 ResetRequest(); | 344 ResetRequest(); |
| 346 next_state_ = STATE_SEND_REQUEST; | 345 next_state_ = STATE_SEND_REQUEST; |
| 347 return OK; | 346 return OK; |
| 348 } | 347 } |
| 349 | 348 |
| 350 DCHECK(current_request_->status().is_success()); | 349 DCHECK_GE(rv, 0); |
| 351 | 350 |
| 352 // Data; append to the dictionary and look for more data. | 351 // Data; append to the dictionary and look for more data. |
| 353 if (rv > 0) { | 352 if (rv > 0) { |
| 354 dictionary_->append(buffer_->data(), rv); | 353 dictionary_->append(buffer_->data(), rv); |
| 355 next_state_ = STATE_READ_BODY; | 354 next_state_ = STATE_READ_BODY; |
| 356 return OK; | 355 return OK; |
| 357 } | 356 } |
| 358 | 357 |
| 359 // End of file; complete the request. | 358 // End of file; complete the request. |
| 360 next_state_ = STATE_REQUEST_COMPLETE; | 359 next_state_ = STATE_REQUEST_COMPLETE; |
| 361 return OK; | 360 return OK; |
| 362 } | 361 } |
| 363 | 362 |
| 364 int SdchDictionaryFetcher::DoCompleteRequest(int rv) { | 363 int SdchDictionaryFetcher::DoCompleteRequest(int rv) { |
| 365 DCHECK(CalledOnValidThread()); | 364 DCHECK(CalledOnValidThread()); |
| 366 | 365 |
| 367 // If the dictionary was successfully fetched, add it to the manager. | 366 // If the dictionary was successfully fetched, add it to the manager. |
| 368 if (rv == OK) { | 367 if (rv == OK) { |
| 369 current_callback_.Run(*dictionary_, current_request_->url(), | 368 current_callback_.Run(*dictionary_, current_request_->url(), |
| 370 current_request_->net_log(), | 369 current_request_->net_log(), |
| 371 current_request_->was_cached()); | 370 current_request_->was_cached()); |
| 372 } | 371 } |
| 373 | 372 |
| 374 ResetRequest(); | 373 ResetRequest(); |
| 375 next_state_ = STATE_SEND_REQUEST; | 374 next_state_ = STATE_SEND_REQUEST; |
| 376 return OK; | 375 return OK; |
| 377 } | 376 } |
| 378 | 377 |
| 379 } // namespace net | 378 } // namespace net |
| OLD | NEW |