Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/http/http_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 #include "base/values.h" | 25 #include "base/values.h" |
| 26 #include "build/build_config.h" | 26 #include "build/build_config.h" |
| 27 #include "net/base/auth.h" | 27 #include "net/base/auth.h" |
| 28 #include "net/base/host_port_pair.h" | 28 #include "net/base/host_port_pair.h" |
| 29 #include "net/base/io_buffer.h" | 29 #include "net/base/io_buffer.h" |
| 30 #include "net/base/load_flags.h" | 30 #include "net/base/load_flags.h" |
| 31 #include "net/base/load_timing_info.h" | 31 #include "net/base/load_timing_info.h" |
| 32 #include "net/base/net_errors.h" | 32 #include "net/base/net_errors.h" |
| 33 #include "net/base/upload_data_stream.h" | 33 #include "net/base/upload_data_stream.h" |
| 34 #include "net/base/url_util.h" | 34 #include "net/base/url_util.h" |
| 35 #include "net/filter/filter_source_stream.h" | |
| 35 #include "net/http/http_auth.h" | 36 #include "net/http/http_auth.h" |
| 36 #include "net/http/http_auth_handler.h" | 37 #include "net/http/http_auth_handler.h" |
| 37 #include "net/http/http_auth_handler_factory.h" | 38 #include "net/http/http_auth_handler_factory.h" |
| 38 #include "net/http/http_basic_stream.h" | 39 #include "net/http/http_basic_stream.h" |
| 39 #include "net/http/http_chunked_decoder.h" | 40 #include "net/http/http_chunked_decoder.h" |
| 40 #include "net/http/http_network_session.h" | 41 #include "net/http/http_network_session.h" |
| 41 #include "net/http/http_proxy_client_socket.h" | 42 #include "net/http/http_proxy_client_socket.h" |
| 42 #include "net/http/http_proxy_client_socket_pool.h" | 43 #include "net/http/http_proxy_client_socket_pool.h" |
| 43 #include "net/http/http_request_headers.h" | 44 #include "net/http/http_request_headers.h" |
| 44 #include "net/http/http_request_info.h" | 45 #include "net/http/http_request_info.h" |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 const HttpResponseInfo& proxy_response, | 539 const HttpResponseInfo& proxy_response, |
| 539 const SSLConfig& used_ssl_config, | 540 const SSLConfig& used_ssl_config, |
| 540 const ProxyInfo& used_proxy_info, | 541 const ProxyInfo& used_proxy_info, |
| 541 HttpAuthController* auth_controller) { | 542 HttpAuthController* auth_controller) { |
| 542 DCHECK(stream_request_.get()); | 543 DCHECK(stream_request_.get()); |
| 543 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | 544 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); |
| 544 | 545 |
| 545 establishing_tunnel_ = true; | 546 establishing_tunnel_ = true; |
| 546 response_.headers = proxy_response.headers; | 547 response_.headers = proxy_response.headers; |
| 547 response_.auth_challenge = proxy_response.auth_challenge; | 548 response_.auth_challenge = proxy_response.auth_challenge; |
| 549 | |
| 550 if (response_.headers.get() && !ContentEncodingsValid()) { | |
| 551 DoCallback(ERR_CONTENT_DECODING_FAILED); | |
| 552 return; | |
| 553 } | |
| 554 | |
| 548 headers_valid_ = true; | 555 headers_valid_ = true; |
| 549 server_ssl_config_ = used_ssl_config; | 556 server_ssl_config_ = used_ssl_config; |
| 550 proxy_info_ = used_proxy_info; | 557 proxy_info_ = used_proxy_info; |
| 551 | 558 |
| 552 auth_controllers_[HttpAuth::AUTH_PROXY] = auth_controller; | 559 auth_controllers_[HttpAuth::AUTH_PROXY] = auth_controller; |
| 553 pending_auth_target_ = HttpAuth::AUTH_PROXY; | 560 pending_auth_target_ = HttpAuth::AUTH_PROXY; |
| 554 | 561 |
| 555 DoCallback(OK); | 562 DoCallback(OK); |
| 556 } | 563 } |
| 557 | 564 |
| (...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1239 // bizarre for SPDY. Assuming this logic is useful at all. | 1246 // bizarre for SPDY. Assuming this logic is useful at all. |
| 1240 // TODO(davidben): Bubble the error code up so we do not cache? | 1247 // TODO(davidben): Bubble the error code up so we do not cache? |
| 1241 if (result == ERR_CONNECTION_CLOSED && response_.headers.get()) | 1248 if (result == ERR_CONNECTION_CLOSED && response_.headers.get()) |
| 1242 result = OK; | 1249 result = OK; |
| 1243 | 1250 |
| 1244 if (result < 0) | 1251 if (result < 0) |
| 1245 return HandleIOError(result); | 1252 return HandleIOError(result); |
| 1246 | 1253 |
| 1247 DCHECK(response_.headers.get()); | 1254 DCHECK(response_.headers.get()); |
| 1248 | 1255 |
| 1256 if (response_.headers.get() && !ContentEncodingsValid()) | |
| 1257 return ERR_CONTENT_DECODING_FAILED; | |
| 1258 | |
| 1249 // On a 408 response from the server ("Request Timeout") on a stale socket, | 1259 // On a 408 response from the server ("Request Timeout") on a stale socket, |
| 1250 // retry the request. | 1260 // retry the request. |
| 1251 // Headers can be NULL because of http://crbug.com/384554. | 1261 // Headers can be NULL because of http://crbug.com/384554. |
| 1252 if (response_.headers.get() && response_.headers->response_code() == 408 && | 1262 if (response_.headers.get() && response_.headers->response_code() == 408 && |
| 1253 stream_->IsConnectionReused()) { | 1263 stream_->IsConnectionReused()) { |
| 1254 net_log_.AddEventWithNetErrorCode( | 1264 net_log_.AddEventWithNetErrorCode( |
| 1255 NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, | 1265 NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, |
| 1256 response_.headers->response_code()); | 1266 response_.headers->response_code()); |
| 1257 // This will close the socket - it would be weird to try and reuse it, even | 1267 // This will close the socket - it would be weird to try and reuse it, even |
| 1258 // if the server doesn't actually close it. | 1268 // if the server doesn't actually close it. |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1704 void HttpNetworkTransaction::CopyConnectionAttemptsFromStreamRequest() { | 1714 void HttpNetworkTransaction::CopyConnectionAttemptsFromStreamRequest() { |
| 1705 DCHECK(stream_request_); | 1715 DCHECK(stream_request_); |
| 1706 | 1716 |
| 1707 // Since the transaction can restart with auth credentials, it may create a | 1717 // Since the transaction can restart with auth credentials, it may create a |
| 1708 // stream more than once. Accumulate all of the connection attempts across | 1718 // stream more than once. Accumulate all of the connection attempts across |
| 1709 // those streams by appending them to the vector: | 1719 // those streams by appending them to the vector: |
| 1710 for (const auto& attempt : stream_request_->connection_attempts()) | 1720 for (const auto& attempt : stream_request_->connection_attempts()) |
| 1711 connection_attempts_.push_back(attempt); | 1721 connection_attempts_.push_back(attempt); |
| 1712 } | 1722 } |
| 1713 | 1723 |
| 1724 bool HttpNetworkTransaction::ContentEncodingsValid() const { | |
| 1725 HttpResponseHeaders* headers = GetResponseHeaders(); | |
| 1726 DCHECK(headers); | |
| 1727 | |
| 1728 std::string accept_encoding; | |
| 1729 request_headers_.GetHeader(HttpRequestHeaders::kAcceptEncoding, | |
| 1730 &accept_encoding); | |
| 1731 std::set<std::string> allowed_encodings; | |
| 1732 if (!HttpUtil::ParseAcceptEncoding(accept_encoding, &allowed_encodings)) { | |
| 1733 FilterSourceStream::ReportContentDecodingRejected( | |
| 1734 SourceStream::TYPE_INVALID); | |
| 1735 return false; | |
| 1736 } | |
| 1737 | |
| 1738 std::string content_encoding; | |
| 1739 headers->GetNormalizedHeader("Content-Encoding", &content_encoding); | |
| 1740 std::set<std::string> used_encodings; | |
| 1741 if (!HttpUtil::ParseContentEncoding(content_encoding, &used_encodings)) { | |
| 1742 FilterSourceStream::ReportContentDecodingRejected( | |
| 1743 SourceStream::TYPE_INVALID); | |
| 1744 return false; | |
| 1745 } | |
| 1746 | |
| 1747 // When "Accept-Encoding" is not specified, or allows "*" encoding, then any | |
| 1748 // encoding should be "accepted". This does not mean, that it will be | |
| 1749 // successfully decoded. | |
|
Randy Smith (Not in Mondays)
2017/03/28 19:55:36
This test doesn't seem to be testing for the lack
eustas
2017/04/04 10:34:30
Updated comment.
| |
| 1750 if (allowed_encodings.find("*") != allowed_encodings.end()) | |
| 1751 return true; | |
|
Randy Smith (Not in Mondays)
2017/03/28 19:55:36
Move this up above the content encoding parsing?
eustas
2017/04/04 10:34:30
If we do so, then malformed header values go throu
| |
| 1752 | |
| 1753 for (auto const& encoding : used_encodings) { | |
| 1754 SourceStream::SourceType source_type = | |
| 1755 FilterSourceStream::ParseEncodingType(encoding); | |
| 1756 // We don't reject encodings we are not aware. They just will not decode. | |
| 1757 if (source_type == SourceStream::TYPE_UNKNOWN) | |
| 1758 continue; | |
| 1759 if (allowed_encodings.find(encoding) == allowed_encodings.end()) { | |
| 1760 FilterSourceStream::ReportContentDecodingRejected(source_type); | |
| 1761 return false; | |
| 1762 } | |
| 1763 } | |
| 1764 return true; | |
| 1765 } | |
| 1766 | |
| 1714 } // namespace net | 1767 } // namespace net |
| OLD | NEW |