url_loader.cc 104 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710
  1. // Copyright 2017 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/url_loader.h"
  5. #include <algorithm>
  6. #include <limits>
  7. #include <string>
  8. #include <utility>
  9. #include <vector>
  10. #include "base/bind.h"
  11. #include "base/command_line.h"
  12. #include "base/containers/fixed_flat_set.h"
  13. #include "base/containers/flat_map.h"
  14. #include "base/debug/alias.h"
  15. #include "base/debug/dump_without_crashing.h"
  16. #include "base/files/file.h"
  17. #include "base/logging.h"
  18. #include "base/memory/raw_ptr.h"
  19. #include "base/memory/weak_ptr.h"
  20. #include "base/metrics/histogram_functions.h"
  21. #include "base/metrics/histogram_macros.h"
  22. #include "base/ranges/algorithm.h"
  23. #include "base/sequence_checker.h"
  24. #include "base/strings/strcat.h"
  25. #include "base/strings/string_split.h"
  26. #include "base/strings/string_util.h"
  27. #include "base/strings/stringprintf.h"
  28. #include "base/task/thread_pool.h"
  29. #include "base/thread_annotations.h"
  30. #include "base/threading/thread_task_runner_handle.h"
  31. #include "base/time/time.h"
  32. #include "base/trace_event/trace_event.h"
  33. #include "base/trace_event/typed_macros.h"
  34. #include "build/build_config.h"
  35. #include "mojo/public/cpp/system/simple_watcher.h"
  36. #include "net/base/elements_upload_data_stream.h"
  37. #include "net/base/isolation_info.h"
  38. #include "net/base/load_flags.h"
  39. #include "net/base/load_timing_info.h"
  40. #include "net/base/mime_sniffer.h"
  41. #include "net/base/schemeful_site.h"
  42. #include "net/base/transport_info.h"
  43. #include "net/base/upload_bytes_element_reader.h"
  44. #include "net/base/upload_file_element_reader.h"
  45. #include "net/cookies/canonical_cookie.h"
  46. #include "net/cookies/cookie_inclusion_status.h"
  47. #include "net/cookies/site_for_cookies.h"
  48. #include "net/cookies/static_cookie_policy.h"
  49. #include "net/dns/public/secure_dns_policy.h"
  50. #include "net/http/http_request_headers.h"
  51. #include "net/http/http_util.h"
  52. #include "net/log/net_log_source_type.h"
  53. #include "net/log/net_log_with_source.h"
  54. #include "net/ssl/client_cert_store.h"
  55. #include "net/ssl/ssl_connection_status_flags.h"
  56. #include "net/ssl/ssl_private_key.h"
  57. #include "net/traffic_annotation/network_traffic_annotation.h"
  58. #include "net/url_request/redirect_info.h"
  59. #include "net/url_request/url_request_context.h"
  60. #include "net/url_request/url_request_context_getter.h"
  61. #include "services/network/chunked_data_pipe_upload_data_stream.h"
  62. #include "services/network/data_pipe_element_reader.h"
  63. #include "services/network/network_service_memory_cache_writer.h"
  64. #include "services/network/public/cpp/client_hints.h"
  65. #include "services/network/public/cpp/constants.h"
  66. #include "services/network/public/cpp/corb/orb_impl.h"
  67. #include "services/network/public/cpp/cors/cors.h"
  68. #include "services/network/public/cpp/cors/origin_access_list.h"
  69. #include "services/network/public/cpp/cross_origin_resource_policy.h"
  70. #include "services/network/public/cpp/empty_url_loader_client.h"
  71. #include "services/network/public/cpp/features.h"
  72. #include "services/network/public/cpp/header_util.h"
  73. #include "services/network/public/cpp/ip_address_space_util.h"
  74. #include "services/network/public/cpp/net_adapters.h"
  75. #include "services/network/public/cpp/network_switches.h"
  76. #include "services/network/public/cpp/parsed_headers.h"
  77. #include "services/network/public/cpp/resource_request.h"
  78. #include "services/network/public/mojom/client_security_state.mojom-forward.h"
  79. #include "services/network/public/mojom/cookie_access_observer.mojom-forward.h"
  80. #include "services/network/public/mojom/cookie_access_observer.mojom.h"
  81. #include "services/network/public/mojom/cookie_manager.mojom.h"
  82. #include "services/network/public/mojom/devtools_observer.mojom.h"
  83. #include "services/network/public/mojom/early_hints.mojom.h"
  84. #include "services/network/public/mojom/fetch_api.mojom.h"
  85. #include "services/network/public/mojom/http_raw_headers.mojom.h"
  86. #include "services/network/public/mojom/url_loader_factory.mojom.h"
  87. #include "services/network/public/mojom/url_response_head.mojom.h"
  88. #include "services/network/resource_scheduler/resource_scheduler_client.h"
  89. #include "services/network/sec_header_helpers.h"
  90. #include "services/network/throttling/scoped_throttling_token.h"
  91. #include "services/network/trust_tokens/trust_token_request_helper.h"
  92. #include "services/network/url_loader_factory.h"
  93. #include "third_party/abseil-cpp/absl/types/optional.h"
  94. #include "url/origin.h"
  95. #if BUILDFLAG(IS_ANDROID)
  96. #include "net/base/features.h"
  97. #include "services/network/radio_monitor_android.h"
  98. #endif
  99. namespace network {
  100. namespace {
  101. using ConcerningHeaderId = URLLoader::ConcerningHeaderId;
  102. // Cannot use 0, because this means "default" in
  103. // mojo::core::Core::CreateDataPipe
  104. constexpr size_t kBlockedBodyAllocationSize = 1;
  105. // A subclass of net::UploadBytesElementReader which owns
  106. // ResourceRequestBody.
  107. class BytesElementReader : public net::UploadBytesElementReader {
  108. public:
  109. BytesElementReader(ResourceRequestBody* resource_request_body,
  110. const DataElementBytes& element)
  111. : net::UploadBytesElementReader(element.AsStringPiece().data(),
  112. element.AsStringPiece().size()),
  113. resource_request_body_(resource_request_body) {}
  114. BytesElementReader(const BytesElementReader&) = delete;
  115. BytesElementReader& operator=(const BytesElementReader&) = delete;
  116. ~BytesElementReader() override {}
  117. private:
  118. scoped_refptr<ResourceRequestBody> resource_request_body_;
  119. };
  120. // A subclass of net::UploadFileElementReader which owns
  121. // ResourceRequestBody.
  122. // This class is necessary to ensure the BlobData and any attached shareable
  123. // files survive until upload completion.
  124. class FileElementReader : public net::UploadFileElementReader {
  125. public:
  126. FileElementReader(ResourceRequestBody* resource_request_body,
  127. base::TaskRunner* task_runner,
  128. const DataElementFile& element,
  129. base::File&& file)
  130. : net::UploadFileElementReader(task_runner,
  131. std::move(file),
  132. element.path(),
  133. element.offset(),
  134. element.length(),
  135. element.expected_modification_time()),
  136. resource_request_body_(resource_request_body) {}
  137. FileElementReader(const FileElementReader&) = delete;
  138. FileElementReader& operator=(const FileElementReader&) = delete;
  139. ~FileElementReader() override {}
  140. private:
  141. scoped_refptr<ResourceRequestBody> resource_request_body_;
  142. };
  143. std::unique_ptr<net::UploadDataStream> CreateUploadDataStream(
  144. ResourceRequestBody* body,
  145. std::vector<base::File>& opened_files,
  146. base::SequencedTaskRunner* file_task_runner) {
  147. // In the case of a chunked upload, there will just be one element.
  148. if (body->elements()->size() == 1) {
  149. if (body->elements()->begin()->type() ==
  150. network::mojom::DataElementDataView::Tag::kChunkedDataPipe) {
  151. auto& element =
  152. body->elements_mutable()->at(0).As<DataElementChunkedDataPipe>();
  153. const bool has_null_source = element.read_only_once().value();
  154. auto upload_data_stream =
  155. std::make_unique<ChunkedDataPipeUploadDataStream>(
  156. body, element.ReleaseChunkedDataPipeGetter(), has_null_source);
  157. if (element.read_only_once()) {
  158. upload_data_stream->EnableCache();
  159. }
  160. return upload_data_stream;
  161. }
  162. }
  163. auto opened_file = opened_files.begin();
  164. std::vector<std::unique_ptr<net::UploadElementReader>> element_readers;
  165. for (const auto& element : *body->elements()) {
  166. switch (element.type()) {
  167. case network::mojom::DataElementDataView::Tag::kBytes:
  168. element_readers.push_back(std::make_unique<BytesElementReader>(
  169. body, element.As<DataElementBytes>()));
  170. break;
  171. case network::mojom::DataElementDataView::Tag::kFile:
  172. DCHECK(opened_file != opened_files.end());
  173. element_readers.push_back(std::make_unique<FileElementReader>(
  174. body, file_task_runner, element.As<network::DataElementFile>(),
  175. std::move(*opened_file++)));
  176. break;
  177. case network::mojom::DataElementDataView::Tag::kDataPipe: {
  178. element_readers.push_back(std::make_unique<DataPipeElementReader>(
  179. body,
  180. element.As<network::DataElementDataPipe>().CloneDataPipeGetter()));
  181. break;
  182. }
  183. case network::mojom::DataElementDataView::Tag::kChunkedDataPipe: {
  184. // This shouldn't happen, as the traits logic should ensure that if
  185. // there's a chunked pipe, there's one and only one element.
  186. NOTREACHED();
  187. break;
  188. }
  189. }
  190. }
  191. DCHECK(opened_file == opened_files.end());
  192. return std::make_unique<net::ElementsUploadDataStream>(
  193. std::move(element_readers), body->identifier());
  194. }
  195. class SSLPrivateKeyInternal : public net::SSLPrivateKey {
  196. public:
  197. SSLPrivateKeyInternal(
  198. const std::string& provider_name,
  199. const std::vector<uint16_t>& algorithm_preferences,
  200. mojo::PendingRemote<mojom::SSLPrivateKey> ssl_private_key)
  201. : provider_name_(provider_name),
  202. algorithm_preferences_(algorithm_preferences),
  203. ssl_private_key_(std::move(ssl_private_key)) {
  204. ssl_private_key_.set_disconnect_handler(
  205. base::BindOnce(&SSLPrivateKeyInternal::HandleSSLPrivateKeyError,
  206. base::Unretained(this)));
  207. }
  208. SSLPrivateKeyInternal(const SSLPrivateKeyInternal&) = delete;
  209. SSLPrivateKeyInternal& operator=(const SSLPrivateKeyInternal&) = delete;
  210. // net::SSLPrivateKey:
  211. std::string GetProviderName() override { return provider_name_; }
  212. std::vector<uint16_t> GetAlgorithmPreferences() override {
  213. return algorithm_preferences_;
  214. }
  215. void Sign(uint16_t algorithm,
  216. base::span<const uint8_t> input,
  217. net::SSLPrivateKey::SignCallback callback) override {
  218. std::vector<uint8_t> input_vector(input.begin(), input.end());
  219. if (!ssl_private_key_ || !ssl_private_key_.is_connected()) {
  220. base::ThreadTaskRunnerHandle::Get()->PostTask(
  221. FROM_HERE,
  222. base::BindOnce(std::move(callback),
  223. net::ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY,
  224. input_vector));
  225. return;
  226. }
  227. ssl_private_key_->Sign(algorithm, input_vector,
  228. base::BindOnce(&SSLPrivateKeyInternal::Callback,
  229. this, std::move(callback)));
  230. }
  231. private:
  232. ~SSLPrivateKeyInternal() override = default;
  233. void HandleSSLPrivateKeyError() { ssl_private_key_.reset(); }
  234. void Callback(net::SSLPrivateKey::SignCallback callback,
  235. int32_t net_error,
  236. const std::vector<uint8_t>& input) {
  237. DCHECK_LE(net_error, 0);
  238. DCHECK_NE(net_error, net::ERR_IO_PENDING);
  239. std::move(callback).Run(static_cast<net::Error>(net_error), input);
  240. }
  241. std::string provider_name_;
  242. std::vector<uint16_t> algorithm_preferences_;
  243. mojo::Remote<mojom::SSLPrivateKey> ssl_private_key_;
  244. };
  245. bool ShouldNotifyAboutCookie(net::CookieInclusionStatus status) {
  246. // Notify about cookies actually used, and those blocked by preferences ---
  247. // for purposes of cookie UI --- as well those carrying warnings pertaining to
  248. // SameSite features and cookies with non-ASCII domain attributes, in order to
  249. // issue a deprecation warning for them.
  250. return status.IsInclude() || status.ShouldWarn() ||
  251. status.HasExclusionReason(
  252. net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES) ||
  253. status.HasExclusionReason(
  254. net::CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY) ||
  255. status.HasExclusionReason(
  256. net::CookieInclusionStatus::EXCLUDE_DOMAIN_NON_ASCII);
  257. }
  258. // Concerning headers that consumers probably shouldn't be allowed to set.
  259. // Gathering numbers on these before adding them to kUnsafeHeaders.
  260. const struct {
  261. const char* name;
  262. ConcerningHeaderId histogram_id;
  263. } kConcerningHeaders[] = {
  264. {net::HttpRequestHeaders::kConnection, ConcerningHeaderId::kConnection},
  265. {net::HttpRequestHeaders::kCookie, ConcerningHeaderId::kCookie},
  266. {"Date", ConcerningHeaderId::kDate},
  267. {"Expect", ConcerningHeaderId::kExpect},
  268. // The referer is passed in from the caller on a per-request basis, but
  269. // there's a separate field for it that should be used instead.
  270. {net::HttpRequestHeaders::kReferer, ConcerningHeaderId::kReferer},
  271. {"Via", ConcerningHeaderId::kVia},
  272. };
  273. // Parses AcceptCHFrame and removes client hints already in the headers.
  274. std::vector<mojom::WebClientHintsType> ComputeAcceptCHFrameHints(
  275. const std::string& accept_ch_frame,
  276. const net::HttpRequestHeaders& headers) {
  277. absl::optional<std::vector<mojom::WebClientHintsType>> maybe_hints =
  278. ParseClientHintsHeader(accept_ch_frame);
  279. if (!maybe_hints)
  280. return {};
  281. // Only look at/add headers that aren't already present.
  282. std::vector<mojom::WebClientHintsType> hints;
  283. for (auto hint : maybe_hints.value()) {
  284. // ResourceWidth is only for images, which won't trigger a restart.
  285. if (hint == mojom::WebClientHintsType::kResourceWidth ||
  286. hint == mojom::WebClientHintsType::kResourceWidth_DEPRECATED) {
  287. continue;
  288. }
  289. const std::string header = GetClientHintToNameMap().at(hint);
  290. if (!headers.HasHeader(header))
  291. hints.push_back(hint);
  292. }
  293. return hints;
  294. }
  295. // Returns true if the |credentials_mode| of the request allows sending
  296. // credentials.
  297. bool ShouldAllowCredentials(mojom::CredentialsMode credentials_mode) {
  298. switch (credentials_mode) {
  299. case mojom::CredentialsMode::kInclude:
  300. // TODO(crbug.com/943939): Make this work with CredentialsMode::kSameOrigin.
  301. case mojom::CredentialsMode::kSameOrigin:
  302. return true;
  303. case mojom::CredentialsMode::kOmit:
  304. case mojom::CredentialsMode::kOmitBug_775438_Workaround:
  305. return false;
  306. }
  307. }
  308. // Returns true when the |credentials_mode| of the request allows sending client
  309. // certificates.
  310. bool ShouldSendClientCertificates(mojom::CredentialsMode credentials_mode) {
  311. switch (credentials_mode) {
  312. case mojom::CredentialsMode::kInclude:
  313. case mojom::CredentialsMode::kSameOrigin:
  314. return true;
  315. // TODO(https://crbug.com/775438): Due to a bug, the default behavior does
  316. // not properly correspond to Fetch's "credentials mode", in that client
  317. // certificates will be sent if available, or the handshake will be aborted
  318. // to allow selecting a client cert.
  319. // With the feature kOmitCorsClientCert enabled, the correct
  320. // behavior is done; omit all client certs and continue the handshake
  321. // without sending one if requested.
  322. case mojom::CredentialsMode::kOmit:
  323. return !base::FeatureList::IsEnabled(features::kOmitCorsClientCert);
  324. case mojom::CredentialsMode::kOmitBug_775438_Workaround:
  325. return false;
  326. }
  327. }
  328. template <typename T>
  329. T* PtrOrFallback(const mojo::Remote<T>& remote, T* fallback) {
  330. return remote.is_bound() ? remote.get() : fallback;
  331. }
  332. // Feature configuration for Cache Transparency is expensive to calculate, so it
  333. // is cached. Not threadsafe.
  334. class CacheTransparencySettings {
  335. public:
  336. // This is not threadsafe, but it doesn't need to be.
  337. static const CacheTransparencySettings& Get() {
  338. if (!singleton_instance_) {
  339. singleton_instance_ = new CacheTransparencySettings();
  340. }
  341. return *singleton_instance_;
  342. }
  343. static void ResetForTesting() {
  344. // `singleton_instance_` needs to be leaked at shutdown but not during
  345. // tests.
  346. delete singleton_instance_;
  347. singleton_instance_ = nullptr;
  348. }
  349. CacheTransparencySettings(CacheTransparencySettings&) = delete;
  350. CacheTransparencySettings& operator=(const CacheTransparencySettings&) =
  351. delete;
  352. bool enabled() const {
  353. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  354. return enabled_;
  355. }
  356. bool PervasivePayloadsEnabled() const {
  357. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  358. return pervasive_payloads_enabled_;
  359. }
  360. absl::optional<int> GetIndexForURL(const GURL& url) const {
  361. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  362. if (!pervasive_payloads_enabled_ || !url.is_valid())
  363. return absl::nullopt;
  364. auto it = map_.find(url.spec());
  365. if (it == map_.end()) {
  366. return absl::nullopt;
  367. }
  368. return std::distance(map_.begin(), it);
  369. }
  370. absl::optional<std::string> GetChecksumForURL(const GURL& url) const {
  371. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  372. if (!enabled_ || !url.is_valid())
  373. return absl::nullopt;
  374. auto it = map_.find(url.spec());
  375. if (it == map_.end()) {
  376. return absl::nullopt;
  377. }
  378. return it->second;
  379. }
  380. private:
  381. using PervasivePayloadsMap = base::flat_map<std::string, std::string>;
  382. CacheTransparencySettings()
  383. : enabled_(
  384. base::FeatureList::IsEnabled(features::kCacheTransparency) &&
  385. base::FeatureList::IsEnabled(features::kPervasivePayloadsList)),
  386. pervasive_payloads_enabled_(
  387. base::FeatureList::IsEnabled(features::kPervasivePayloadsList)),
  388. map_(CreateMap()) {
  389. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  390. }
  391. ~CacheTransparencySettings() = default;
  392. PervasivePayloadsMap CreateMap() {
  393. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  394. if (!pervasive_payloads_enabled_)
  395. return PervasivePayloadsMap();
  396. const std::string comma_separated =
  397. features::kCacheTransparencyPervasivePayloads.Get();
  398. auto split = base::SplitStringPiece(
  399. comma_separated, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  400. if (split.empty()) {
  401. // The code below safely produces an empty map in this case.
  402. DLOG(WARNING) << "Pervasive payload list is empty.";
  403. } else {
  404. const auto version_string = split[0];
  405. int version_number = 0;
  406. if (StringToInt(version_string, &version_number)) {
  407. base::UmaHistogramExactLinear("Network.CacheTransparency.ListVersion",
  408. version_number, 101);
  409. } else {
  410. LOG(WARNING) << "Could not parse pervasive payload version number";
  411. }
  412. // The number of items cannot be large, so this O(N) algorithm is
  413. // acceptable.
  414. split.erase(split.begin());
  415. }
  416. if (split.size() % 2 == 1) {
  417. DLOG(WARNING)
  418. << "Pervasive payload list contains an odd number of elements."
  419. << comma_separated;
  420. }
  421. using Container = PervasivePayloadsMap::container_type;
  422. Container pairs;
  423. pairs.reserve(split.size() / 2);
  424. // `split` has to fit in memory, therefore split.size() cannot be the
  425. // largest possible value, therefore adding 1 to i will not overflow.
  426. for (size_t i = 0; i + 1 < split.size(); i += 2) {
  427. pairs.emplace_back(split[i], split[i + 1]);
  428. }
  429. return PervasivePayloadsMap(std::move(pairs));
  430. }
  431. SEQUENCE_CHECKER(sequence_checker_);
  432. const bool enabled_ GUARDED_BY_CONTEXT(sequence_checker_);
  433. const bool pervasive_payloads_enabled_ GUARDED_BY_CONTEXT(sequence_checker_);
  434. const PervasivePayloadsMap map_ GUARDED_BY_CONTEXT(sequence_checker_);
  435. // This is normally leaked to avoid running a destructor. It's only
  436. // re-allocated in tests.
  437. static CacheTransparencySettings* singleton_instance_;
  438. };
  439. CacheTransparencySettings* CacheTransparencySettings::singleton_instance_ =
  440. nullptr;
  441. bool HasFlagsIncompatibleWithSingleKeyedCache(int load_flags) {
  442. return load_flags &
  443. (net::LOAD_VALIDATE_CACHE | net::LOAD_BYPASS_CACHE |
  444. net::LOAD_SKIP_CACHE_VALIDATION | net::LOAD_ONLY_FROM_CACHE |
  445. net::LOAD_DISABLE_CACHE | net::LOAD_SKIP_VARY_CHECK);
  446. }
  447. bool HasHeadersIncompatibleWithSingleKeyedCache(
  448. const net::HttpRequestHeaders& headers) {
  449. // These are lowercase to permit case-insensitive matching.
  450. auto incompatible_headers = base::MakeFixedFlatSet<base::StringPiece>({
  451. "accept-charset",
  452. "accept-encoding",
  453. "authorization",
  454. "cache-control",
  455. "if-match",
  456. "if-modified-since",
  457. "if-none-match",
  458. "if-range",
  459. "if-unmodified-since",
  460. "pragma",
  461. "range",
  462. });
  463. // HttpRequestHeaders::FindHeader() would iterate through the headers for each
  464. // name in the above list. To reduce the cost of this function, iterate
  465. // manually instead
  466. net::HttpRequestHeaders::Iterator it(headers);
  467. while (it.GetNext()) {
  468. if (incompatible_headers.contains(base::ToLowerASCII(it.name()))) {
  469. return true;
  470. }
  471. }
  472. return false;
  473. }
  474. } // namespace
  475. URLLoader::MaybeSyncURLLoaderClient::MaybeSyncURLLoaderClient(
  476. mojo::PendingRemote<mojom::URLLoaderClient> mojo_client,
  477. base::WeakPtr<mojom::URLLoaderClient> sync_client)
  478. : mojo_client_(std::move(mojo_client)),
  479. sync_client_(std::move(sync_client)) {}
  480. URLLoader::MaybeSyncURLLoaderClient::~MaybeSyncURLLoaderClient() = default;
  481. void URLLoader::MaybeSyncURLLoaderClient::Reset() {
  482. mojo_client_.reset();
  483. sync_client_.reset();
  484. }
  485. mojo::PendingReceiver<mojom::URLLoaderClient>
  486. URLLoader::MaybeSyncURLLoaderClient::BindNewPipeAndPassReceiver() {
  487. sync_client_.reset();
  488. return mojo_client_.BindNewPipeAndPassReceiver();
  489. }
  490. mojom::URLLoaderClient* URLLoader::MaybeSyncURLLoaderClient::Get() {
  491. if (sync_client_)
  492. return sync_client_.get();
  493. if (mojo_client_)
  494. return mojo_client_.get();
  495. return nullptr;
  496. }
  497. URLLoader::URLLoader(
  498. URLLoaderContext& context,
  499. DeleteCallback delete_callback,
  500. mojo::PendingReceiver<mojom::URLLoader> url_loader_receiver,
  501. int32_t options,
  502. const ResourceRequest& request,
  503. mojo::PendingRemote<mojom::URLLoaderClient> url_loader_client,
  504. base::WeakPtr<mojom::URLLoaderClient> sync_url_loader_client,
  505. const net::NetworkTrafficAnnotationTag& traffic_annotation,
  506. uint32_t request_id,
  507. int keepalive_request_size,
  508. base::WeakPtr<KeepaliveStatisticsRecorder> keepalive_statistics_recorder,
  509. std::unique_ptr<TrustTokenRequestHelperFactory> trust_token_helper_factory,
  510. mojo::PendingRemote<mojom::CookieAccessObserver> cookie_observer,
  511. mojo::PendingRemote<mojom::URLLoaderNetworkServiceObserver>
  512. url_loader_network_observer,
  513. mojo::PendingRemote<mojom::DevToolsObserver> devtools_observer,
  514. mojo::PendingRemote<mojom::AcceptCHFrameObserver> accept_ch_frame_observer,
  515. bool third_party_cookies_enabled)
  516. : url_request_context_(context.GetUrlRequestContext()),
  517. network_context_client_(context.GetNetworkContextClient()),
  518. delete_callback_(std::move(delete_callback)),
  519. options_(options),
  520. corb_detachable_(request.corb_detachable),
  521. resource_type_(request.resource_type),
  522. is_load_timing_enabled_(request.enable_load_timing),
  523. factory_params_(context.GetFactoryParams()),
  524. coep_reporter_(context.GetCoepReporter()),
  525. request_id_(request_id),
  526. keepalive_request_size_(keepalive_request_size),
  527. keepalive_(request.keepalive),
  528. do_not_prompt_for_login_(request.do_not_prompt_for_login),
  529. receiver_(this, std::move(url_loader_receiver)),
  530. url_loader_client_(std::move(url_loader_client),
  531. std::move(sync_url_loader_client)),
  532. writable_handle_watcher_(FROM_HERE,
  533. mojo::SimpleWatcher::ArmingPolicy::MANUAL,
  534. base::SequencedTaskRunnerHandle::Get()),
  535. peer_closed_handle_watcher_(FROM_HERE,
  536. mojo::SimpleWatcher::ArmingPolicy::MANUAL,
  537. base::SequencedTaskRunnerHandle::Get()),
  538. per_factory_corb_state_(context.GetMutableCorbState()),
  539. devtools_request_id_(request.devtools_request_id),
  540. request_mode_(request.mode),
  541. request_credentials_mode_(request.credentials_mode),
  542. request_destination_(request.destination),
  543. resource_scheduler_client_(context.GetResourceSchedulerClient()),
  544. keepalive_statistics_recorder_(std::move(keepalive_statistics_recorder)),
  545. custom_proxy_pre_cache_headers_(request.custom_proxy_pre_cache_headers),
  546. custom_proxy_post_cache_headers_(request.custom_proxy_post_cache_headers),
  547. fetch_window_id_(request.fetch_window_id),
  548. private_network_access_checker_(request, &factory_params_, options_),
  549. trust_token_helper_factory_(std::move(trust_token_helper_factory)),
  550. origin_access_list_(context.GetOriginAccessList()),
  551. cookie_observer_remote_(std::move(cookie_observer)),
  552. cookie_observer_(PtrOrFallback(cookie_observer_remote_,
  553. context.GetCookieAccessObserver())),
  554. url_loader_network_observer_remote_(
  555. std::move(url_loader_network_observer)),
  556. url_loader_network_observer_(
  557. PtrOrFallback(url_loader_network_observer_remote_,
  558. context.GetURLLoaderNetworkServiceObserver())),
  559. devtools_observer_remote_(std::move(devtools_observer)),
  560. devtools_observer_(PtrOrFallback(devtools_observer_remote_,
  561. context.GetDevToolsObserver())),
  562. has_fetch_streaming_upload_body_(HasFetchStreamingUploadBody(&request)),
  563. allow_http1_for_streaming_upload_(
  564. request.request_body &&
  565. request.request_body->AllowHTTP1ForStreamingUpload()),
  566. third_party_cookies_enabled_(third_party_cookies_enabled),
  567. accept_ch_frame_observer_(std::move(accept_ch_frame_observer)) {
  568. TRACE_EVENT("loading", "URLLoader::URLLoader",
  569. perfetto::Flow::FromPointer(this));
  570. DCHECK(delete_callback_);
  571. mojom::TrustedURLLoaderHeaderClient* url_loader_header_client =
  572. context.GetUrlLoaderHeaderClient();
  573. if (url_loader_header_client &&
  574. (options_ & mojom::kURLLoadOptionUseHeaderClient)) {
  575. if (options_ & mojom::kURLLoadOptionAsCorsPreflight) {
  576. url_loader_header_client->OnLoaderForCorsPreflightCreated(
  577. request, header_client_.BindNewPipeAndPassReceiver());
  578. } else {
  579. url_loader_header_client->OnLoaderCreated(
  580. request_id_, header_client_.BindNewPipeAndPassReceiver());
  581. }
  582. // Make sure the loader dies if |header_client_| has an error, otherwise
  583. // requests can hang.
  584. header_client_.set_disconnect_handler(
  585. base::BindOnce(&URLLoader::OnMojoDisconnect, base::Unretained(this)));
  586. }
  587. if (devtools_request_id()) {
  588. options_ |= mojom::kURLLoadOptionSendSSLInfoWithResponse |
  589. mojom::kURLLoadOptionSendSSLInfoForCertificateError;
  590. }
  591. receiver_.set_disconnect_handler(
  592. base::BindOnce(&URLLoader::OnMojoDisconnect, base::Unretained(this)));
  593. url_request_ = url_request_context_->CreateRequest(
  594. GURL(request.url), request.priority, this, traffic_annotation,
  595. /*is_for_websockets=*/false, request.net_log_create_info);
  596. url_request_->set_method(request.method);
  597. url_request_->set_site_for_cookies(request.site_for_cookies);
  598. if (ShouldForceIgnoreSiteForCookies(request))
  599. url_request_->set_force_ignore_site_for_cookies(true);
  600. if (!request.navigation_redirect_chain.empty()) {
  601. DCHECK_EQ(request.mode, mojom::RequestMode::kNavigate);
  602. url_request_->SetURLChain(request.navigation_redirect_chain);
  603. }
  604. url_request_->SetReferrer(request.referrer.GetAsReferrer().spec());
  605. url_request_->set_referrer_policy(request.referrer_policy);
  606. url_request_->set_upgrade_if_insecure(request.upgrade_if_insecure);
  607. if (!factory_params_.isolation_info.IsEmpty()) {
  608. url_request_->set_isolation_info(factory_params_.isolation_info);
  609. } else if (request.trusted_params &&
  610. !request.trusted_params->isolation_info.IsEmpty()) {
  611. url_request_->set_isolation_info(request.trusted_params->isolation_info);
  612. if (request.credentials_mode != network::mojom::CredentialsMode::kOmit) {
  613. DCHECK(url_request_->isolation_info().site_for_cookies().IsEquivalent(
  614. request.site_for_cookies));
  615. }
  616. } else if (factory_params_.automatically_assign_isolation_info) {
  617. url::Origin origin = url::Origin::Create(request.url);
  618. url_request_->set_isolation_info(
  619. net::IsolationInfo::Create(net::IsolationInfo::RequestType::kOther,
  620. origin, origin, net::SiteForCookies()));
  621. }
  622. if (context.ShouldRequireNetworkIsolationKey())
  623. DCHECK(!url_request_->isolation_info().IsEmpty());
  624. if (ShouldForceIgnoreTopFramePartyForCookies())
  625. url_request_->set_force_ignore_top_frame_party_for_cookies(true);
  626. // When a service worker forwards a navigation request it uses the
  627. // service worker's IsolationInfo. This causes the cookie code to fail
  628. // to send SameSite=Lax cookies for main-frame navigations passed through
  629. // a service worker. To fix this we check to see if the original destination
  630. // of the request was a main frame document and then set a flag indicating
  631. // SameSite cookies should treat it as a main frame navigation.
  632. if (request.mode == mojom::RequestMode::kNavigate &&
  633. request.destination == mojom::RequestDestination::kEmpty &&
  634. request.original_destination == mojom::RequestDestination::kDocument) {
  635. url_request_->set_force_main_frame_for_same_site_cookies(true);
  636. }
  637. if (factory_params_.disable_secure_dns ||
  638. (request.trusted_params && request.trusted_params->disable_secure_dns)) {
  639. url_request_->SetSecureDnsPolicy(net::SecureDnsPolicy::kDisable);
  640. }
  641. // |cors_exempt_headers| must be merged here to avoid breaking CORS checks.
  642. // They are non-empty when the values are given by the UA code, therefore
  643. // they should be ignored by CORS checks.
  644. net::HttpRequestHeaders merged_headers = request.headers;
  645. merged_headers.MergeFrom(request.cors_exempt_headers);
  646. // This should be ensured by the CorsURLLoaderFactory(), which is called
  647. // before URLLoaders are created.
  648. DCHECK(AreRequestHeadersSafe(merged_headers));
  649. url_request_->SetExtraRequestHeaders(merged_headers);
  650. url_request_->SetUserData(kUserDataKey,
  651. std::make_unique<UnownedPointer>(this));
  652. url_request_->set_accepted_stream_types(
  653. request.devtools_accepted_stream_types);
  654. if (request.trusted_params) {
  655. has_user_activation_ = request.trusted_params->has_user_activation;
  656. }
  657. throttling_token_ = network::ScopedThrottlingToken::MaybeCreate(
  658. url_request_->net_log().source().id, request.throttling_profile_id);
  659. url_request_->set_initiator(request.request_initiator);
  660. SetFetchMetadataHeaders(url_request_.get(), request_mode_,
  661. has_user_activation_, request_destination_, nullptr,
  662. factory_params_, origin_access_list_);
  663. if (request.update_first_party_url_on_redirect) {
  664. url_request_->set_first_party_url_policy(
  665. net::RedirectInfo::FirstPartyURLPolicy::UPDATE_URL_ON_REDIRECT);
  666. }
  667. int request_load_flags = request.load_flags;
  668. if (CacheTransparencySettings::Get().PervasivePayloadsEnabled()) {
  669. auto index = CacheTransparencySettings::Get().GetIndexForURL(request.url);
  670. if (index.has_value()) {
  671. // Remember that a pervasive payload was found so we can annotate the
  672. // URLLoaderCompletionStatus with it later.
  673. pervasive_payload_requested_ = true;
  674. url_request_->set_pervasive_payloads_index_for_logging(index.value());
  675. base::UmaHistogramExactLinear("Network.CacheTransparency.URLMatched",
  676. index.value(), 101);
  677. DVLOG(2) << "Found pervasive payload: " << request.url.spec();
  678. }
  679. }
  680. if (CacheTransparencySettings::Get().enabled() &&
  681. ThirdPartyCookiesEnabled()) {
  682. auto checksum =
  683. CacheTransparencySettings::Get().GetChecksumForURL(request.url);
  684. if (checksum.has_value()) {
  685. CacheTransparencyCacheNotUsedReason cache_not_used_reason =
  686. CacheTransparencyCacheNotUsedReason::kTryingSingleKeyedCache;
  687. if (request.method != net::HttpRequestHeaders::kGetMethod) {
  688. cache_not_used_reason =
  689. CacheTransparencyCacheNotUsedReason::kIncompatibleRequestType;
  690. } else if (HasFlagsIncompatibleWithSingleKeyedCache(request_load_flags)) {
  691. cache_not_used_reason =
  692. CacheTransparencyCacheNotUsedReason::kIncompatibleRequestLoadFlags;
  693. } else if (HasHeadersIncompatibleWithSingleKeyedCache(request.headers)) {
  694. cache_not_used_reason =
  695. CacheTransparencyCacheNotUsedReason::kIncompatibleRequestHeaders;
  696. } else {
  697. url_request_->set_expected_response_checksum(checksum.value());
  698. }
  699. base::UmaHistogramEnumeration("Network.CacheTransparency.CacheNotUsed",
  700. cache_not_used_reason);
  701. }
  702. }
  703. url_request_->SetLoadFlags(request_load_flags);
  704. SetRequestCredentials(request.url);
  705. url_request_->SetRequestHeadersCallback(base::BindRepeating(
  706. &URLLoader::SetRawRequestHeadersAndNotify, base::Unretained(this)));
  707. if (devtools_request_id()) {
  708. url_request_->SetResponseHeadersCallback(base::BindRepeating(
  709. &URLLoader::SetRawResponseHeaders, base::Unretained(this)));
  710. }
  711. url_request_->SetEarlyResponseHeadersCallback(base::BindRepeating(
  712. &URLLoader::NotifyEarlyResponse, base::Unretained(this)));
  713. if (keepalive_ && keepalive_statistics_recorder_) {
  714. keepalive_statistics_recorder_->OnLoadStarted(*factory_params_.top_frame_id,
  715. keepalive_request_size_);
  716. }
  717. if (request.net_log_reference_info) {
  718. // Log source object that created the request, if avairable.
  719. url_request_->net_log().AddEventReferencingSource(
  720. net::NetLogEventType::CREATED_BY,
  721. request.net_log_reference_info.value());
  722. }
  723. #if BUILDFLAG(IS_ANDROID)
  724. if (base::FeatureList::IsEnabled(net::features::kRecordRadioWakeupTrigger)) {
  725. MaybeRecordURLLoaderCreationForWakeupTrigger(request, traffic_annotation);
  726. }
  727. #endif
  728. // Resolve elements from request_body and prepare upload data.
  729. if (request.request_body.get()) {
  730. OpenFilesForUpload(request);
  731. return;
  732. }
  733. BeginTrustTokenOperationIfNecessaryAndThenScheduleStart(request);
  734. }
  735. // This class is used to manage the queue of pending file upload operations
  736. // initiated by the URLLoader::OpenFilesForUpload().
  737. class URLLoader::FileOpenerForUpload {
  738. public:
  739. typedef base::OnceCallback<void(int, std::vector<base::File>)>
  740. SetUpUploadCallback;
  741. FileOpenerForUpload(std::vector<base::FilePath> paths,
  742. URLLoader* url_loader,
  743. int32_t process_id,
  744. mojom::NetworkContextClient* const network_context_client,
  745. SetUpUploadCallback set_up_upload_callback)
  746. : paths_(std::move(paths)),
  747. url_loader_(url_loader),
  748. process_id_(process_id),
  749. network_context_client_(network_context_client),
  750. set_up_upload_callback_(std::move(set_up_upload_callback)) {
  751. StartOpeningNextBatch();
  752. }
  753. FileOpenerForUpload(const FileOpenerForUpload&) = delete;
  754. FileOpenerForUpload& operator=(const FileOpenerForUpload&) = delete;
  755. ~FileOpenerForUpload() {
  756. if (!opened_files_.empty())
  757. PostCloseFiles(std::move(opened_files_));
  758. }
  759. private:
  760. static void OnFilesForUploadOpened(
  761. base::WeakPtr<FileOpenerForUpload> file_opener,
  762. size_t num_files_requested,
  763. int error_code,
  764. std::vector<base::File> opened_files) {
  765. if (!file_opener) {
  766. PostCloseFiles(std::move(opened_files));
  767. return;
  768. }
  769. if (error_code == net::OK && num_files_requested != opened_files.size())
  770. error_code = net::ERR_FAILED;
  771. if (error_code != net::OK) {
  772. PostCloseFiles(std::move(opened_files));
  773. file_opener->FilesForUploadOpenedDone(error_code);
  774. return;
  775. }
  776. for (base::File& file : opened_files)
  777. file_opener->opened_files_.push_back(std::move(file));
  778. if (file_opener->opened_files_.size() < file_opener->paths_.size()) {
  779. file_opener->StartOpeningNextBatch();
  780. return;
  781. }
  782. file_opener->FilesForUploadOpenedDone(net::OK);
  783. }
  784. // |opened_files| need to be closed on a blocking task runner, so move the
  785. // |opened_files| vector onto a sequence that can block so it gets destroyed
  786. // there.
  787. static void PostCloseFiles(std::vector<base::File> opened_files) {
  788. base::ThreadPool::PostTask(
  789. FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
  790. base::BindOnce([](std::vector<base::File>) {},
  791. std::move(opened_files)));
  792. }
  793. void StartOpeningNextBatch() {
  794. size_t num_files_to_request = std::min(paths_.size() - opened_files_.size(),
  795. kMaxFileUploadRequestsPerBatch);
  796. std::vector<base::FilePath> batch_paths(
  797. paths_.begin() + opened_files_.size(),
  798. paths_.begin() + opened_files_.size() + num_files_to_request);
  799. network_context_client_->OnFileUploadRequested(
  800. process_id_, /*async=*/true, batch_paths,
  801. url_loader_->url_request_->url(),
  802. base::BindOnce(&FileOpenerForUpload::OnFilesForUploadOpened,
  803. weak_ptr_factory_.GetWeakPtr(), num_files_to_request));
  804. }
  805. void FilesForUploadOpenedDone(int error_code) {
  806. url_loader_->url_request_->LogUnblocked();
  807. if (error_code == net::OK)
  808. std::move(set_up_upload_callback_).Run(net::OK, std::move(opened_files_));
  809. else
  810. std::move(set_up_upload_callback_).Run(error_code, {});
  811. }
  812. // The paths of files for upload
  813. const std::vector<base::FilePath> paths_;
  814. const raw_ptr<URLLoader> url_loader_;
  815. const int32_t process_id_;
  816. const raw_ptr<mojom::NetworkContextClient> network_context_client_;
  817. SetUpUploadCallback set_up_upload_callback_;
  818. // The files opened so far.
  819. std::vector<base::File> opened_files_;
  820. base::WeakPtrFactory<FileOpenerForUpload> weak_ptr_factory_{this};
  821. };
  822. void URLLoader::OpenFilesForUpload(const ResourceRequest& request) {
  823. std::vector<base::FilePath> paths;
  824. for (const auto& element : *request.request_body.get()->elements()) {
  825. if (element.type() == mojom::DataElementDataView::Tag::kFile) {
  826. paths.push_back(element.As<network::DataElementFile>().path());
  827. }
  828. }
  829. if (paths.empty()) {
  830. SetUpUpload(request, net::OK, std::vector<base::File>());
  831. return;
  832. }
  833. if (!network_context_client_) {
  834. DLOG(ERROR) << "URLLoader couldn't upload a file because no "
  835. "NetworkContextClient is set.";
  836. // Defer calling NotifyCompleted to make sure the URLLoader finishes
  837. // initializing before getting deleted.
  838. base::SequencedTaskRunnerHandle::Get()->PostTask(
  839. FROM_HERE,
  840. base::BindOnce(&URLLoader::NotifyCompleted,
  841. weak_ptr_factory_.GetWeakPtr(), net::ERR_ACCESS_DENIED));
  842. return;
  843. }
  844. url_request_->LogBlockedBy("Opening Files");
  845. file_opener_for_upload_ = std::make_unique<FileOpenerForUpload>(
  846. std::move(paths), this, factory_params_.process_id,
  847. network_context_client_,
  848. base::BindOnce(&URLLoader::SetUpUpload, base::Unretained(this), request));
  849. }
  850. void URLLoader::SetUpUpload(const ResourceRequest& request,
  851. int error_code,
  852. std::vector<base::File> opened_files) {
  853. if (error_code != net::OK) {
  854. DCHECK(opened_files.empty());
  855. // Defer calling NotifyCompleted to make sure the URLLoader finishes
  856. // initializing before getting deleted.
  857. base::SequencedTaskRunnerHandle::Get()->PostTask(
  858. FROM_HERE, base::BindOnce(&URLLoader::NotifyCompleted,
  859. weak_ptr_factory_.GetWeakPtr(), error_code));
  860. return;
  861. }
  862. scoped_refptr<base::SequencedTaskRunner> task_runner =
  863. base::ThreadPool::CreateSequencedTaskRunner(
  864. {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
  865. url_request_->set_upload(CreateUploadDataStream(
  866. request.request_body.get(), opened_files, task_runner.get()));
  867. if (request.enable_upload_progress) {
  868. upload_progress_tracker_ = std::make_unique<UploadProgressTracker>(
  869. FROM_HERE,
  870. base::BindRepeating(&URLLoader::SendUploadProgress,
  871. base::Unretained(this)),
  872. url_request_.get());
  873. }
  874. BeginTrustTokenOperationIfNecessaryAndThenScheduleStart(request);
  875. }
  876. void URLLoader::BeginTrustTokenOperationIfNecessaryAndThenScheduleStart(
  877. const ResourceRequest& request) {
  878. if (!request.trust_token_params) {
  879. ScheduleStart();
  880. return;
  881. }
  882. // Since the request has trust token parameters, |trust_token_helper_factory_|
  883. // is guaranteed to be non-null by URLLoader's constructor's contract.
  884. DCHECK(trust_token_helper_factory_);
  885. trust_token_helper_factory_->CreateTrustTokenHelperForRequest(
  886. *url_request_, request.trust_token_params.value(),
  887. base::BindOnce(&URLLoader::OnDoneConstructingTrustTokenHelper,
  888. weak_ptr_factory_.GetWeakPtr(),
  889. request.trust_token_params->type));
  890. }
  891. void URLLoader::OnDoneConstructingTrustTokenHelper(
  892. mojom::TrustTokenOperationType type,
  893. TrustTokenStatusOrRequestHelper status_or_helper) {
  894. if (!status_or_helper.ok()) {
  895. trust_token_status_ = status_or_helper.status();
  896. // Defer calling NotifyCompleted to make sure the URLLoader
  897. // finishes initializing before getting deleted.
  898. base::SequencedTaskRunnerHandle::Get()->PostTask(
  899. FROM_HERE, base::BindOnce(&URLLoader::NotifyCompleted,
  900. weak_ptr_factory_.GetWeakPtr(),
  901. net::ERR_TRUST_TOKEN_OPERATION_FAILED));
  902. if (devtools_observer_ && devtools_request_id()) {
  903. mojom::TrustTokenOperationResultPtr operation_result =
  904. mojom::TrustTokenOperationResult::New();
  905. operation_result->status = *trust_token_status_;
  906. operation_result->type = type;
  907. devtools_observer_->OnTrustTokenOperationDone(
  908. devtools_request_id().value(), std::move(operation_result));
  909. }
  910. return;
  911. }
  912. trust_token_helper_ = status_or_helper.TakeOrCrash();
  913. trust_token_helper_->Begin(
  914. url_request_.get(),
  915. base::BindOnce(&URLLoader::OnDoneBeginningTrustTokenOperation,
  916. weak_ptr_factory_.GetWeakPtr()));
  917. }
  918. void URLLoader::OnDoneBeginningTrustTokenOperation(
  919. mojom::TrustTokenOperationStatus status) {
  920. trust_token_status_ = status;
  921. // In case the operation failed or it succeeded in a manner where the request
  922. // does not need to be sent onwards, the DevTools event is emitted from here.
  923. // Otherwise the DevTools event is always emitted from
  924. // |OnDoneFinalizingTrustTokenOperation|.
  925. if (status != mojom::TrustTokenOperationStatus::kOk) {
  926. MaybeSendTrustTokenOperationResultToDevTools();
  927. }
  928. if (status == mojom::TrustTokenOperationStatus::kOk) {
  929. ScheduleStart();
  930. } else if (status == mojom::TrustTokenOperationStatus::kAlreadyExists ||
  931. status == mojom::TrustTokenOperationStatus::
  932. kOperationSuccessfullyFulfilledLocally) {
  933. // The Trust Tokens operation succeeded without needing to send the request;
  934. // we return early with an "error" representing this success.
  935. //
  936. // Here and below, defer calling NotifyCompleted to make sure the URLLoader
  937. // finishes initializing before getting deleted.
  938. base::SequencedTaskRunnerHandle::Get()->PostTask(
  939. FROM_HERE,
  940. base::BindOnce(
  941. &URLLoader::NotifyCompleted, weak_ptr_factory_.GetWeakPtr(),
  942. net::ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST));
  943. } else {
  944. base::SequencedTaskRunnerHandle::Get()->PostTask(
  945. FROM_HERE, base::BindOnce(&URLLoader::NotifyCompleted,
  946. weak_ptr_factory_.GetWeakPtr(),
  947. net::ERR_TRUST_TOKEN_OPERATION_FAILED));
  948. }
  949. }
  950. void URLLoader::ScheduleStart() {
  951. bool defer = false;
  952. if (resource_scheduler_client_) {
  953. resource_scheduler_request_handle_ =
  954. resource_scheduler_client_->ScheduleRequest(
  955. !(options_ & mojom::kURLLoadOptionSynchronous), url_request_.get());
  956. resource_scheduler_request_handle_->set_resume_callback(
  957. base::BindOnce(&URLLoader::ResumeStart, base::Unretained(this)));
  958. resource_scheduler_request_handle_->WillStartRequest(&defer);
  959. }
  960. if (defer)
  961. url_request_->LogBlockedBy("ResourceScheduler");
  962. else
  963. url_request_->Start();
  964. }
  965. URLLoader::~URLLoader() {
  966. TRACE_EVENT("loading", "URLLoader::~URLLoader",
  967. perfetto::TerminatingFlow::FromPointer(this));
  968. RecordBodyReadFromNetBeforePausedIfNeeded();
  969. if (keepalive_ && keepalive_statistics_recorder_) {
  970. keepalive_statistics_recorder_->OnLoadFinished(
  971. *factory_params_.top_frame_id, keepalive_request_size_);
  972. }
  973. }
  974. // static
  975. const void* const URLLoader::kUserDataKey = &URLLoader::kUserDataKey;
  976. void URLLoader::FollowRedirect(
  977. const std::vector<std::string>& removed_headers,
  978. const net::HttpRequestHeaders& modified_headers,
  979. const net::HttpRequestHeaders& modified_cors_exempt_headers,
  980. const absl::optional<GURL>& new_url) {
  981. if (!deferred_redirect_url_) {
  982. NOTREACHED();
  983. return;
  984. }
  985. // Set seen_raw_request_headers_ to false in order to make sure this redirect
  986. // also calls the devtools observer.
  987. seen_raw_request_headers_ = false;
  988. // Reset the state of the PNA checker - redirects should be treated like new
  989. // requests by the same client.
  990. private_network_access_checker_.Reset();
  991. memory_cache_writer_.reset();
  992. // Removing headers can't make the set of pre-existing headers unsafe, but
  993. // adding headers can.
  994. if (!AreRequestHeadersSafe(modified_headers) ||
  995. !AreRequestHeadersSafe(modified_cors_exempt_headers)) {
  996. NotifyCompleted(net::ERR_INVALID_ARGUMENT);
  997. // |this| may have been deleted.
  998. return;
  999. }
  1000. if (!modified_headers.IsEmpty())
  1001. LogConcerningRequestHeaders(modified_headers,
  1002. true /* added_during_redirect */);
  1003. deferred_redirect_url_.reset();
  1004. new_redirect_url_ = new_url;
  1005. net::HttpRequestHeaders merged_modified_headers;
  1006. merged_modified_headers.CopyFrom(modified_headers);
  1007. merged_modified_headers.MergeFrom(modified_cors_exempt_headers);
  1008. url_request_->FollowDeferredRedirect(removed_headers,
  1009. merged_modified_headers);
  1010. new_redirect_url_.reset();
  1011. }
  1012. void URLLoader::SetPriority(net::RequestPriority priority,
  1013. int32_t intra_priority_value) {
  1014. if (url_request_ && resource_scheduler_client_) {
  1015. resource_scheduler_client_->ReprioritizeRequest(
  1016. url_request_.get(), priority, intra_priority_value);
  1017. }
  1018. }
  1019. void URLLoader::PauseReadingBodyFromNet() {
  1020. DVLOG(1) << "URLLoader pauses fetching response body for "
  1021. << (url_request_ ? url_request_->original_url().spec()
  1022. : "a URL that has completed loading or failed.");
  1023. // Please note that we pause reading body in all cases. Even if the URL
  1024. // request indicates that the response was cached, there could still be
  1025. // network activity involved. For example, the response was only partially
  1026. // cached.
  1027. //
  1028. // On the other hand, we only report BodyReadFromNetBeforePaused histogram
  1029. // when we are sure that the response body hasn't been read from cache. This
  1030. // avoids polluting the histogram data with data points from cached responses.
  1031. should_pause_reading_body_ = true;
  1032. if (read_in_progress_) {
  1033. update_body_read_before_paused_ = true;
  1034. } else {
  1035. body_read_before_paused_ = url_request_->GetRawBodyBytes();
  1036. }
  1037. }
  1038. void URLLoader::ResumeReadingBodyFromNet() {
  1039. DVLOG(1) << "URLLoader resumes fetching response body for "
  1040. << (url_request_ ? url_request_->original_url().spec()
  1041. : "a URL that has completed loading or failed.");
  1042. should_pause_reading_body_ = false;
  1043. if (paused_reading_body_) {
  1044. paused_reading_body_ = false;
  1045. ReadMore();
  1046. }
  1047. }
  1048. PrivateNetworkAccessCheckResult URLLoader::PrivateNetworkAccessCheck(
  1049. const net::TransportInfo& transport_info) {
  1050. PrivateNetworkAccessCheckResult result =
  1051. private_network_access_checker_.Check(transport_info);
  1052. mojom::IPAddressSpace response_address_space =
  1053. *private_network_access_checker_.ResponseAddressSpace();
  1054. url_request_->net_log().AddEvent(
  1055. net::NetLogEventType::PRIVATE_NETWORK_ACCESS_CHECK, [&] {
  1056. base::Value dict(base::Value::Type::DICTIONARY);
  1057. dict.SetStringKey(
  1058. "client_address_space",
  1059. IPAddressSpaceToStringPiece(
  1060. private_network_access_checker_.ClientAddressSpace()));
  1061. dict.SetStringKey("resource_address_space",
  1062. IPAddressSpaceToStringPiece(response_address_space));
  1063. dict.SetStringKey("result",
  1064. PrivateNetworkAccessCheckResultToStringPiece(result));
  1065. return dict;
  1066. });
  1067. bool is_warning = false;
  1068. switch (result) {
  1069. case PrivateNetworkAccessCheckResult::kAllowedByPolicyWarn:
  1070. is_warning = true;
  1071. break;
  1072. case PrivateNetworkAccessCheckResult::kBlockedByPolicyBlock:
  1073. is_warning = false;
  1074. break;
  1075. default:
  1076. // Do not report anything to DevTools in these cases.
  1077. return result;
  1078. }
  1079. // If `security_state` was nullptr, then `result` should not have mentioned
  1080. // the policy set in `security_state->private_network_request_policy`.
  1081. const mojom::ClientSecurityState* security_state =
  1082. private_network_access_checker_.client_security_state();
  1083. DCHECK(security_state);
  1084. if (devtools_observer_) {
  1085. devtools_observer_->OnPrivateNetworkRequest(
  1086. devtools_request_id(), url_request_->url(), is_warning,
  1087. response_address_space, security_state->Clone());
  1088. }
  1089. return result;
  1090. }
  1091. int URLLoader::OnConnected(net::URLRequest* url_request,
  1092. const net::TransportInfo& info,
  1093. net::CompletionOnceCallback callback) {
  1094. DCHECK_EQ(url_request, url_request_.get());
  1095. transport_info_ = info;
  1096. // Now that the request endpoint's address has been resolved, check if
  1097. // this request should be blocked per Private Network Access.
  1098. PrivateNetworkAccessCheckResult result = PrivateNetworkAccessCheck(info);
  1099. absl::optional<mojom::CorsError> cors_error =
  1100. PrivateNetworkAccessCheckResultToCorsError(result);
  1101. if (cors_error.has_value()) {
  1102. if (result == PrivateNetworkAccessCheckResult::kBlockedByPolicyBlock &&
  1103. (info.type == net::TransportType::kCached ||
  1104. info.type == net::TransportType::kCachedFromProxy)) {
  1105. // If the cached entry was blocked by the private network access check
  1106. // without a preflight, we'll start over and attempt to request from the
  1107. // network, so resetting the checker.
  1108. private_network_access_checker_.Reset();
  1109. return net::
  1110. ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY;
  1111. }
  1112. // Remember the CORS error so we can annotate the URLLoaderCompletionStatus
  1113. // with it later, then fail the request with the same net error code as
  1114. // other CORS errors.
  1115. cors_error_status_ = CorsErrorStatus(
  1116. *cors_error, private_network_access_checker_.TargetAddressSpace(),
  1117. *private_network_access_checker_.ResponseAddressSpace());
  1118. if (result == PrivateNetworkAccessCheckResult::
  1119. kBlockedByInconsistentIpAddressSpace ||
  1120. result ==
  1121. PrivateNetworkAccessCheckResult::kBlockedByTargetIpAddressSpace) {
  1122. return net::ERR_INCONSISTENT_IP_ADDRESS_SPACE;
  1123. }
  1124. return net::ERR_FAILED;
  1125. }
  1126. if (!accept_ch_frame_observer_ || info.accept_ch_frame.empty() ||
  1127. !base::FeatureList::IsEnabled(features::kAcceptCHFrame)) {
  1128. return net::OK;
  1129. }
  1130. // Find client hints that are in the ACCEPT_CH frame that were not already
  1131. // included in the request
  1132. std::vector<mojom::WebClientHintsType> hints = ComputeAcceptCHFrameHints(
  1133. info.accept_ch_frame, url_request->extra_request_headers());
  1134. // If there are hints in the ACCEPT_CH frame that weren't included in the
  1135. // original request, notify the observer. If those hints can be included,
  1136. // this URLLoader will be destroyed and another with the correct hints
  1137. // started. Otherwise, the callback to continue the network transaction will
  1138. // be called and the URLLoader will continue as normal.
  1139. if (!hints.empty()) {
  1140. accept_ch_frame_observer_->OnAcceptCHFrameReceived(
  1141. url::Origin::Create(url_request->url()), hints, std::move(callback));
  1142. return net::ERR_IO_PENDING;
  1143. }
  1144. return net::OK;
  1145. }
  1146. mojom::URLResponseHeadPtr URLLoader::BuildResponseHead() const {
  1147. auto response = mojom::URLResponseHead::New();
  1148. response->request_time = url_request_->request_time();
  1149. response->response_time = url_request_->response_time();
  1150. response->headers = url_request_->response_headers();
  1151. response->parsed_headers =
  1152. PopulateParsedHeaders(response->headers.get(), url_request_->url());
  1153. url_request_->GetCharset(&response->charset);
  1154. response->content_length = url_request_->GetExpectedContentSize();
  1155. url_request_->GetMimeType(&response->mime_type);
  1156. net::HttpResponseInfo response_info = url_request_->response_info();
  1157. response->was_fetched_via_spdy = response_info.was_fetched_via_spdy;
  1158. response->was_alpn_negotiated = response_info.was_alpn_negotiated;
  1159. response->alpn_negotiated_protocol = response_info.alpn_negotiated_protocol;
  1160. response->connection_info = response_info.connection_info;
  1161. response->remote_endpoint = response_info.remote_endpoint;
  1162. response->was_fetched_via_cache = url_request_->was_cached();
  1163. response->is_validated = (response_info.cache_entry_status ==
  1164. net::HttpResponseInfo::ENTRY_VALIDATED);
  1165. response->proxy_server = url_request_->proxy_server();
  1166. response->network_accessed = response_info.network_accessed;
  1167. response->async_revalidation_requested =
  1168. response_info.async_revalidation_requested;
  1169. response->was_in_prefetch_cache =
  1170. !(url_request_->load_flags() & net::LOAD_PREFETCH) &&
  1171. response_info.unused_since_prefetch;
  1172. response->was_cookie_in_request = false;
  1173. for (const auto& cookie_with_access_result :
  1174. url_request_->maybe_sent_cookies()) {
  1175. if (cookie_with_access_result.access_result.status.IsInclude()) {
  1176. // IsInclude() true means the cookie was sent.
  1177. response->was_cookie_in_request = true;
  1178. break;
  1179. }
  1180. }
  1181. if (is_load_timing_enabled_)
  1182. url_request_->GetLoadTimingInfo(&response->load_timing);
  1183. if (url_request_->ssl_info().cert.get()) {
  1184. response->ct_policy_compliance =
  1185. url_request_->ssl_info().ct_policy_compliance;
  1186. response->cert_status = url_request_->ssl_info().cert_status;
  1187. net::SSLVersion ssl_version = net::SSLConnectionStatusToVersion(
  1188. url_request_->ssl_info().connection_status);
  1189. response->is_legacy_tls_version =
  1190. ssl_version == net::SSLVersion::SSL_CONNECTION_VERSION_TLS1 ||
  1191. ssl_version == net::SSLVersion::SSL_CONNECTION_VERSION_TLS1_1;
  1192. if ((options_ & mojom::kURLLoadOptionSendSSLInfoWithResponse) ||
  1193. (net::IsCertStatusError(url_request_->ssl_info().cert_status) &&
  1194. (options_ & mojom::kURLLoadOptionSendSSLInfoForCertificateError))) {
  1195. response->ssl_info = url_request_->ssl_info();
  1196. }
  1197. }
  1198. response->request_start = url_request_->creation_time();
  1199. response->response_start = base::TimeTicks::Now();
  1200. response->encoded_data_length = url_request_->GetTotalReceivedBytes();
  1201. response->auth_challenge_info = url_request_->auth_challenge_info();
  1202. response->has_range_requested =
  1203. url_request_->extra_request_headers().HasHeader(
  1204. net::HttpRequestHeaders::kRange);
  1205. base::ranges::copy(url_request_->response_info().dns_aliases,
  1206. std::back_inserter(response->dns_aliases));
  1207. // [spec]: https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
  1208. // 13. Set response’s request-includes-credentials to includeCredentials.
  1209. response->request_include_credentials = url_request_->allow_credentials();
  1210. response->response_address_space =
  1211. private_network_access_checker_.ResponseAddressSpace().value_or(
  1212. mojom::IPAddressSpace::kUnknown);
  1213. response->client_address_space =
  1214. private_network_access_checker_.ClientAddressSpace();
  1215. response->has_partitioned_cookie = url_request_->HasPartitionedCookie();
  1216. return response;
  1217. }
  1218. void URLLoader::OnReceivedRedirect(net::URLRequest* url_request,
  1219. const net::RedirectInfo& redirect_info,
  1220. bool* defer_redirect) {
  1221. DCHECK(url_request == url_request_.get());
  1222. DCHECK(!deferred_redirect_url_);
  1223. deferred_redirect_url_ = std::make_unique<GURL>(redirect_info.new_url);
  1224. // Send the redirect response to the client, allowing them to inspect it and
  1225. // optionally follow the redirect.
  1226. *defer_redirect = true;
  1227. mojom::URLResponseHeadPtr response = BuildResponseHead();
  1228. DispatchOnRawResponse();
  1229. ReportFlaggedResponseCookies();
  1230. if (memory_cache_)
  1231. memory_cache_->OnRedirect(url_request_.get(), request_destination_);
  1232. const CrossOriginEmbedderPolicy kEmpty;
  1233. // Enforce the Cross-Origin-Resource-Policy (CORP) header.
  1234. const CrossOriginEmbedderPolicy& cross_origin_embedder_policy =
  1235. factory_params_.client_security_state
  1236. ? factory_params_.client_security_state->cross_origin_embedder_policy
  1237. : kEmpty;
  1238. if (absl::optional<mojom::BlockedByResponseReason> blocked_reason =
  1239. CrossOriginResourcePolicy::IsBlocked(
  1240. url_request_->url(), url_request_->original_url(),
  1241. url_request_->initiator(), *response, request_mode_,
  1242. request_destination_, cross_origin_embedder_policy,
  1243. coep_reporter_)) {
  1244. CompleteBlockedResponse(net::ERR_BLOCKED_BY_RESPONSE, false,
  1245. blocked_reason);
  1246. // TODO(https://crbug.com/1154250): Close the socket here.
  1247. // For more details see https://crbug.com/1154250#c17.
  1248. // Item 2 discusses redirect handling.
  1249. //
  1250. // "url_request_->AbortAndCloseConnection()" should ideally close the
  1251. // socket, but unfortunately, URLRequestHttpJob caches redirects in a way
  1252. // that ignores their response bodies, since they'll never be read. It does
  1253. // this by calling HttpCache::Transaction::StopCaching(), which also has the
  1254. // effect of detaching the HttpNetworkTransaction, which owns the socket,
  1255. // from the HttpCache::Transaction. To fix this, we'd either need to call
  1256. // StopCaching() later in the process, or make the HttpCache::Transaction
  1257. // continue to hang onto the HttpNetworkTransaction after this call.
  1258. DeleteSelf();
  1259. return;
  1260. }
  1261. SetRequestCredentials(redirect_info.new_url);
  1262. // We may need to clear out old Sec- prefixed request headers. We'll attempt
  1263. // to do this before we re-add any.
  1264. MaybeRemoveSecHeaders(url_request_.get(), redirect_info.new_url);
  1265. SetFetchMetadataHeaders(url_request_.get(), request_mode_,
  1266. has_user_activation_, request_destination_,
  1267. &redirect_info.new_url, factory_params_,
  1268. origin_access_list_);
  1269. DCHECK_EQ(emitted_devtools_raw_request_, emitted_devtools_raw_response_);
  1270. response->emitted_extra_info = emitted_devtools_raw_request_;
  1271. // Ensure that the redirect target is not treated as a pervasive payload.
  1272. url_request_->set_expected_response_checksum(std::string());
  1273. url_loader_client_.Get()->OnReceiveRedirect(redirect_info,
  1274. std::move(response));
  1275. }
  1276. // static
  1277. bool URLLoader::HasFetchStreamingUploadBody(const ResourceRequest* request) {
  1278. const ResourceRequestBody* request_body = request->request_body.get();
  1279. if (!request_body)
  1280. return false;
  1281. const std::vector<DataElement>* elements = request_body->elements();
  1282. if (elements->size() != 1u)
  1283. return false;
  1284. const auto& element = elements->front();
  1285. return element.type() == mojom::DataElementDataView::Tag::kChunkedDataPipe &&
  1286. element.As<network::DataElementChunkedDataPipe>().read_only_once();
  1287. }
  1288. // static
  1289. void URLLoader::ResetPervasivePayloadsListForTesting() {
  1290. CacheTransparencySettings::ResetForTesting();
  1291. }
  1292. void URLLoader::OnAuthRequired(net::URLRequest* url_request,
  1293. const net::AuthChallengeInfo& auth_info) {
  1294. if (has_fetch_streaming_upload_body_) {
  1295. NotifyCompleted(net::ERR_FAILED);
  1296. // |this| may have been deleted.
  1297. return;
  1298. }
  1299. if (!url_loader_network_observer_) {
  1300. OnAuthCredentials(absl::nullopt);
  1301. return;
  1302. }
  1303. if (do_not_prompt_for_login_) {
  1304. OnAuthCredentials(absl::nullopt);
  1305. return;
  1306. }
  1307. DCHECK(!auth_challenge_responder_receiver_.is_bound());
  1308. url_loader_network_observer_->OnAuthRequired(
  1309. fetch_window_id_, request_id_, url_request_->url(), first_auth_attempt_,
  1310. auth_info, url_request->response_headers(),
  1311. auth_challenge_responder_receiver_.BindNewPipeAndPassRemote());
  1312. auth_challenge_responder_receiver_.set_disconnect_handler(
  1313. base::BindOnce(&URLLoader::DeleteSelf, base::Unretained(this)));
  1314. first_auth_attempt_ = false;
  1315. }
  1316. void URLLoader::OnCertificateRequested(net::URLRequest* unused,
  1317. net::SSLCertRequestInfo* cert_info) {
  1318. DCHECK(!client_cert_responder_receiver_.is_bound());
  1319. if (base::CommandLine::ForCurrentProcess()->HasSwitch(
  1320. switches::kIgnoreUrlFetcherCertRequests) &&
  1321. factory_params_.is_trusted) {
  1322. ContinueWithoutCertificate();
  1323. return;
  1324. }
  1325. if (!url_loader_network_observer_) {
  1326. CancelRequest();
  1327. return;
  1328. }
  1329. // Set up mojo endpoints for ClientCertificateResponder and bind to the
  1330. // Receiver. This enables us to receive messages regarding the client
  1331. // certificate selection.
  1332. url_loader_network_observer_->OnCertificateRequested(
  1333. fetch_window_id_, cert_info,
  1334. client_cert_responder_receiver_.BindNewPipeAndPassRemote());
  1335. client_cert_responder_receiver_.set_disconnect_handler(
  1336. base::BindOnce(&URLLoader::CancelRequest, base::Unretained(this)));
  1337. }
  1338. void URLLoader::OnSSLCertificateError(net::URLRequest* request,
  1339. int net_error,
  1340. const net::SSLInfo& ssl_info,
  1341. bool fatal) {
  1342. if (!url_loader_network_observer_) {
  1343. OnSSLCertificateErrorResponse(ssl_info, net::ERR_INSECURE_RESPONSE);
  1344. return;
  1345. }
  1346. url_loader_network_observer_->OnSSLCertificateError(
  1347. url_request_->url(), net_error, ssl_info, fatal,
  1348. base::BindOnce(&URLLoader::OnSSLCertificateErrorResponse,
  1349. weak_ptr_factory_.GetWeakPtr(), ssl_info));
  1350. }
  1351. void URLLoader::OnResponseStarted(net::URLRequest* url_request, int net_error) {
  1352. DCHECK(url_request == url_request_.get());
  1353. has_received_response_ = true;
  1354. ReportFlaggedResponseCookies();
  1355. if (net_error != net::OK) {
  1356. NotifyCompleted(net_error);
  1357. // |this| may have been deleted.
  1358. return;
  1359. }
  1360. response_ = BuildResponseHead();
  1361. DispatchOnRawResponse();
  1362. // Parse and remove the Trust Tokens response headers, if any are expected,
  1363. // potentially failing the request if an error occurs.
  1364. if (trust_token_helper_) {
  1365. trust_token_helper_->Finalize(
  1366. response_.get(),
  1367. base::BindOnce(&URLLoader::OnDoneFinalizingTrustTokenOperation,
  1368. weak_ptr_factory_.GetWeakPtr()));
  1369. // |this| may have been deleted.
  1370. return;
  1371. }
  1372. if (memory_cache_) {
  1373. memory_cache_writer_ = memory_cache_->MaybeCreateWriter(
  1374. url_request_.get(), request_destination_, transport_info_, response_);
  1375. }
  1376. ContinueOnResponseStarted();
  1377. }
  1378. void URLLoader::OnDoneFinalizingTrustTokenOperation(
  1379. mojom::TrustTokenOperationStatus status) {
  1380. trust_token_status_ = status;
  1381. MaybeSendTrustTokenOperationResultToDevTools();
  1382. if (status != mojom::TrustTokenOperationStatus::kOk) {
  1383. NotifyCompleted(net::ERR_TRUST_TOKEN_OPERATION_FAILED);
  1384. // |this| may have been deleted.
  1385. return;
  1386. }
  1387. ContinueOnResponseStarted();
  1388. }
  1389. void URLLoader::MaybeSendTrustTokenOperationResultToDevTools() {
  1390. CHECK(trust_token_helper_ && trust_token_status_);
  1391. if (!devtools_observer_ || !devtools_request_id())
  1392. return;
  1393. mojom::TrustTokenOperationResultPtr operation_result =
  1394. trust_token_helper_->CollectOperationResultWithStatus(
  1395. *trust_token_status_);
  1396. devtools_observer_->OnTrustTokenOperationDone(devtools_request_id().value(),
  1397. std::move(operation_result));
  1398. }
  1399. void URLLoader::ContinueOnResponseStarted() {
  1400. MojoCreateDataPipeOptions options;
  1401. options.struct_size = sizeof(MojoCreateDataPipeOptions);
  1402. options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
  1403. options.element_num_bytes = 1;
  1404. options.capacity_num_bytes =
  1405. network::features::GetDataPipeDefaultAllocationSize(
  1406. features::DataPipeAllocationSize::kLargerSizeIfPossible);
  1407. MojoResult result =
  1408. mojo::CreateDataPipe(&options, response_body_stream_, consumer_handle_);
  1409. if (result != MOJO_RESULT_OK) {
  1410. NotifyCompleted(net::ERR_INSUFFICIENT_RESOURCES);
  1411. return;
  1412. }
  1413. DCHECK(response_body_stream_.is_valid());
  1414. DCHECK(consumer_handle_.is_valid());
  1415. // Do not account header bytes when reporting received body bytes to client.
  1416. reported_total_encoded_bytes_ = url_request_->GetTotalReceivedBytes();
  1417. if (upload_progress_tracker_) {
  1418. upload_progress_tracker_->OnUploadCompleted();
  1419. upload_progress_tracker_ = nullptr;
  1420. }
  1421. peer_closed_handle_watcher_.Watch(
  1422. response_body_stream_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
  1423. base::BindRepeating(&URLLoader::OnResponseBodyStreamConsumerClosed,
  1424. base::Unretained(this)));
  1425. peer_closed_handle_watcher_.ArmOrNotify();
  1426. writable_handle_watcher_.Watch(
  1427. response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
  1428. base::BindRepeating(&URLLoader::OnResponseBodyStreamReady,
  1429. base::Unretained(this)));
  1430. // Enforce the Cross-Origin-Resource-Policy (CORP) header.
  1431. const CrossOriginEmbedderPolicy kEmpty;
  1432. const CrossOriginEmbedderPolicy& cross_origin_embedder_policy =
  1433. factory_params_.client_security_state
  1434. ? factory_params_.client_security_state->cross_origin_embedder_policy
  1435. : kEmpty;
  1436. if (absl::optional<mojom::BlockedByResponseReason> blocked_reason =
  1437. CrossOriginResourcePolicy::IsBlocked(
  1438. url_request_->url(), url_request_->original_url(),
  1439. url_request_->initiator(), *response_, request_mode_,
  1440. request_destination_, cross_origin_embedder_policy,
  1441. coep_reporter_)) {
  1442. CompleteBlockedResponse(net::ERR_BLOCKED_BY_RESPONSE, false,
  1443. blocked_reason);
  1444. // Close the socket associated with the request, to prevent leaking
  1445. // information.
  1446. url_request_->AbortAndCloseConnection();
  1447. DeleteSelf();
  1448. return;
  1449. }
  1450. // Enforce FLEDGE auction-only signals -- the renderer process isn't allowed
  1451. // to read auction-only signals for FLEDGE auctions; only the browser process
  1452. // is allowed to read those, and only the browser process can issue trusted
  1453. // requests.
  1454. std::string fledge_auction_only_signals;
  1455. if (!factory_params_.is_trusted && response_->headers &&
  1456. response_->headers->GetNormalizedHeader("X-FLEDGE-Auction-Only",
  1457. &fledge_auction_only_signals) &&
  1458. base::EqualsCaseInsensitiveASCII(fledge_auction_only_signals, "true")) {
  1459. CompleteBlockedResponse(net::ERR_BLOCKED_BY_RESPONSE, false);
  1460. url_request_->AbortAndCloseConnection();
  1461. DeleteSelf();
  1462. return;
  1463. }
  1464. // Figure out if we need to sniff (for MIME type detection or for Cross-Origin
  1465. // Read Blocking / CORB).
  1466. if (factory_params_.is_corb_enabled) {
  1467. corb_analyzer_ = corb::ResponseAnalyzer::Create(per_factory_corb_state_);
  1468. auto decision =
  1469. corb_analyzer_->Init(url_request_->url(), url_request_->initiator(),
  1470. request_mode_, *response_);
  1471. switch (decision) {
  1472. case network::corb::ResponseAnalyzer::Decision::kBlock: {
  1473. bool should_report_corb_blocking =
  1474. corb_analyzer_->ShouldReportBlockedResponse();
  1475. corb_analyzer_.reset();
  1476. is_more_corb_sniffing_needed_ = false;
  1477. if (BlockResponseForCorb(should_report_corb_blocking) ==
  1478. kWillCancelRequest)
  1479. return;
  1480. break;
  1481. }
  1482. case network::corb::ResponseAnalyzer::Decision::kAllow:
  1483. corb_analyzer_.reset();
  1484. is_more_corb_sniffing_needed_ = false;
  1485. break;
  1486. case network::corb::ResponseAnalyzer::Decision::kSniffMore:
  1487. is_more_corb_sniffing_needed_ = true;
  1488. break;
  1489. }
  1490. }
  1491. if ((options_ & mojom::kURLLoadOptionSniffMimeType)) {
  1492. if (ShouldSniffContent(url_request_->url(), *response_)) {
  1493. // We're going to look at the data before deciding what the content type
  1494. // is. That means we need to delay sending the response started IPC.
  1495. VLOG(1) << "Will sniff content for mime type: " << url_request_->url();
  1496. is_more_mime_sniffing_needed_ = true;
  1497. } else if (response_->mime_type.empty()) {
  1498. // Ugg. The server told us not to sniff the content but didn't give us
  1499. // a mime type. What's a browser to do? Turns out, we're supposed to
  1500. // treat the response as "text/plain". This is the most secure option.
  1501. response_->mime_type.assign("text/plain");
  1502. }
  1503. }
  1504. StartReading();
  1505. }
  1506. void URLLoader::ReadMore() {
  1507. DCHECK(!read_in_progress_);
  1508. // Once the MIME type is sniffed, all data is sent as soon as it is read from
  1509. // the network.
  1510. DCHECK(consumer_handle_.is_valid() || !pending_write_);
  1511. if (should_pause_reading_body_) {
  1512. paused_reading_body_ = true;
  1513. return;
  1514. }
  1515. if (!pending_write_.get()) {
  1516. // TODO: we should use the abstractions in MojoAsyncResourceHandler.
  1517. DCHECK_EQ(0u, pending_write_buffer_offset_);
  1518. MojoResult result = NetToMojoPendingBuffer::BeginWrite(
  1519. &response_body_stream_, &pending_write_, &pending_write_buffer_size_);
  1520. if (result != MOJO_RESULT_OK && result != MOJO_RESULT_SHOULD_WAIT) {
  1521. // The response body stream is in a bad state. Bail.
  1522. NotifyCompleted(net::ERR_FAILED);
  1523. return;
  1524. }
  1525. DCHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()),
  1526. pending_write_buffer_size_);
  1527. if (consumer_handle_.is_valid()) {
  1528. DCHECK_GE(pending_write_buffer_size_,
  1529. static_cast<uint32_t>(net::kMaxBytesToSniff));
  1530. }
  1531. if (result == MOJO_RESULT_SHOULD_WAIT) {
  1532. // The pipe is full. We need to wait for it to have more space.
  1533. writable_handle_watcher_.ArmOrNotify();
  1534. return;
  1535. }
  1536. }
  1537. auto buf = base::MakeRefCounted<NetToMojoIOBuffer>(
  1538. pending_write_.get(), pending_write_buffer_offset_);
  1539. read_in_progress_ = true;
  1540. int bytes_read = url_request_->Read(
  1541. buf.get(), static_cast<int>(pending_write_buffer_size_ -
  1542. pending_write_buffer_offset_));
  1543. if (bytes_read != net::ERR_IO_PENDING) {
  1544. DidRead(bytes_read, true);
  1545. // |this| may have been deleted.
  1546. }
  1547. }
  1548. void URLLoader::DidRead(int num_bytes, bool completed_synchronously) {
  1549. DCHECK(read_in_progress_);
  1550. read_in_progress_ = false;
  1551. if (memory_cache_writer_ && pending_write_ && num_bytes > 0) {
  1552. if (!memory_cache_writer_->OnDataRead(
  1553. pending_write_->buffer() + pending_write_buffer_offset_,
  1554. num_bytes)) {
  1555. memory_cache_writer_.reset();
  1556. }
  1557. }
  1558. size_t new_data_offset = pending_write_buffer_offset_;
  1559. if (num_bytes > 0) {
  1560. pending_write_buffer_offset_ += num_bytes;
  1561. // Only notify client of download progress if we're done sniffing and
  1562. // started sending response.
  1563. if (!consumer_handle_.is_valid()) {
  1564. int64_t total_encoded_bytes = url_request_->GetTotalReceivedBytes();
  1565. int64_t delta = total_encoded_bytes - reported_total_encoded_bytes_;
  1566. DCHECK_LE(0, delta);
  1567. if (delta)
  1568. url_loader_client_.Get()->OnTransferSizeUpdated(delta);
  1569. reported_total_encoded_bytes_ = total_encoded_bytes;
  1570. }
  1571. }
  1572. if (update_body_read_before_paused_) {
  1573. update_body_read_before_paused_ = false;
  1574. body_read_before_paused_ = url_request_->GetRawBodyBytes();
  1575. }
  1576. bool complete_read = true;
  1577. if (consumer_handle_.is_valid()) {
  1578. // |pending_write_| may be null if the job self-aborts due to a suspend;
  1579. // this will have |consumer_handle_| valid when the loader is paused.
  1580. if (pending_write_) {
  1581. // Limit sniffing to the first net::kMaxBytesToSniff.
  1582. size_t data_length = pending_write_buffer_offset_;
  1583. if (data_length > net::kMaxBytesToSniff)
  1584. data_length = net::kMaxBytesToSniff;
  1585. base::StringPiece data(pending_write_->buffer(), data_length);
  1586. bool stop_sniffing_after_processing_current_data =
  1587. (num_bytes <= 0 ||
  1588. pending_write_buffer_offset_ >= net::kMaxBytesToSniff);
  1589. if (is_more_mime_sniffing_needed_) {
  1590. const std::string& type_hint = response_->mime_type;
  1591. std::string new_type;
  1592. is_more_mime_sniffing_needed_ = !net::SniffMimeType(
  1593. data, url_request_->url(), type_hint,
  1594. net::ForceSniffFileUrlsForHtml::kDisabled, &new_type);
  1595. // SniffMimeType() returns false if there is not enough data to
  1596. // determine the mime type. However, even if it returns false, it
  1597. // returns a new type that is probably better than the current one.
  1598. response_->mime_type.assign(new_type);
  1599. response_->did_mime_sniff = true;
  1600. if (stop_sniffing_after_processing_current_data)
  1601. is_more_mime_sniffing_needed_ = false;
  1602. }
  1603. if (is_more_corb_sniffing_needed_) {
  1604. corb::ResponseAnalyzer::Decision corb_decision =
  1605. corb::ResponseAnalyzer::Decision::kSniffMore;
  1606. // `has_new_data_to_sniff` can be false at the end-of-stream.
  1607. bool has_new_data_to_sniff = new_data_offset < data.length();
  1608. if (has_new_data_to_sniff)
  1609. corb_decision = corb_analyzer_->Sniff(data);
  1610. if (corb_decision == corb::ResponseAnalyzer::Decision::kSniffMore &&
  1611. stop_sniffing_after_processing_current_data) {
  1612. corb_decision = corb_analyzer_->HandleEndOfSniffableResponseBody();
  1613. DCHECK_NE(corb::ResponseAnalyzer::Decision::kSniffMore,
  1614. corb_decision);
  1615. }
  1616. switch (corb_decision) {
  1617. case network::corb::ResponseAnalyzer::Decision::kBlock: {
  1618. bool should_report_corb_blocking =
  1619. corb_analyzer_->ShouldReportBlockedResponse();
  1620. corb_analyzer_.reset();
  1621. is_more_corb_sniffing_needed_ = false;
  1622. if (BlockResponseForCorb(should_report_corb_blocking) ==
  1623. kWillCancelRequest)
  1624. return;
  1625. break;
  1626. }
  1627. case network::corb::ResponseAnalyzer::Decision::kAllow:
  1628. corb_analyzer_.reset();
  1629. is_more_corb_sniffing_needed_ = false;
  1630. break;
  1631. case network::corb::ResponseAnalyzer::Decision::kSniffMore:
  1632. break;
  1633. }
  1634. }
  1635. }
  1636. if (!is_more_mime_sniffing_needed_ && !is_more_corb_sniffing_needed_) {
  1637. SendResponseToClient();
  1638. } else {
  1639. complete_read = false;
  1640. }
  1641. }
  1642. if (num_bytes <= 0) {
  1643. // There may be no |pending_write_| if a URLRequestJob cancelled itself in
  1644. // URLRequestJob::OnSuspend() after receiving headers, while there was no
  1645. // pending read.
  1646. // TODO(mmenke): That case is rather unfortunate - something should be done
  1647. // at the socket layer instead, both to make for a better API (Only complete
  1648. // reads when there's a pending read), and to cover all TCP socket uses,
  1649. // since the concern is the effect that entering suspend mode has on
  1650. // sockets. See https://crbug.com/651120.
  1651. if (pending_write_)
  1652. CompletePendingWrite(num_bytes == 0);
  1653. NotifyCompleted(num_bytes);
  1654. // |this| will have been deleted.
  1655. return;
  1656. }
  1657. if (complete_read) {
  1658. CompletePendingWrite(true /* success */);
  1659. }
  1660. if (completed_synchronously) {
  1661. base::ThreadTaskRunnerHandle::Get()->PostTask(
  1662. FROM_HERE,
  1663. base::BindOnce(&URLLoader::ReadMore, weak_ptr_factory_.GetWeakPtr()));
  1664. } else {
  1665. ReadMore();
  1666. }
  1667. }
  1668. void URLLoader::OnReadCompleted(net::URLRequest* url_request, int bytes_read) {
  1669. DCHECK(url_request == url_request_.get());
  1670. DidRead(bytes_read, false);
  1671. // |this| may have been deleted.
  1672. }
  1673. int URLLoader::OnBeforeStartTransaction(
  1674. const net::HttpRequestHeaders& headers,
  1675. net::NetworkDelegate::OnBeforeStartTransactionCallback callback) {
  1676. if (header_client_) {
  1677. header_client_->OnBeforeSendHeaders(
  1678. headers,
  1679. base::BindOnce(&URLLoader::OnBeforeSendHeadersComplete,
  1680. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  1681. return net::ERR_IO_PENDING;
  1682. }
  1683. return net::OK;
  1684. }
  1685. int URLLoader::OnHeadersReceived(
  1686. net::CompletionOnceCallback callback,
  1687. const net::HttpResponseHeaders* original_response_headers,
  1688. scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
  1689. const net::IPEndPoint& endpoint,
  1690. absl::optional<GURL>* preserve_fragment_on_redirect_url) {
  1691. if (header_client_) {
  1692. header_client_->OnHeadersReceived(
  1693. original_response_headers->raw_headers(), endpoint,
  1694. base::BindOnce(&URLLoader::OnHeadersReceivedComplete,
  1695. weak_ptr_factory_.GetWeakPtr(), std::move(callback),
  1696. override_response_headers,
  1697. preserve_fragment_on_redirect_url));
  1698. return net::ERR_IO_PENDING;
  1699. }
  1700. return net::OK;
  1701. }
  1702. mojom::LoadInfoPtr URLLoader::CreateLoadInfo() {
  1703. auto load_info = mojom::LoadInfo::New();
  1704. load_info->timestamp = base::TimeTicks::Now();
  1705. load_info->host = url_request_->url().host();
  1706. auto load_state = url_request_->GetLoadState();
  1707. load_info->load_state = static_cast<uint32_t>(load_state.state);
  1708. load_info->state_param = std::move(load_state.param);
  1709. auto upload_progress = url_request_->GetUploadProgress();
  1710. load_info->upload_size = upload_progress.size();
  1711. load_info->upload_position = upload_progress.position();
  1712. return load_info;
  1713. }
  1714. net::LoadState URLLoader::GetLoadState() const {
  1715. return url_request_->GetLoadState().state;
  1716. }
  1717. net::UploadProgress URLLoader::GetUploadProgress() const {
  1718. return url_request_->GetUploadProgress();
  1719. }
  1720. int32_t URLLoader::GetProcessId() const {
  1721. return factory_params_.process_id;
  1722. }
  1723. void URLLoader::SetEnableReportingRawHeaders(bool allow) {
  1724. enable_reporting_raw_headers_ = allow;
  1725. }
  1726. uint32_t URLLoader::GetResourceType() const {
  1727. return resource_type_;
  1728. }
  1729. bool URLLoader::AllowCookies(
  1730. const GURL& url,
  1731. const net::SiteForCookies& site_for_cookies) const {
  1732. net::StaticCookiePolicy::Type policy =
  1733. net::StaticCookiePolicy::ALLOW_ALL_COOKIES;
  1734. if (options_ & mojom::kURLLoadOptionBlockAllCookies) {
  1735. policy = net::StaticCookiePolicy::BLOCK_ALL_COOKIES;
  1736. } else if (options_ & mojom::kURLLoadOptionBlockThirdPartyCookies) {
  1737. policy = net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES;
  1738. } else {
  1739. return true;
  1740. }
  1741. return net::StaticCookiePolicy(policy).CanAccessCookies(
  1742. url, site_for_cookies) == net::OK;
  1743. }
  1744. // static
  1745. URLLoader* URLLoader::ForRequest(const net::URLRequest& request) {
  1746. auto* pointer =
  1747. static_cast<UnownedPointer*>(request.GetUserData(kUserDataKey));
  1748. if (!pointer)
  1749. return nullptr;
  1750. return pointer->get();
  1751. }
  1752. // static
  1753. void URLLoader::LogConcerningRequestHeaders(
  1754. const net::HttpRequestHeaders& request_headers,
  1755. bool added_during_redirect) {
  1756. net::HttpRequestHeaders::Iterator it(request_headers);
  1757. bool concerning_header_found = false;
  1758. while (it.GetNext()) {
  1759. for (const auto& header : kConcerningHeaders) {
  1760. if (base::EqualsCaseInsensitiveASCII(header.name, it.name())) {
  1761. concerning_header_found = true;
  1762. if (added_during_redirect) {
  1763. UMA_HISTOGRAM_ENUMERATION(
  1764. "NetworkService.ConcerningRequestHeader.HeaderAddedOnRedirect",
  1765. header.histogram_id);
  1766. } else {
  1767. UMA_HISTOGRAM_ENUMERATION(
  1768. "NetworkService.ConcerningRequestHeader.HeaderPresentOnStart",
  1769. header.histogram_id);
  1770. }
  1771. }
  1772. }
  1773. }
  1774. if (added_during_redirect) {
  1775. UMA_HISTOGRAM_BOOLEAN(
  1776. "NetworkService.ConcerningRequestHeader.AddedOnRedirect",
  1777. concerning_header_found);
  1778. } else {
  1779. UMA_HISTOGRAM_BOOLEAN(
  1780. "NetworkService.ConcerningRequestHeader.PresentOnStart",
  1781. concerning_header_found);
  1782. }
  1783. }
  1784. void URLLoader::OnAuthCredentials(
  1785. const absl::optional<net::AuthCredentials>& credentials) {
  1786. auth_challenge_responder_receiver_.reset();
  1787. if (!credentials.has_value()) {
  1788. url_request_->CancelAuth();
  1789. } else {
  1790. // CancelAuth will proceed to the body, so cookies only need to be reported
  1791. // here.
  1792. ReportFlaggedResponseCookies();
  1793. url_request_->SetAuth(credentials.value());
  1794. }
  1795. }
  1796. void URLLoader::ContinueWithCertificate(
  1797. const scoped_refptr<net::X509Certificate>& x509_certificate,
  1798. const std::string& provider_name,
  1799. const std::vector<uint16_t>& algorithm_preferences,
  1800. mojo::PendingRemote<mojom::SSLPrivateKey> ssl_private_key) {
  1801. client_cert_responder_receiver_.reset();
  1802. auto key = base::MakeRefCounted<SSLPrivateKeyInternal>(
  1803. provider_name, algorithm_preferences, std::move(ssl_private_key));
  1804. url_request_->ContinueWithCertificate(std::move(x509_certificate),
  1805. std::move(key));
  1806. }
  1807. void URLLoader::ContinueWithoutCertificate() {
  1808. client_cert_responder_receiver_.reset();
  1809. url_request_->ContinueWithCertificate(nullptr, nullptr);
  1810. }
  1811. void URLLoader::CancelRequest() {
  1812. client_cert_responder_receiver_.reset();
  1813. url_request_->CancelWithError(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
  1814. }
  1815. void URLLoader::NotifyCompleted(int error_code) {
  1816. // Ensure sending the final upload progress message here, since
  1817. // OnResponseCompleted can be called without OnResponseStarted on cancellation
  1818. // or error cases.
  1819. if (upload_progress_tracker_) {
  1820. upload_progress_tracker_->OnUploadCompleted();
  1821. upload_progress_tracker_ = nullptr;
  1822. }
  1823. if (url_loader_network_observer_ &&
  1824. (url_request_->GetTotalReceivedBytes() > 0 ||
  1825. url_request_->GetTotalSentBytes() > 0)) {
  1826. url_loader_network_observer_->OnDataUseUpdate(
  1827. url_request_->traffic_annotation().unique_id_hash_code,
  1828. url_request_->GetTotalReceivedBytes(),
  1829. url_request_->GetTotalSentBytes());
  1830. }
  1831. if (url_loader_client_.Get()) {
  1832. if (consumer_handle_.is_valid())
  1833. SendResponseToClient();
  1834. URLLoaderCompletionStatus status;
  1835. status.error_code = error_code;
  1836. if (error_code == net::ERR_QUIC_PROTOCOL_ERROR) {
  1837. net::NetErrorDetails details;
  1838. url_request_->PopulateNetErrorDetails(&details);
  1839. status.extended_error_code = details.quic_connection_error;
  1840. } else if (error_code == net::ERR_INCONSISTENT_IP_ADDRESS_SPACE) {
  1841. // The error code is only used internally, translate it into a CORS error.
  1842. DCHECK(cors_error_status_.has_value());
  1843. status.error_code = net::ERR_FAILED;
  1844. }
  1845. status.exists_in_cache = url_request_->response_info().was_cached;
  1846. status.completion_time = base::TimeTicks::Now();
  1847. status.encoded_data_length = url_request_->GetTotalReceivedBytes();
  1848. status.encoded_body_length = url_request_->GetRawBodyBytes();
  1849. status.decoded_body_length = total_written_bytes_;
  1850. status.proxy_server = url_request_->proxy_server();
  1851. status.resolve_error_info =
  1852. url_request_->response_info().resolve_error_info;
  1853. if (trust_token_status_)
  1854. status.trust_token_operation_status = *trust_token_status_;
  1855. status.cors_error_status = cors_error_status_;
  1856. if ((options_ & mojom::kURLLoadOptionSendSSLInfoForCertificateError) &&
  1857. net::IsCertStatusError(url_request_->ssl_info().cert_status)) {
  1858. status.ssl_info = url_request_->ssl_info();
  1859. }
  1860. status.pervasive_payload_requested = pervasive_payload_requested_;
  1861. if (memory_cache_writer_)
  1862. memory_cache_writer_->OnCompleted(status);
  1863. url_loader_client_.Get()->OnComplete(status);
  1864. }
  1865. DeleteSelf();
  1866. }
  1867. void URLLoader::OnMojoDisconnect() {
  1868. NotifyCompleted(net::ERR_FAILED);
  1869. }
  1870. void URLLoader::OnResponseBodyStreamConsumerClosed(MojoResult result) {
  1871. NotifyCompleted(net::ERR_FAILED);
  1872. }
  1873. void URLLoader::OnResponseBodyStreamReady(MojoResult result) {
  1874. if (result != MOJO_RESULT_OK) {
  1875. NotifyCompleted(net::ERR_FAILED);
  1876. return;
  1877. }
  1878. ReadMore();
  1879. }
  1880. void URLLoader::DeleteSelf() {
  1881. std::move(delete_callback_).Run(this);
  1882. }
  1883. void URLLoader::SendResponseToClient() {
  1884. TRACE_EVENT("loading", "network::URLLoader::SendResponseToClient",
  1885. perfetto::Flow::FromPointer(this), "url", url_request_->url());
  1886. DCHECK_EQ(emitted_devtools_raw_request_, emitted_devtools_raw_response_);
  1887. response_->emitted_extra_info = emitted_devtools_raw_request_;
  1888. url_loader_client_.Get()->OnReceiveResponse(response_->Clone(),
  1889. std::move(consumer_handle_));
  1890. }
  1891. void URLLoader::CompletePendingWrite(bool success) {
  1892. if (success) {
  1893. // The write can only be completed immediately in case of a success, since
  1894. // doing so invalidates memory of any attached NetToMojoIOBuffer's; but in
  1895. // case of an abort, particularly one caused by a suspend, the failure may
  1896. // be delivered to URLLoader while the disk_cache layer is still hanging on
  1897. // to the now-invalid IOBuffer in some worker thread trying to commit it to
  1898. // disk. In case of an error, this will have to wait till everything is
  1899. // destroyed.
  1900. response_body_stream_ =
  1901. pending_write_->Complete(pending_write_buffer_offset_);
  1902. }
  1903. total_written_bytes_ += pending_write_buffer_offset_;
  1904. pending_write_ = nullptr;
  1905. pending_write_buffer_offset_ = 0;
  1906. }
  1907. void URLLoader::SetRawResponseHeaders(
  1908. scoped_refptr<const net::HttpResponseHeaders> headers) {
  1909. raw_response_headers_ = headers;
  1910. }
  1911. void URLLoader::NotifyEarlyResponse(
  1912. scoped_refptr<const net::HttpResponseHeaders> headers) {
  1913. DCHECK(!has_received_response_);
  1914. DCHECK(url_loader_client_.Get());
  1915. DCHECK(headers);
  1916. DCHECK_EQ(headers->response_code(), 103);
  1917. // Calculate IP address space.
  1918. mojom::ParsedHeadersPtr parsed_headers =
  1919. PopulateParsedHeaders(headers.get(), url_request_->url());
  1920. std::vector<GURL> url_list_via_service_worker;
  1921. net::IPEndPoint transaction_endpoint;
  1922. bool has_endpoint =
  1923. url_request_->GetTransactionRemoteEndpoint(&transaction_endpoint);
  1924. DCHECK(has_endpoint);
  1925. CalculateClientAddressSpaceParams params(
  1926. url_list_via_service_worker, parsed_headers, transaction_endpoint);
  1927. mojom::IPAddressSpace ip_address_space =
  1928. CalculateClientAddressSpace(url_request_->url(), params);
  1929. mojom::ReferrerPolicy referrer_policy = ParseReferrerPolicy(*headers);
  1930. url_loader_client_.Get()->OnReceiveEarlyHints(mojom::EarlyHints::New(
  1931. std::move(parsed_headers), referrer_policy, ip_address_space));
  1932. }
  1933. void URLLoader::SetRawRequestHeadersAndNotify(
  1934. net::HttpRawRequestHeaders headers) {
  1935. // If we have seen_raw_request_headers_, then don't notify DevTools to prevent
  1936. // duplicate ExtraInfo events.
  1937. if (!seen_raw_request_headers_ && devtools_observer_ &&
  1938. devtools_request_id()) {
  1939. std::vector<network::mojom::HttpRawHeaderPairPtr> header_array;
  1940. header_array.reserve(headers.headers().size());
  1941. for (const auto& header : headers.headers()) {
  1942. network::mojom::HttpRawHeaderPairPtr pair =
  1943. network::mojom::HttpRawHeaderPair::New();
  1944. pair->key = header.first;
  1945. pair->value = header.second;
  1946. header_array.push_back(std::move(pair));
  1947. }
  1948. DispatchOnRawRequest(std::move(header_array));
  1949. }
  1950. if (cookie_observer_) {
  1951. std::vector<mojom::CookieOrLineWithAccessResultPtr> reported_cookies;
  1952. for (const auto& cookie_with_access_result :
  1953. url_request_->maybe_sent_cookies()) {
  1954. if (ShouldNotifyAboutCookie(
  1955. cookie_with_access_result.access_result.status)) {
  1956. reported_cookies.push_back(mojom::CookieOrLineWithAccessResult::New(
  1957. mojom::CookieOrLine::NewCookie(cookie_with_access_result.cookie),
  1958. cookie_with_access_result.access_result));
  1959. }
  1960. }
  1961. if (!reported_cookies.empty()) {
  1962. cookie_observer_->OnCookiesAccessed(mojom::CookieAccessDetails::New(
  1963. mojom::CookieAccessDetails::Type::kRead, url_request_->url(),
  1964. url_request_->site_for_cookies(), std::move(reported_cookies),
  1965. devtools_request_id()));
  1966. }
  1967. }
  1968. }
  1969. void URLLoader::DispatchOnRawRequest(
  1970. std::vector<network::mojom::HttpRawHeaderPairPtr> headers) {
  1971. DCHECK(devtools_observer_ && devtools_request_id());
  1972. seen_raw_request_headers_ = true;
  1973. net::LoadTimingInfo load_timing_info;
  1974. url_request_->GetLoadTimingInfo(&load_timing_info);
  1975. emitted_devtools_raw_request_ = true;
  1976. devtools_observer_->OnRawRequest(
  1977. devtools_request_id().value(), url_request_->maybe_sent_cookies(),
  1978. std::move(headers), load_timing_info.request_start,
  1979. private_network_access_checker_.CloneClientSecurityState());
  1980. }
  1981. bool URLLoader::DispatchOnRawResponse() {
  1982. if (!devtools_observer_ || !devtools_request_id() ||
  1983. !url_request_->response_headers()) {
  1984. return false;
  1985. }
  1986. std::vector<network::mojom::HttpRawHeaderPairPtr> header_array;
  1987. // This is gated by enable_reporting_raw_headers_ to be backwards compatible
  1988. // with the old report_raw_headers behavior, where we wouldn't even send
  1989. // raw_response_headers_ to the trusted browser process based devtools
  1990. // instrumentation. This is observed in the case of HSTS redirects, where
  1991. // url_request_->response_headers has the HSTS redirect headers, like
  1992. // Non-Authoritative-Reason, but raw_response_headers_ has something else
  1993. // which doesn't include HSTS information. This is tested by
  1994. // DevToolsTest.TestRawHeadersWithRedirectAndHSTS.
  1995. // TODO(crbug.com/1234823): Remove enable_reporting_raw_headers_
  1996. const net::HttpResponseHeaders* response_headers =
  1997. raw_response_headers_ && enable_reporting_raw_headers_
  1998. ? raw_response_headers_.get()
  1999. : url_request_->response_headers();
  2000. size_t iterator = 0;
  2001. std::string name, value;
  2002. while (response_headers->EnumerateHeaderLines(&iterator, &name, &value)) {
  2003. network::mojom::HttpRawHeaderPairPtr pair =
  2004. network::mojom::HttpRawHeaderPair::New();
  2005. pair->key = name;
  2006. pair->value = value;
  2007. header_array.push_back(std::move(pair));
  2008. }
  2009. // Only send the "raw" header text when the headers were actually send in
  2010. // text form (i.e. not QUIC or SPDY)
  2011. absl::optional<std::string> raw_response_headers;
  2012. const net::HttpResponseInfo& response_info = url_request_->response_info();
  2013. if (!response_info.DidUseQuic() && !response_info.was_fetched_via_spdy) {
  2014. raw_response_headers =
  2015. absl::make_optional(net::HttpUtil::ConvertHeadersBackToHTTPResponse(
  2016. response_headers->raw_headers()));
  2017. }
  2018. if (!seen_raw_request_headers_) {
  2019. // If we send OnRawResponse(), make sure we send OnRawRequest() event if
  2020. // we haven't had the callback from net, to make the client life easier.
  2021. DispatchOnRawRequest({});
  2022. }
  2023. emitted_devtools_raw_response_ = true;
  2024. devtools_observer_->OnRawResponse(
  2025. devtools_request_id().value(), url_request_->maybe_stored_cookies(),
  2026. std::move(header_array), raw_response_headers,
  2027. private_network_access_checker_.ResponseAddressSpace().value_or(
  2028. mojom::IPAddressSpace::kUnknown),
  2029. response_headers->response_code());
  2030. return true;
  2031. }
  2032. void URLLoader::SendUploadProgress(const net::UploadProgress& progress) {
  2033. url_loader_client_.Get()->OnUploadProgress(
  2034. progress.position(), progress.size(),
  2035. base::BindOnce(&URLLoader::OnUploadProgressACK,
  2036. weak_ptr_factory_.GetWeakPtr()));
  2037. }
  2038. void URLLoader::OnUploadProgressACK() {
  2039. if (upload_progress_tracker_)
  2040. upload_progress_tracker_->OnAckReceived();
  2041. }
  2042. void URLLoader::OnSSLCertificateErrorResponse(const net::SSLInfo& ssl_info,
  2043. int net_error) {
  2044. if (net_error == net::OK) {
  2045. url_request_->ContinueDespiteLastError();
  2046. return;
  2047. }
  2048. url_request_->CancelWithSSLError(net_error, ssl_info);
  2049. }
  2050. bool URLLoader::HasDataPipe() const {
  2051. return pending_write_ || response_body_stream_.is_valid();
  2052. }
  2053. void URLLoader::RecordBodyReadFromNetBeforePausedIfNeeded() {
  2054. if (update_body_read_before_paused_)
  2055. body_read_before_paused_ = url_request_->GetRawBodyBytes();
  2056. if (body_read_before_paused_ != -1) {
  2057. if (!url_request_->was_cached()) {
  2058. UMA_HISTOGRAM_COUNTS_1M("Network.URLLoader.BodyReadFromNetBeforePaused",
  2059. body_read_before_paused_);
  2060. } else {
  2061. DVLOG(1) << "The request has been paused, but "
  2062. << "Network.URLLoader.BodyReadFromNetBeforePaused is not "
  2063. << "reported because the response body may be from cache. "
  2064. << "body_read_before_paused_: " << body_read_before_paused_;
  2065. }
  2066. }
  2067. }
  2068. void URLLoader::ResumeStart() {
  2069. url_request_->LogUnblocked();
  2070. url_request_->Start();
  2071. }
  2072. void URLLoader::OnBeforeSendHeadersComplete(
  2073. net::NetworkDelegate::OnBeforeStartTransactionCallback callback,
  2074. int result,
  2075. const absl::optional<net::HttpRequestHeaders>& headers) {
  2076. std::move(callback).Run(result, headers);
  2077. }
  2078. void URLLoader::OnHeadersReceivedComplete(
  2079. net::CompletionOnceCallback callback,
  2080. scoped_refptr<net::HttpResponseHeaders>* out_headers,
  2081. absl::optional<GURL>* out_preserve_fragment_on_redirect_url,
  2082. int result,
  2083. const absl::optional<std::string>& headers,
  2084. const absl::optional<GURL>& preserve_fragment_on_redirect_url) {
  2085. if (headers) {
  2086. *out_headers =
  2087. base::MakeRefCounted<net::HttpResponseHeaders>(headers.value());
  2088. }
  2089. *out_preserve_fragment_on_redirect_url = preserve_fragment_on_redirect_url;
  2090. std::move(callback).Run(result);
  2091. }
  2092. void URLLoader::CompleteBlockedResponse(
  2093. int error_code,
  2094. bool should_report_corb_blocking,
  2095. absl::optional<mojom::BlockedByResponseReason> reason) {
  2096. if (has_received_response_) {
  2097. // The response headers and body shouldn't yet be sent to the
  2098. // URLLoaderClient.
  2099. DCHECK(response_);
  2100. DCHECK(consumer_handle_.is_valid());
  2101. }
  2102. // Tell the URLLoaderClient that the response has been completed.
  2103. URLLoaderCompletionStatus status;
  2104. status.error_code = error_code;
  2105. status.completion_time = base::TimeTicks::Now();
  2106. status.encoded_data_length = 0;
  2107. status.encoded_body_length = 0;
  2108. status.decoded_body_length = 0;
  2109. status.should_report_corb_blocking = should_report_corb_blocking;
  2110. status.blocked_by_response_reason = reason;
  2111. if (memory_cache_writer_)
  2112. memory_cache_writer_->OnCompleted(status);
  2113. url_loader_client_.Get()->OnComplete(status);
  2114. // Reset the connection to the URLLoaderClient. This helps ensure that we
  2115. // won't accidentally leak any data to the renderer from this point on.
  2116. url_loader_client_.Reset();
  2117. memory_cache_writer_.reset();
  2118. }
  2119. URLLoader::BlockResponseForCorbResult URLLoader::BlockResponseForCorb(
  2120. bool should_report_corb_blocking) {
  2121. // CORB should only do work after the response headers have been received.
  2122. DCHECK(has_received_response_);
  2123. // The response headers and body shouldn't yet be sent to the URLLoaderClient.
  2124. DCHECK(response_);
  2125. DCHECK(consumer_handle_.is_valid());
  2126. // Send stripped headers to the real URLLoaderClient.
  2127. corb::SanitizeBlockedResponseHeaders(*response_);
  2128. // Send empty body to the real URLLoaderClient.
  2129. mojo::ScopedDataPipeProducerHandle producer_handle;
  2130. mojo::ScopedDataPipeConsumerHandle consumer_handle;
  2131. MojoResult result = mojo::CreateDataPipe(kBlockedBodyAllocationSize,
  2132. producer_handle, consumer_handle);
  2133. if (result != MOJO_RESULT_OK) {
  2134. NotifyCompleted(net::ERR_INSUFFICIENT_RESOURCES);
  2135. return kWillCancelRequest;
  2136. }
  2137. producer_handle.reset();
  2138. url_loader_client_.Get()->OnReceiveResponse(response_->Clone(),
  2139. std::move(consumer_handle));
  2140. // Tell the real URLLoaderClient that the response has been completed.
  2141. if (corb_detachable_) {
  2142. // TODO(lukasza): https://crbug.com/827633#c5: Consider passing net::ERR_OK
  2143. // instead. net::ERR_ABORTED was chosen for consistency with the old CORB
  2144. // implementation that used to go through DetachableResourceHandler.
  2145. CompleteBlockedResponse(net::ERR_ABORTED, should_report_corb_blocking);
  2146. } else {
  2147. // CORB responses are reported as a success.
  2148. CompleteBlockedResponse(net::OK, should_report_corb_blocking);
  2149. }
  2150. // If the factory is asking to complete requests of this type, then we need to
  2151. // continue processing the response to make sure the network cache is
  2152. // populated. Otherwise we can cancel the request.
  2153. if (corb_detachable_) {
  2154. // Discard any remaining callbacks or data by rerouting the pipes to
  2155. // EmptyURLLoaderClient.
  2156. receiver_.reset();
  2157. EmptyURLLoaderClientWrapper::DrainURLRequest(
  2158. url_loader_client_.BindNewPipeAndPassReceiver(),
  2159. receiver_.BindNewPipeAndPassRemote());
  2160. receiver_.set_disconnect_handler(
  2161. base::BindOnce(&URLLoader::OnMojoDisconnect, base::Unretained(this)));
  2162. // Ask the caller to continue processing the request.
  2163. return kContinueRequest;
  2164. }
  2165. // Close the socket associated with the request, to prevent leaking
  2166. // information.
  2167. url_request_->AbortAndCloseConnection();
  2168. // Delete self and cancel the request - the caller doesn't need to continue.
  2169. //
  2170. // DeleteSelf is posted asynchronously, to make sure that the callers (e.g.
  2171. // URLLoader::OnResponseStarted and/or URLLoader::DidRead instance methods)
  2172. // can still safely dereference |this|.
  2173. base::ThreadTaskRunnerHandle::Get()->PostTask(
  2174. FROM_HERE,
  2175. base::BindOnce(&URLLoader::DeleteSelf, weak_ptr_factory_.GetWeakPtr()));
  2176. return kWillCancelRequest;
  2177. }
  2178. void URLLoader::ReportFlaggedResponseCookies() {
  2179. if (cookie_observer_) {
  2180. std::vector<mojom::CookieOrLineWithAccessResultPtr> reported_cookies;
  2181. for (const auto& cookie_line_and_access_result :
  2182. url_request_->maybe_stored_cookies()) {
  2183. if (ShouldNotifyAboutCookie(
  2184. cookie_line_and_access_result.access_result.status)) {
  2185. mojom::CookieOrLinePtr cookie_or_line;
  2186. if (cookie_line_and_access_result.cookie.has_value()) {
  2187. cookie_or_line = mojom::CookieOrLine::NewCookie(
  2188. cookie_line_and_access_result.cookie.value());
  2189. } else {
  2190. cookie_or_line = mojom::CookieOrLine::NewCookieString(
  2191. cookie_line_and_access_result.cookie_string);
  2192. }
  2193. reported_cookies.push_back(mojom::CookieOrLineWithAccessResult::New(
  2194. std::move(cookie_or_line),
  2195. cookie_line_and_access_result.access_result));
  2196. }
  2197. }
  2198. if (!reported_cookies.empty()) {
  2199. cookie_observer_->OnCookiesAccessed(mojom::CookieAccessDetails::New(
  2200. mojom::CookieAccessDetails::Type::kChange, url_request_->url(),
  2201. url_request_->site_for_cookies(), std::move(reported_cookies),
  2202. devtools_request_id()));
  2203. }
  2204. }
  2205. }
  2206. void URLLoader::StartReading() {
  2207. if (!is_more_mime_sniffing_needed_ && !is_more_corb_sniffing_needed_) {
  2208. // Treat feed types as text/plain.
  2209. if (response_->mime_type == "application/rss+xml" ||
  2210. response_->mime_type == "application/atom+xml") {
  2211. response_->mime_type.assign("text/plain");
  2212. }
  2213. SendResponseToClient();
  2214. }
  2215. // Start reading...
  2216. ReadMore();
  2217. }
  2218. bool URLLoader::ShouldForceIgnoreSiteForCookies(
  2219. const ResourceRequest& request) {
  2220. // Ignore site for cookies in requests from an initiator covered by the
  2221. // same-origin-policy exclusions in `origin_access_list_` (typically requests
  2222. // initiated by Chrome Extensions).
  2223. if (request.request_initiator.has_value() &&
  2224. cors::OriginAccessList::AccessState::kAllowed ==
  2225. origin_access_list_.CheckAccessState(
  2226. request.request_initiator.value(), request.url)) {
  2227. return true;
  2228. }
  2229. // Convert `site_for_cookies` into an origin (an opaque origin if
  2230. // `net::SiteForCookies::IsNull()` returns true).
  2231. //
  2232. // Note that `site_for_cookies` is a _site_ rather than an _origin_, but for
  2233. // Chrome Extensions the _site_ and _origin_ of a host are the same extension
  2234. // id. Thanks to this, for Chrome Extensions, we can pass a _site_ into
  2235. // OriginAccessChecks (which normally expect an _origin_).
  2236. url::Origin site_origin =
  2237. url::Origin::Create(request.site_for_cookies.RepresentativeUrl());
  2238. // If `site_for_cookies` represents an origin that is granted access to the
  2239. // initiator and the target by `origin_access_list_` (typically such
  2240. // `site_for_cookies` represents a Chrome Extension), then we also should
  2241. // force ignoring of site for cookies if the initiator and the target are
  2242. // same-site.
  2243. //
  2244. // Ideally we would walk up the frame tree and check that each ancestor is
  2245. // first-party to the main frame (treating the `origin_access_list_`
  2246. // exceptions as "first-party"). But walking up the tree is not possible in
  2247. // //services/network and so we make do with just checking the direct
  2248. // initiator of the request.
  2249. //
  2250. // We also check same-siteness between the initiator and the requested URL,
  2251. // because setting `force_ignore_site_for_cookies` to true causes Strict
  2252. // cookies to be attached, and having the initiator be same-site to the
  2253. // request URL is a requirement for Strict cookies (see
  2254. // net::cookie_util::ComputeSameSiteContext).
  2255. if (!site_origin.opaque() && request.request_initiator.has_value()) {
  2256. bool site_can_access_target =
  2257. cors::OriginAccessList::AccessState::kAllowed ==
  2258. origin_access_list_.CheckAccessState(site_origin, request.url);
  2259. bool site_can_access_initiator =
  2260. cors::OriginAccessList::AccessState::kAllowed ==
  2261. origin_access_list_.CheckAccessState(
  2262. site_origin, request.request_initiator->GetURL());
  2263. net::SiteForCookies site_of_initiator =
  2264. net::SiteForCookies::FromOrigin(request.request_initiator.value());
  2265. bool are_initiator_and_target_same_site =
  2266. site_of_initiator.IsFirstParty(request.url);
  2267. if (site_can_access_initiator && site_can_access_target &&
  2268. are_initiator_and_target_same_site) {
  2269. return true;
  2270. }
  2271. }
  2272. return false;
  2273. }
  2274. bool URLLoader::ShouldForceIgnoreTopFramePartyForCookies() const {
  2275. const net::IsolationInfo& isolation_info = url_request_->isolation_info();
  2276. const absl::optional<url::Origin>& top_frame_origin =
  2277. isolation_info.top_frame_origin();
  2278. if (!top_frame_origin || top_frame_origin->opaque())
  2279. return false;
  2280. const absl::optional<std::set<net::SchemefulSite>>& party_context =
  2281. isolation_info.party_context();
  2282. if (!party_context)
  2283. return false;
  2284. // The top frame origin must have access to the request URL.
  2285. if (cors::OriginAccessList::AccessState::kAllowed !=
  2286. origin_access_list_.CheckAccessState(*top_frame_origin,
  2287. url_request_->url())) {
  2288. return false;
  2289. }
  2290. // The top frame origin must have access to each site in the party_context.
  2291. return base::ranges::all_of(
  2292. *party_context,
  2293. [this, &top_frame_origin](const net::SchemefulSite& site) {
  2294. return origin_access_list_.CheckAccessState(*top_frame_origin,
  2295. site.GetURL()) ==
  2296. cors::OriginAccessList::AccessState::kAllowed;
  2297. });
  2298. }
  2299. void URLLoader::SetRequestCredentials(const GURL& url) {
  2300. bool coep_allow_credentials = CoepAllowCredentials(url);
  2301. bool allow_credentials = ShouldAllowCredentials(request_credentials_mode_) &&
  2302. coep_allow_credentials;
  2303. bool allow_client_certificates =
  2304. ShouldSendClientCertificates(request_credentials_mode_) &&
  2305. coep_allow_credentials;
  2306. // The decision not to include credentials is sticky. This is equivalent to
  2307. // checking the tainted origin flag in the fetch specification.
  2308. if (!allow_credentials)
  2309. url_request_->set_allow_credentials(false);
  2310. if (!allow_client_certificates)
  2311. url_request_->set_send_client_certs(false);
  2312. // Contrary to Firefox or blink's cache, the HTTP cache doesn't distinguish
  2313. // requests including user's credentials from the anonymous ones yet. See
  2314. // https://docs.google.com/document/d/1lvbiy4n-GM5I56Ncw304sgvY5Td32R6KHitjRXvkZ6U
  2315. // As a workaround until a solution is implemented, the cached responses
  2316. // aren't used for those requests.
  2317. if (!coep_allow_credentials) {
  2318. url_request_->SetLoadFlags(url_request_->load_flags() |
  2319. net::LOAD_BYPASS_CACHE);
  2320. }
  2321. }
  2322. // [spec]:
  2323. // https://fetch.spec.whatwg.org/#cross-origin-embedder-policy-allows-credentials
  2324. bool URLLoader::CoepAllowCredentials(const GURL& url) {
  2325. // [spec]: To check if Cross-Origin-Embedder-Policy allows credentials, given
  2326. // a request request, run these steps:
  2327. // [spec] 1. If request’s mode is not "no-cors", then return true.
  2328. switch (request_mode_) {
  2329. case mojom::RequestMode::kCors:
  2330. case mojom::RequestMode::kCorsWithForcedPreflight:
  2331. case mojom::RequestMode::kNavigate:
  2332. case mojom::RequestMode::kSameOrigin:
  2333. return true;
  2334. case mojom::RequestMode::kNoCors:
  2335. break;
  2336. }
  2337. // [spec]: 2. If request’s client is null, then return true.
  2338. if (!factory_params_.client_security_state)
  2339. return true;
  2340. // [spec]: 3. If request’s client’s policy container’s embedder policy’s value
  2341. // is not "credentialless", then return true.
  2342. if (factory_params_.client_security_state->cross_origin_embedder_policy
  2343. .value != mojom::CrossOriginEmbedderPolicyValue::kCredentialless) {
  2344. return true;
  2345. }
  2346. // [spec]: 4. If request’s origin is same origin with request’s current URL’s
  2347. // origin and request does not have a redirect-tainted origin, then
  2348. // return true.
  2349. url::Origin request_initiator =
  2350. url_request_->initiator().value_or(url::Origin());
  2351. if (request_initiator.IsSameOriginWith(url))
  2352. return true;
  2353. // [spec]: 5. Return false.
  2354. return false;
  2355. }
  2356. bool URLLoader::ThirdPartyCookiesEnabled() const {
  2357. return third_party_cookies_enabled_ &&
  2358. !(options_ & (mojom::kURLLoadOptionBlockThirdPartyCookies |
  2359. mojom::kURLLoadOptionBlockAllCookies));
  2360. }
  2361. } // namespace network