No bug - tagging b4d3227540c9ebc43d64aac6168fdca7019c22d8 with FIREFOX_BETA_126_BASE...
[gecko.git] / layout / style / FontLoaderUtils.cpp
blob9690e703fd8e0233d9e9a47c5a2fb452d2882122
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/FontLoaderUtils.h"
9 #include "mozilla/dom/Document.h"
10 #include "mozilla/dom/ReferrerInfo.h"
11 #include "mozilla/dom/WorkerPrivate.h"
12 #include "gfxUserFontSet.h"
13 #include "nsCOMPtr.h"
14 #include "nsIChannel.h"
15 #include "nsIClassOfService.h"
16 #include "nsIContentPolicy.h"
17 #include "nsIHttpChannel.h"
18 #include "nsILoadInfo.h"
19 #include "nsIReferrerInfo.h"
20 #include "nsISupportsPriority.h"
21 #include "nsIURI.h"
22 #include "nsNetUtil.h"
24 namespace mozilla {
26 /* static */ void FontLoaderUtils::BuildChannelFlags(
27 nsIURI* aURI, bool aIsPreload,
28 nsContentSecurityManager::CORSSecurityMapping& aCorsMapping,
29 nsSecurityFlags& aSecurityFlags, nsContentPolicyType& aContentPolicyType) {
30 // aCORSMode is ignored. We always load as crossorigin=anonymous, but a
31 // preload started with anything other then "anonymous" will never be found.
32 aCorsMapping =
33 aURI->SchemeIs("file")
34 ? nsContentSecurityManager::CORSSecurityMapping::
35 CORS_NONE_MAPS_TO_INHERITED_CONTEXT
36 : nsContentSecurityManager::CORSSecurityMapping::REQUIRE_CORS_CHECKS;
38 aSecurityFlags = nsContentSecurityManager::ComputeSecurityFlags(
39 CORSMode::CORS_NONE, aCorsMapping);
41 aContentPolicyType = aIsPreload ? nsIContentPolicy::TYPE_INTERNAL_FONT_PRELOAD
42 : nsIContentPolicy::TYPE_FONT;
45 /* static */ nsresult FontLoaderUtils::BuildChannelSetup(
46 nsIChannel* aChannel, nsIHttpChannel* aHttpChannel,
47 nsIReferrerInfo* aReferrerInfo, const gfxFontFaceSrc* aFontFaceSrc,
48 int32_t aSupportsPriorityValue) {
49 if (aHttpChannel) {
50 nsresult rv = aHttpChannel->SetRequestHeader(
51 "Accept"_ns,
52 "application/font-woff2;q=1.0,application/font-woff;q=0.9,*/*;q=0.8"_ns,
53 false);
54 NS_ENSURE_SUCCESS(rv, rv);
56 if (aReferrerInfo) {
57 rv = aHttpChannel->SetReferrerInfoWithoutClone(aReferrerInfo);
58 MOZ_ASSERT(NS_SUCCEEDED(rv));
59 } else {
60 MOZ_ASSERT(aFontFaceSrc);
62 rv = aHttpChannel->SetReferrerInfo(aFontFaceSrc->mReferrerInfo);
63 Unused << NS_WARN_IF(NS_FAILED(rv));
65 // For WOFF and WOFF2, we should tell servers/proxies/etc NOT to try
66 // and apply additional compression at the content-encoding layer
67 if (aFontFaceSrc->mFormatHint == StyleFontFaceSourceFormatKeyword::Woff ||
68 aFontFaceSrc->mFormatHint ==
69 StyleFontFaceSourceFormatKeyword::Woff2) {
70 rv = aHttpChannel->SetRequestHeader("Accept-Encoding"_ns, "identity"_ns,
71 false);
72 NS_ENSURE_SUCCESS(rv, rv);
77 nsCOMPtr<nsISupportsPriority> priorityChannel(do_QueryInterface(aChannel));
78 if (priorityChannel) {
79 priorityChannel->SetPriority(aSupportsPriorityValue);
81 nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(aChannel));
82 if (cos) {
83 cos->AddClassFlags(nsIClassOfService::TailForbidden);
86 return NS_OK;
89 // static
90 nsresult FontLoaderUtils::BuildChannel(
91 nsIChannel** aChannel, nsIURI* aURI, const CORSMode aCORSMode,
92 const dom::ReferrerPolicy& aReferrerPolicy,
93 gfxUserFontEntry* aUserFontEntry, const gfxFontFaceSrc* aFontFaceSrc,
94 dom::Document* aDocument, nsILoadGroup* aLoadGroup,
95 nsIInterfaceRequestor* aCallbacks, bool aIsPreload,
96 int32_t aSupportsPriorityValue) {
97 nsresult rv;
99 nsIPrincipal* principal =
100 aUserFontEntry ? (aUserFontEntry->GetPrincipal()
101 ? aUserFontEntry->GetPrincipal()->NodePrincipal()
102 : nullptr)
103 : aDocument->NodePrincipal();
105 nsContentSecurityManager::CORSSecurityMapping corsMapping;
106 nsSecurityFlags securityFlags;
107 nsContentPolicyType contentPolicyType;
108 BuildChannelFlags(aURI, aIsPreload, corsMapping, securityFlags,
109 contentPolicyType);
111 nsCOMPtr<nsIChannel> channel;
112 // Note we are calling NS_NewChannelWithTriggeringPrincipal() with both a
113 // node and a principal. This is because the document where the font is
114 // being loaded might have a different origin from the principal of the
115 // stylesheet that initiated the font load.
116 rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel), aURI,
117 aDocument, principal, securityFlags,
118 contentPolicyType,
119 nullptr, // PerformanceStorage
120 aLoadGroup);
121 NS_ENSURE_SUCCESS(rv, rv);
123 nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
124 nsCOMPtr<nsIReferrerInfo> referrerInfo;
125 if (httpChannel && !aFontFaceSrc) {
126 referrerInfo = new dom::ReferrerInfo(aDocument->GetDocumentURIAsReferrer(),
127 aReferrerPolicy);
128 rv = httpChannel->SetReferrerInfoWithoutClone(referrerInfo);
129 MOZ_ASSERT(NS_SUCCEEDED(rv));
132 rv = BuildChannelSetup(channel, httpChannel, referrerInfo, aFontFaceSrc,
133 aSupportsPriorityValue);
134 NS_ENSURE_SUCCESS(rv, rv);
136 channel.forget(aChannel);
137 return NS_OK;
140 // static
141 nsresult FontLoaderUtils::BuildChannel(
142 nsIChannel** aChannel, nsIURI* aURI, const CORSMode aCORSMode,
143 const dom::ReferrerPolicy& aReferrerPolicy,
144 gfxUserFontEntry* aUserFontEntry, const gfxFontFaceSrc* aFontFaceSrc,
145 dom::WorkerPrivate* aWorkerPrivate, nsILoadGroup* aLoadGroup,
146 nsIInterfaceRequestor* aCallbacks) {
147 nsresult rv;
149 nsIPrincipal* principal =
150 aUserFontEntry ? (aUserFontEntry->GetPrincipal()
151 ? aUserFontEntry->GetPrincipal()->NodePrincipal()
152 : nullptr)
153 : aWorkerPrivate->GetPrincipal();
155 nsContentSecurityManager::CORSSecurityMapping corsMapping;
156 nsSecurityFlags securityFlags;
157 nsContentPolicyType contentPolicyType;
158 BuildChannelFlags(aURI, /* aIsPreload */ false, corsMapping, securityFlags,
159 contentPolicyType);
161 nsCOMPtr<nsIChannel> channel;
162 rv = NS_NewChannelWithTriggeringPrincipal(
163 getter_AddRefs(channel), aURI, aWorkerPrivate->GetLoadingPrincipal(),
164 principal, securityFlags, contentPolicyType, nullptr, nullptr,
165 aLoadGroup);
166 NS_ENSURE_SUCCESS(rv, rv);
168 nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
170 nsCOMPtr<nsIReferrerInfo> referrerInfo;
171 if (httpChannel && !aFontFaceSrc) {
172 referrerInfo =
173 static_cast<dom::ReferrerInfo*>(aWorkerPrivate->GetReferrerInfo())
174 ->CloneWithNewPolicy(aReferrerPolicy);
177 rv = BuildChannelSetup(channel, httpChannel, referrerInfo, aFontFaceSrc,
178 nsISupportsPriority::PRIORITY_HIGH);
179 NS_ENSURE_SUCCESS(rv, rv);
181 channel.forget(aChannel);
182 return NS_OK;
185 } // namespace mozilla