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 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 // bizarre for SPDY. Assuming this logic is useful at all. | 1237 // bizarre for SPDY. Assuming this logic is useful at all. |
1231 // TODO(davidben): Bubble the error code up so we do not cache? | 1238 // TODO(davidben): Bubble the error code up so we do not cache? |
1232 if (result == ERR_CONNECTION_CLOSED && response_.headers.get()) | 1239 if (result == ERR_CONNECTION_CLOSED && response_.headers.get()) |
1233 result = OK; | 1240 result = OK; |
1234 | 1241 |
1235 if (result < 0) | 1242 if (result < 0) |
1236 return HandleIOError(result); | 1243 return HandleIOError(result); |
1237 | 1244 |
1238 DCHECK(response_.headers.get()); | 1245 DCHECK(response_.headers.get()); |
1239 | 1246 |
| 1247 if (response_.headers.get() && !ContentEncodingsValid()) |
| 1248 return ERR_CONTENT_DECODING_FAILED; |
| 1249 |
1240 // On a 408 response from the server ("Request Timeout") on a stale socket, | 1250 // On a 408 response from the server ("Request Timeout") on a stale socket, |
1241 // retry the request. | 1251 // retry the request. |
1242 // Headers can be NULL because of http://crbug.com/384554. | 1252 // Headers can be NULL because of http://crbug.com/384554. |
1243 if (response_.headers.get() && response_.headers->response_code() == 408 && | 1253 if (response_.headers.get() && response_.headers->response_code() == 408 && |
1244 stream_->IsConnectionReused()) { | 1254 stream_->IsConnectionReused()) { |
1245 net_log_.AddEventWithNetErrorCode( | 1255 net_log_.AddEventWithNetErrorCode( |
1246 NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, | 1256 NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, |
1247 response_.headers->response_code()); | 1257 response_.headers->response_code()); |
1248 // This will close the socket - it would be weird to try and reuse it, even | 1258 // This will close the socket - it would be weird to try and reuse it, even |
1249 // if the server doesn't actually close it. | 1259 // if the server doesn't actually close it. |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1711 void HttpNetworkTransaction::CopyConnectionAttemptsFromStreamRequest() { | 1721 void HttpNetworkTransaction::CopyConnectionAttemptsFromStreamRequest() { |
1712 DCHECK(stream_request_); | 1722 DCHECK(stream_request_); |
1713 | 1723 |
1714 // Since the transaction can restart with auth credentials, it may create a | 1724 // Since the transaction can restart with auth credentials, it may create a |
1715 // stream more than once. Accumulate all of the connection attempts across | 1725 // stream more than once. Accumulate all of the connection attempts across |
1716 // those streams by appending them to the vector: | 1726 // those streams by appending them to the vector: |
1717 for (const auto& attempt : stream_request_->connection_attempts()) | 1727 for (const auto& attempt : stream_request_->connection_attempts()) |
1718 connection_attempts_.push_back(attempt); | 1728 connection_attempts_.push_back(attempt); |
1719 } | 1729 } |
1720 | 1730 |
| 1731 bool HttpNetworkTransaction::ContentEncodingsValid() const { |
| 1732 HttpResponseHeaders* headers = GetResponseHeaders(); |
| 1733 DCHECK(headers); |
| 1734 |
| 1735 std::string accept_encoding; |
| 1736 request_headers_.GetHeader(HttpRequestHeaders::kAcceptEncoding, |
| 1737 &accept_encoding); |
| 1738 std::set<std::string> allowed_encodings; |
| 1739 if (!HttpUtil::ParseAcceptEncoding(accept_encoding, &allowed_encodings)) { |
| 1740 FilterSourceStream::ReportContentDecodingFailed(SourceStream::TYPE_INVALID); |
| 1741 return false; |
| 1742 } |
| 1743 |
| 1744 std::string content_encoding; |
| 1745 headers->GetNormalizedHeader("Content-Encoding", &content_encoding); |
| 1746 std::set<std::string> used_encodings; |
| 1747 if (!HttpUtil::ParseContentEncoding(content_encoding, &used_encodings)) { |
| 1748 FilterSourceStream::ReportContentDecodingFailed(SourceStream::TYPE_INVALID); |
| 1749 return false; |
| 1750 } |
| 1751 |
| 1752 // When "Accept-Encoding" is not specified, it is parsed as "*". |
| 1753 // If "*" encoding is advertised, then any encoding should be "accepted". |
| 1754 // This does not mean, that it will be successfully decoded. |
| 1755 if (allowed_encodings.find("*") != allowed_encodings.end()) |
| 1756 return true; |
| 1757 |
| 1758 for (auto const& encoding : used_encodings) { |
| 1759 SourceStream::SourceType source_type = |
| 1760 FilterSourceStream::ParseEncodingType(encoding); |
| 1761 // We don't reject encodings we are not aware. They just will not decode. |
| 1762 if (source_type == SourceStream::TYPE_UNKNOWN) |
| 1763 continue; |
| 1764 if (allowed_encodings.find(encoding) == allowed_encodings.end()) { |
| 1765 FilterSourceStream::ReportContentDecodingFailed(source_type); |
| 1766 return false; |
| 1767 } |
| 1768 } |
| 1769 return true; |
| 1770 } |
| 1771 |
1721 } // namespace net | 1772 } // namespace net |
OLD | NEW |