network_service_network_delegate.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/network/network_service_network_delegate.h"
  5. #include <string>
  6. #include "base/bind.h"
  7. #include "base/debug/dump_without_crashing.h"
  8. #include "base/stl_util.h"
  9. #include "base/strings/utf_string_conversions.h"
  10. #include "build/build_config.h"
  11. #include "components/domain_reliability/monitor.h"
  12. #include "net/base/features.h"
  13. #include "net/base/isolation_info.h"
  14. #include "net/base/load_flags.h"
  15. #include "net/base/net_errors.h"
  16. #include "net/cookies/same_party_context.h"
  17. #include "net/url_request/referrer_policy.h"
  18. #include "net/url_request/url_request.h"
  19. #include "services/network/cookie_manager.h"
  20. #include "services/network/network_context.h"
  21. #include "services/network/network_service.h"
  22. #include "services/network/network_service_proxy_delegate.h"
  23. #include "services/network/pending_callback_chain.h"
  24. #include "services/network/url_loader.h"
  25. #include "url/gurl.h"
  26. #if !BUILDFLAG(IS_IOS)
  27. #include "services/network/websocket.h"
  28. #endif
  29. namespace network {
  30. namespace {
  31. const char kClearSiteDataHeader[] = "Clear-Site-Data";
  32. } // anonymous namespace
  33. NetworkServiceNetworkDelegate::NetworkServiceNetworkDelegate(
  34. bool enable_referrers,
  35. bool validate_referrer_policy_on_initial_request,
  36. mojo::PendingRemote<mojom::ProxyErrorClient> proxy_error_client_remote,
  37. NetworkContext* network_context)
  38. : enable_referrers_(enable_referrers),
  39. validate_referrer_policy_on_initial_request_(
  40. validate_referrer_policy_on_initial_request),
  41. network_context_(network_context) {
  42. if (proxy_error_client_remote)
  43. proxy_error_client_.Bind(std::move(proxy_error_client_remote));
  44. }
  45. NetworkServiceNetworkDelegate::~NetworkServiceNetworkDelegate() = default;
  46. void NetworkServiceNetworkDelegate::MaybeTruncateReferrer(
  47. net::URLRequest* const request,
  48. const GURL& effective_url) {
  49. if (!enable_referrers_) {
  50. request->SetReferrer(std::string());
  51. request->set_referrer_policy(net::ReferrerPolicy::NO_REFERRER);
  52. return;
  53. }
  54. if (base::FeatureList::IsEnabled(
  55. net::features::kCapReferrerToOriginOnCrossOrigin)) {
  56. if (!url::IsSameOriginWith(effective_url, GURL(request->referrer()))) {
  57. auto capped_referrer = url::Origin::Create(GURL(request->referrer()));
  58. request->SetReferrer(capped_referrer.GetURL().spec());
  59. }
  60. }
  61. }
  62. int NetworkServiceNetworkDelegate::OnBeforeURLRequest(
  63. net::URLRequest* request,
  64. net::CompletionOnceCallback callback,
  65. GURL* new_url) {
  66. DCHECK(request);
  67. auto* const loader = URLLoader::ForRequest(*request);
  68. const GURL* effective_url = nullptr;
  69. if (loader && loader->new_redirect_url()) {
  70. DCHECK(new_url);
  71. *new_url = loader->new_redirect_url().value();
  72. effective_url = new_url;
  73. } else {
  74. effective_url = &request->url();
  75. }
  76. MaybeTruncateReferrer(request, *effective_url);
  77. if (!loader)
  78. return net::OK;
  79. NetworkService* network_service = network_context_->network_service();
  80. if (network_service) {
  81. loader->SetEnableReportingRawHeaders(network_service->HasRawHeadersAccess(
  82. loader->GetProcessId(), *effective_url));
  83. }
  84. return net::OK;
  85. }
  86. int NetworkServiceNetworkDelegate::OnBeforeStartTransaction(
  87. net::URLRequest* request,
  88. const net::HttpRequestHeaders& headers,
  89. OnBeforeStartTransactionCallback callback) {
  90. URLLoader* url_loader = URLLoader::ForRequest(*request);
  91. if (url_loader)
  92. return url_loader->OnBeforeStartTransaction(headers, std::move(callback));
  93. #if !BUILDFLAG(IS_IOS)
  94. WebSocket* web_socket = WebSocket::ForRequest(*request);
  95. if (web_socket)
  96. return web_socket->OnBeforeStartTransaction(headers, std::move(callback));
  97. #endif // !BUILDFLAG(IS_IOS)
  98. return net::OK;
  99. }
  100. int NetworkServiceNetworkDelegate::OnHeadersReceived(
  101. net::URLRequest* request,
  102. net::CompletionOnceCallback callback,
  103. const net::HttpResponseHeaders* original_response_headers,
  104. scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
  105. const net::IPEndPoint& endpoint,
  106. absl::optional<GURL>* preserve_fragment_on_redirect_url) {
  107. auto chain = base::MakeRefCounted<PendingCallbackChain>(std::move(callback));
  108. URLLoader* url_loader = URLLoader::ForRequest(*request);
  109. if (url_loader) {
  110. chain->AddResult(url_loader->OnHeadersReceived(
  111. chain->CreateCallback(), original_response_headers,
  112. override_response_headers, endpoint,
  113. preserve_fragment_on_redirect_url));
  114. }
  115. #if !BUILDFLAG(IS_IOS)
  116. WebSocket* web_socket = WebSocket::ForRequest(*request);
  117. if (web_socket) {
  118. chain->AddResult(web_socket->OnHeadersReceived(
  119. chain->CreateCallback(), original_response_headers,
  120. override_response_headers, preserve_fragment_on_redirect_url));
  121. }
  122. #endif // !BUILDFLAG(IS_IOS)
  123. chain->AddResult(HandleClearSiteDataHeader(request, chain->CreateCallback(),
  124. original_response_headers));
  125. return chain->GetResult();
  126. }
  127. void NetworkServiceNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
  128. const GURL& new_location) {
  129. if (network_context_->domain_reliability_monitor())
  130. network_context_->domain_reliability_monitor()->OnBeforeRedirect(request);
  131. }
  132. void NetworkServiceNetworkDelegate::OnResponseStarted(net::URLRequest* request,
  133. int net_error) {
  134. ForwardProxyErrors(net_error);
  135. }
  136. void NetworkServiceNetworkDelegate::OnCompleted(net::URLRequest* request,
  137. bool started,
  138. int net_error) {
  139. // TODO(mmenke): Once the network service ships on all platforms, can move
  140. // this logic into URLLoader's completion method.
  141. DCHECK_NE(net::ERR_IO_PENDING, net_error);
  142. if (network_context_->domain_reliability_monitor()) {
  143. network_context_->domain_reliability_monitor()->OnCompleted(
  144. request, started, net_error);
  145. }
  146. ForwardProxyErrors(net_error);
  147. }
  148. void NetworkServiceNetworkDelegate::OnPACScriptError(
  149. int line_number,
  150. const std::u16string& error) {
  151. if (!proxy_error_client_)
  152. return;
  153. proxy_error_client_->OnPACScriptError(line_number, base::UTF16ToUTF8(error));
  154. }
  155. bool NetworkServiceNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies(
  156. const net::URLRequest& request,
  157. net::CookieAccessResultList& maybe_included_cookies,
  158. net::CookieAccessResultList& excluded_cookies) {
  159. if (!network_context_->cookie_manager()
  160. ->cookie_settings()
  161. .AnnotateAndMoveUserBlockedCookies(
  162. request.url(), request.site_for_cookies(),
  163. base::OptionalOrNullptr(
  164. request.isolation_info().top_frame_origin()),
  165. maybe_included_cookies, excluded_cookies)) {
  166. // CookieSettings has already moved and annotated the cookies.
  167. return false;
  168. }
  169. bool allowed = true;
  170. URLLoader* url_loader = URLLoader::ForRequest(request);
  171. if (url_loader) {
  172. allowed =
  173. url_loader->AllowCookies(request.url(), request.site_for_cookies());
  174. #if !BUILDFLAG(IS_IOS)
  175. } else {
  176. WebSocket* web_socket = WebSocket::ForRequest(request);
  177. if (web_socket) {
  178. allowed = web_socket->AllowCookies(request.url());
  179. }
  180. #endif // !BUILDFLAG(IS_IOS)
  181. }
  182. if (!allowed)
  183. ExcludeAllCookies(net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES,
  184. maybe_included_cookies, excluded_cookies);
  185. return allowed;
  186. }
  187. bool NetworkServiceNetworkDelegate::OnCanSetCookie(
  188. const net::URLRequest& request,
  189. const net::CanonicalCookie& cookie,
  190. net::CookieOptions* options) {
  191. bool allowed =
  192. network_context_->cookie_manager()->cookie_settings().IsCookieAccessible(
  193. cookie, request.url(), request.site_for_cookies(),
  194. request.isolation_info().top_frame_origin());
  195. if (!allowed)
  196. return false;
  197. URLLoader* url_loader = URLLoader::ForRequest(request);
  198. if (url_loader)
  199. return url_loader->AllowCookies(request.url(), request.site_for_cookies());
  200. #if !BUILDFLAG(IS_IOS)
  201. WebSocket* web_socket = WebSocket::ForRequest(request);
  202. if (web_socket)
  203. return web_socket->AllowCookies(request.url());
  204. #endif // !BUILDFLAG(IS_IOS)
  205. return true;
  206. }
  207. net::NetworkDelegate::PrivacySetting
  208. NetworkServiceNetworkDelegate::OnForcePrivacyMode(
  209. const GURL& url,
  210. const net::SiteForCookies& site_for_cookies,
  211. const absl::optional<url::Origin>& top_frame_origin,
  212. net::SamePartyContext::Type same_party_context_type) const {
  213. return network_context_->cookie_manager()
  214. ->cookie_settings()
  215. .IsPrivacyModeEnabled(url, site_for_cookies, top_frame_origin,
  216. same_party_context_type);
  217. }
  218. bool NetworkServiceNetworkDelegate::
  219. OnCancelURLRequestWithPolicyViolatingReferrerHeader(
  220. const net::URLRequest& request,
  221. const GURL& target_url,
  222. const GURL& referrer_url) const {
  223. // TODO(mmenke): Once the network service has shipped on all platforms,
  224. // consider moving this logic into URLLoader, and removing this method from
  225. // NetworkDelegate. Can just have a DCHECK in URLRequest instead.
  226. if (!validate_referrer_policy_on_initial_request_)
  227. return false;
  228. LOG(ERROR) << "Cancelling request to " << target_url
  229. << " with invalid referrer " << referrer_url;
  230. // Record information to help debug issues like http://crbug.com/422871.
  231. if (target_url.SchemeIsHTTPOrHTTPS()) {
  232. auto referrer_policy = request.referrer_policy();
  233. base::debug::Alias(&referrer_policy);
  234. DEBUG_ALIAS_FOR_GURL(target_buf, target_url);
  235. DEBUG_ALIAS_FOR_GURL(referrer_buf, referrer_url);
  236. base::debug::DumpWithoutCrashing();
  237. }
  238. return true;
  239. }
  240. bool NetworkServiceNetworkDelegate::OnCanQueueReportingReport(
  241. const url::Origin& origin) const {
  242. return network_context_->cookie_manager()
  243. ->cookie_settings()
  244. .IsFullCookieAccessAllowed(origin.GetURL(), origin.GetURL(),
  245. QueryReason::kSiteStorage);
  246. }
  247. void NetworkServiceNetworkDelegate::OnCanSendReportingReports(
  248. std::set<url::Origin> origins,
  249. base::OnceCallback<void(std::set<url::Origin>)> result_callback) const {
  250. auto* client = network_context_->client();
  251. if (!client) {
  252. origins.clear();
  253. std::move(result_callback).Run(std::move(origins));
  254. return;
  255. }
  256. if (network_context_->SkipReportingPermissionCheck()) {
  257. std::move(result_callback).Run(std::move(origins));
  258. return;
  259. }
  260. std::vector<url::Origin> origin_vector;
  261. std::copy(origins.begin(), origins.end(), std::back_inserter(origin_vector));
  262. client->OnCanSendReportingReports(
  263. origin_vector,
  264. base::BindOnce(
  265. &NetworkServiceNetworkDelegate::FinishedCanSendReportingReports,
  266. weak_ptr_factory_.GetWeakPtr(), std::move(result_callback)));
  267. }
  268. bool NetworkServiceNetworkDelegate::OnCanSetReportingClient(
  269. const url::Origin& origin,
  270. const GURL& endpoint) const {
  271. return network_context_->cookie_manager()
  272. ->cookie_settings()
  273. .IsFullCookieAccessAllowed(origin.GetURL(), origin.GetURL(),
  274. QueryReason::kSiteStorage);
  275. }
  276. bool NetworkServiceNetworkDelegate::OnCanUseReportingClient(
  277. const url::Origin& origin,
  278. const GURL& endpoint) const {
  279. return network_context_->cookie_manager()
  280. ->cookie_settings()
  281. .IsFullCookieAccessAllowed(origin.GetURL(), origin.GetURL(),
  282. QueryReason::kSiteStorage);
  283. }
  284. int NetworkServiceNetworkDelegate::HandleClearSiteDataHeader(
  285. net::URLRequest* request,
  286. net::CompletionOnceCallback callback,
  287. const net::HttpResponseHeaders* original_response_headers) {
  288. DCHECK(request);
  289. if (!original_response_headers)
  290. return net::OK;
  291. URLLoader* url_loader = URLLoader::ForRequest(*request);
  292. if (!url_loader)
  293. return net::OK;
  294. auto* url_loader_network_observer =
  295. url_loader->GetURLLoaderNetworkServiceObserver();
  296. if (!url_loader_network_observer)
  297. return net::OK;
  298. std::string header_value;
  299. if (!original_response_headers->GetNormalizedHeader(kClearSiteDataHeader,
  300. &header_value)) {
  301. return net::OK;
  302. }
  303. url_loader_network_observer->OnClearSiteData(
  304. request->url(), header_value, request->load_flags(),
  305. net::CookiePartitionKey::FromNetworkIsolationKey(
  306. request->isolation_info().network_isolation_key()),
  307. base::BindOnce(&NetworkServiceNetworkDelegate::FinishedClearSiteData,
  308. weak_ptr_factory_.GetWeakPtr(), request->GetWeakPtr(),
  309. std::move(callback)));
  310. return net::ERR_IO_PENDING;
  311. }
  312. void NetworkServiceNetworkDelegate::FinishedClearSiteData(
  313. base::WeakPtr<net::URLRequest> request,
  314. net::CompletionOnceCallback callback) {
  315. if (request)
  316. std::move(callback).Run(net::OK);
  317. }
  318. void NetworkServiceNetworkDelegate::FinishedCanSendReportingReports(
  319. base::OnceCallback<void(std::set<url::Origin>)> result_callback,
  320. const std::vector<url::Origin>& origins) {
  321. std::set<url::Origin> origin_set(origins.begin(), origins.end());
  322. std::move(result_callback).Run(origin_set);
  323. }
  324. void NetworkServiceNetworkDelegate::ForwardProxyErrors(int net_error) {
  325. if (!proxy_error_client_)
  326. return;
  327. // TODO(https://crbug.com/876848): Provide justification for the currently
  328. // enumerated errors.
  329. switch (net_error) {
  330. case net::ERR_PROXY_AUTH_UNSUPPORTED:
  331. case net::ERR_PROXY_CONNECTION_FAILED:
  332. case net::ERR_TUNNEL_CONNECTION_FAILED:
  333. proxy_error_client_->OnRequestMaybeFailedDueToProxySettings(net_error);
  334. break;
  335. }
  336. }
  337. } // namespace network