url_request_http_job.cc 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743
  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
  3. // found in the LICENSE file.
  4. #include "net/url_request/url_request_http_job.h"
  5. #include <algorithm>
  6. #include <iterator>
  7. #include <memory>
  8. #include <utility>
  9. #include <vector>
  10. #include "base/base_switches.h"
  11. #include "base/bind.h"
  12. #include "base/callback_helpers.h"
  13. #include "base/check_op.h"
  14. #include "base/command_line.h"
  15. #include "base/compiler_specific.h"
  16. #include "base/containers/adapters.h"
  17. #include "base/file_version_info.h"
  18. #include "base/location.h"
  19. #include "base/memory/ptr_util.h"
  20. #include "base/metrics/field_trial.h"
  21. #include "base/metrics/histogram_functions.h"
  22. #include "base/metrics/histogram_macros.h"
  23. #include "base/numerics/safe_conversions.h"
  24. #include "base/rand_util.h"
  25. #include "base/stl_util.h"
  26. #include "base/strings/string_util.h"
  27. #include "base/strings/stringprintf.h"
  28. #include "base/task/single_thread_task_runner.h"
  29. #include "base/threading/thread_task_runner_handle.h"
  30. #include "base/time/time.h"
  31. #include "base/trace_event/trace_event.h"
  32. #include "base/values.h"
  33. #include "build/build_config.h"
  34. #include "net/base/features.h"
  35. #include "net/base/host_port_pair.h"
  36. #include "net/base/http_user_agent_settings.h"
  37. #include "net/base/load_flags.h"
  38. #include "net/base/net_errors.h"
  39. #include "net/base/network_delegate.h"
  40. #include "net/base/network_isolation_key.h"
  41. #include "net/base/privacy_mode.h"
  42. #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
  43. #include "net/base/trace_constants.h"
  44. #include "net/base/url_util.h"
  45. #include "net/cert/cert_status_flags.h"
  46. #include "net/cert/ct_policy_status.h"
  47. #include "net/cert/known_roots.h"
  48. #include "net/cookies/canonical_cookie.h"
  49. #include "net/cookies/cookie_access_delegate.h"
  50. #include "net/cookies/cookie_constants.h"
  51. #include "net/cookies/cookie_store.h"
  52. #include "net/cookies/cookie_util.h"
  53. #include "net/cookies/first_party_set_metadata.h"
  54. #include "net/cookies/parsed_cookie.h"
  55. #include "net/cookies/same_party_context.h"
  56. #include "net/filter/brotli_source_stream.h"
  57. #include "net/filter/filter_source_stream.h"
  58. #include "net/filter/gzip_source_stream.h"
  59. #include "net/filter/source_stream.h"
  60. #include "net/http/http_content_disposition.h"
  61. #include "net/http/http_log_util.h"
  62. #include "net/http/http_network_session.h"
  63. #include "net/http/http_request_headers.h"
  64. #include "net/http/http_response_headers.h"
  65. #include "net/http/http_response_info.h"
  66. #include "net/http/http_status_code.h"
  67. #include "net/http/http_transaction.h"
  68. #include "net/http/http_transaction_factory.h"
  69. #include "net/http/http_util.h"
  70. #include "net/http/transport_security_state.h"
  71. #include "net/log/net_log.h"
  72. #include "net/log/net_log_event_type.h"
  73. #include "net/log/net_log_values.h"
  74. #include "net/log/net_log_with_source.h"
  75. #include "net/nqe/network_quality_estimator.h"
  76. #include "net/proxy_resolution/proxy_info.h"
  77. #include "net/proxy_resolution/proxy_resolution_service.h"
  78. #include "net/proxy_resolution/proxy_retry_info.h"
  79. #include "net/ssl/ssl_cert_request_info.h"
  80. #include "net/ssl/ssl_config_service.h"
  81. #include "net/ssl/ssl_connection_status_flags.h"
  82. #include "net/url_request/redirect_util.h"
  83. #include "net/url_request/url_request.h"
  84. #include "net/url_request/url_request_context.h"
  85. #include "net/url_request/url_request_error_job.h"
  86. #include "net/url_request/url_request_job_factory.h"
  87. #include "net/url_request/url_request_redirect_job.h"
  88. #include "net/url_request/url_request_throttler_manager.h"
  89. #include "net/url_request/websocket_handshake_userdata_key.h"
  90. #include "third_party/abseil-cpp/absl/types/optional.h"
  91. #include "url/gurl.h"
  92. #include "url/origin.h"
  93. #include "url/url_constants.h"
  94. #if BUILDFLAG(IS_ANDROID)
  95. #include "net/android/network_library.h"
  96. #endif
  97. namespace {
  98. base::Value CookieInclusionStatusNetLogParams(
  99. const std::string& operation,
  100. const std::string& cookie_name,
  101. const std::string& cookie_domain,
  102. const std::string& cookie_path,
  103. const net::CookieInclusionStatus& status,
  104. net::NetLogCaptureMode capture_mode) {
  105. base::Value::Dict dict;
  106. dict.Set("operation", operation);
  107. dict.Set("status", status.GetDebugString());
  108. if (net::NetLogCaptureIncludesSensitive(capture_mode)) {
  109. if (!cookie_name.empty())
  110. dict.Set("name", cookie_name);
  111. if (!cookie_domain.empty())
  112. dict.Set("domain", cookie_domain);
  113. if (!cookie_path.empty())
  114. dict.Set("path", cookie_path);
  115. }
  116. return base::Value(std::move(dict));
  117. }
  118. // Records details about the most-specific trust anchor in |spki_hashes|,
  119. // which is expected to be ordered with the leaf cert first and the root cert
  120. // last. This complements the per-verification histogram
  121. // Net.Certificate.TrustAnchor.Verify
  122. void LogTrustAnchor(const net::HashValueVector& spki_hashes) {
  123. // Don't record metrics if there are no hashes; this is true if the HTTP
  124. // load did not come from an active network connection, such as the disk
  125. // cache or a synthesized response.
  126. if (spki_hashes.empty())
  127. return;
  128. int32_t id = 0;
  129. for (const auto& hash : spki_hashes) {
  130. id = net::GetNetTrustAnchorHistogramIdForSPKI(hash);
  131. if (id != 0)
  132. break;
  133. }
  134. base::UmaHistogramSparse("Net.Certificate.TrustAnchor.Request", id);
  135. }
  136. net::CookieOptions CreateCookieOptions(
  137. net::CookieOptions::SameSiteCookieContext same_site_context,
  138. const net::SamePartyContext& same_party_context,
  139. const net::IsolationInfo& isolation_info,
  140. bool is_in_nontrivial_first_party_set) {
  141. net::CookieOptions options;
  142. options.set_return_excluded_cookies();
  143. options.set_include_httponly();
  144. options.set_same_site_cookie_context(same_site_context);
  145. options.set_same_party_context(same_party_context);
  146. if (isolation_info.party_context().has_value()) {
  147. // Count the top-frame site since it's not in the party_context.
  148. options.set_full_party_context_size(isolation_info.party_context()->size() +
  149. 1);
  150. }
  151. options.set_is_in_nontrivial_first_party_set(
  152. is_in_nontrivial_first_party_set);
  153. return options;
  154. }
  155. bool IsTLS13OverTCP(const net::HttpResponseInfo& response_info) {
  156. // Although IETF QUIC also uses TLS 1.3, our QUIC connections report
  157. // SSL_CONNECTION_VERSION_QUIC.
  158. return net::SSLConnectionStatusToVersion(
  159. response_info.ssl_info.connection_status) ==
  160. net::SSL_CONNECTION_VERSION_TLS1_3;
  161. }
  162. GURL UpgradeSchemeToCryptographic(const GURL& insecure_url) {
  163. DCHECK(!insecure_url.SchemeIsCryptographic());
  164. DCHECK(insecure_url.SchemeIs(url::kHttpScheme) ||
  165. insecure_url.SchemeIs(url::kWsScheme));
  166. GURL::Replacements replacements;
  167. replacements.SetSchemeStr(insecure_url.SchemeIs(url::kHttpScheme)
  168. ? url::kHttpsScheme
  169. : url::kWssScheme);
  170. GURL secure_url = insecure_url.ReplaceComponents(replacements);
  171. DCHECK(secure_url.SchemeIsCryptographic());
  172. return secure_url;
  173. }
  174. } // namespace
  175. namespace net {
  176. std::unique_ptr<URLRequestJob> URLRequestHttpJob::Create(URLRequest* request) {
  177. const GURL& url = request->url();
  178. // URLRequestContext must have been initialized.
  179. DCHECK(request->context()->http_transaction_factory());
  180. DCHECK(url.SchemeIsHTTPOrHTTPS() || url.SchemeIsWSOrWSS());
  181. // Check for reasons not to return a URLRequestHttpJob. These don't apply to
  182. // https and wss requests.
  183. if (!url.SchemeIsCryptographic()) {
  184. // Check for HSTS upgrade.
  185. TransportSecurityState* hsts =
  186. request->context()->transport_security_state();
  187. if (hsts && hsts->ShouldUpgradeToSSL(url.host(), request->net_log())) {
  188. return std::make_unique<URLRequestRedirectJob>(
  189. request, UpgradeSchemeToCryptographic(url),
  190. // Use status code 307 to preserve the method, so POST requests work.
  191. RedirectUtil::ResponseCode::REDIRECT_307_TEMPORARY_REDIRECT, "HSTS");
  192. }
  193. #if BUILDFLAG(IS_ANDROID)
  194. // Check whether the app allows cleartext traffic to this host, and return
  195. // ERR_CLEARTEXT_NOT_PERMITTED if not.
  196. if (request->context()->check_cleartext_permitted() &&
  197. !android::IsCleartextPermitted(url.host())) {
  198. return std::make_unique<URLRequestErrorJob>(request,
  199. ERR_CLEARTEXT_NOT_PERMITTED);
  200. }
  201. #endif
  202. }
  203. return base::WrapUnique<URLRequestJob>(new URLRequestHttpJob(
  204. request, request->context()->http_user_agent_settings()));
  205. }
  206. URLRequestHttpJob::URLRequestHttpJob(
  207. URLRequest* request,
  208. const HttpUserAgentSettings* http_user_agent_settings)
  209. : URLRequestJob(request),
  210. http_user_agent_settings_(http_user_agent_settings) {
  211. URLRequestThrottlerManager* manager = request->context()->throttler_manager();
  212. if (manager)
  213. throttling_entry_ = manager->RegisterRequestUrl(request->url());
  214. ResetTimer();
  215. }
  216. URLRequestHttpJob::~URLRequestHttpJob() {
  217. CHECK(!awaiting_callback_);
  218. DoneWithRequest(ABORTED);
  219. }
  220. void URLRequestHttpJob::SetPriority(RequestPriority priority) {
  221. priority_ = priority;
  222. if (transaction_)
  223. transaction_->SetPriority(priority_);
  224. }
  225. void URLRequestHttpJob::Start() {
  226. DCHECK(!transaction_.get());
  227. request_info_.url = request_->url();
  228. request_info_.method = request_->method();
  229. request_info_.network_isolation_key =
  230. request_->isolation_info().network_isolation_key();
  231. request_info_.possibly_top_frame_origin =
  232. request_->isolation_info().top_frame_origin();
  233. request_info_.is_subframe_document_resource =
  234. request_->isolation_info().request_type() ==
  235. net::IsolationInfo::RequestType::kSubFrame;
  236. request_info_.load_flags = request_->load_flags();
  237. request_info_.secure_dns_policy = request_->secure_dns_policy();
  238. request_info_.traffic_annotation =
  239. net::MutableNetworkTrafficAnnotationTag(request_->traffic_annotation());
  240. request_info_.socket_tag = request_->socket_tag();
  241. request_info_.idempotency = request_->GetIdempotency();
  242. request_info_.pervasive_payloads_index_for_logging =
  243. request_->pervasive_payloads_index_for_logging();
  244. request_info_.checksum = request_->expected_response_checksum();
  245. #if BUILDFLAG(ENABLE_REPORTING)
  246. request_info_.reporting_upload_depth = request_->reporting_upload_depth();
  247. #endif
  248. bool should_add_cookie_header = ShouldAddCookieHeader();
  249. UMA_HISTOGRAM_BOOLEAN("Net.HttpJob.CanIncludeCookies",
  250. should_add_cookie_header);
  251. if (!should_add_cookie_header) {
  252. OnGotFirstPartySetMetadata(FirstPartySetMetadata());
  253. return;
  254. }
  255. absl::optional<FirstPartySetMetadata> metadata =
  256. cookie_util::ComputeFirstPartySetMetadataMaybeAsync(
  257. SchemefulSite(request()->url()), request()->isolation_info(),
  258. request()->context()->cookie_store()->cookie_access_delegate(),
  259. request()->force_ignore_top_frame_party_for_cookies(),
  260. base::BindOnce(&URLRequestHttpJob::OnGotFirstPartySetMetadata,
  261. weak_factory_.GetWeakPtr()));
  262. if (metadata.has_value())
  263. OnGotFirstPartySetMetadata(std::move(metadata.value()));
  264. }
  265. void URLRequestHttpJob::OnGotFirstPartySetMetadata(
  266. FirstPartySetMetadata first_party_set_metadata) {
  267. first_party_set_metadata_ = std::move(first_party_set_metadata);
  268. // Privacy mode could still be disabled in SetCookieHeaderAndStart if we are
  269. // going to send previously saved cookies.
  270. request_info_.privacy_mode = DeterminePrivacyMode();
  271. request()->net_log().AddEventWithStringParams(
  272. NetLogEventType::COMPUTED_PRIVACY_MODE, "privacy_mode",
  273. PrivacyModeToDebugString(request_info_.privacy_mode));
  274. // Strip Referer from request_info_.extra_headers to prevent, e.g., plugins
  275. // from overriding headers that are controlled using other means. Otherwise a
  276. // plugin could set a referrer although sending the referrer is inhibited.
  277. request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer);
  278. // URLRequest::SetReferrer ensures that we do not send username and password
  279. // fields in the referrer.
  280. GURL referrer(request_->referrer());
  281. // Our consumer should have made sure that this is a safe referrer (e.g. via
  282. // URLRequestJob::ComputeReferrerForPolicy).
  283. if (referrer.is_valid()) {
  284. std::string referer_value = referrer.spec();
  285. request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
  286. referer_value);
  287. }
  288. request_info_.extra_headers.SetHeaderIfMissing(
  289. HttpRequestHeaders::kUserAgent,
  290. http_user_agent_settings_ ?
  291. http_user_agent_settings_->GetUserAgent() : std::string());
  292. AddExtraHeaders();
  293. if (ShouldAddCookieHeader()) {
  294. // We shouldn't overwrite this if we've already computed the key.
  295. DCHECK(!cookie_partition_key_.has_value());
  296. cookie_partition_key_ = CookiePartitionKey::FromNetworkIsolationKey(
  297. request_->isolation_info().network_isolation_key(),
  298. base::OptionalOrNullptr(
  299. first_party_set_metadata_.top_frame_entry().has_value()
  300. ? absl::make_optional(
  301. first_party_set_metadata_.top_frame_entry()->primary())
  302. : absl::nullopt));
  303. AddCookieHeaderAndStart();
  304. } else {
  305. StartTransaction();
  306. }
  307. }
  308. void URLRequestHttpJob::Kill() {
  309. weak_factory_.InvalidateWeakPtrs();
  310. if (transaction_)
  311. DestroyTransaction();
  312. URLRequestJob::Kill();
  313. }
  314. ConnectionAttempts URLRequestHttpJob::GetConnectionAttempts() const {
  315. if (transaction_)
  316. return transaction_->GetConnectionAttempts();
  317. return {};
  318. }
  319. void URLRequestHttpJob::CloseConnectionOnDestruction() {
  320. DCHECK(transaction_);
  321. transaction_->CloseConnectionOnDestruction();
  322. }
  323. int URLRequestHttpJob::NotifyConnectedCallback(
  324. const TransportInfo& info,
  325. CompletionOnceCallback callback) {
  326. return URLRequestJob::NotifyConnected(info, std::move(callback));
  327. }
  328. PrivacyMode URLRequestHttpJob::DeterminePrivacyMode() const {
  329. if (!request()->allow_credentials()) {
  330. // |allow_credentials_| implies LOAD_DO_NOT_SAVE_COOKIES.
  331. DCHECK(request_->load_flags() & LOAD_DO_NOT_SAVE_COOKIES);
  332. // TODO(https://crbug.com/775438): Client certs should always be
  333. // affirmatively omitted for these requests.
  334. return request()->send_client_certs()
  335. ? PRIVACY_MODE_ENABLED
  336. : PRIVACY_MODE_ENABLED_WITHOUT_CLIENT_CERTS;
  337. }
  338. // Otherwise, check with the delegate if present, or base it off of
  339. // |URLRequest::DefaultCanUseCookies()| if not.
  340. // TODO(mmenke): Looks like |URLRequest::DefaultCanUseCookies()| is not too
  341. // useful, with the network service - remove it.
  342. NetworkDelegate::PrivacySetting privacy_setting =
  343. URLRequest::DefaultCanUseCookies()
  344. ? NetworkDelegate::PrivacySetting::kStateAllowed
  345. : NetworkDelegate::PrivacySetting::kStateDisallowed;
  346. if (request_->network_delegate()) {
  347. privacy_setting = request()->network_delegate()->ForcePrivacyMode(
  348. request_->url(), request_->site_for_cookies(),
  349. request_->isolation_info().top_frame_origin(),
  350. first_party_set_metadata_.context().context_type());
  351. }
  352. switch (privacy_setting) {
  353. case NetworkDelegate::PrivacySetting::kStateAllowed:
  354. return PRIVACY_MODE_DISABLED;
  355. case NetworkDelegate::PrivacySetting::kPartitionedStateAllowedOnly:
  356. return PRIVACY_MODE_ENABLED_PARTITIONED_STATE_ALLOWED;
  357. case NetworkDelegate::PrivacySetting::kStateDisallowed:
  358. return PRIVACY_MODE_ENABLED;
  359. }
  360. NOTREACHED();
  361. return PRIVACY_MODE_ENABLED;
  362. }
  363. void URLRequestHttpJob::NotifyHeadersComplete() {
  364. DCHECK(!response_info_);
  365. DCHECK_EQ(0, num_cookie_lines_left_);
  366. DCHECK(request_->maybe_stored_cookies().empty());
  367. if (override_response_info_) {
  368. DCHECK(!transaction_);
  369. response_info_ = override_response_info_.get();
  370. } else {
  371. response_info_ = transaction_->GetResponseInfo();
  372. }
  373. if (!response_info_->was_cached && throttling_entry_.get())
  374. throttling_entry_->UpdateWithResponse(GetResponseCode());
  375. // The ordering of these calls is not important.
  376. ProcessStrictTransportSecurityHeader();
  377. ProcessExpectCTHeader();
  378. // Clear |set_cookie_access_result_list_| after any processing in case
  379. // SaveCookiesAndNotifyHeadersComplete is called again.
  380. request_->set_maybe_stored_cookies(std::move(set_cookie_access_result_list_));
  381. // The HTTP transaction may be restarted several times for the purposes
  382. // of sending authorization information. Each time it restarts, we get
  383. // notified of the headers completion so that we can update the cookie store.
  384. if (transaction_ && transaction_->IsReadyToRestartForAuth()) {
  385. // TODO(battre): This breaks the webrequest API for
  386. // URLRequestTestHTTP.BasicAuthWithCookies
  387. // where OnBeforeStartTransaction -> OnStartTransaction ->
  388. // OnBeforeStartTransaction occurs.
  389. RestartTransactionWithAuth(AuthCredentials());
  390. return;
  391. }
  392. URLRequestJob::NotifyHeadersComplete();
  393. }
  394. void URLRequestHttpJob::DestroyTransaction() {
  395. DCHECK(transaction_.get());
  396. DoneWithRequest(ABORTED);
  397. total_received_bytes_from_previous_transactions_ +=
  398. transaction_->GetTotalReceivedBytes();
  399. total_sent_bytes_from_previous_transactions_ +=
  400. transaction_->GetTotalSentBytes();
  401. response_info_ = nullptr;
  402. transaction_.reset();
  403. override_response_headers_ = nullptr;
  404. receive_headers_end_ = base::TimeTicks();
  405. }
  406. void URLRequestHttpJob::StartTransaction() {
  407. DCHECK(!override_response_info_);
  408. NetworkDelegate* network_delegate = request()->network_delegate();
  409. if (network_delegate) {
  410. OnCallToDelegate(
  411. NetLogEventType::NETWORK_DELEGATE_BEFORE_START_TRANSACTION);
  412. int rv = network_delegate->NotifyBeforeStartTransaction(
  413. request_, request_info_.extra_headers,
  414. base::BindOnce(&URLRequestHttpJob::NotifyBeforeStartTransactionCallback,
  415. weak_factory_.GetWeakPtr()));
  416. // If an extension blocks the request, we rely on the callback to
  417. // MaybeStartTransactionInternal().
  418. if (rv == ERR_IO_PENDING)
  419. return;
  420. MaybeStartTransactionInternal(rv);
  421. return;
  422. }
  423. StartTransactionInternal();
  424. }
  425. void URLRequestHttpJob::NotifyBeforeStartTransactionCallback(
  426. int result,
  427. const absl::optional<HttpRequestHeaders>& headers) {
  428. // The request should not have been cancelled or have already completed.
  429. DCHECK(!is_done());
  430. if (headers)
  431. request_info_.extra_headers = headers.value();
  432. MaybeStartTransactionInternal(result);
  433. }
  434. void URLRequestHttpJob::MaybeStartTransactionInternal(int result) {
  435. OnCallToDelegateComplete();
  436. if (result == OK) {
  437. StartTransactionInternal();
  438. } else {
  439. request_->net_log().AddEventWithStringParams(NetLogEventType::CANCELLED,
  440. "source", "delegate");
  441. // Don't call back synchronously to the delegate.
  442. base::ThreadTaskRunnerHandle::Get()->PostTask(
  443. FROM_HERE, base::BindOnce(&URLRequestHttpJob::NotifyStartError,
  444. weak_factory_.GetWeakPtr(), result));
  445. }
  446. }
  447. void URLRequestHttpJob::StartTransactionInternal() {
  448. DCHECK(!override_response_headers_);
  449. // NOTE: This method assumes that request_info_ is already setup properly.
  450. // If we already have a transaction, then we should restart the transaction
  451. // with auth provided by auth_credentials_.
  452. int rv;
  453. // Notify NetworkQualityEstimator.
  454. NetworkQualityEstimator* network_quality_estimator =
  455. request()->context()->network_quality_estimator();
  456. if (network_quality_estimator)
  457. network_quality_estimator->NotifyStartTransaction(*request_);
  458. if (transaction_.get()) {
  459. rv = transaction_->RestartWithAuth(
  460. auth_credentials_, base::BindOnce(&URLRequestHttpJob::OnStartCompleted,
  461. base::Unretained(this)));
  462. auth_credentials_ = AuthCredentials();
  463. } else {
  464. DCHECK(request_->context()->http_transaction_factory());
  465. rv = request_->context()->http_transaction_factory()->CreateTransaction(
  466. priority_, &transaction_);
  467. if (rv == OK && request_info_.url.SchemeIsWSOrWSS()) {
  468. base::SupportsUserData::Data* data =
  469. request_->GetUserData(kWebSocketHandshakeUserDataKey);
  470. if (data) {
  471. transaction_->SetWebSocketHandshakeStreamCreateHelper(
  472. static_cast<WebSocketHandshakeStreamBase::CreateHelper*>(data));
  473. } else {
  474. rv = ERR_DISALLOWED_URL_SCHEME;
  475. }
  476. }
  477. if (rv == OK) {
  478. transaction_->SetConnectedCallback(base::BindRepeating(
  479. &URLRequestHttpJob::NotifyConnectedCallback, base::Unretained(this)));
  480. transaction_->SetRequestHeadersCallback(request_headers_callback_);
  481. transaction_->SetEarlyResponseHeadersCallback(
  482. early_response_headers_callback_);
  483. transaction_->SetResponseHeadersCallback(response_headers_callback_);
  484. if (!throttling_entry_.get() ||
  485. !throttling_entry_->ShouldRejectRequest(*request_)) {
  486. rv = transaction_->Start(
  487. &request_info_,
  488. base::BindOnce(&URLRequestHttpJob::OnStartCompleted,
  489. base::Unretained(this)),
  490. request_->net_log());
  491. start_time_ = base::TimeTicks::Now();
  492. } else {
  493. // Special error code for the exponential back-off module.
  494. rv = ERR_TEMPORARILY_THROTTLED;
  495. }
  496. }
  497. }
  498. if (rv == ERR_IO_PENDING)
  499. return;
  500. // The transaction started synchronously, but we need to notify the
  501. // URLRequest delegate via the message loop.
  502. base::ThreadTaskRunnerHandle::Get()->PostTask(
  503. FROM_HERE, base::BindOnce(&URLRequestHttpJob::OnStartCompleted,
  504. weak_factory_.GetWeakPtr(), rv));
  505. }
  506. void URLRequestHttpJob::AddExtraHeaders() {
  507. request_info_.extra_headers.SetAcceptEncodingIfMissing(
  508. request()->url(), request()->accepted_stream_types(),
  509. request()->context()->enable_brotli());
  510. if (http_user_agent_settings_) {
  511. // Only add default Accept-Language if the request didn't have it
  512. // specified.
  513. std::string accept_language =
  514. http_user_agent_settings_->GetAcceptLanguage();
  515. if (!accept_language.empty()) {
  516. request_info_.extra_headers.SetHeaderIfMissing(
  517. HttpRequestHeaders::kAcceptLanguage,
  518. accept_language);
  519. }
  520. }
  521. }
  522. void URLRequestHttpJob::AddCookieHeaderAndStart() {
  523. CookieStore* cookie_store = request_->context()->cookie_store();
  524. DCHECK(cookie_store);
  525. DCHECK(ShouldAddCookieHeader());
  526. bool force_ignore_site_for_cookies =
  527. request_->force_ignore_site_for_cookies();
  528. if (cookie_store->cookie_access_delegate() &&
  529. cookie_store->cookie_access_delegate()->ShouldIgnoreSameSiteRestrictions(
  530. request_->url(), request_->site_for_cookies())) {
  531. force_ignore_site_for_cookies = true;
  532. }
  533. bool is_main_frame_navigation =
  534. IsolationInfo::RequestType::kMainFrame ==
  535. request_->isolation_info().request_type() ||
  536. request_->force_main_frame_for_same_site_cookies();
  537. CookieOptions::SameSiteCookieContext same_site_context =
  538. net::cookie_util::ComputeSameSiteContextForRequest(
  539. request_->method(), request_->url_chain(),
  540. request_->site_for_cookies(), request_->initiator(),
  541. is_main_frame_navigation, force_ignore_site_for_cookies);
  542. bool is_in_nontrivial_first_party_set =
  543. first_party_set_metadata_.frame_entry().has_value();
  544. CookieOptions options = CreateCookieOptions(
  545. same_site_context, first_party_set_metadata_.context(),
  546. request_->isolation_info(), is_in_nontrivial_first_party_set);
  547. cookie_store->GetCookieListWithOptionsAsync(
  548. request_->url(), options,
  549. CookiePartitionKeyCollection::FromOptional(cookie_partition_key_.value()),
  550. base::BindOnce(&URLRequestHttpJob::SetCookieHeaderAndStart,
  551. weak_factory_.GetWeakPtr(), options));
  552. }
  553. namespace {
  554. bool ShouldBlockAllCookies(const PrivacyMode& privacy_mode) {
  555. return privacy_mode == PRIVACY_MODE_ENABLED ||
  556. privacy_mode == PRIVACY_MODE_ENABLED_WITHOUT_CLIENT_CERTS;
  557. }
  558. bool ShouldBlockUnpartitionedCookiesOnly(const PrivacyMode& privacy_mode) {
  559. return privacy_mode == PRIVACY_MODE_ENABLED_PARTITIONED_STATE_ALLOWED;
  560. }
  561. } // namespace
  562. void URLRequestHttpJob::SetCookieHeaderAndStart(
  563. const CookieOptions& options,
  564. const CookieAccessResultList& cookies_with_access_result_list,
  565. const CookieAccessResultList& excluded_list) {
  566. DCHECK(request_->maybe_sent_cookies().empty());
  567. CookieAccessResultList maybe_included_cookies =
  568. cookies_with_access_result_list;
  569. CookieAccessResultList excluded_cookies = excluded_list;
  570. if (ShouldBlockAllCookies(request_info_.privacy_mode)) {
  571. // If cookies are blocked (without our needing to consult the delegate),
  572. // we move them to `excluded_cookies` and ensure that they have the
  573. // correct exclusion reason.
  574. excluded_cookies.insert(
  575. excluded_cookies.end(),
  576. std::make_move_iterator(maybe_included_cookies.begin()),
  577. std::make_move_iterator(maybe_included_cookies.end()));
  578. maybe_included_cookies.clear();
  579. for (auto& cookie : excluded_cookies) {
  580. cookie.access_result.status.AddExclusionReason(
  581. CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
  582. }
  583. }
  584. if (ShouldBlockUnpartitionedCookiesOnly(request_info_.privacy_mode)) {
  585. auto partition_it = base::ranges::stable_partition(
  586. maybe_included_cookies, [](const CookieWithAccessResult& el) {
  587. return el.cookie.IsPartitioned();
  588. });
  589. for (auto it = partition_it; it < maybe_included_cookies.end(); ++it) {
  590. it->access_result.status.AddExclusionReason(
  591. CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
  592. }
  593. excluded_cookies.insert(
  594. excluded_cookies.end(), std::make_move_iterator(partition_it),
  595. std::make_move_iterator(maybe_included_cookies.end()));
  596. maybe_included_cookies.erase(partition_it, maybe_included_cookies.end());
  597. }
  598. if (request_info_.privacy_mode == PRIVACY_MODE_DISABLED ||
  599. !maybe_included_cookies.empty()) {
  600. AnnotateAndMoveUserBlockedCookies(maybe_included_cookies, excluded_cookies);
  601. if (!maybe_included_cookies.empty()) {
  602. std::string cookie_line =
  603. CanonicalCookie::BuildCookieLine(maybe_included_cookies);
  604. UMA_HISTOGRAM_COUNTS_10000("Cookie.HeaderLength", cookie_line.length());
  605. request_info_.extra_headers.SetHeader(HttpRequestHeaders::kCookie,
  606. cookie_line);
  607. size_t n_partitioned_cookies = 0;
  608. size_t n_partitioned_cookies_no_nonce = 0;
  609. // TODO(crbug.com/1031664): Reduce the number of times the cookie list
  610. // is iterated over. Get metrics for every cookie which is included.
  611. for (const auto& c : maybe_included_cookies) {
  612. bool request_is_secure = request_->url().SchemeIsCryptographic();
  613. net::CookieSourceScheme cookie_scheme = c.cookie.SourceScheme();
  614. CookieRequestScheme cookie_request_schemes;
  615. switch (cookie_scheme) {
  616. case net::CookieSourceScheme::kSecure:
  617. cookie_request_schemes =
  618. request_is_secure
  619. ? CookieRequestScheme::kSecureSetSecureRequest
  620. : CookieRequestScheme::kSecureSetNonsecureRequest;
  621. break;
  622. case net::CookieSourceScheme::kNonSecure:
  623. cookie_request_schemes =
  624. request_is_secure
  625. ? CookieRequestScheme::kNonsecureSetSecureRequest
  626. : CookieRequestScheme::kNonsecureSetNonsecureRequest;
  627. break;
  628. case net::CookieSourceScheme::kUnset:
  629. cookie_request_schemes = CookieRequestScheme::kUnsetCookieScheme;
  630. break;
  631. }
  632. UMA_HISTOGRAM_ENUMERATION("Cookie.CookieSchemeRequestScheme",
  633. cookie_request_schemes);
  634. if (c.cookie.IsPartitioned()) {
  635. ++n_partitioned_cookies;
  636. if (!c.cookie.PartitionKey()->nonce())
  637. ++n_partitioned_cookies_no_nonce;
  638. }
  639. }
  640. if (IsPartitionedCookiesEnabled()) {
  641. base::UmaHistogramCounts100("Cookie.PartitionedCookiesInRequest",
  642. n_partitioned_cookies);
  643. // TODO(crbug.com/1296161): Remove this code when the partitioned
  644. // cookies Origin Trial is over.
  645. if (n_partitioned_cookies_no_nonce > 0 &&
  646. !request_info_.extra_headers.HasHeader(
  647. "Sec-CH-Partitioned-Cookies")) {
  648. // If the cookie store has partitioned cookies and there is no
  649. // Sec-CH-Partitioned-Cookies header set by the process that initiated
  650. // the request, then the site was in the Origin Trial at one point,
  651. // but we have not yet received a valid token or Accept-CH header.
  652. //
  653. // In this case, we still send the partitioned cookies and set the
  654. // Sec-CH-Partitioned-Cookies structured header to false.
  655. //
  656. // If the site does not respond with the Accept-CH header and OT token
  657. // in the response, the partitioned cookies will be converted to
  658. // unpartitioned cookies. This conversion is done by
  659. // CookieManager::ConvertPartitionedCookiesToUnpartitioned.
  660. request_info_.extra_headers.SetHeader("Sec-CH-Partitioned-Cookies",
  661. "?0");
  662. }
  663. }
  664. }
  665. }
  666. CookieAccessResultList maybe_sent_cookies = std::move(excluded_cookies);
  667. maybe_sent_cookies.insert(
  668. maybe_sent_cookies.end(),
  669. std::make_move_iterator(maybe_included_cookies.begin()),
  670. std::make_move_iterator(maybe_included_cookies.end()));
  671. maybe_included_cookies.clear();
  672. if (request_->net_log().IsCapturing()) {
  673. for (const auto& cookie_with_access_result : maybe_sent_cookies) {
  674. request_->net_log().AddEvent(
  675. NetLogEventType::COOKIE_INCLUSION_STATUS,
  676. [&](NetLogCaptureMode capture_mode) {
  677. return CookieInclusionStatusNetLogParams(
  678. "send", cookie_with_access_result.cookie.Name(),
  679. cookie_with_access_result.cookie.Domain(),
  680. cookie_with_access_result.cookie.Path(),
  681. cookie_with_access_result.access_result.status, capture_mode);
  682. });
  683. }
  684. }
  685. request_->set_maybe_sent_cookies(std::move(maybe_sent_cookies));
  686. StartTransaction();
  687. }
  688. void URLRequestHttpJob::AnnotateAndMoveUserBlockedCookies(
  689. CookieAccessResultList& maybe_included_cookies,
  690. CookieAccessResultList& excluded_cookies) const {
  691. DCHECK(request_info_.privacy_mode == PrivacyMode::PRIVACY_MODE_DISABLED ||
  692. (request_info_.privacy_mode ==
  693. PrivacyMode::PRIVACY_MODE_ENABLED_PARTITIONED_STATE_ALLOWED &&
  694. base::ranges::all_of(maybe_included_cookies,
  695. [](const CookieWithAccessResult& el) {
  696. return el.cookie.IsPartitioned();
  697. })))
  698. << request_info_.privacy_mode;
  699. bool can_get_cookies = URLRequest::DefaultCanUseCookies();
  700. if (request()->network_delegate()) {
  701. can_get_cookies =
  702. request()->network_delegate()->AnnotateAndMoveUserBlockedCookies(
  703. *request(), maybe_included_cookies, excluded_cookies);
  704. }
  705. if (!can_get_cookies) {
  706. request()->net_log().AddEvent(
  707. NetLogEventType::COOKIE_GET_BLOCKED_BY_NETWORK_DELEGATE);
  708. }
  709. }
  710. void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) {
  711. DCHECK(set_cookie_access_result_list_.empty());
  712. // TODO(crbug.com/1186863): Turn this CHECK into DCHECK once the investigation
  713. // is done.
  714. CHECK_EQ(0, num_cookie_lines_left_);
  715. // End of the call started in OnStartCompleted.
  716. OnCallToDelegateComplete();
  717. if (result != OK) {
  718. request_->net_log().AddEventWithStringParams(NetLogEventType::CANCELLED,
  719. "source", "delegate");
  720. NotifyStartError(result);
  721. return;
  722. }
  723. CookieStore* cookie_store = request_->context()->cookie_store();
  724. if ((request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) || !cookie_store) {
  725. NotifyHeadersComplete();
  726. return;
  727. }
  728. base::Time response_date;
  729. absl::optional<base::Time> server_time = absl::nullopt;
  730. if (GetResponseHeaders()->GetDateValue(&response_date))
  731. server_time = absl::make_optional(response_date);
  732. bool force_ignore_site_for_cookies =
  733. request_->force_ignore_site_for_cookies();
  734. if (cookie_store->cookie_access_delegate() &&
  735. cookie_store->cookie_access_delegate()->ShouldIgnoreSameSiteRestrictions(
  736. request_->url(), request_->site_for_cookies())) {
  737. force_ignore_site_for_cookies = true;
  738. }
  739. bool is_main_frame_navigation =
  740. IsolationInfo::RequestType::kMainFrame ==
  741. request_->isolation_info().request_type() ||
  742. request_->force_main_frame_for_same_site_cookies();
  743. CookieOptions::SameSiteCookieContext same_site_context =
  744. net::cookie_util::ComputeSameSiteContextForResponse(
  745. request_->url_chain(), request_->site_for_cookies(),
  746. request_->initiator(), is_main_frame_navigation,
  747. force_ignore_site_for_cookies);
  748. bool is_in_nontrivial_first_party_set =
  749. first_party_set_metadata_.frame_entry().has_value();
  750. CookieOptions options = CreateCookieOptions(
  751. same_site_context, first_party_set_metadata_.context(),
  752. request_->isolation_info(), is_in_nontrivial_first_party_set);
  753. // Set all cookies, without waiting for them to be set. Any subsequent
  754. // read will see the combined result of all cookie operation.
  755. const base::StringPiece name("Set-Cookie");
  756. std::string cookie_string;
  757. size_t iter = 0;
  758. HttpResponseHeaders* headers = GetResponseHeaders();
  759. // NotifyHeadersComplete needs to be called once and only once after the
  760. // list has been fully processed, and it can either be called in the
  761. // callback or after the loop is called, depending on how the last element
  762. // was handled. |num_cookie_lines_left_| keeps track of how many async
  763. // callbacks are currently out (starting from 1 to make sure the loop runs
  764. // all the way through before trying to exit). If there are any callbacks
  765. // still waiting when the loop ends, then NotifyHeadersComplete will be
  766. // called when it reaches 0 in the callback itself.
  767. num_cookie_lines_left_ = 1;
  768. while (headers->EnumerateHeader(&iter, name, &cookie_string)) {
  769. CookieInclusionStatus returned_status;
  770. num_cookie_lines_left_++;
  771. // `cookie_partition_key_` is only non-null when partitioned cookie are
  772. // enabled.
  773. if (cookie_partition_key_ && ParsedCookie(cookie_string).IsPartitioned()) {
  774. request_->SetHasPartitionedCookie();
  775. }
  776. std::unique_ptr<CanonicalCookie> cookie = net::CanonicalCookie::Create(
  777. request_->url(), cookie_string, base::Time::Now(), server_time,
  778. cookie_partition_key_.value(), &returned_status);
  779. absl::optional<CanonicalCookie> cookie_to_return = absl::nullopt;
  780. if (returned_status.IsInclude()) {
  781. DCHECK(cookie);
  782. // Make a copy of the cookie if we successfully made one.
  783. cookie_to_return = *cookie;
  784. }
  785. if (cookie && !CanSetCookie(*cookie, &options)) {
  786. returned_status.AddExclusionReason(
  787. CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
  788. }
  789. if (!returned_status.IsInclude()) {
  790. OnSetCookieResult(options, cookie_to_return, std::move(cookie_string),
  791. CookieAccessResult(returned_status));
  792. continue;
  793. }
  794. CookieAccessResult cookie_access_result(returned_status);
  795. cookie_store->SetCanonicalCookieAsync(
  796. std::move(cookie), request_->url(), options,
  797. base::BindOnce(&URLRequestHttpJob::OnSetCookieResult,
  798. weak_factory_.GetWeakPtr(), options, cookie_to_return,
  799. cookie_string),
  800. std::move(cookie_access_result));
  801. }
  802. // Removing the 1 that |num_cookie_lines_left| started with, signifing that
  803. // loop has been exited.
  804. num_cookie_lines_left_--;
  805. if (num_cookie_lines_left_ == 0)
  806. NotifyHeadersComplete();
  807. }
  808. void URLRequestHttpJob::OnSetCookieResult(
  809. const CookieOptions& options,
  810. absl::optional<CanonicalCookie> cookie,
  811. std::string cookie_string,
  812. CookieAccessResult access_result) {
  813. if (request_->net_log().IsCapturing()) {
  814. request_->net_log().AddEvent(NetLogEventType::COOKIE_INCLUSION_STATUS,
  815. [&](NetLogCaptureMode capture_mode) {
  816. return CookieInclusionStatusNetLogParams(
  817. "store",
  818. cookie ? cookie.value().Name() : "",
  819. cookie ? cookie.value().Domain() : "",
  820. cookie ? cookie.value().Path() : "",
  821. access_result.status, capture_mode);
  822. });
  823. }
  824. set_cookie_access_result_list_.emplace_back(
  825. std::move(cookie), std::move(cookie_string), access_result);
  826. num_cookie_lines_left_--;
  827. // If all the cookie lines have been handled, |set_cookie_access_result_list_|
  828. // now reflects the result of all Set-Cookie lines, and the request can be
  829. // continued.
  830. if (num_cookie_lines_left_ == 0)
  831. NotifyHeadersComplete();
  832. }
  833. void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() {
  834. DCHECK(response_info_);
  835. TransportSecurityState* security_state =
  836. request_->context()->transport_security_state();
  837. const SSLInfo& ssl_info = response_info_->ssl_info;
  838. // Only accept HSTS headers on HTTPS connections that have no
  839. // certificate errors.
  840. if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) ||
  841. !security_state) {
  842. return;
  843. }
  844. // Don't accept HSTS headers when the hostname is an IP address.
  845. if (request_info_.url.HostIsIPAddress())
  846. return;
  847. // http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec:
  848. //
  849. // If a UA receives more than one STS header field in a HTTP response
  850. // message over secure transport, then the UA MUST process only the
  851. // first such header field.
  852. HttpResponseHeaders* headers = GetResponseHeaders();
  853. std::string value;
  854. if (headers->EnumerateHeader(nullptr, "Strict-Transport-Security", &value))
  855. security_state->AddHSTSHeader(request_info_.url.host(), value);
  856. }
  857. void URLRequestHttpJob::ProcessExpectCTHeader() {
  858. DCHECK(response_info_);
  859. TransportSecurityState* security_state =
  860. request_->context()->transport_security_state();
  861. const SSLInfo& ssl_info = response_info_->ssl_info;
  862. // Only accept Expect CT headers on HTTPS connections that have no
  863. // certificate errors.
  864. if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) ||
  865. !security_state) {
  866. return;
  867. }
  868. HttpResponseHeaders* headers = GetResponseHeaders();
  869. std::string value;
  870. bool has_expect_ct_header = headers->GetNormalizedHeader("Expect-CT", &value);
  871. base::UmaHistogramBoolean("Net.ExpectCT.HeaderPresentOnResponse",
  872. has_expect_ct_header);
  873. if (has_expect_ct_header) {
  874. security_state->ProcessExpectCTHeader(
  875. value, HostPortPair::FromURL(request_info_.url), ssl_info,
  876. request_->isolation_info().network_isolation_key());
  877. }
  878. }
  879. void URLRequestHttpJob::OnStartCompleted(int result) {
  880. TRACE_EVENT0(NetTracingCategory(), "URLRequestHttpJob::OnStartCompleted");
  881. RecordTimer();
  882. // If the job is done (due to cancellation), can just ignore this
  883. // notification.
  884. if (done_)
  885. return;
  886. receive_headers_end_ = base::TimeTicks::Now();
  887. const URLRequestContext* context = request_->context();
  888. if (transaction_ && transaction_->GetResponseInfo()) {
  889. const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info;
  890. if (!IsCertificateError(result)) {
  891. LogTrustAnchor(ssl_info.public_key_hashes);
  892. }
  893. }
  894. if (transaction_ && transaction_->GetResponseInfo()) {
  895. SetProxyServer(transaction_->GetResponseInfo()->proxy_server);
  896. }
  897. if (result == OK) {
  898. scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders();
  899. NetworkDelegate* network_delegate = request()->network_delegate();
  900. if (network_delegate) {
  901. // Note that |this| may not be deleted until
  902. // |URLRequestHttpJob::OnHeadersReceivedCallback()| or
  903. // |NetworkDelegate::URLRequestDestroyed()| has been called.
  904. OnCallToDelegate(NetLogEventType::NETWORK_DELEGATE_HEADERS_RECEIVED);
  905. preserve_fragment_on_redirect_url_ = absl::nullopt;
  906. IPEndPoint endpoint;
  907. if (transaction_)
  908. transaction_->GetRemoteEndpoint(&endpoint);
  909. // The NetworkDelegate must watch for OnRequestDestroyed and not modify
  910. // any of the arguments after it's called.
  911. // TODO(mattm): change the API to remove the out-params and take the
  912. // results as params of the callback.
  913. int error = network_delegate->NotifyHeadersReceived(
  914. request_,
  915. base::BindOnce(&URLRequestHttpJob::OnHeadersReceivedCallback,
  916. weak_factory_.GetWeakPtr()),
  917. headers.get(), &override_response_headers_, endpoint,
  918. &preserve_fragment_on_redirect_url_);
  919. if (error != OK) {
  920. if (error == ERR_IO_PENDING) {
  921. awaiting_callback_ = true;
  922. } else {
  923. request_->net_log().AddEventWithStringParams(
  924. NetLogEventType::CANCELLED, "source", "delegate");
  925. OnCallToDelegateComplete();
  926. NotifyStartError(error);
  927. }
  928. return;
  929. }
  930. }
  931. SaveCookiesAndNotifyHeadersComplete(OK);
  932. } else if (IsCertificateError(result)) {
  933. // We encountered an SSL certificate error.
  934. // Maybe overridable, maybe not. Ask the delegate to decide.
  935. TransportSecurityState* state = context->transport_security_state();
  936. NotifySSLCertificateError(
  937. result, transaction_->GetResponseInfo()->ssl_info,
  938. state->ShouldSSLErrorsBeFatal(request_info_.url.host()) &&
  939. result != ERR_CERT_KNOWN_INTERCEPTION_BLOCKED);
  940. } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
  941. NotifyCertificateRequested(
  942. transaction_->GetResponseInfo()->cert_request_info.get());
  943. } else if (result == ERR_DNS_NAME_HTTPS_ONLY) {
  944. // If DNS indicated the name is HTTPS-only, synthesize a redirect to either
  945. // HTTPS or WSS.
  946. DCHECK(features::kUseDnsHttpsSvcbHttpUpgrade.Get());
  947. DCHECK(!request_->url().SchemeIsCryptographic());
  948. base::Time request_time =
  949. transaction_ && transaction_->GetResponseInfo()
  950. ? transaction_->GetResponseInfo()->request_time
  951. : base::Time::Now();
  952. DestroyTransaction();
  953. override_response_info_ = std::make_unique<HttpResponseInfo>();
  954. override_response_info_->request_time = request_time;
  955. override_response_info_->headers = RedirectUtil::SynthesizeRedirectHeaders(
  956. UpgradeSchemeToCryptographic(request_->url()),
  957. RedirectUtil::ResponseCode::REDIRECT_307_TEMPORARY_REDIRECT, "DNS",
  958. request_->extra_request_headers());
  959. NetLogResponseHeaders(
  960. request_->net_log(),
  961. NetLogEventType::URL_REQUEST_FAKE_RESPONSE_HEADERS_CREATED,
  962. override_response_info_->headers.get());
  963. NotifyHeadersComplete();
  964. } else {
  965. // Even on an error, there may be useful information in the response
  966. // info (e.g. whether there's a cached copy).
  967. if (transaction_.get())
  968. response_info_ = transaction_->GetResponseInfo();
  969. NotifyStartError(result);
  970. }
  971. }
  972. void URLRequestHttpJob::OnHeadersReceivedCallback(int result) {
  973. // The request should not have been cancelled or have already completed.
  974. DCHECK(!is_done());
  975. awaiting_callback_ = false;
  976. SaveCookiesAndNotifyHeadersComplete(result);
  977. }
  978. void URLRequestHttpJob::OnReadCompleted(int result) {
  979. TRACE_EVENT0(NetTracingCategory(), "URLRequestHttpJob::OnReadCompleted");
  980. read_in_progress_ = false;
  981. DCHECK_NE(ERR_IO_PENDING, result);
  982. if (ShouldFixMismatchedContentLength(result))
  983. result = OK;
  984. // EOF or error, done with this job.
  985. if (result <= 0)
  986. DoneWithRequest(FINISHED);
  987. ReadRawDataComplete(result);
  988. }
  989. void URLRequestHttpJob::RestartTransactionWithAuth(
  990. const AuthCredentials& credentials) {
  991. DCHECK(!override_response_info_);
  992. auth_credentials_ = credentials;
  993. // These will be reset in OnStartCompleted.
  994. response_info_ = nullptr;
  995. override_response_headers_ = nullptr; // See https://crbug.com/801237.
  996. receive_headers_end_ = base::TimeTicks();
  997. ResetTimer();
  998. // Update the cookies, since the cookie store may have been updated from the
  999. // headers in the 401/407. Since cookies were already appended to
  1000. // extra_headers, we need to strip them out before adding them again.
  1001. request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kCookie);
  1002. // TODO(https://crbug.com/968327/): This is weird, as all other clearing is at
  1003. // the URLRequest layer. Should this call into URLRequest so it can share
  1004. // logic at that layer with SetAuth()?
  1005. request_->set_maybe_sent_cookies({});
  1006. request_->set_maybe_stored_cookies({});
  1007. if (ShouldAddCookieHeader()) {
  1008. // Since `request_->isolation_info()` hasn't changed, we don't need to
  1009. // recompute the cookie partition key.
  1010. AddCookieHeaderAndStart();
  1011. } else {
  1012. StartTransaction();
  1013. }
  1014. }
  1015. void URLRequestHttpJob::SetUpload(UploadDataStream* upload) {
  1016. DCHECK(!transaction_.get() && !override_response_info_)
  1017. << "cannot change once started";
  1018. request_info_.upload_data_stream = upload;
  1019. }
  1020. void URLRequestHttpJob::SetExtraRequestHeaders(
  1021. const HttpRequestHeaders& headers) {
  1022. DCHECK(!transaction_.get() && !override_response_info_)
  1023. << "cannot change once started";
  1024. request_info_.extra_headers.CopyFrom(headers);
  1025. }
  1026. LoadState URLRequestHttpJob::GetLoadState() const {
  1027. return transaction_.get() ?
  1028. transaction_->GetLoadState() : LOAD_STATE_IDLE;
  1029. }
  1030. bool URLRequestHttpJob::GetMimeType(std::string* mime_type) const {
  1031. DCHECK(transaction_.get() || override_response_info_);
  1032. if (!response_info_)
  1033. return false;
  1034. HttpResponseHeaders* headers = GetResponseHeaders();
  1035. if (!headers)
  1036. return false;
  1037. return headers->GetMimeType(mime_type);
  1038. }
  1039. bool URLRequestHttpJob::GetCharset(std::string* charset) {
  1040. DCHECK(transaction_.get() || override_response_info_);
  1041. if (!response_info_)
  1042. return false;
  1043. return GetResponseHeaders()->GetCharset(charset);
  1044. }
  1045. void URLRequestHttpJob::GetResponseInfo(HttpResponseInfo* info) {
  1046. if (override_response_info_) {
  1047. DCHECK(!transaction_.get());
  1048. *info = *override_response_info_;
  1049. return;
  1050. }
  1051. if (response_info_) {
  1052. DCHECK(transaction_.get());
  1053. *info = *response_info_;
  1054. if (override_response_headers_.get())
  1055. info->headers = override_response_headers_;
  1056. }
  1057. }
  1058. void URLRequestHttpJob::GetLoadTimingInfo(
  1059. LoadTimingInfo* load_timing_info) const {
  1060. // If haven't made it far enough to receive any headers, don't return
  1061. // anything. This makes for more consistent behavior in the case of errors.
  1062. if (!transaction_ || receive_headers_end_.is_null())
  1063. return;
  1064. if (transaction_->GetLoadTimingInfo(load_timing_info))
  1065. load_timing_info->receive_headers_end = receive_headers_end_;
  1066. }
  1067. bool URLRequestHttpJob::GetTransactionRemoteEndpoint(
  1068. IPEndPoint* endpoint) const {
  1069. if (!transaction_)
  1070. return false;
  1071. return transaction_->GetRemoteEndpoint(endpoint);
  1072. }
  1073. int URLRequestHttpJob::GetResponseCode() const {
  1074. DCHECK(transaction_.get());
  1075. if (!response_info_)
  1076. return -1;
  1077. return GetResponseHeaders()->response_code();
  1078. }
  1079. void URLRequestHttpJob::PopulateNetErrorDetails(
  1080. NetErrorDetails* details) const {
  1081. if (!transaction_)
  1082. return;
  1083. return transaction_->PopulateNetErrorDetails(details);
  1084. }
  1085. std::unique_ptr<SourceStream> URLRequestHttpJob::SetUpSourceStream() {
  1086. DCHECK(transaction_.get());
  1087. if (!response_info_)
  1088. return nullptr;
  1089. std::unique_ptr<SourceStream> upstream = URLRequestJob::SetUpSourceStream();
  1090. HttpResponseHeaders* headers = GetResponseHeaders();
  1091. std::vector<SourceStream::SourceType> types;
  1092. size_t iter = 0;
  1093. for (std::string type;
  1094. headers->EnumerateHeader(&iter, "Content-Encoding", &type);) {
  1095. SourceStream::SourceType source_type =
  1096. FilterSourceStream::ParseEncodingType(type);
  1097. switch (source_type) {
  1098. case SourceStream::TYPE_BROTLI:
  1099. case SourceStream::TYPE_DEFLATE:
  1100. case SourceStream::TYPE_GZIP:
  1101. if (request_->accepted_stream_types() &&
  1102. !request_->accepted_stream_types()->contains(source_type)) {
  1103. // If the source type is disabled, we treat it
  1104. // in the same way as SourceStream::TYPE_UNKNOWN.
  1105. return upstream;
  1106. }
  1107. types.push_back(source_type);
  1108. break;
  1109. case SourceStream::TYPE_NONE:
  1110. // Identity encoding type. Pass through raw response body.
  1111. return upstream;
  1112. case SourceStream::TYPE_UNKNOWN:
  1113. // Unknown encoding type. Pass through raw response body.
  1114. // Request will not be canceled; though
  1115. // it is expected that user will see malformed / garbage response.
  1116. return upstream;
  1117. }
  1118. }
  1119. for (const auto& type : base::Reversed(types)) {
  1120. std::unique_ptr<FilterSourceStream> downstream;
  1121. switch (type) {
  1122. case SourceStream::TYPE_BROTLI:
  1123. downstream = CreateBrotliSourceStream(std::move(upstream));
  1124. break;
  1125. case SourceStream::TYPE_GZIP:
  1126. case SourceStream::TYPE_DEFLATE:
  1127. downstream = GzipSourceStream::Create(std::move(upstream), type);
  1128. break;
  1129. case SourceStream::TYPE_NONE:
  1130. case SourceStream::TYPE_UNKNOWN:
  1131. NOTREACHED();
  1132. return nullptr;
  1133. }
  1134. if (downstream == nullptr)
  1135. return nullptr;
  1136. upstream = std::move(downstream);
  1137. }
  1138. return upstream;
  1139. }
  1140. bool URLRequestHttpJob::CopyFragmentOnRedirect(const GURL& location) const {
  1141. // Allow modification of reference fragments by default, unless
  1142. // |preserve_fragment_on_redirect_url_| is set and equal to the redirect URL.
  1143. return !preserve_fragment_on_redirect_url_.has_value() ||
  1144. preserve_fragment_on_redirect_url_ != location;
  1145. }
  1146. bool URLRequestHttpJob::IsSafeRedirect(const GURL& location) {
  1147. // HTTP is always safe.
  1148. // TODO(pauljensen): Remove once crbug.com/146591 is fixed.
  1149. if (location.is_valid() &&
  1150. (location.scheme() == "http" || location.scheme() == "https")) {
  1151. return true;
  1152. }
  1153. // Query URLRequestJobFactory as to whether |location| would be safe to
  1154. // redirect to.
  1155. return request_->context()->job_factory() &&
  1156. request_->context()->job_factory()->IsSafeRedirectTarget(location);
  1157. }
  1158. bool URLRequestHttpJob::NeedsAuth() {
  1159. int code = GetResponseCode();
  1160. if (code == -1)
  1161. return false;
  1162. // Check if we need either Proxy or WWW Authentication. This could happen
  1163. // because we either provided no auth info, or provided incorrect info.
  1164. switch (code) {
  1165. case 407:
  1166. if (proxy_auth_state_ == AUTH_STATE_CANCELED)
  1167. return false;
  1168. proxy_auth_state_ = AUTH_STATE_NEED_AUTH;
  1169. return true;
  1170. case 401:
  1171. if (server_auth_state_ == AUTH_STATE_CANCELED)
  1172. return false;
  1173. server_auth_state_ = AUTH_STATE_NEED_AUTH;
  1174. return true;
  1175. }
  1176. return false;
  1177. }
  1178. std::unique_ptr<AuthChallengeInfo> URLRequestHttpJob::GetAuthChallengeInfo() {
  1179. DCHECK(transaction_.get());
  1180. DCHECK(response_info_);
  1181. // sanity checks:
  1182. DCHECK(proxy_auth_state_ == AUTH_STATE_NEED_AUTH ||
  1183. server_auth_state_ == AUTH_STATE_NEED_AUTH);
  1184. DCHECK((GetResponseHeaders()->response_code() == HTTP_UNAUTHORIZED) ||
  1185. (GetResponseHeaders()->response_code() ==
  1186. HTTP_PROXY_AUTHENTICATION_REQUIRED));
  1187. if (!response_info_->auth_challenge.has_value())
  1188. return nullptr;
  1189. return std::make_unique<AuthChallengeInfo>(
  1190. response_info_->auth_challenge.value());
  1191. }
  1192. void URLRequestHttpJob::SetAuth(const AuthCredentials& credentials) {
  1193. DCHECK(transaction_.get());
  1194. // Proxy gets set first, then WWW.
  1195. if (proxy_auth_state_ == AUTH_STATE_NEED_AUTH) {
  1196. proxy_auth_state_ = AUTH_STATE_HAVE_AUTH;
  1197. } else {
  1198. DCHECK_EQ(server_auth_state_, AUTH_STATE_NEED_AUTH);
  1199. server_auth_state_ = AUTH_STATE_HAVE_AUTH;
  1200. }
  1201. RestartTransactionWithAuth(credentials);
  1202. }
  1203. void URLRequestHttpJob::CancelAuth() {
  1204. if (proxy_auth_state_ == AUTH_STATE_NEED_AUTH) {
  1205. proxy_auth_state_ = AUTH_STATE_CANCELED;
  1206. } else {
  1207. DCHECK_EQ(server_auth_state_, AUTH_STATE_NEED_AUTH);
  1208. server_auth_state_ = AUTH_STATE_CANCELED;
  1209. }
  1210. // The above lines should ensure this is the case.
  1211. DCHECK(!NeedsAuth());
  1212. // Let the consumer read the HTTP error page. NeedsAuth() should now return
  1213. // false, so NotifyHeadersComplete() should not request auth from the client
  1214. // again.
  1215. //
  1216. // Have to do this via PostTask to avoid re-entrantly calling into the
  1217. // consumer.
  1218. base::ThreadTaskRunnerHandle::Get()->PostTask(
  1219. FROM_HERE, base::BindOnce(&URLRequestHttpJob::NotifyFinalHeadersReceived,
  1220. weak_factory_.GetWeakPtr()));
  1221. }
  1222. void URLRequestHttpJob::ContinueWithCertificate(
  1223. scoped_refptr<X509Certificate> client_cert,
  1224. scoped_refptr<SSLPrivateKey> client_private_key) {
  1225. DCHECK(transaction_);
  1226. DCHECK(!response_info_) << "should not have a response yet";
  1227. DCHECK(!override_response_headers_);
  1228. receive_headers_end_ = base::TimeTicks();
  1229. ResetTimer();
  1230. int rv = transaction_->RestartWithCertificate(
  1231. std::move(client_cert), std::move(client_private_key),
  1232. base::BindOnce(&URLRequestHttpJob::OnStartCompleted,
  1233. base::Unretained(this)));
  1234. if (rv == ERR_IO_PENDING)
  1235. return;
  1236. // The transaction started synchronously, but we need to notify the
  1237. // URLRequest delegate via the message loop.
  1238. base::ThreadTaskRunnerHandle::Get()->PostTask(
  1239. FROM_HERE, base::BindOnce(&URLRequestHttpJob::OnStartCompleted,
  1240. weak_factory_.GetWeakPtr(), rv));
  1241. }
  1242. void URLRequestHttpJob::ContinueDespiteLastError() {
  1243. // If the transaction was destroyed, then the job was cancelled.
  1244. if (!transaction_.get())
  1245. return;
  1246. DCHECK(!response_info_) << "should not have a response yet";
  1247. DCHECK(!override_response_headers_);
  1248. receive_headers_end_ = base::TimeTicks();
  1249. ResetTimer();
  1250. int rv = transaction_->RestartIgnoringLastError(base::BindOnce(
  1251. &URLRequestHttpJob::OnStartCompleted, base::Unretained(this)));
  1252. if (rv == ERR_IO_PENDING)
  1253. return;
  1254. // The transaction started synchronously, but we need to notify the
  1255. // URLRequest delegate via the message loop.
  1256. base::ThreadTaskRunnerHandle::Get()->PostTask(
  1257. FROM_HERE, base::BindOnce(&URLRequestHttpJob::OnStartCompleted,
  1258. weak_factory_.GetWeakPtr(), rv));
  1259. }
  1260. bool URLRequestHttpJob::ShouldFixMismatchedContentLength(int rv) const {
  1261. // Some servers send the body compressed, but specify the content length as
  1262. // the uncompressed size. Although this violates the HTTP spec we want to
  1263. // support it (as IE and FireFox do), but *only* for an exact match.
  1264. // See http://crbug.com/79694.
  1265. if (rv == ERR_CONTENT_LENGTH_MISMATCH ||
  1266. rv == ERR_INCOMPLETE_CHUNKED_ENCODING) {
  1267. if (request_->response_headers()) {
  1268. int64_t expected_length =
  1269. request_->response_headers()->GetContentLength();
  1270. VLOG(1) << __func__ << "() \"" << request_->url().spec() << "\""
  1271. << " content-length = " << expected_length
  1272. << " pre total = " << prefilter_bytes_read()
  1273. << " post total = " << postfilter_bytes_read();
  1274. if (postfilter_bytes_read() == expected_length) {
  1275. // Clear the error.
  1276. return true;
  1277. }
  1278. }
  1279. }
  1280. return false;
  1281. }
  1282. int URLRequestHttpJob::ReadRawData(IOBuffer* buf, int buf_size) {
  1283. DCHECK_NE(buf_size, 0);
  1284. DCHECK(!read_in_progress_);
  1285. int rv =
  1286. transaction_->Read(buf, buf_size,
  1287. base::BindOnce(&URLRequestHttpJob::OnReadCompleted,
  1288. base::Unretained(this)));
  1289. if (ShouldFixMismatchedContentLength(rv))
  1290. rv = OK;
  1291. if (rv == 0 || (rv < 0 && rv != ERR_IO_PENDING))
  1292. DoneWithRequest(FINISHED);
  1293. if (rv == ERR_IO_PENDING)
  1294. read_in_progress_ = true;
  1295. return rv;
  1296. }
  1297. int64_t URLRequestHttpJob::GetTotalReceivedBytes() const {
  1298. int64_t total_received_bytes =
  1299. total_received_bytes_from_previous_transactions_;
  1300. if (transaction_)
  1301. total_received_bytes += transaction_->GetTotalReceivedBytes();
  1302. return total_received_bytes;
  1303. }
  1304. int64_t URLRequestHttpJob::GetTotalSentBytes() const {
  1305. int64_t total_sent_bytes = total_sent_bytes_from_previous_transactions_;
  1306. if (transaction_)
  1307. total_sent_bytes += transaction_->GetTotalSentBytes();
  1308. return total_sent_bytes;
  1309. }
  1310. void URLRequestHttpJob::DoneReading() {
  1311. if (transaction_) {
  1312. transaction_->DoneReading();
  1313. }
  1314. DoneWithRequest(FINISHED);
  1315. }
  1316. void URLRequestHttpJob::DoneReadingRedirectResponse() {
  1317. if (transaction_) {
  1318. DCHECK(!override_response_info_);
  1319. if (transaction_->GetResponseInfo()->headers->IsRedirect(nullptr)) {
  1320. // If the original headers indicate a redirect, go ahead and cache the
  1321. // response, even if the |override_response_headers_| are a redirect to
  1322. // another location.
  1323. transaction_->DoneReading();
  1324. } else {
  1325. // Otherwise, |override_response_headers_| must be non-NULL and contain
  1326. // bogus headers indicating a redirect.
  1327. DCHECK(override_response_headers_.get());
  1328. DCHECK(override_response_headers_->IsRedirect(nullptr));
  1329. transaction_->StopCaching();
  1330. }
  1331. }
  1332. DoneWithRequest(FINISHED);
  1333. }
  1334. IPEndPoint URLRequestHttpJob::GetResponseRemoteEndpoint() const {
  1335. return response_info_ ? response_info_->remote_endpoint : IPEndPoint();
  1336. }
  1337. void URLRequestHttpJob::RecordTimer() {
  1338. if (request_creation_time_.is_null()) {
  1339. NOTREACHED()
  1340. << "The same transaction shouldn't start twice without new timing.";
  1341. return;
  1342. }
  1343. base::TimeDelta to_start = base::Time::Now() - request_creation_time_;
  1344. request_creation_time_ = base::Time();
  1345. UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpTimeToFirstByte", to_start);
  1346. // Record additional metrics for TLS 1.3 servers. This is to help measure the
  1347. // impact of enabling 0-RTT. The effects of 0-RTT will be muted because not
  1348. // all TLS 1.3 servers enable 0-RTT, and only the first round-trip on a
  1349. // connection makes use of 0-RTT. However, 0-RTT can affect how requests are
  1350. // bound to connections and which connections offer resumption. We look at all
  1351. // TLS 1.3 responses for an apples-to-apples comparison.
  1352. //
  1353. // Additionally record metrics for Google hosts. Most Google hosts are known
  1354. // to implement 0-RTT, so this gives more targeted metrics as we initially
  1355. // roll out client support.
  1356. //
  1357. // TODO(https://crbug.com/641225): Remove these metrics after launching 0-RTT.
  1358. if (transaction_ && transaction_->GetResponseInfo() &&
  1359. IsTLS13OverTCP(*transaction_->GetResponseInfo())) {
  1360. base::UmaHistogramMediumTimes("Net.HttpTimeToFirstByte.TLS13", to_start);
  1361. if (HasGoogleHost(request()->url())) {
  1362. base::UmaHistogramMediumTimes("Net.HttpTimeToFirstByte.TLS13.Google",
  1363. to_start);
  1364. }
  1365. }
  1366. }
  1367. void URLRequestHttpJob::ResetTimer() {
  1368. if (!request_creation_time_.is_null()) {
  1369. NOTREACHED()
  1370. << "The timer was reset before it was recorded.";
  1371. return;
  1372. }
  1373. request_creation_time_ = base::Time::Now();
  1374. }
  1375. void URLRequestHttpJob::SetRequestHeadersCallback(
  1376. RequestHeadersCallback callback) {
  1377. DCHECK(!transaction_);
  1378. DCHECK(!request_headers_callback_);
  1379. request_headers_callback_ = std::move(callback);
  1380. }
  1381. void URLRequestHttpJob::SetEarlyResponseHeadersCallback(
  1382. ResponseHeadersCallback callback) {
  1383. DCHECK(!transaction_);
  1384. DCHECK(!early_response_headers_callback_);
  1385. early_response_headers_callback_ = std::move(callback);
  1386. }
  1387. void URLRequestHttpJob::SetResponseHeadersCallback(
  1388. ResponseHeadersCallback callback) {
  1389. DCHECK(!transaction_);
  1390. DCHECK(!response_headers_callback_);
  1391. response_headers_callback_ = std::move(callback);
  1392. }
  1393. void URLRequestHttpJob::RecordCompletionHistograms(CompletionCause reason) {
  1394. if (start_time_.is_null())
  1395. return;
  1396. base::TimeDelta total_time = base::TimeTicks::Now() - start_time_;
  1397. UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTime", total_time);
  1398. if (reason == FINISHED) {
  1399. UmaHistogramTimes(
  1400. base::StringPrintf("Net.HttpJob.TotalTimeSuccess.Priority%d",
  1401. request()->priority()),
  1402. total_time);
  1403. UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeSuccess", total_time);
  1404. } else {
  1405. UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeCancel", total_time);
  1406. }
  1407. if (response_info_) {
  1408. // QUIC (by default) supports https scheme only, thus track https URLs only
  1409. // for QUIC.
  1410. bool is_https_google = request() && request()->url().SchemeIs("https") &&
  1411. HasGoogleHost(request()->url());
  1412. bool used_quic = response_info_->DidUseQuic();
  1413. if (is_https_google) {
  1414. if (used_quic) {
  1415. UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpJob.TotalTime.Secure.Quic",
  1416. total_time);
  1417. }
  1418. }
  1419. // Record metrics for TLS 1.3 to measure the impact of 0-RTT. See comment in
  1420. // RecordTimer().
  1421. //
  1422. // TODO(https://crbug.com/641225): Remove these metrics after launching
  1423. // 0-RTT.
  1424. if (IsTLS13OverTCP(*response_info_)) {
  1425. base::UmaHistogramTimes("Net.HttpJob.TotalTime.TLS13", total_time);
  1426. if (is_https_google) {
  1427. base::UmaHistogramTimes("Net.HttpJob.TotalTime.TLS13.Google",
  1428. total_time);
  1429. }
  1430. }
  1431. UMA_HISTOGRAM_CUSTOM_COUNTS("Net.HttpJob.PrefilterBytesRead",
  1432. prefilter_bytes_read(), 1, 50000000, 50);
  1433. if (response_info_->was_cached) {
  1434. UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeCached", total_time);
  1435. UMA_HISTOGRAM_CUSTOM_COUNTS("Net.HttpJob.PrefilterBytesRead.Cache",
  1436. prefilter_bytes_read(), 1, 50000000, 50);
  1437. if (response_info_->unused_since_prefetch)
  1438. UMA_HISTOGRAM_COUNTS_1M("Net.Prefetch.HitBytes",
  1439. prefilter_bytes_read());
  1440. } else {
  1441. UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeNotCached", total_time);
  1442. UMA_HISTOGRAM_CUSTOM_COUNTS("Net.HttpJob.PrefilterBytesRead.Net",
  1443. prefilter_bytes_read(), 1, 50000000, 50);
  1444. if (request_info_.load_flags & LOAD_PREFETCH) {
  1445. UMA_HISTOGRAM_COUNTS_1M("Net.Prefetch.PrefilterBytesReadFromNetwork",
  1446. prefilter_bytes_read());
  1447. }
  1448. if (is_https_google) {
  1449. if (used_quic) {
  1450. UMA_HISTOGRAM_MEDIUM_TIMES(
  1451. "Net.HttpJob.TotalTimeNotCached.Secure.Quic", total_time);
  1452. } else {
  1453. UMA_HISTOGRAM_MEDIUM_TIMES(
  1454. "Net.HttpJob.TotalTimeNotCached.Secure.NotQuic", total_time);
  1455. }
  1456. }
  1457. }
  1458. }
  1459. start_time_ = base::TimeTicks();
  1460. }
  1461. void URLRequestHttpJob::DoneWithRequest(CompletionCause reason) {
  1462. if (done_)
  1463. return;
  1464. done_ = true;
  1465. // Notify NetworkQualityEstimator.
  1466. NetworkQualityEstimator* network_quality_estimator =
  1467. request()->context()->network_quality_estimator();
  1468. if (network_quality_estimator) {
  1469. network_quality_estimator->NotifyRequestCompleted(*request());
  1470. }
  1471. RecordCompletionHistograms(reason);
  1472. request()->set_received_response_content_length(prefilter_bytes_read());
  1473. }
  1474. HttpResponseHeaders* URLRequestHttpJob::GetResponseHeaders() const {
  1475. if (override_response_info_) {
  1476. DCHECK(!transaction_.get());
  1477. return override_response_info_->headers.get();
  1478. }
  1479. DCHECK(transaction_.get());
  1480. DCHECK(transaction_->GetResponseInfo());
  1481. return override_response_headers_.get() ?
  1482. override_response_headers_.get() :
  1483. transaction_->GetResponseInfo()->headers.get();
  1484. }
  1485. void URLRequestHttpJob::NotifyURLRequestDestroyed() {
  1486. awaiting_callback_ = false;
  1487. // Notify NetworkQualityEstimator.
  1488. NetworkQualityEstimator* network_quality_estimator =
  1489. request()->context()->network_quality_estimator();
  1490. if (network_quality_estimator)
  1491. network_quality_estimator->NotifyURLRequestDestroyed(*request());
  1492. }
  1493. bool URLRequestHttpJob::ShouldAddCookieHeader() const {
  1494. // Read cookies whenever allow_credentials() is true, even if the PrivacyMode
  1495. // is being overridden by NetworkDelegate and will eventually block them, as
  1496. // blocked cookies still need to be logged in that case.
  1497. return request_->context()->cookie_store() && request_->allow_credentials();
  1498. }
  1499. bool URLRequestHttpJob::IsPartitionedCookiesEnabled() const {
  1500. // Only valid to call this after we've computed the key.
  1501. DCHECK(cookie_partition_key_.has_value());
  1502. return cookie_partition_key_.value().has_value();
  1503. }
  1504. } // namespace net