| Index: components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc | 
| diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc | 
| index f232e945e03ec905fc9263f217c6114737cf8c69..3e79f4a6a98b8f89b3cf574a21d12b2d73c861a1 100644 | 
| --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc | 
| +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc | 
| @@ -19,6 +19,7 @@ | 
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h" | 
| #include "components/data_reduction_proxy/core/browser/data_use_group.h" | 
| #include "components/data_reduction_proxy/core/browser/data_use_group_provider.h" | 
| +#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h" | 
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" | 
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h" | 
| #include "components/data_reduction_proxy/core/common/lofi_decider.h" | 
| @@ -26,6 +27,7 @@ | 
| #include "net/base/mime_util.h" | 
| #include "net/http/http_request_headers.h" | 
| #include "net/http/http_response_headers.h" | 
| +#include "net/nqe/effective_connection_type.h" | 
| #include "net/nqe/network_quality_estimator.h" | 
| #include "net/proxy/proxy_info.h" | 
| #include "net/proxy/proxy_server.h" | 
| @@ -136,9 +138,11 @@ void VerifyHttpRequestHeaders(bool via_chrome_proxy, | 
| const net::HttpRequestHeaders& headers) { | 
| if (via_chrome_proxy) { | 
| DCHECK(headers.HasHeader(chrome_proxy_header())); | 
| +    DCHECK(headers.HasHeader(chrome_proxy_ect_header())); | 
| } else { | 
| DCHECK(!headers.HasHeader(chrome_proxy_header())); | 
| DCHECK(!headers.HasHeader(chrome_proxy_accept_transform_header())); | 
| +    DCHECK(!headers.HasHeader(chrome_proxy_ect_header())); | 
| } | 
| } | 
|  | 
| @@ -223,6 +227,8 @@ void DataReductionProxyNetworkDelegate::OnBeforeStartTransactionInternal( | 
| ->MaybeSetAcceptTransformHeader( | 
| *request, data_reduction_proxy_config_->lofi_off(), headers); | 
| } | 
| + | 
| +  MaybeAddChromeProxyECTHeader(headers, *request); | 
| } | 
|  | 
| void DataReductionProxyNetworkDelegate::OnBeforeSendHeadersInternal( | 
| @@ -281,6 +287,7 @@ void DataReductionProxyNetworkDelegate::OnBeforeSendHeadersInternal( | 
| // Chrome-Proxy-Accept-Transform header. | 
| lofi_decider->RemoveAcceptTransformHeader(headers); | 
| } | 
| +    RemoveChromeProxyECTHeader(headers); | 
| VerifyHttpRequestHeaders(false, *headers); | 
| return; | 
| } | 
| @@ -574,4 +581,48 @@ void DataReductionProxyNetworkDelegate::MaybeAddBrotliToAcceptEncodingHeader( | 
| header_value); | 
| } | 
|  | 
| +void DataReductionProxyNetworkDelegate::MaybeAddChromeProxyECTHeader( | 
| +    net::HttpRequestHeaders* request_headers, | 
| +    const net::URLRequest& request) const { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| + | 
| +  // This method should be called only when the resolved proxy was a data | 
| +  // saver proxy. | 
| +  DCHECK(request.url().is_valid()); | 
| +  DCHECK(!request.url().SchemeIsCryptographic()); | 
| +  DCHECK(request.url().SchemeIsHTTPOrHTTPS()); | 
| + | 
| +  if (request_headers->HasHeader(chrome_proxy_ect_header())) | 
| +    request_headers->RemoveHeader(chrome_proxy_ect_header()); | 
| + | 
| +  if (request.context()->network_quality_estimator()) { | 
| +    net::EffectiveConnectionType type = request.context() | 
| +                                            ->network_quality_estimator() | 
| +                                            ->GetEffectiveConnectionType(); | 
| +    if (type > net::EFFECTIVE_CONNECTION_TYPE_OFFLINE) { | 
| +      DCHECK_NE(net::EFFECTIVE_CONNECTION_TYPE_LAST, type); | 
| +      request_headers->SetHeader(chrome_proxy_ect_header(), | 
| +                                 net::GetNameForEffectiveConnectionType(type)); | 
| +      return; | 
| +    } | 
| +  } | 
| +  request_headers->SetHeader(chrome_proxy_ect_header(), | 
| +                             net::GetNameForEffectiveConnectionType( | 
| +                                 net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN)); | 
| + | 
| +  static_assert(net::EFFECTIVE_CONNECTION_TYPE_OFFLINE + 1 == | 
| +                    net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G, | 
| +                "ECT enum value is not handled."); | 
| +  static_assert(net::EFFECTIVE_CONNECTION_TYPE_4G + 1 == | 
| +                    net::EFFECTIVE_CONNECTION_TYPE_LAST, | 
| +                "ECT enum value is not handled."); | 
| +} | 
| + | 
| +void DataReductionProxyNetworkDelegate::RemoveChromeProxyECTHeader( | 
| +    net::HttpRequestHeaders* request_headers) const { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| + | 
| +  request_headers->RemoveHeader(chrome_proxy_ect_header()); | 
| +} | 
| + | 
| }  // namespace data_reduction_proxy | 
|  |