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 |