| Index: net/http/http_network_transaction.cc
|
| diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
|
| index e0105c60396fe3f891916b12114cff7c14da899b..5961f423e766591d02a2c748242bad60d9a8ad64 100644
|
| --- a/net/http/http_network_transaction.cc
|
| +++ b/net/http/http_network_transaction.cc
|
| @@ -32,6 +32,7 @@
|
| #include "net/base/net_errors.h"
|
| #include "net/base/upload_data_stream.h"
|
| #include "net/base/url_util.h"
|
| +#include "net/filter/filter_source_stream.h"
|
| #include "net/http/http_auth.h"
|
| #include "net/http/http_auth_handler.h"
|
| #include "net/http/http_auth_handler_factory.h"
|
| @@ -545,6 +546,12 @@ void HttpNetworkTransaction::OnNeedsProxyAuth(
|
| establishing_tunnel_ = true;
|
| response_.headers = proxy_response.headers;
|
| response_.auth_challenge = proxy_response.auth_challenge;
|
| +
|
| + if (response_.headers.get() && !ContentEncodingsValid()) {
|
| + DoCallback(ERR_CONTENT_DECODING_FAILED);
|
| + return;
|
| + }
|
| +
|
| headers_valid_ = true;
|
| server_ssl_config_ = used_ssl_config;
|
| proxy_info_ = used_proxy_info;
|
| @@ -1237,6 +1244,9 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
|
|
|
| DCHECK(response_.headers.get());
|
|
|
| + if (response_.headers.get() && !ContentEncodingsValid())
|
| + return ERR_CONTENT_DECODING_FAILED;
|
| +
|
| // On a 408 response from the server ("Request Timeout") on a stale socket,
|
| // retry the request.
|
| // Headers can be NULL because of http://crbug.com/384554.
|
| @@ -1718,4 +1728,45 @@ void HttpNetworkTransaction::CopyConnectionAttemptsFromStreamRequest() {
|
| connection_attempts_.push_back(attempt);
|
| }
|
|
|
| +bool HttpNetworkTransaction::ContentEncodingsValid() const {
|
| + HttpResponseHeaders* headers = GetResponseHeaders();
|
| + DCHECK(headers);
|
| +
|
| + std::string accept_encoding;
|
| + request_headers_.GetHeader(HttpRequestHeaders::kAcceptEncoding,
|
| + &accept_encoding);
|
| + std::set<std::string> allowed_encodings;
|
| + if (!HttpUtil::ParseAcceptEncoding(accept_encoding, &allowed_encodings)) {
|
| + FilterSourceStream::ReportContentDecodingFailed(SourceStream::TYPE_INVALID);
|
| + return false;
|
| + }
|
| +
|
| + std::string content_encoding;
|
| + headers->GetNormalizedHeader("Content-Encoding", &content_encoding);
|
| + std::set<std::string> used_encodings;
|
| + if (!HttpUtil::ParseContentEncoding(content_encoding, &used_encodings)) {
|
| + FilterSourceStream::ReportContentDecodingFailed(SourceStream::TYPE_INVALID);
|
| + return false;
|
| + }
|
| +
|
| + // When "Accept-Encoding" is not specified, it is parsed as "*".
|
| + // If "*" encoding is advertised, then any encoding should be "accepted".
|
| + // This does not mean, that it will be successfully decoded.
|
| + if (allowed_encodings.find("*") != allowed_encodings.end())
|
| + return true;
|
| +
|
| + for (auto const& encoding : used_encodings) {
|
| + SourceStream::SourceType source_type =
|
| + FilterSourceStream::ParseEncodingType(encoding);
|
| + // We don't reject encodings we are not aware. They just will not decode.
|
| + if (source_type == SourceStream::TYPE_UNKNOWN)
|
| + continue;
|
| + if (allowed_encodings.find(encoding) == allowed_encodings.end()) {
|
| + FilterSourceStream::ReportContentDecodingFailed(source_type);
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| } // namespace net
|
|
|