Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/netwerk/protocol/http/./../../../../netwerk/protocol/http/HttpBaseChannel.cpp
Warning:line 1628, column 5
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_protocol_http2.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/netwerk/protocol/http -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/netwerk/protocol/http -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_APP_UA_NAME="" -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/netwerk/protocol/http -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/netwerk/protocol/http -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/toolkit/components/telemetry -I /root/firefox-clang/xpcom/base -I /root/firefox-clang/dom/base -I /root/firefox-clang/netwerk/base -I /root/firefox-clang/netwerk/cookie -I /root/firefox-clang/netwerk/dns -I /root/firefox-clang/netwerk/ipc -I /root/firefox-clang/netwerk/socket/neqo_glue -I /root/firefox-clang/netwerk/url-classifier -I /root/firefox-clang/extensions/auth -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ Unified_cpp_protocol_http2.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5// HttpLog.h should generally be included first
6#include "mozilla/net/HttpBaseChannel.h"
7
8#include <algorithm>
9#include <utility>
10
11#include "HttpBaseChannel.h"
12#include "HttpLog.h"
13#include "LoadInfo.h"
14#include "ReferrerInfo.h"
15#include "mozIRemoteLazyInputStream.h"
16#include "mozIThirdPartyUtil.h"
17#include "mozilla/AntiTrackingUtils.h"
18#include "mozilla/BasePrincipal.h"
19#include "mozilla/BinarySearch.h"
20#include "mozilla/CompactPair.h"
21#include "mozilla/Components.h"
22#include "mozilla/ConsoleReportCollector.h"
23#include "mozilla/DebugOnly.h"
24#include "mozilla/InputStreamLengthHelper.h"
25#include "mozilla/LoadInfo.h"
26#include "mozilla/Mutex.h"
27#include "mozilla/NullPrincipal.h"
28#include "mozilla/PermissionManager.h"
29#include "mozilla/RemoteLazyInputStreamChild.h"
30#include "mozilla/StaticPrefs_browser.h"
31#include "mozilla/StaticPrefs_fission.h"
32#include "mozilla/StaticPrefs_javascript.h"
33#include "mozilla/StaticPrefs_network.h"
34#include "mozilla/StaticPrefs_security.h"
35#include "mozilla/Telemetry.h"
36#include "mozilla/Tokenizer.h"
37#include "mozilla/browser/NimbusFeatures.h"
38#include "mozilla/dom/BrowsingContext.h"
39#include "mozilla/dom/CanonicalBrowsingContext.h"
40#include "mozilla/dom/ContentChild.h"
41#include "mozilla/dom/Document.h"
42#include "mozilla/dom/FetchPriority.h"
43#include "mozilla/dom/LoadURIOptionsBinding.h"
44#include "mozilla/dom/ParentProcessChannelHandle.h"
45#include "mozilla/dom/Performance.h"
46#include "mozilla/dom/PerformanceStorage.h"
47#include "mozilla/dom/PolicyContainer.h"
48#include "mozilla/dom/ProcessIsolation.h"
49#include "mozilla/dom/RequestBinding.h"
50#include "mozilla/dom/WindowGlobalParent.h"
51#include "mozilla/dom/nsHTTPSOnlyUtils.h"
52#include "mozilla/dom/nsMixedContentBlocker.h"
53#include "mozilla/glean/NetwerkProtocolHttpMetrics.h"
54#include "mozilla/net/ChannelClassifierUtils.h"
55#include "mozilla/net/OpaqueResponseUtils.h"
56#include "mozilla/net/SFV.h"
57#include "nsBufferedStreams.h"
58#include "nsCOMPtr.h"
59#include "nsCRT.h"
60#include "nsContentSecurityManager.h"
61#include "nsContentSecurityUtils.h"
62#include "nsContentUtils.h"
63#include "nsDebug.h"
64#include "nsEscape.h"
65#include "nsGlobalWindowInner.h"
66#include "nsGlobalWindowOuter.h"
67#include "nsHTTPCompressConv.h"
68#include "nsHttpChannel.h"
69#include "nsHttpHandler.h"
70#include "nsICacheInfoChannel.h"
71#include "nsICachingChannel.h"
72#include "nsIChannelEventSink.h"
73#include "nsIConsoleService.h"
74#include "nsIContentPolicy.h"
75#include "nsICookieService.h"
76#include "nsIDNSService.h"
77#include "nsIDOMWindowUtils.h"
78#include "nsIDocShell.h"
79#include "nsIEncodedChannel.h"
80#include "nsIHttpHeaderVisitor.h"
81#include "nsILoadGroupChild.h"
82#include "nsIMIMEInputStream.h"
83#include "nsIMultiplexInputStream.h"
84#include "nsIMutableArray.h"
85#include "nsINetworkInterceptController.h"
86#include "nsIOService.h"
87#include "nsIObserverService.h"
88#include "nsIPrincipal.h"
89#include "nsIProtocolProxyService.h"
90#include "nsIScriptError.h"
91#include "nsIScriptSecurityManager.h"
92#include "nsISecurityConsoleMessage.h"
93#include "nsISeekableStream.h"
94#include "nsIStorageStream.h"
95#include "nsIStreamConverterService.h"
96#include "nsITimedChannel.h"
97#include "nsITransportSecurityInfo.h"
98#include "nsIURIMutator.h"
99#include "nsMimeTypes.h"
100#include "nsNetCID.h"
101#include "nsNetUtil.h"
102#include "nsPIDOMWindow.h"
103#include "nsProxyRelease.h"
104#include "nsQueryObject.h"
105#include "nsReadableUtils.h"
106#include "nsRedirectHistoryEntry.h"
107#include "nsServerTiming.h"
108#include "nsStreamListenerWrapper.h"
109#include "nsStreamUtils.h"
110#include "nsString.h"
111#include "nsThreadUtils.h"
112#include "nsURLHelper.h"
113
114using mozilla::dom::ForceMediaDocument;
115using mozilla::dom::RequestMode;
116
117#define LOGORB(msg, ...) \
118 MOZ_LOG(GetORBLog(), LogLevel::Debug, \do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " msg, __func__, this, ##__VA_ARGS__
); } } while (0)
119 ("%s: %p " msg, __func__, this, ##__VA_ARGS__))do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " msg, __func__, this, ##__VA_ARGS__
); } } while (0)
120
121namespace mozilla {
122namespace net {
123
124static bool IsHeaderBlacklistedForRedirectCopy(nsHttpAtom const& aHeader) {
125 // IMPORTANT: keep this list ASCII-code sorted
126 static nsHttpAtomLiteral const* blackList[] = {
127 &nsHttp::Accept,
128 &nsHttp::Accept_Encoding,
129 &nsHttp::Accept_Language,
130 &nsHttp::Alternate_Service_Used,
131 &nsHttp::Authentication,
132 &nsHttp::Authorization,
133 &nsHttp::Connection,
134 &nsHttp::Content_Length,
135 &nsHttp::Cookie,
136 &nsHttp::Host,
137 &nsHttp::If,
138 &nsHttp::If_Match,
139 &nsHttp::If_Modified_Since,
140 &nsHttp::If_None_Match,
141 &nsHttp::If_None_Match_Any,
142 &nsHttp::If_Range,
143 &nsHttp::If_Unmodified_Since,
144 &nsHttp::Proxy_Authenticate,
145 &nsHttp::Proxy_Authorization,
146 &nsHttp::Range,
147 &nsHttp::TE,
148 &nsHttp::Transfer_Encoding,
149 &nsHttp::Upgrade,
150 &nsHttp::User_Agent,
151 &nsHttp::WWW_Authenticate};
152
153 class HttpAtomComparator {
154 nsHttpAtom const& mTarget;
155
156 public:
157 explicit HttpAtomComparator(nsHttpAtom const& aTarget) : mTarget(aTarget) {}
158 int operator()(nsHttpAtom const* aVal) const {
159 if (mTarget == *aVal) {
160 return 0;
161 }
162 return strcmp(mTarget.get(), aVal->get());
163 }
164 int operator()(nsHttpAtomLiteral const* aVal) const {
165 if (mTarget == *aVal) {
166 return 0;
167 }
168 return strcmp(mTarget.get(), aVal->get());
169 }
170 };
171
172 size_t unused;
173 return BinarySearchIf(blackList, 0, std::size(blackList),
174 HttpAtomComparator(aHeader), &unused);
175}
176
177class AddHeadersToChannelVisitor final : public nsIHttpHeaderVisitor {
178 public:
179 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::false_type;
protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
180
181 explicit AddHeadersToChannelVisitor(nsIHttpChannel* aChannel)
182 : mChannel(aChannel) {}
183
184 NS_IMETHODvirtual nsresult VisitHeader(const nsACString& aHeader,
185 const nsACString& aValue) override {
186 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
187 if (!IsHeaderBlacklistedForRedirectCopy(atom)) {
188 DebugOnly<nsresult> rv =
189 mChannel->SetRequestHeader(aHeader, aValue, false);
190 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 190); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 190); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
191 }
192 return NS_OK;
193 }
194
195 private:
196 ~AddHeadersToChannelVisitor() = default;
197
198 nsCOMPtr<nsIHttpChannel> mChannel;
199};
200
201NS_IMPL_ISUPPORTS(AddHeadersToChannelVisitor, nsIHttpHeaderVisitor)MozExternalRefCountType AddHeadersToChannelVisitor::AddRef(void
) { static_assert(!std::is_destructible_v<AddHeadersToChannelVisitor
>, "Reference-counted class " "AddHeadersToChannelVisitor"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 201
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("AddHeadersToChannelVisitor" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("AddHeadersToChannelVisitor" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"AddHeadersToChannelVisitor\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"AddHeadersToChannelVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 201); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("AddHeadersToChannelVisitor" " not thread-safe"); nsrefcnt count
= ++mRefCnt; NS_LogAddRef((this), (count), ("AddHeadersToChannelVisitor"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
AddHeadersToChannelVisitor::Release(void) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 201
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("AddHeadersToChannelVisitor" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("AddHeadersToChannelVisitor" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"AddHeadersToChannelVisitor\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"AddHeadersToChannelVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 201); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("AddHeadersToChannelVisitor" " not thread-safe"); const char
* const nametmp = "AddHeadersToChannelVisitor"; nsrefcnt count
= --mRefCnt; NS_LogRelease((this), (count), (nametmp)); if (
count == 0) { mRefCnt = 1; delete (this); return 0; } return count
; } nsresult AddHeadersToChannelVisitor::QueryInterface(const
nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 201); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<AddHeadersToChannelVisitor, nsIHttpHeaderVisitor
>, int32_t( reinterpret_cast<char*>(static_cast<nsIHttpHeaderVisitor
*>((AddHeadersToChannelVisitor*)0x1000)) - reinterpret_cast
<char*>((AddHeadersToChannelVisitor*)0x1000))}, {&mozilla
::detail::kImplementedIID<AddHeadersToChannelVisitor, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIHttpHeaderVisitor*>((AddHeadersToChannelVisitor
*)0x1000))) - reinterpret_cast<char*>((AddHeadersToChannelVisitor
*)0x1000))}, { nullptr, 0 } } ; static_assert(std::size(table
) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
202
203static OpaqueResponseFilterFetch ConfiguredFilterFetchResponseBehaviour() {
204 uint32_t pref = StaticPrefs::
205 browser_opaqueResponseBlocking_filterFetchResponse_DoNotUseDirectly();
206 if (NS_WARN_IF(pref >NS_warn_if_impl(pref > static_cast<uint32_t>(OpaqueResponseFilterFetch
::All), "pref > static_cast<uint32_t>(OpaqueResponseFilterFetch::All)"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 207
)
207 static_cast<uint32_t>(OpaqueResponseFilterFetch::All))NS_warn_if_impl(pref > static_cast<uint32_t>(OpaqueResponseFilterFetch
::All), "pref > static_cast<uint32_t>(OpaqueResponseFilterFetch::All)"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 207
)
) {
208 return OpaqueResponseFilterFetch::All;
209 }
210
211 return static_cast<OpaqueResponseFilterFetch>(pref);
212}
213
214HttpBaseChannel::HttpBaseChannel()
215 : mReportCollector(new ConsoleReportCollector()),
216 mHttpHandler(gHttpHandler),
217 mClassOfService(0, false),
218 mRequestMode(RequestMode::No_cors),
219 mRedirectionLimit(gHttpHandler->RedirectionLimit()),
220 mCachedOpaqueResponseBlockingPref(
221 StaticPrefs::browser_opaqueResponseBlocking()) {
222 StoreApplyConversion(true);
223 StoreAllowSTS(true);
224 StoreTracingEnabled(true);
225 StoreReportTiming(true);
226 StoreAllowSpdy(true);
227 StoreAllowHttp3(true);
228 StoreAllowAltSvc(true);
229 StoreResponseTimeoutEnabled(true);
230 StoreAllRedirectsSameOrigin(true);
231 StoreAllRedirectsSameOriginIgnoringInternal(true);
232 StoreAllRedirectsPassTimingAllowCheck(true);
233 StoreUpgradableToSecure(true);
234 StoreIsUserAgentHeaderModified(false);
235
236 this->mSelfAddr.inet = {};
237 this->mPeerAddr.inet = {};
238 LOG(("Creating HttpBaseChannel @%p\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Creating HttpBaseChannel @%p\n", this); } } while (0)
;
239
240 // Subfields of unions cannot be targeted in an initializer list.
241#ifdef MOZ_VALGRIND
242 // Zero the entire unions so that Valgrind doesn't complain when we send them
243 // to another process.
244 memset(&mSelfAddr, 0, sizeof(NetAddr));
245 memset(&mPeerAddr, 0, sizeof(NetAddr));
246#endif
247 mSelfAddr.raw.family = PR_AF_UNSPEC0;
248 mPeerAddr.raw.family = PR_AF_UNSPEC0;
249}
250
251HttpBaseChannel::~HttpBaseChannel() {
252 LOG(("Destroying HttpBaseChannel @%p\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Destroying HttpBaseChannel @%p\n", this); } } while (0)
;
253
254 // Make sure we don't leak
255 CleanRedirectCacheChainIfNecessary();
256
257 ReleaseMainThreadOnlyReferences();
258}
259
260namespace { // anon
261
262class NonTailRemover : public nsISupports {
263 NS_DECL_THREADSAFE_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::true_type; protected
: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; nsAutoOwningThread
_mOwningThread; public:
264
265 explicit NonTailRemover(nsIRequestContext* rc) : mRequestContext(rc) {}
266
267 private:
268 virtual ~NonTailRemover() {
269 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 269
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 269); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
270 mRequestContext->RemoveNonTailRequest();
271 }
272
273 nsCOMPtr<nsIRequestContext> mRequestContext;
274};
275
276NS_IMPL_ISUPPORTS0(NonTailRemover)MozExternalRefCountType NonTailRemover::AddRef(void) { static_assert
(!std::is_destructible_v<NonTailRemover>, "Reference-counted class "
"NonTailRemover" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 276
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("NonTailRemover" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("NonTailRemover" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"NonTailRemover\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"NonTailRemover\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 276); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("NonTailRemover" " not thread-safe"); nsrefcnt count = ++mRefCnt
; NS_LogAddRef((this), (count), ("NonTailRemover"), (uint32_t
)(sizeof(*this))); return count; } MozExternalRefCountType NonTailRemover
::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 276
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("NonTailRemover" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("NonTailRemover" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"NonTailRemover\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"NonTailRemover\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 276); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("NonTailRemover" " not thread-safe"); const char* const nametmp
= "NonTailRemover"; nsrefcnt count = --mRefCnt; NS_LogRelease
((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete
(this); return 0; } return count; } nsresult NonTailRemover::
QueryInterface(const nsIID& aIID, void** aInstancePtr) { do
{ if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 276); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<NonTailRemover, nsISupports>, int32_t
( reinterpret_cast<char*>(static_cast<nsISupports*>
((NonTailRemover*)0x1000)) - reinterpret_cast<char*>((NonTailRemover
*)0x1000))}, { nullptr, 0 } } ; static_assert(std::size(table
) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
277
278} // namespace
279
280void HttpBaseChannel::ReleaseMainThreadOnlyReferences() {
281 if (NS_IsMainThread()) {
282 // Already on main thread, let dtor to
283 // take care of releasing references
284 RemoveAsNonTailRequest();
285 return;
286 }
287
288 nsTArray<nsCOMPtr<nsISupports>> arrayToRelease;
289 arrayToRelease.AppendElement(mLoadGroup.forget());
290 arrayToRelease.AppendElement(mLoadInfo.forget());
291 arrayToRelease.AppendElement(mCallbacks.forget());
292 arrayToRelease.AppendElement(mProgressSink.forget());
293 arrayToRelease.AppendElement(mPrincipal.forget());
294 arrayToRelease.AppendElement(mListener.forget());
295 arrayToRelease.AppendElement(mCompressListener.forget());
296 arrayToRelease.AppendElement(mORB.forget());
297
298 if (LoadAddedAsNonTailRequest()) {
299 // RemoveNonTailRequest() on our request context must be called on the main
300 // thread
301 MOZ_RELEASE_ASSERT(mRequestContext,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRequestContext)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mRequestContext))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mRequestContext"
" (" "Someone released rc or set flags w/o having it?" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 302); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mRequestContext"
") (" "Someone released rc or set flags w/o having it?" ")")
; do { MOZ_CrashSequence(__null, 302); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
302 "Someone released rc or set flags w/o having it?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRequestContext)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mRequestContext))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mRequestContext"
" (" "Someone released rc or set flags w/o having it?" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 302); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mRequestContext"
") (" "Someone released rc or set flags w/o having it?" ")")
; do { MOZ_CrashSequence(__null, 302); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
303
304 nsCOMPtr<nsISupports> nonTailRemover(new NonTailRemover(mRequestContext));
305 arrayToRelease.AppendElement(nonTailRemover.forget());
306 }
307
308 NS_DispatchToMainThread(new ProxyReleaseRunnable(std::move(arrayToRelease)));
309}
310
311void HttpBaseChannel::AddClassificationFlags(uint32_t aClassificationFlags,
312 bool aIsThirdParty) {
313 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::AddClassificationFlags classificationFlags=%d "
"thirdparty=%d %p", aClassificationFlags, static_cast<int
>(aIsThirdParty), this); } } while (0)
314 ("HttpBaseChannel::AddClassificationFlags classificationFlags=%d "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::AddClassificationFlags classificationFlags=%d "
"thirdparty=%d %p", aClassificationFlags, static_cast<int
>(aIsThirdParty), this); } } while (0)
315 "thirdparty=%d %p",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::AddClassificationFlags classificationFlags=%d "
"thirdparty=%d %p", aClassificationFlags, static_cast<int
>(aIsThirdParty), this); } } while (0)
316 aClassificationFlags, static_cast<int>(aIsThirdParty), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::AddClassificationFlags classificationFlags=%d "
"thirdparty=%d %p", aClassificationFlags, static_cast<int
>(aIsThirdParty), this); } } while (0)
;
317
318 if (aIsThirdParty) {
319 mThirdPartyClassificationFlags |= aClassificationFlags;
320 } else {
321 mFirstPartyClassificationFlags |= aClassificationFlags;
322 }
323}
324
325static bool isSecureOrTrustworthyURL(nsIURI* aURI) {
326 return aURI->SchemeIs("https") ||
327 (StaticPrefs::network_http_encoding_trustworthy_is_https() &&
328 nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(aURI));
329}
330
331nsresult HttpBaseChannel::Init(nsIURI* aURI, uint32_t aCaps,
332 nsProxyInfo* aProxyInfo,
333 uint32_t aProxyResolveFlags, nsIURI* aProxyURI,
334 uint64_t aChannelId, nsILoadInfo* aLoadInfo) {
335 LOG1(("HttpBaseChannel::Init [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla::
detail::log_print(moz_real_module, mozilla::LogLevel::Error, "HttpBaseChannel::Init [this=%p]\n"
, this); } } while (0)
;
336
337 MOZ_ASSERT(aURI, "null uri")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aURI)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aURI))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aURI" " (" "null uri" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 337); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aURI" ") (" "null uri"
")"); do { MOZ_CrashSequence(__null, 337); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
338
339 mURI = aURI;
340 mOriginalURI = aURI;
341 mDocumentURI = nullptr;
342 mCaps = aCaps;
343 mProxyResolveFlags = aProxyResolveFlags;
344 mProxyURI = aProxyURI;
345 mChannelId = aChannelId;
346 mLoadInfo = aLoadInfo;
347
348 // Construct connection info object
349 nsAutoCString host;
350 int32_t port = -1;
351 bool isHTTPS = isSecureOrTrustworthyURL(mURI);
352
353 nsresult rv = mURI->GetAsciiHost(host);
354 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
355
356 // Reject the URL if it doesn't specify a host
357 if (host.IsEmpty()) return NS_ERROR_MALFORMED_URI;
358
359 rv = mURI->GetPort(&port);
360 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
361
362 LOG1(("host=%s port=%d\n", host.get(), port))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla::
detail::log_print(moz_real_module, mozilla::LogLevel::Error, "host=%s port=%d\n"
, host.get(), port); } } while (0)
;
363
364 rv = mURI->GetAsciiSpec(mSpec);
365 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
366 LOG1(("uri=%s\n", mSpec.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla::
detail::log_print(moz_real_module, mozilla::LogLevel::Error, "uri=%s\n"
, mSpec.get()); } } while (0)
;
367
368 // Assert default request method
369 MOZ_ASSERT(mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get)",
"./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 369
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get)"
")"); do { MOZ_CrashSequence(__null, 369); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
370
371 // Set request headers
372 nsAutoCString hostLine;
373 rv = nsHttpHandler::GenerateHostPort(host, port, hostLine);
374 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
375
376 rv = mRequestHead.SetHeader(nsHttp::Host, hostLine);
377 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
378
379 // Override the Accept header if a specific MediaDocument kind is forced.
380 ExtContentPolicy contentPolicyType =
381 mLoadInfo->GetExternalContentPolicyType();
382 // TRRLoadInfo doesn't implement GetForceMediaDocument.
383 ForceMediaDocument forceMediaDocument;
384 if (NS_SUCCEEDED(mLoadInfo->GetForceMediaDocument(&forceMediaDocument))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mLoadInfo->GetForceMediaDocument
(&forceMediaDocument))), 1)))
) {
385 switch (forceMediaDocument) {
386 case ForceMediaDocument::Image:
387 contentPolicyType = ExtContentPolicy::TYPE_IMAGE;
388 break;
389 case ForceMediaDocument::Video:
390 contentPolicyType = ExtContentPolicy::TYPE_MEDIA;
391 break;
392 case ForceMediaDocument::None:
393 break;
394 }
395 }
396
397 RefPtr<mozilla::dom::BrowsingContext> browsingContext;
398 mLoadInfo->GetBrowsingContext(getter_AddRefs(browsingContext));
399 if (!browsingContext) {
400 mLoadInfo->GetAssociatedBrowsingContext(getter_AddRefs(browsingContext));
401 }
402
403 const nsCString& languageOverride =
404 browsingContext ? browsingContext->Top()->GetLanguageOverride()
405 : EmptyCString();
406
407 rv = gHttpHandler->AddStandardRequestHeaders(
408 &mRequestHead, aURI, isHTTPS, contentPolicyType,
409 nsContentUtils::ShouldResistFingerprinting(this,
410 RFPTarget::HttpUserAgent),
411 languageOverride);
412 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
413
414 nsAutoCString type;
415 if (aProxyInfo && NS_SUCCEEDED(aProxyInfo->GetType(type))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aProxyInfo->GetType
(type))), 1)))
&&
416 !type.EqualsLiteral("unknown")) {
417 mProxyInfo = aProxyInfo;
418 }
419
420 mCurrentThread = GetCurrentSerialEventTarget();
421 return rv;
422}
423
424//-----------------------------------------------------------------------------
425// HttpBaseChannel::nsISupports
426//-----------------------------------------------------------------------------
427
428NS_IMPL_ADDREF(HttpBaseChannel)MozExternalRefCountType HttpBaseChannel::AddRef(void) { static_assert
(!std::is_destructible_v<HttpBaseChannel>, "Reference-counted class "
"HttpBaseChannel" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 428); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 428
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("HttpBaseChannel" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"HttpBaseChannel\" != nullptr" " (" "Must specify a name" ")"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 428
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 428); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("HttpBaseChannel" " not thread-safe"); nsrefcnt count = ++mRefCnt
; NS_LogAddRef((this), (count), ("HttpBaseChannel"), (uint32_t
)(sizeof(*this))); return count; }
429NS_IMPL_RELEASE(HttpBaseChannel)MozExternalRefCountType HttpBaseChannel::Release(void) { do {
static_assert( mozilla::detail::AssertionConditionType<decltype
(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 429); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 429
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("HttpBaseChannel" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"HttpBaseChannel\" != nullptr" " (" "Must specify a name" ")"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 429
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 429); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("HttpBaseChannel" " not thread-safe"); const char* const nametmp
= "HttpBaseChannel"; nsrefcnt count = --mRefCnt; NS_LogRelease
((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete
(this); return 0; } return count; }
430
431NS_INTERFACE_MAP_BEGIN(HttpBaseChannel)nsresult HttpBaseChannel::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 431); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
432 NS_INTERFACE_MAP_ENTRY(nsIRequest)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequest>)) foundInterface = static_cast
<nsIRequest*>(this); else
433 NS_INTERFACE_MAP_ENTRY(nsIChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIChannel>)) foundInterface = static_cast
<nsIChannel*>(this); else
434 NS_INTERFACE_MAP_ENTRY(nsIIdentChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIIdentChannel>)) foundInterface
= static_cast<nsIIdentChannel*>(this); else
435 NS_INTERFACE_MAP_ENTRY(nsIEncodedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIEncodedChannel>)) foundInterface
= static_cast<nsIEncodedChannel*>(this); else
436 NS_INTERFACE_MAP_ENTRY(nsIHttpChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpChannel>)) foundInterface =
static_cast<nsIHttpChannel*>(this); else
437 NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpChannelInternal>)) foundInterface
= static_cast<nsIHttpChannelInternal*>(this); else
438 NS_INTERFACE_MAP_ENTRY(nsIForcePendingChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIForcePendingChannel>)) foundInterface
= static_cast<nsIForcePendingChannel*>(this); else
439 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIUploadChannel>)) foundInterface
= static_cast<nsIUploadChannel*>(this); else
440 NS_INTERFACE_MAP_ENTRY(nsIFormPOSTActionChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIFormPOSTActionChannel>)) foundInterface
= static_cast<nsIFormPOSTActionChannel*>(this); else
441 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIUploadChannel2>)) foundInterface
= static_cast<nsIUploadChannel2*>(this); else
442 NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsPriority>)) foundInterface
= static_cast<nsISupportsPriority*>(this); else
443 NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsITraceableChannel>)) foundInterface
= static_cast<nsITraceableChannel*>(this); else
444 NS_INTERFACE_MAP_ENTRY(nsIPrivateBrowsingChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIPrivateBrowsingChannel>)) foundInterface
= static_cast<nsIPrivateBrowsingChannel*>(this); else
445 NS_INTERFACE_MAP_ENTRY(nsITimedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsITimedChannel>)) foundInterface
= static_cast<nsITimedChannel*>(this); else
446 NS_INTERFACE_MAP_ENTRY(nsIConsoleReportCollector)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIConsoleReportCollector>)) foundInterface
= static_cast<nsIConsoleReportCollector*>(this); else
447 NS_INTERFACE_MAP_ENTRY(nsIThrottledInputChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThrottledInputChannel>)) foundInterface
= static_cast<nsIThrottledInputChannel*>(this); else
448 NS_INTERFACE_MAP_ENTRY(nsIClassifiedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIClassifiedChannel>)) foundInterface
= static_cast<nsIClassifiedChannel*>(this); else
449 NS_INTERFACE_MAP_ENTRY_CONCRETE(HttpBaseChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, HttpBaseChannel>)) { *aInstancePtr
= do_AddRef(static_cast<HttpBaseChannel*>(this)).take(
); return NS_OK; } else
450NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag)foundInterface = 0; nsresult status; if (!foundInterface) status
= nsHashPropertyBag::QueryInterface(aIID, (void**)&foundInterface
); else { (foundInterface)->AddRef(); status = NS_OK; } *aInstancePtr
= foundInterface; return status; }
451
452//-----------------------------------------------------------------------------
453// HttpBaseChannel::nsIRequest
454//-----------------------------------------------------------------------------
455
456NS_IMETHODIMPnsresult
457HttpBaseChannel::GetName(nsACString& aName) {
458 aName = mSpec;
459 return NS_OK;
460}
461
462NS_IMETHODIMPnsresult
463HttpBaseChannel::IsPending(bool* aIsPending) {
464 NS_ENSURE_ARG_POINTER(aIsPending)do { if ((__builtin_expect(!!(!(aIsPending)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aIsPending" ") failed",
nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 464); return NS_ERROR_INVALID_POINTER; } } while (false)
;
465 *aIsPending = LoadIsPending() || LoadForcePending();
466 return NS_OK;
467}
468
469NS_IMETHODIMPnsresult
470HttpBaseChannel::GetStatus(nsresult* aStatus) {
471 NS_ENSURE_ARG_POINTER(aStatus)do { if ((__builtin_expect(!!(!(aStatus)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aStatus" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 471
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
472 *aStatus = mStatus;
473 return NS_OK;
474}
475
476NS_IMETHODIMPnsresult
477HttpBaseChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) {
478 NS_ENSURE_ARG_POINTER(aLoadGroup)do { if ((__builtin_expect(!!(!(aLoadGroup)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aLoadGroup" ") failed",
nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 478); return NS_ERROR_INVALID_POINTER; } } while (false)
;
479 *aLoadGroup = do_AddRef(mLoadGroup).take();
480 return NS_OK;
481}
482
483NS_IMETHODIMPnsresult
484HttpBaseChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) {
485 MOZ_ASSERT(NS_IsMainThread(), "Should only be called on the main thread.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Should only be called on the main thread." ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 485); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should only be called on the main thread." ")"); do {
MOZ_CrashSequence(__null, 485); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
486
487 if (!CanSetLoadGroup(aLoadGroup)) {
488 return NS_ERROR_FAILURE;
489 }
490
491 mLoadGroup = aLoadGroup;
492 mProgressSink = nullptr;
493 UpdatePrivateBrowsing();
494 return NS_OK;
495}
496
497NS_IMETHODIMPnsresult
498HttpBaseChannel::GetLoadFlags(nsLoadFlags* aLoadFlags) {
499 NS_ENSURE_ARG_POINTER(aLoadFlags)do { if ((__builtin_expect(!!(!(aLoadFlags)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aLoadFlags" ") failed",
nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 499); return NS_ERROR_INVALID_POINTER; } } while (false)
;
500 *aLoadFlags = mLoadFlags;
501 return NS_OK;
502}
503
504NS_IMETHODIMPnsresult
505HttpBaseChannel::SetLoadFlags(nsLoadFlags aLoadFlags) {
506 mLoadFlags = aLoadFlags;
507 return NS_OK;
508}
509
510NS_IMETHODIMPnsresult
511HttpBaseChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
512 if (!LoadIsOCSP()) {
513 return GetTRRModeImpl(aTRRMode);
514 }
515
516 nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID"@mozilla.org/network/dns-service;1");
517 nsIDNSService::ResolverMode trrMode = nsIDNSService::MODE_NATIVEONLY;
518 // If this is an OCSP channel, and the global TRR mode is TRR_ONLY (3)
519 // then we set the mode for this channel as TRR_DISABLED_MODE.
520 // We do this to prevent a TRR service channel's OCSP validation from
521 // blocking DNS resolution completely.
522 if (dns && NS_SUCCEEDED(dns->GetCurrentTrrMode(&trrMode))((bool)(__builtin_expect(!!(!NS_FAILED_impl(dns->GetCurrentTrrMode
(&trrMode))), 1)))
&&
523 trrMode == nsIDNSService::MODE_TRRONLY) {
524 *aTRRMode = nsIRequest::TRR_DISABLED_MODE;
525 return NS_OK;
526 }
527
528 return GetTRRModeImpl(aTRRMode);
529}
530
531NS_IMETHODIMPnsresult
532HttpBaseChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
533 return SetTRRModeImpl(aTRRMode);
534}
535
536NS_IMETHODIMPnsresult
537HttpBaseChannel::SetDocshellUserAgentOverride() {
538 RefPtr<dom::BrowsingContext> bc;
539 MOZ_ALWAYS_SUCCEEDS(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))), 1)))
), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 539
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
")"); do { MOZ_CrashSequence(__null, 539); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
540 if (!bc) {
541 return NS_OK;
542 }
543
544 nsAutoString customUserAgent;
545 bc->GetCustomUserAgent(customUserAgent);
546 if (customUserAgent.IsEmpty() || customUserAgent.IsVoid()) {
547 return NS_OK;
548 }
549
550 NS_ConvertUTF16toUTF8 utf8CustomUserAgent(customUserAgent);
551 nsresult rv = SetRequestHeaderInternal(
552 "User-Agent"_ns, utf8CustomUserAgent, false,
553 nsHttpHeaderArray::eVarietyRequestEnforceDefault);
554 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
555 return rv;
556 }
557
558 return NS_OK;
559}
560
561//-----------------------------------------------------------------------------
562// HttpBaseChannel::nsIChannel
563//-----------------------------------------------------------------------------
564
565NS_IMETHODIMPnsresult
566HttpBaseChannel::GetOriginalURI(nsIURI** aOriginalURI) {
567 NS_ENSURE_ARG_POINTER(aOriginalURI)do { if ((__builtin_expect(!!(!(aOriginalURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOriginalURI" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 567); return NS_ERROR_INVALID_POINTER; } } while (false)
;
568 *aOriginalURI = do_AddRef(mOriginalURI).take();
569 return NS_OK;
570}
571
572NS_IMETHODIMPnsresult
573HttpBaseChannel::SetOriginalURI(nsIURI* aOriginalURI) {
574 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 574); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 574, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 574); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 574
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 574); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
575
576 NS_ENSURE_ARG_POINTER(aOriginalURI)do { if ((__builtin_expect(!!(!(aOriginalURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOriginalURI" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 576); return NS_ERROR_INVALID_POINTER; } } while (false)
;
577 mOriginalURI = aOriginalURI;
578 return NS_OK;
579}
580
581NS_IMETHODIMPnsresult
582HttpBaseChannel::GetURI(nsIURI** aURI) {
583 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 583
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
584 *aURI = do_AddRef(mURI).take();
585 return NS_OK;
586}
587
588NS_IMETHODIMPnsresult
589HttpBaseChannel::GetOwner(nsISupports** aOwner) {
590 NS_ENSURE_ARG_POINTER(aOwner)do { if ((__builtin_expect(!!(!(aOwner)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOwner" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 590
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
591 *aOwner = do_AddRef(mOwner).take();
592 return NS_OK;
593}
594
595NS_IMETHODIMPnsresult
596HttpBaseChannel::SetOwner(nsISupports* aOwner) {
597 mOwner = aOwner;
598 return NS_OK;
599}
600
601NS_IMETHODIMPnsresult
602HttpBaseChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
603 MOZ_RELEASE_ASSERT(aLoadInfo, "loadinfo can't be null")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadInfo))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aLoadInfo" " (" "loadinfo can't be null"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 603); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aLoadInfo"
") (" "loadinfo can't be null" ")"); do { MOZ_CrashSequence(
__null, 603); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
604 mLoadInfo = aLoadInfo;
605 return NS_OK;
606}
607
608NS_IMETHODIMPnsresult
609HttpBaseChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) {
610 *aLoadInfo = do_AddRef(mLoadInfo).take();
611 return NS_OK;
612}
613
614NS_IMETHODIMPnsresult
615HttpBaseChannel::GetIsDocument(bool* aIsDocument) {
616 return NS_GetIsDocumentChannel(this, aIsDocument);
617}
618
619NS_IMETHODIMPnsresult
620HttpBaseChannel::GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks) {
621 *aCallbacks = do_AddRef(mCallbacks).take();
622 return NS_OK;
623}
624
625NS_IMETHODIMPnsresult
626HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) {
627 MOZ_ASSERT(NS_IsMainThread(), "Should only be called on the main thread.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Should only be called on the main thread." ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 627); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should only be called on the main thread." ")"); do {
MOZ_CrashSequence(__null, 627); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
628
629 if (!CanSetCallbacks(aCallbacks)) {
630 return NS_ERROR_FAILURE;
631 }
632
633 mCallbacks = aCallbacks;
634 mProgressSink = nullptr;
635
636 UpdatePrivateBrowsing();
637 return NS_OK;
638}
639
640NS_IMETHODIMPnsresult
641HttpBaseChannel::GetContentType(nsACString& aContentType) {
642 if (!mResponseHead) {
643 aContentType.Truncate();
644 return NS_ERROR_NOT_AVAILABLE;
645 }
646
647 mResponseHead->ContentType(aContentType);
648 if (!aContentType.IsEmpty()) {
649 return NS_OK;
650 }
651
652 aContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE"application/x-unknown-content-type");
653 return NS_OK;
654}
655
656NS_IMETHODIMPnsresult
657HttpBaseChannel::SetContentType(const nsACString& aContentType) {
658 if (mListener || LoadWasOpened() || mDummyChannelForCachedResource) {
659 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
660
661 nsAutoCString contentTypeBuf, charsetBuf;
662 bool hadCharset;
663 net_ParseContentType(aContentType, contentTypeBuf, charsetBuf, &hadCharset);
664
665 mResponseHead->SetContentType(contentTypeBuf);
666
667 // take care not to stomp on an existing charset
668 if (hadCharset) mResponseHead->SetContentCharset(charsetBuf);
669
670 } else {
671 // We are being given a content-type hint.
672 bool dummy;
673 net_ParseContentType(aContentType, mContentTypeHint, mContentCharsetHint,
674 &dummy);
675 }
676
677 return NS_OK;
678}
679
680NS_IMETHODIMPnsresult
681HttpBaseChannel::GetContentCharset(nsACString& aContentCharset) {
682 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
683
684 mResponseHead->ContentCharset(aContentCharset);
685 return NS_OK;
686}
687
688NS_IMETHODIMPnsresult
689HttpBaseChannel::SetContentCharset(const nsACString& aContentCharset) {
690 if (mListener) {
691 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
692
693 mResponseHead->SetContentCharset(aContentCharset);
694 } else {
695 // Charset hint
696 mContentCharsetHint = aContentCharset;
697 }
698 return NS_OK;
699}
700
701NS_IMETHODIMPnsresult
702HttpBaseChannel::GetContentDisposition(uint32_t* aContentDisposition) {
703 if (mLoadInfo->GetForceMediaDocument() != ForceMediaDocument::None) {
704 *aContentDisposition = nsIChannel::DISPOSITION_FORCE_INLINE;
705 return NS_OK;
706 }
707
708 // See bug 1658877. If mContentDispositionHint is already
709 // DISPOSITION_ATTACHMENT, it means this channel is created from a
710 // download attribute. In this case, we should prefer the value from the
711 // download attribute rather than the value in content disposition header.
712 // DISPOSITION_FORCE_INLINE is used to explicitly set inline, used by
713 // the pdf reader when loading a attachment pdf without having to
714 // download it.
715 if (mContentDispositionHint == nsIChannel::DISPOSITION_ATTACHMENT ||
716 mContentDispositionHint == nsIChannel::DISPOSITION_FORCE_INLINE) {
717 *aContentDisposition = mContentDispositionHint;
718 return NS_OK;
719 }
720
721 nsresult rv;
722 nsCString header;
723
724 rv = GetContentDispositionHeader(header);
725 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
726 if (mContentDispositionHint == UINT32_MAX(4294967295U)) return rv;
727
728 *aContentDisposition = mContentDispositionHint;
729 return NS_OK;
730 }
731
732 *aContentDisposition = NS_GetContentDispositionFromHeader(header, this);
733 return NS_OK;
734}
735
736NS_IMETHODIMPnsresult
737HttpBaseChannel::SetContentDisposition(uint32_t aContentDisposition) {
738 mContentDispositionHint = aContentDisposition;
739 return NS_OK;
740}
741
742NS_IMETHODIMPnsresult
743HttpBaseChannel::GetContentDispositionFilename(
744 nsAString& aContentDispositionFilename) {
745 aContentDispositionFilename.Truncate();
746 nsresult rv;
747 nsCString header;
748
749 rv = GetContentDispositionHeader(header);
750 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
751 rv = NS_GetFilenameFromDisposition(aContentDispositionFilename, header);
752 }
753
754 // If we failed to get the filename from header, we should use
755 // mContentDispositionFilename, since mContentDispositionFilename is set from
756 // the download attribute.
757 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
758 if (!mContentDispositionFilename) {
759 return rv;
760 }
761
762 aContentDispositionFilename = *mContentDispositionFilename;
763 return NS_OK;
764 }
765
766 return rv;
767}
768
769NS_IMETHODIMPnsresult
770HttpBaseChannel::SetContentDispositionFilename(
771 const nsAString& aContentDispositionFilename) {
772 mContentDispositionFilename =
773 MakeUnique<nsString>(aContentDispositionFilename);
774
775 // For safety reasons ensure the filename doesn't contain null characters and
776 // replace them with underscores. We may later pass the extension to system
777 // MIME APIs that expect null terminated strings.
778 mContentDispositionFilename->ReplaceChar(char16_t(0), '_');
779
780 return NS_OK;
781}
782
783NS_IMETHODIMPnsresult
784HttpBaseChannel::GetContentDispositionHeader(
785 nsACString& aContentDispositionHeader) {
786 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
787
788 nsresult rv = mResponseHead->GetHeader(nsHttp::Content_Disposition,
789 aContentDispositionHeader);
790 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || aContentDispositionHeader.IsEmpty()) {
791 return NS_ERROR_NOT_AVAILABLE;
792 }
793
794 return NS_OK;
795}
796
797NS_IMETHODIMPnsresult
798HttpBaseChannel::GetContentLength(int64_t* aContentLength) {
799 NS_ENSURE_ARG_POINTER(aContentLength)do { if ((__builtin_expect(!!(!(aContentLength)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aContentLength" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 799); return NS_ERROR_INVALID_POINTER; } } while (false)
;
800
801 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
802
803 if (LoadDeliveringAltData()) {
804 MOZ_ASSERT(!mAvailableCachedAltDataType.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mAvailableCachedAltDataType.IsEmpty())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mAvailableCachedAltDataType.IsEmpty()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mAvailableCachedAltDataType.IsEmpty()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 804
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mAvailableCachedAltDataType.IsEmpty()"
")"); do { MOZ_CrashSequence(__null, 804); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
805 *aContentLength = mAltDataLength;
806 return NS_OK;
807 }
808
809 *aContentLength = mResponseHead->ContentLength();
810 return NS_OK;
811}
812
813NS_IMETHODIMPnsresult
814HttpBaseChannel::SetContentLength(int64_t value) {
815 if (!mDummyChannelForCachedResource) {
816 MOZ_ASSERT_UNREACHABLE("HttpBaseChannel::SetContentLength")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"HttpBaseChannel::SetContentLength" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 816); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "HttpBaseChannel::SetContentLength"
")"); do { MOZ_CrashSequence(__null, 816); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
817 return NS_ERROR_NOT_IMPLEMENTED;
818 }
819 MOZ_ASSERT(mResponseHead)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mResponseHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mResponseHead))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mResponseHead",
"./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 819
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mResponseHead" ")"
); do { MOZ_CrashSequence(__null, 819); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
820 mResponseHead->SetContentLength(value);
821 return NS_OK;
822}
823
824NS_IMETHODIMPnsresult
825HttpBaseChannel::Open(nsIInputStream** aStream) {
826 if (!gHttpHandler->Active()) {
827 LOG(("HttpBaseChannel::Open after HTTP shutdown..."))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::Open after HTTP shutdown..."); } } while (
0)
;
828 return NS_ERROR_NOT_AVAILABLE;
829 }
830
831 nsCOMPtr<nsIStreamListener> listener;
832 nsresult rv =
833 nsContentSecurityManager::doContentSecurityCheck(this, listener);
834 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 834); return rv; } } while (false)
;
835
836 NS_ENSURE_TRUE(!LoadWasOpened(), NS_ERROR_IN_PROGRESS)do { if ((__builtin_expect(!!(!(!LoadWasOpened())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!LoadWasOpened()" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 836); return NS_ERROR_IN_PROGRESS; } } while (false)
;
837
838 if (!gHttpHandler->Active()) {
839 LOG(("HttpBaseChannel::Open after HTTP shutdown..."))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::Open after HTTP shutdown..."); } } while (
0)
;
840 return NS_ERROR_NOT_AVAILABLE;
841 }
842
843 return NS_ImplementChannelOpen(this, aStream);
844}
845
846NS_IMETHODIMPnsresult
847HttpBaseChannel::GetParentProcessChannelHandle(
848 mozilla::dom::ParentProcessChannelHandle** aValue) {
849 *aValue = do_AddRef(mParentProcessChannelHandle).take();
850 return NS_OK;
851}
852
853NS_IMETHODIMPnsresult
854HttpBaseChannel::SetParentProcessChannelHandle(
855 mozilla::dom::ParentProcessChannelHandle* aValue) {
856 if (XRE_IsParentProcess()) {
857 MOZ_ASSERT_UNREACHABLE(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"SetParentProcessChannelHandle in the parent process would leak"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 858); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "SetParentProcessChannelHandle in the parent process would leak"
")"); do { MOZ_CrashSequence(__null, 858); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
858 "SetParentProcessChannelHandle in the parent process would leak")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"SetParentProcessChannelHandle in the parent process would leak"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 858); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "SetParentProcessChannelHandle in the parent process would leak"
")"); do { MOZ_CrashSequence(__null, 858); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
859 return NS_ERROR_NOT_AVAILABLE;
860 }
861
862 mParentProcessChannelHandle = aValue;
863 return NS_OK;
864}
865
866//-----------------------------------------------------------------------------
867// HttpBaseChannel::nsIUploadChannel
868//-----------------------------------------------------------------------------
869
870NS_IMETHODIMPnsresult
871HttpBaseChannel::GetUploadStream(nsIInputStream** stream) {
872 NS_ENSURE_ARG_POINTER(stream)do { if ((__builtin_expect(!!(!(stream)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stream" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 872
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
873 *stream = do_AddRef(mUploadStream).take();
874 return NS_OK;
875}
876
877NS_IMETHODIMPnsresult
878HttpBaseChannel::SetUploadStream(nsIInputStream* stream,
879 const nsACString& contentTypeArg,
880 int64_t contentLength) {
881 // NOTE: for backwards compatibility and for compatibility with old style
882 // plugins, |stream| may include headers, specifically Content-Type and
883 // Content-Length headers. in this case, |contentType| and |contentLength|
884 // would be unspecified. this is traditionally the case of a POST request,
885 // and so we select POST as the request method if contentType and
886 // contentLength are unspecified.
887
888 if (stream) {
889 nsAutoCString method;
890
891 // This method and ExplicitSetUploadStream mean different things by "empty
892 // content type string". This method means "no header", but
893 // ExplicitSetUploadStream means "header with empty value". So we have to
894 // massage the contentType argument into the form ExplicitSetUploadStream
895 // expects.
896 nsCOMPtr<nsIMIMEInputStream> mimeStream;
897 nsCString contentType(contentTypeArg);
898 if (contentType.IsEmpty()) {
899 contentType.SetIsVoid(true);
900 method = "POST"_ns;
901
902 // MIME streams are a special case, and include headers which need to be
903 // copied to the channel.
904 mimeStream = do_QueryInterface(stream);
905 if (mimeStream) {
906 // Copy non-origin related headers to the channel.
907 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
908 new AddHeadersToChannelVisitor(this);
909 mimeStream->VisitHeaders(visitor);
910
911 return ExplicitSetUploadStream(stream, contentType, contentLength,
912 method);
913 }
914 } else {
915 method = "PUT"_ns;
916
917 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface
(stream, getter_AddRefs(mimeStream)))), 0))))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(((bool)(__builtin_expect(!!(
NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream
)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
" (" "nsIMIMEInputStream should not be set with an explicit content type"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 919); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
") (" "nsIMIMEInputStream should not be set with an explicit content type"
")"); do { MOZ_CrashSequence(__null, 919); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
918 NS_FAILED(CallQueryInterface(stream, getter_AddRefs(mimeStream))),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface
(stream, getter_AddRefs(mimeStream)))), 0))))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(((bool)(__builtin_expect(!!(
NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream
)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
" (" "nsIMIMEInputStream should not be set with an explicit content type"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 919); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
") (" "nsIMIMEInputStream should not be set with an explicit content type"
")"); do { MOZ_CrashSequence(__null, 919); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
919 "nsIMIMEInputStream should not be set with an explicit content type")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface
(stream, getter_AddRefs(mimeStream)))), 0))))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(((bool)(__builtin_expect(!!(
NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream
)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
" (" "nsIMIMEInputStream should not be set with an explicit content type"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 919); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
") (" "nsIMIMEInputStream should not be set with an explicit content type"
")"); do { MOZ_CrashSequence(__null, 919); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
920 }
921 return ExplicitSetUploadStream(stream, contentType, contentLength, method);
922 }
923
924 // if stream is null, ExplicitSetUploadStream returns error.
925 // So we need special case for GET method.
926 SetRequestMethod("GET"_ns); // revert to GET request
927 mUploadStream = nullptr;
928 return NS_OK;
929}
930
931namespace {
932
933class MIMEHeaderCopyVisitor final : public nsIHttpHeaderVisitor {
934 public:
935 explicit MIMEHeaderCopyVisitor(nsIMIMEInputStream* aDest) : mDest(aDest) {}
936
937 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::false_type;
protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
938 NS_IMETHODvirtual nsresult VisitHeader(const nsACString& aName,
939 const nsACString& aValue) override {
940 return mDest->AddHeader(PromiseFlatCStringTPromiseFlatString<char>(aName).get(),
941 PromiseFlatCStringTPromiseFlatString<char>(aValue).get());
942 }
943
944 private:
945 ~MIMEHeaderCopyVisitor() = default;
946
947 nsCOMPtr<nsIMIMEInputStream> mDest;
948};
949
950NS_IMPL_ISUPPORTS(MIMEHeaderCopyVisitor, nsIHttpHeaderVisitor)MozExternalRefCountType MIMEHeaderCopyVisitor::AddRef(void) {
static_assert(!std::is_destructible_v<MIMEHeaderCopyVisitor
>, "Reference-counted class " "MIMEHeaderCopyVisitor" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 950); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 950
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("MIMEHeaderCopyVisitor" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("MIMEHeaderCopyVisitor" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"MIMEHeaderCopyVisitor\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 950); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MIMEHeaderCopyVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 950); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("MIMEHeaderCopyVisitor" " not thread-safe"); nsrefcnt count =
++mRefCnt; NS_LogAddRef((this), (count), ("MIMEHeaderCopyVisitor"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
MIMEHeaderCopyVisitor::Release(void) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(int32_t(mRefCnt)
> 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 950); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 950
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("MIMEHeaderCopyVisitor" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("MIMEHeaderCopyVisitor" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"MIMEHeaderCopyVisitor\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 950); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MIMEHeaderCopyVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 950); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("MIMEHeaderCopyVisitor" " not thread-safe"); const char* const
nametmp = "MIMEHeaderCopyVisitor"; nsrefcnt count = --mRefCnt
; NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; } nsresult
MIMEHeaderCopyVisitor::QueryInterface(const nsIID& aIID,
void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 950); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<MIMEHeaderCopyVisitor, nsIHttpHeaderVisitor
>, int32_t( reinterpret_cast<char*>(static_cast<nsIHttpHeaderVisitor
*>((MIMEHeaderCopyVisitor*)0x1000)) - reinterpret_cast<
char*>((MIMEHeaderCopyVisitor*)0x1000))}, {&mozilla::detail
::kImplementedIID<MIMEHeaderCopyVisitor, nsISupports>, int32_t
(reinterpret_cast<char*>(static_cast<nsISupports*>
( static_cast<nsIHttpHeaderVisitor*>((MIMEHeaderCopyVisitor
*)0x1000))) - reinterpret_cast<char*>((MIMEHeaderCopyVisitor
*)0x1000))}, { nullptr, 0 } } ; static_assert(std::size(table
) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
951
952static void NormalizeCopyComplete(void* aClosure, nsresult aStatus) {
953#ifdef DEBUG1
954 // Called on the STS thread by NS_AsyncCopy
955 nsCOMPtr<nsIEventTarget> sts =
956 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/stream-transport-service;1");
957 bool result = false;
958 sts->IsOnCurrentThread(&result);
959 MOZ_ASSERT(result, "Should only be called on the STS thread.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(result)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(result))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("result" " (" "Should only be called on the STS thread."
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 959); AnnotateMozCrashReason("MOZ_ASSERT" "(" "result" ") ("
"Should only be called on the STS thread." ")"); do { MOZ_CrashSequence
(__null, 959); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
960#endif
961
962 RefPtr<GenericPromise::Private> ready =
963 already_AddRefed(static_cast<GenericPromise::Private*>(aClosure));
964 if (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)))) {
965 ready->Resolve(true, __func__);
966 } else {
967 ready->Reject(aStatus, __func__);
968 }
969}
970
971// Normalize the upload stream for a HTTP channel, so that is one of the
972// expected and compatible types. Components like WebExtensions and DevTools
973// expect that upload streams in the parent process are cloneable, seekable, and
974// synchronous to read, which this function helps guarantee somewhat efficiently
975// and without loss of information.
976//
977// If the replacement stream outparameter is not initialized to `nullptr`, the
978// returned stream should be used instead of `aUploadStream` as the upload
979// stream for the HTTP channel, and the previous stream should not be touched
980// again.
981//
982// If aReadyPromise is non-nullptr after the function is called, it is a promise
983// which should be awaited before continuing to `AsyncOpen` the HTTP channel,
984// as the replacement stream will not be ready until it is resolved.
985static nsresult NormalizeUploadStream(nsIInputStream* aUploadStream,
986 nsIInputStream** aReplacementStream,
987 GenericPromise** aReadyPromise) {
988 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 988
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 988); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
989
990 *aReplacementStream = nullptr;
991 *aReadyPromise = nullptr;
992
993 // Unwrap RemoteLazyInputStream and normalize the contents as we're in the
994 // parent process.
995 if (nsCOMPtr<mozIRemoteLazyInputStream> lazyStream =
996 do_QueryInterface(aUploadStream)) {
997 nsCOMPtr<nsIInputStream> internal;
998 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(lazyStream->TakeInternalStream
(getter_AddRefs(internal)))), 1)))
999 lazyStream->TakeInternalStream(getter_AddRefs(internal)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(lazyStream->TakeInternalStream
(getter_AddRefs(internal)))), 1)))
) {
1000 nsCOMPtr<nsIInputStream> replacement;
1001 nsresult rv = NormalizeUploadStream(internal, getter_AddRefs(replacement),
1002 aReadyPromise);
1003 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1003); return rv; } } while (false)
;
1004
1005 if (replacement) {
1006 replacement.forget(aReplacementStream);
1007 } else {
1008 internal.forget(aReplacementStream);
1009 }
1010 return NS_OK;
1011 }
1012 }
1013
1014 // Preserve MIME information on the stream when normalizing.
1015 if (nsCOMPtr<nsIMIMEInputStream> mime = do_QueryInterface(aUploadStream)) {
1016 nsCOMPtr<nsIInputStream> data;
1017 nsresult rv = mime->GetData(getter_AddRefs(data));
1018 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1018); return rv; } } while (false)
;
1019
1020 nsCOMPtr<nsIInputStream> replacement;
1021 rv =
1022 NormalizeUploadStream(data, getter_AddRefs(replacement), aReadyPromise);
1023 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1023); return rv; } } while (false)
;
1024
1025 if (replacement) {
1026 nsCOMPtr<nsIMIMEInputStream> replacementMime(
1027 do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv));
1028 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1028); return rv; } } while (false)
;
1029
1030 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
1031 new MIMEHeaderCopyVisitor(replacementMime);
1032 rv = mime->VisitHeaders(visitor);
1033 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1033); return rv; } } while (false)
;
1034
1035 rv = replacementMime->SetData(replacement);
1036 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1036); return rv; } } while (false)
;
1037
1038 replacementMime.forget(aReplacementStream);
1039 }
1040 return NS_OK;
1041 }
1042
1043 // Preserve "real" buffered input streams which wrap data (i.e. are backed by
1044 // nsBufferedInputStream), but normalize the wrapped stream.
1045 if (nsCOMPtr<nsIBufferedInputStream> buffered =
1046 do_QueryInterface(aUploadStream)) {
1047 nsCOMPtr<nsIInputStream> data;
1048 if (NS_SUCCEEDED(buffered->GetData(getter_AddRefs(data)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(buffered->GetData
(getter_AddRefs(data)))), 1)))
) {
1049 nsCOMPtr<nsIInputStream> replacement;
1050 nsresult rv = NormalizeUploadStream(data, getter_AddRefs(replacement),
1051 aReadyPromise);
1052 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1052); return rv; } } while (false)
;
1053 if (replacement) {
1054 // This buffer size should be kept in sync with HTMLFormSubmission.
1055 rv = NS_NewBufferedInputStream(aReplacementStream, replacement.forget(),
1056 8192);
1057 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1057); return rv; } } while (false)
;
1058 }
1059 return NS_OK;
1060 }
1061 }
1062
1063 // Preserve multiplex input streams, normalizing each individual inner stream
1064 // to avoid unnecessary copying.
1065 if (nsCOMPtr<nsIMultiplexInputStream> multiplex =
1066 do_QueryInterface(aUploadStream)) {
1067 uint32_t count = multiplex->GetCount();
1068 nsTArray<nsCOMPtr<nsIInputStream>> streams(count);
1069 nsTArray<RefPtr<GenericPromise>> promises(count);
1070 bool replace = false;
1071 for (uint32_t i = 0; i < count; ++i) {
1072 nsCOMPtr<nsIInputStream> inner;
1073 nsresult rv = multiplex->GetStream(i, getter_AddRefs(inner));
1074 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1074); return rv; } } while (false)
;
1075
1076 RefPtr<GenericPromise> promise;
1077 nsCOMPtr<nsIInputStream> replacement;
1078 rv = NormalizeUploadStream(inner, getter_AddRefs(replacement),
1079 getter_AddRefs(promise));
1080 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1080); return rv; } } while (false)
;
1081 if (promise) {
1082 promises.AppendElement(promise);
1083 }
1084 if (replacement) {
1085 streams.AppendElement(replacement);
1086 replace = true;
1087 } else {
1088 streams.AppendElement(inner);
1089 }
1090 }
1091
1092 // If any of the inner streams needed to be replaced, replace the entire
1093 // nsIMultiplexInputStream.
1094 if (replace) {
1095 nsresult rv;
1096 nsCOMPtr<nsIMultiplexInputStream> replacement =
1097 do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1", &rv);
1098 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1098); return rv; } } while (false)
;
1099 for (auto& stream : streams) {
1100 rv = replacement->AppendStream(stream);
1101 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1101); return rv; } } while (false)
;
1102 }
1103
1104 MOZ_ALWAYS_SUCCEEDS(CallQueryInterface(replacement, aReplacementStream))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(CallQueryInterface(replacement, aReplacementStream))), 1))))
, 1))) { } else { do { do { } while (false); MOZ_ReportCrash(
"" "NS_SUCCEEDED(CallQueryInterface(replacement, aReplacementStream))"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1104
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(CallQueryInterface(replacement, aReplacementStream))"
")"); do { MOZ_CrashSequence(__null, 1104); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
1105 }
1106
1107 // Wait for all inner promises to settle before resolving the final promise.
1108 if (!promises.IsEmpty()) {
1109 RefPtr<GenericPromise> ready =
1110 GenericPromise::AllSettled(GetCurrentSerialEventTarget(), promises)
1111 ->Then(GetCurrentSerialEventTarget(), __func__,
1112 [](GenericPromise::AllSettledPromiseType::
1113 ResolveOrRejectValue&& aResults)
1114 -> RefPtr<GenericPromise> {
1115 MOZ_ASSERT(aResults.IsResolve(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aResults.IsResolve())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aResults.IsResolve()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("aResults.IsResolve()"
" (" "AllSettled never rejects" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1116); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aResults.IsResolve()"
") (" "AllSettled never rejects" ")"); do { MOZ_CrashSequence
(__null, 1116); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1116 "AllSettled never rejects")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aResults.IsResolve())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aResults.IsResolve()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("aResults.IsResolve()"
" (" "AllSettled never rejects" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1116); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aResults.IsResolve()"
") (" "AllSettled never rejects" ")"); do { MOZ_CrashSequence
(__null, 1116); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1117 for (auto& result : aResults.ResolveValue()) {
1118 if (result.IsReject()) {
1119 return GenericPromise::CreateAndReject(
1120 result.RejectValue(), __func__);
1121 }
1122 }
1123 return GenericPromise::CreateAndResolve(true, __func__);
1124 });
1125 ready.forget(aReadyPromise);
1126 }
1127 return NS_OK;
1128 }
1129
1130 // If the stream is cloneable, seekable and non-async, we can allow it. Async
1131 // input streams can cause issues, as various consumers of input streams
1132 // expect the payload to be synchronous and `Available()` to be the length of
1133 // the stream, which is not true for asynchronous streams.
1134 nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(aUploadStream);
1135 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(aUploadStream);
1136 if (NS_InputStreamIsCloneable(aUploadStream) && seekable && !async) {
1137 return NS_OK;
1138 }
1139
1140 // Asynchronously copy our non-normalized stream into a StorageStream so that
1141 // it is seekable, cloneable, and synchronous once the copy completes.
1142
1143 NS_WARNING("Upload Stream is being copied into StorageStream")NS_DebugBreak(NS_DEBUG_WARNING, "Upload Stream is being copied into StorageStream"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1143)
;
1144
1145 nsCOMPtr<nsIStorageStream> storageStream;
1146 nsresult rv =
1147 NS_NewStorageStream(4096, UINT32_MAX(4294967295U), getter_AddRefs(storageStream));
1148 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1148); return rv; } } while (false)
;
1149
1150 nsCOMPtr<nsIOutputStream> sink;
1151 rv = storageStream->GetOutputStream(0, getter_AddRefs(sink));
1152 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1152); return rv; } } while (false)
;
1153
1154 nsCOMPtr<nsIInputStream> replacementStream;
1155 rv = storageStream->NewInputStream(0, getter_AddRefs(replacementStream));
1156 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1156); return rv; } } while (false)
;
1157
1158 // Ensure the source stream is buffered before starting the copy so we can use
1159 // ReadSegments, as nsStorageStream doesn't implement WriteSegments.
1160 nsCOMPtr<nsIInputStream> source = aUploadStream;
1161 if (!NS_InputStreamIsBuffered(aUploadStream)) {
1162 nsCOMPtr<nsIInputStream> bufferedSource;
1163 rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedSource),
1164 source.forget(), 4096);
1165 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1165); return rv; } } while (false)
;
1166 source = bufferedSource.forget();
1167 }
1168
1169 // Perform an AsyncCopy into the input stream on the STS.
1170 nsCOMPtr<nsIEventTarget> target =
1171 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/stream-transport-service;1");
1172 RefPtr<GenericPromise::Private> ready = new GenericPromise::Private(__func__);
1173 rv = NS_AsyncCopy(source, sink, target, NS_ASYNCCOPY_VIA_READSEGMENTS, 4096,
1174 NormalizeCopyComplete, do_AddRef(ready).take());
1175 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1175)
) {
1176 ready.get()->Release();
1177 return rv;
1178 }
1179
1180 replacementStream.forget(aReplacementStream);
1181 ready.forget(aReadyPromise);
1182 return NS_OK;
1183}
1184
1185} // anonymous namespace
1186
1187NS_IMETHODIMPnsresult
1188HttpBaseChannel::CloneUploadStream(int64_t* aContentLength,
1189 nsIInputStream** aClonedStream) {
1190 NS_ENSURE_ARG_POINTER(aContentLength)do { if ((__builtin_expect(!!(!(aContentLength)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aContentLength" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1190); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1191 NS_ENSURE_ARG_POINTER(aClonedStream)do { if ((__builtin_expect(!!(!(aClonedStream)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aClonedStream" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1191); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1192 *aClonedStream = nullptr;
1193
1194 if (!XRE_IsParentProcess()) {
1195 NS_WARNING("CloneUploadStream is only supported in the parent process")NS_DebugBreak(NS_DEBUG_WARNING, "CloneUploadStream is only supported in the parent process"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1195)
;
1196 return NS_ERROR_NOT_AVAILABLE;
1197 }
1198
1199 if (!mUploadStream) {
1200 return NS_OK;
1201 }
1202
1203 nsCOMPtr<nsIInputStream> clonedStream;
1204 nsresult rv =
1205 NS_CloneInputStream(mUploadStream, getter_AddRefs(clonedStream));
1206 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1206); return rv; } } while (false)
;
1207
1208 clonedStream.forget(aClonedStream);
1209
1210 *aContentLength = mReqContentLength;
1211 return NS_OK;
1212}
1213
1214//-----------------------------------------------------------------------------
1215// HttpBaseChannel::nsIUploadChannel2
1216//-----------------------------------------------------------------------------
1217
1218NS_IMETHODIMPnsresult
1219HttpBaseChannel::ExplicitSetUploadStream(nsIInputStream* aStream,
1220 const nsACString& aContentType,
1221 int64_t aContentLength,
1222 const nsACString& aMethod) {
1223 // Ensure stream is set and method is valid
1224 NS_ENSURE_TRUE(aStream, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(aStream)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aStream" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1224
); return NS_ERROR_FAILURE; } } while (false)
;
1225
1226 nsresult rv = SetRequestMethod(aMethod);
1227 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1227); return rv; } } while (false)
;
1228
1229 if (!aContentType.IsVoid()) {
1230 if (aContentType.IsEmpty()) {
1231 SetEmptyRequestHeader("Content-Type"_ns);
1232 } else {
1233 SetRequestHeader("Content-Type"_ns, aContentType, false);
1234 }
1235 }
1236
1237 return InternalSetUploadStream(aStream, aContentLength, true);
1238}
1239
1240nsresult HttpBaseChannel::InternalSetUploadStream(
1241 nsIInputStream* aUploadStream, int64_t aContentLength,
1242 bool aSetContentLengthHeader) {
1243 // If we're not on the main thread, such as for TRR, the content length must
1244 // be provided, as we can't normalize our upload stream.
1245 if (!NS_IsMainThread()) {
1246 if (aContentLength < 0) {
1247 MOZ_ASSERT_UNREACHABLE(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Upload content length must be explicit off-main-thread" ")"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1248
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: "
"Upload content length must be explicit off-main-thread" ")"
); do { MOZ_CrashSequence(__null, 1248); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1248 "Upload content length must be explicit off-main-thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Upload content length must be explicit off-main-thread" ")"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1248
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: "
"Upload content length must be explicit off-main-thread" ")"
); do { MOZ_CrashSequence(__null, 1248); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1249 return NS_ERROR_INVALID_ARG;
1250 }
1251
1252 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(aUploadStream);
1253 if (!NS_InputStreamIsCloneable(aUploadStream) || !seekable) {
1254 MOZ_ASSERT_UNREACHABLE(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Upload stream must be cloneable & seekable off-main-thread"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1255); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload stream must be cloneable & seekable off-main-thread"
")"); do { MOZ_CrashSequence(__null, 1255); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1255 "Upload stream must be cloneable & seekable off-main-thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Upload stream must be cloneable & seekable off-main-thread"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1255); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload stream must be cloneable & seekable off-main-thread"
")"); do { MOZ_CrashSequence(__null, 1255); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1256 return NS_ERROR_INVALID_ARG;
1257 }
1258
1259 mUploadStream = aUploadStream;
1260 ExplicitSetUploadStreamLength(aContentLength, aSetContentLengthHeader);
1261 return NS_OK;
1262 }
1263
1264 // Normalize the upload stream we're provided to ensure that it is cloneable,
1265 // seekable, and synchronous when in the parent process.
1266 //
1267 // This might be an async operation, in which case ready will be returned and
1268 // resolved when the operation is complete.
1269 nsCOMPtr<nsIInputStream> replacement;
1270 RefPtr<GenericPromise> ready;
1271 if (XRE_IsParentProcess()) {
1272 nsresult rv = NormalizeUploadStream(
1273 aUploadStream, getter_AddRefs(replacement), getter_AddRefs(ready));
1274 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1274); return rv; } } while (false)
;
1275 }
1276
1277 mUploadStream = replacement ? replacement.get() : aUploadStream;
1278
1279 // Once the upload stream is ready, fetch its length before proceeding with
1280 // AsyncOpen.
1281 auto onReady = [self = RefPtr{this}, aContentLength, aSetContentLengthHeader,
1282 stream = mUploadStream]() {
1283 auto setLengthAndResume = [self, aSetContentLengthHeader](int64_t aLength) {
1284 self->StorePendingUploadStreamNormalization(false);
1285 self->ExplicitSetUploadStreamLength(aLength >= 0 ? aLength : 0,
1286 aSetContentLengthHeader);
1287 self->MaybeResumeAsyncOpen();
1288 };
1289
1290 if (aContentLength >= 0) {
1291 setLengthAndResume(aContentLength);
1292 return;
1293 }
1294
1295 int64_t length;
1296 if (InputStreamLengthHelper::GetSyncLength(stream, &length)) {
1297 setLengthAndResume(length);
1298 return;
1299 }
1300
1301 InputStreamLengthHelper::GetAsyncLength(stream, setLengthAndResume);
1302 };
1303 StorePendingUploadStreamNormalization(true);
1304
1305 // Resolve onReady synchronously unless a promise is returned.
1306 if (ready) {
1307 ready->Then(GetCurrentSerialEventTarget(), __func__,
1308 [onReady = std::move(onReady)](
1309 GenericPromise::ResolveOrRejectValue&&) { onReady(); });
1310 } else {
1311 onReady();
1312 }
1313 return NS_OK;
1314}
1315
1316void HttpBaseChannel::ExplicitSetUploadStreamLength(
1317 uint64_t aContentLength, bool aSetContentLengthHeader) {
1318 // We already have the content length. We don't need to determinate it.
1319 mReqContentLength = aContentLength;
1320
1321 if (!aSetContentLengthHeader) {
1322 return;
1323 }
1324
1325 nsAutoCString header;
1326 header.AssignLiteral("Content-Length");
1327
1328 // Maybe the content-length header has been already set.
1329 nsAutoCString value;
1330 nsresult rv = GetRequestHeader(header, value);
1331 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !value.IsEmpty()) {
1332 return;
1333 }
1334
1335 nsAutoCString contentLengthStr;
1336 contentLengthStr.AppendInt(aContentLength);
1337 SetRequestHeader(header, contentLengthStr, false);
1338}
1339
1340bool HttpBaseChannel::MaybeWaitForUploadStreamNormalization(
1341 nsIStreamListener* aListener, nsISupports* aContext) {
1342 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1342
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1342); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1343 MOZ_ASSERT(!LoadAsyncOpenWaitingForStreamNormalization(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadAsyncOpenWaitingForStreamNormalization())>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!LoadAsyncOpenWaitingForStreamNormalization()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!LoadAsyncOpenWaitingForStreamNormalization()"
" (" "AsyncOpen() called twice?" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadAsyncOpenWaitingForStreamNormalization()"
") (" "AsyncOpen() called twice?" ")"); do { MOZ_CrashSequence
(__null, 1344); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1344 "AsyncOpen() called twice?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadAsyncOpenWaitingForStreamNormalization())>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!LoadAsyncOpenWaitingForStreamNormalization()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!LoadAsyncOpenWaitingForStreamNormalization()"
" (" "AsyncOpen() called twice?" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadAsyncOpenWaitingForStreamNormalization()"
") (" "AsyncOpen() called twice?" ")"); do { MOZ_CrashSequence
(__null, 1344); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1345
1346 if (!LoadPendingUploadStreamNormalization()) {
1347 return false;
1348 }
1349
1350 mListener = aListener;
1351 StoreAsyncOpenWaitingForStreamNormalization(true);
1352 return true;
1353}
1354
1355void HttpBaseChannel::MaybeResumeAsyncOpen() {
1356 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1356
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1356); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1357 MOZ_ASSERT(!LoadPendingUploadStreamNormalization())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadPendingUploadStreamNormalization())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!LoadPendingUploadStreamNormalization()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!LoadPendingUploadStreamNormalization()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1357
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadPendingUploadStreamNormalization()"
")"); do { MOZ_CrashSequence(__null, 1357); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1358
1359 if (!LoadAsyncOpenWaitingForStreamNormalization()) {
1360 return;
1361 }
1362
1363 nsCOMPtr<nsIStreamListener> listener;
1364 listener.swap(mListener);
1365
1366 StoreAsyncOpenWaitingForStreamNormalization(false);
1367
1368 nsresult rv = AsyncOpen(listener);
1369 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1369)
) {
1370 DoAsyncAbort(rv);
1371 }
1372}
1373
1374//-----------------------------------------------------------------------------
1375// HttpBaseChannel::nsIEncodedChannel
1376//-----------------------------------------------------------------------------
1377
1378NS_IMETHODIMPnsresult
1379HttpBaseChannel::GetApplyConversion(bool* value) {
1380 *value = LoadApplyConversion();
1381 return NS_OK;
1382}
1383
1384NS_IMETHODIMPnsresult
1385HttpBaseChannel::SetApplyConversion(bool value) {
1386 LOG(("HttpBaseChannel::SetApplyConversion [this=%p value=%d]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetApplyConversion [this=%p value=%d]\n",
this, value); } } while (0)
1387 value))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetApplyConversion [this=%p value=%d]\n",
this, value); } } while (0)
;
1388 StoreApplyConversion(value);
1389 return NS_OK;
1390}
1391
1392nsresult HttpBaseChannel::DoApplyContentConversions(
1393 nsIStreamListener* aNextListener, nsIStreamListener** aNewNextListener) {
1394 return DoApplyContentConversionsInternal(aNextListener, aNewNextListener,
1395 false, nullptr);
1396}
1397
1398// create a listener chain that looks like this
1399// http-channel -> decompressor (n times) -> InterceptFailedOnSTop ->
1400// channel-creator-listener
1401//
1402// we need to do this because not every decompressor has fully streamed output
1403// so may need a call to OnStopRequest to identify its completion state.. and if
1404// it creates an error there the channel status code needs to be updated before
1405// calling the terminal listener. Having the decompress do it via cancel() means
1406// channels cannot effectively be used in two contexts (specifically this one
1407// and a peek context for sniffing)
1408//
1409class InterceptFailedOnStop : public nsIThreadRetargetableStreamListener {
1410 virtual ~InterceptFailedOnStop() = default;
1411 nsCOMPtr<nsIStreamListener> mNext;
1412 HttpBaseChannel* mChannel;
1413
1414 public:
1415 InterceptFailedOnStop(nsIStreamListener* arg, HttpBaseChannel* chan)
1416 : mNext(arg), mChannel(chan) {}
1417 NS_DECL_THREADSAFE_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::true_type; protected
: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; nsAutoOwningThread
_mOwningThread; public:
1418 NS_DECL_NSITHREADRETARGETABLESTREAMLISTENERvirtual nsresult CheckListenerChain(void) override; virtual nsresult
OnDataFinished(nsresult aStatusCode) override;
1419
1420 NS_IMETHODvirtual nsresult OnStartRequest(nsIRequest* aRequest) override {
1421 nsCOMPtr<nsIStreamListener> next = mNext;
1422 return next->OnStartRequest(aRequest);
1423 }
1424
1425 NS_IMETHODvirtual nsresult OnStopRequest(nsIRequest* aRequest,
1426 nsresult aStatusCode) override {
1427 if (NS_FAILED(aStatusCode)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatusCode)), 0))
)
&& NS_SUCCEEDED(mChannel->mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mChannel->mStatus
)), 1)))
) {
1428 LOG(("HttpBaseChannel::InterceptFailedOnStop %p seting status %" PRIx32,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::InterceptFailedOnStop %p seting status %"
"x", mChannel, static_cast<uint32_t>(aStatusCode)); } }
while (0)
1429 mChannel, static_cast<uint32_t>(aStatusCode)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::InterceptFailedOnStop %p seting status %"
"x", mChannel, static_cast<uint32_t>(aStatusCode)); } }
while (0)
;
1430 mChannel->mStatus = aStatusCode;
1431 }
1432 nsCOMPtr<nsIStreamListener> next = mNext;
1433 return next->OnStopRequest(aRequest, aStatusCode);
1434 }
1435
1436 NS_IMETHODvirtual nsresult OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
1437 uint64_t aOffset, uint32_t aCount) override {
1438 nsCOMPtr<nsIStreamListener> next = mNext;
1439 return next->OnDataAvailable(aRequest, aInputStream, aOffset, aCount);
1440 }
1441};
1442
1443NS_IMPL_ADDREF(InterceptFailedOnStop)MozExternalRefCountType InterceptFailedOnStop::AddRef(void) {
static_assert(!std::is_destructible_v<InterceptFailedOnStop
>, "Reference-counted class " "InterceptFailedOnStop" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1443); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1443
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("InterceptFailedOnStop" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("InterceptFailedOnStop" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"InterceptFailedOnStop\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1443); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"InterceptFailedOnStop\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 1443); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("InterceptFailedOnStop" " not thread-safe");
nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), ("InterceptFailedOnStop"
), (uint32_t)(sizeof(*this))); return count; }
1444NS_IMPL_RELEASE(InterceptFailedOnStop)MozExternalRefCountType InterceptFailedOnStop::Release(void) {
do { static_assert( mozilla::detail::AssertionConditionType<
decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1444); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1444
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("InterceptFailedOnStop" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("InterceptFailedOnStop" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"InterceptFailedOnStop\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1444); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"InterceptFailedOnStop\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 1444); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("InterceptFailedOnStop" " not thread-safe");
const char* const nametmp = "InterceptFailedOnStop"; nsrefcnt
count = --mRefCnt; NS_LogRelease((this), (count), (nametmp))
; if (count == 0) { mRefCnt = 1; delete (this); return 0; } return
count; }
1445
1446NS_INTERFACE_MAP_BEGIN(InterceptFailedOnStop)nsresult InterceptFailedOnStop::QueryInterface(const nsIID&
aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1446); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
1447 NS_INTERFACE_MAP_ENTRY(nsIStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIStreamListener>)) foundInterface
= static_cast<nsIStreamListener*>(this); else
1448 NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequestObserver>)) foundInterface
= static_cast<nsIRequestObserver*>(this); else
1449 NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThreadRetargetableStreamListener>
)) foundInterface = static_cast<nsIThreadRetargetableStreamListener
*>(this); else
1450 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequestObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsIRequestObserver*>(this
)); else
1451NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1451); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 1451); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
1452
1453NS_IMETHODIMPnsresult
1454InterceptFailedOnStop::CheckListenerChain() {
1455 nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
1456 do_QueryInterface(mNext);
1457 if (!listener) {
1458 return NS_ERROR_NO_INTERFACE;
1459 }
1460
1461 return listener->CheckListenerChain();
1462}
1463
1464NS_IMETHODIMPnsresult
1465InterceptFailedOnStop::OnDataFinished(nsresult aStatus) {
1466 nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
1467 do_QueryInterface(mNext);
1468 if (listener) {
1469 return listener->OnDataFinished(aStatus);
1470 }
1471
1472 return NS_OK;
1473}
1474
1475NS_IMETHODIMPnsresult
1476HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
1477 nsIStreamListener** aNewNextListener,
1478 nsISupports* aCtxt) {
1479 return DoApplyContentConversionsInternal(aNextListener, aNewNextListener,
1480 false, aCtxt);
1481}
1482
1483nsresult HttpBaseChannel::DoApplyContentConversionsInternal(
1484 nsIStreamListener* aNextListener, nsIStreamListener** aNewNextListener,
1485 bool aRemoveEncodings, nsISupports* aCtxt) {
1486 *aNewNextListener = nullptr;
1487 if (!mResponseHead || !aNextListener) {
1488 return NS_OK;
1489 }
1490
1491 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::DoApplyContentConversions [this=%p], " "removeEncodings=%d\n"
, this, aRemoveEncodings); } } while (0)
1492 ("HttpBaseChannel::DoApplyContentConversions [this=%p], "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::DoApplyContentConversions [this=%p], " "removeEncodings=%d\n"
, this, aRemoveEncodings); } } while (0)
1493 "removeEncodings=%d\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::DoApplyContentConversions [this=%p], " "removeEncodings=%d\n"
, this, aRemoveEncodings); } } while (0)
1494 this, aRemoveEncodings))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::DoApplyContentConversions [this=%p], " "removeEncodings=%d\n"
, this, aRemoveEncodings); } } while (0)
;
1495
1496#ifdef DEBUG1
1497 {
1498 nsAutoCString contentEncoding;
1499 nsresult rv =
1500 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
1501 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !contentEncoding.IsEmpty()) {
1502 nsAutoCString newEncoding;
1503 char* cePtr = contentEncoding.BeginWriting();
1504 while (char* val = nsCRT::strtok(cePtr, HTTP_LWS" \t" ",", &cePtr)) {
1505 if (strcmp(val, "dcb") == 0 || strcmp(val, "dcz") == 0) {
1506 MOZ_ASSERT(LoadApplyConversion() && !LoadHasAppliedConversion())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadApplyConversion() && !LoadHasAppliedConversion
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(LoadApplyConversion() && !LoadHasAppliedConversion
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("LoadApplyConversion() && !LoadHasAppliedConversion()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1506
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadApplyConversion() && !LoadHasAppliedConversion()"
")"); do { MOZ_CrashSequence(__null, 1506); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1507 }
1508 }
1509 }
1510 }
1511#endif
1512 // dcb/dcz must be decompressed in the parent process. If we reach here
1513 // in the content process with dcb/dcz, the parent failed to handle it.
1514 if (XRE_IsContentProcess()) {
1515 nsAutoCString contentEncoding;
1516 nsresult rv =
1517 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
1518 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && (contentEncoding.LowerCaseEqualsLiteral("dcb") ||
1519 contentEncoding.LowerCaseEqualsLiteral("dcz"))) {
1520 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "dcb/dcz Content-Encoding reached the content process"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1521); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "dcb/dcz Content-Encoding reached the content process"
")"); do { MOZ_CrashSequence(__null, 1521); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1521 false, "dcb/dcz Content-Encoding reached the content process")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "dcb/dcz Content-Encoding reached the content process"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1521); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "dcb/dcz Content-Encoding reached the content process"
")"); do { MOZ_CrashSequence(__null, 1521); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1522 return NS_ERROR_INVALID_CONTENT_ENCODING;
1523 }
1524 }
1525
1526 if (!LoadApplyConversion()) {
1527 LOG(("not applying conversion per ApplyConversion\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "not applying conversion per ApplyConversion\n"); } } while
(0)
;
1528 return NS_OK;
1529 }
1530
1531 if (LoadHasAppliedConversion()) {
1532 LOG(("not applying conversion because HasAppliedConversion is true\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "not applying conversion because HasAppliedConversion is true\n"
); } } while (0)
;
1533 return NS_OK;
1534 }
1535
1536 if (LoadDeliveringAltData()) {
1537 MOZ_ASSERT(!mAvailableCachedAltDataType.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mAvailableCachedAltDataType.IsEmpty())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mAvailableCachedAltDataType.IsEmpty()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mAvailableCachedAltDataType.IsEmpty()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1537
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mAvailableCachedAltDataType.IsEmpty()"
")"); do { MOZ_CrashSequence(__null, 1537); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1538 LOG(("not applying conversion because delivering alt-data\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "not applying conversion because delivering alt-data\n"); }
} while (0)
;
1539 return NS_OK;
1540 }
1541
1542 nsAutoCString contentEncoding;
1543 nsresult rv =
1544 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
1545 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || contentEncoding.IsEmpty()) return NS_OK;
1546
1547 nsCOMPtr<nsIStreamListener> nextListener =
1548 new InterceptFailedOnStop(aNextListener, this);
1549
1550 // The encodings are listed in the order they were applied
1551 // (see rfc 2616 section 14.11), so they need to removed in reverse
1552 // order. This is accomplished because the converter chain ends up
1553 // being a stack with the last converter created being the first one
1554 // to accept the raw network data.
1555
1556 char* cePtr = contentEncoding.BeginWriting();
1557 uint32_t count = 0;
1558 while (char* val = nsCRT::strtok(cePtr, HTTP_LWS" \t" ",", &cePtr)) {
1559 if (++count > 16) {
1560 // For compatibility with old code, we will just carry on without
1561 // removing the encodings
1562 LOG(("Too many Content-Encodings. Ignoring remainder.\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Too many Content-Encodings. Ignoring remainder.\n"); } } while
(0)
;
1563 break;
1564 }
1565
1566 if (gHttpHandler->IsAcceptableEncoding(val,
1567 isSecureOrTrustworthyURL(mURI))) {
1568 RefPtr<nsHTTPCompressConv> converter = new nsHTTPCompressConv();
1569 nsAutoCString from(val);
1570 ToLowerCase(from);
1571 rv = converter->AsyncConvertData(from.get(), "uncompressed", nextListener,
1572 aCtxt);
1573 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1574 LOG(("Unexpected failure of AsyncConvertData %s\n", val))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Unexpected failure of AsyncConvertData %s\n", val); } } while
(0)
;
1575 return rv;
1576 }
1577
1578 LOG(("Adding converter for content-encoding '%s'", val))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Adding converter for content-encoding '%s'", val); } } while
(0)
;
1579 if (Telemetry::CanRecordPrereleaseData()) {
1580 int mode = 0;
1581 if (from.EqualsLiteral("gzip") || from.EqualsLiteral("x-gzip")) {
1582 mode = 1;
1583 } else if (from.EqualsLiteral("deflate") ||
1584 from.EqualsLiteral("x-deflate")) {
1585 mode = 2;
1586 } else if (from.EqualsLiteral("br")) {
1587 mode = 3;
1588 } else if (from.EqualsLiteral("zstd")) {
1589 mode = 4;
1590 } else if (from.EqualsLiteral("dcb")) {
1591 mode = 5;
1592 } else if (from.EqualsLiteral("dcz")) {
1593 mode = 6;
1594 }
1595 glean::http::content_encoding.AccumulateSingleSample(mode);
1596 }
1597#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED1
1598 if (from.EqualsLiteral("dcb") || from.EqualsLiteral("dcz")) {
1599 MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1599
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 1599); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1600 }
1601#endif
1602 nextListener = converter;
1603 } else {
1604 if (val) {
1605 LOG(("Unknown content encoding '%s'\n", val))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Unknown content encoding '%s'\n", val); } } while (0)
;
1606 }
1607 // we *should* return NS_ERROR_UNEXPECTED here, but that will break sites
1608 // that use things like content-encoding: x-gzip, x-gzip (or any other
1609 // weird encoding)
1610 }
1611 }
1612
1613 // dcb and dcz encodings are removed when it's decompressed (always in
1614 // the parent process). However, in theory you could have
1615 // Content-Encoding: dcb,gzip
1616 // in which case we could pass it down to the content process as
1617 // Content-Encoding: gzip. We won't do that; we'll remove all compressors
1618 // if we need to remove any.
1619 // This double compression of course is silly, but supported by the spec.
1620 if (aRemoveEncodings) {
1621 // If we have dcb or dcz, all content-encodings in the header should be
1622 // removed as we're decompressing before the tee in the parent
1623 // process. Also we should remove any encodings if it's a dictionary
1624 // so we can load it quickly
1625 LOG(("Changing Content-Encoding from '%s' to ''", contentEncoding.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Changing Content-Encoding from '%s' to ''", contentEncoding
.get()); } } while (0)
;
1626 // Can't use SetHeader; we need to overwrite the current value
1627 rv = mResponseHead->SetHeaderOverride(nsHttp::Content_Encoding, ""_ns);
1628 rv = mResponseHead->SetHeaderOverride(nsHttp::Content_Length, ""_ns);
Value stored to 'rv' is never read
1629 }
1630 *aNewNextListener = do_AddRef(nextListener).take();
1631 return NS_OK;
1632}
1633
1634NS_IMETHODIMPnsresult
1635HttpBaseChannel::GetContentEncodings(nsIUTF8StringEnumerator** aEncodings) {
1636 if (!mResponseHead) {
1637 *aEncodings = nullptr;
1638 return NS_OK;
1639 }
1640
1641 nsAutoCString encoding;
1642 (void)mResponseHead->GetHeader(nsHttp::Content_Encoding, encoding);
1643 if (encoding.IsEmpty()) {
1644 *aEncodings = nullptr;
1645 return NS_OK;
1646 }
1647 RefPtr<nsContentEncodings> enumerator =
1648 new nsContentEncodings(this, encoding.get());
1649 enumerator.forget(aEncodings);
1650 return NS_OK;
1651}
1652
1653//-----------------------------------------------------------------------------
1654// HttpBaseChannel::nsContentEncodings <public>
1655//-----------------------------------------------------------------------------
1656
1657HttpBaseChannel::nsContentEncodings::nsContentEncodings(
1658 nsIHttpChannel* aChannel, const char* aEncodingHeader)
1659 : mEncodingHeader(aEncodingHeader), mChannel(aChannel), mReady(false) {
1660 mCurEnd = aEncodingHeader + strlen(aEncodingHeader);
1661 mCurStart = mCurEnd;
1662}
1663
1664//-----------------------------------------------------------------------------
1665// HttpBaseChannel::nsContentEncodings::nsISimpleEnumerator
1666//-----------------------------------------------------------------------------
1667
1668NS_IMETHODIMPnsresult
1669HttpBaseChannel::nsContentEncodings::HasMore(bool* aMoreEncodings) {
1670 if (mReady) {
1671 *aMoreEncodings = true;
1672 return NS_OK;
1673 }
1674
1675 nsresult rv = PrepareForNext();
1676 *aMoreEncodings = NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)));
1677 return NS_OK;
1678}
1679
1680NS_IMETHODIMPnsresult
1681HttpBaseChannel::nsContentEncodings::GetNext(nsACString& aNextEncoding) {
1682 aNextEncoding.Truncate();
1683 if (!mReady) {
1684 nsresult rv = PrepareForNext();
1685 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1686 return NS_ERROR_FAILURE;
1687 }
1688 }
1689
1690 const nsACString& encoding = Substring(mCurStart, mCurEnd);
1691
1692 nsACString::const_iterator start, end;
1693 encoding.BeginReading(start);
1694 encoding.EndReading(end);
1695
1696 bool haveType = false;
1697 if (CaseInsensitiveFindInReadable("gzip"_ns, start, end)) {
1698 aNextEncoding.AssignLiteral(APPLICATION_GZIP"application/x-gzip");
1699 haveType = true;
1700 }
1701
1702 if (!haveType) {
1703 encoding.BeginReading(start);
1704 if (CaseInsensitiveFindInReadable("compress"_ns, start, end)) {
1705 aNextEncoding.AssignLiteral(APPLICATION_COMPRESS"application/x-compress");
1706 haveType = true;
1707 }
1708 }
1709
1710 if (!haveType) {
1711 encoding.BeginReading(start);
1712 if (CaseInsensitiveFindInReadable("deflate"_ns, start, end)) {
1713 aNextEncoding.AssignLiteral(APPLICATION_ZIP"application/zip");
1714 haveType = true;
1715 }
1716 }
1717
1718 if (!haveType) {
1719 encoding.BeginReading(start);
1720 if (CaseInsensitiveFindInReadable("br"_ns, start, end)) {
1721 aNextEncoding.AssignLiteral(APPLICATION_BROTLI"application/brotli");
1722 haveType = true;
1723 }
1724 }
1725
1726 if (!haveType) {
1727 encoding.BeginReading(start);
1728 if (CaseInsensitiveFindInReadable("zstd"_ns, start, end)) {
1729 aNextEncoding.AssignLiteral(APPLICATION_ZSTD"application/zstd");
1730 haveType = true;
1731 }
1732 }
1733
1734 // Prepare to fetch the next encoding
1735 mCurEnd = mCurStart;
1736 mReady = false;
1737
1738 if (haveType) return NS_OK;
1739
1740 NS_WARNING("Unknown encoding type")NS_DebugBreak(NS_DEBUG_WARNING, "Unknown encoding type", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1740
)
;
1741 return NS_ERROR_FAILURE;
1742}
1743
1744//-----------------------------------------------------------------------------
1745// HttpBaseChannel::nsContentEncodings::nsISupports
1746//-----------------------------------------------------------------------------
1747
1748NS_IMPL_ISUPPORTS(HttpBaseChannel::nsContentEncodings, nsIUTF8StringEnumerator,MozExternalRefCountType HttpBaseChannel::nsContentEncodings::
AddRef(void) { static_assert(!std::is_destructible_v<HttpBaseChannel
::nsContentEncodings>, "Reference-counted class " "HttpBaseChannel::nsContentEncodings"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1749
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel::nsContentEncodings" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("HttpBaseChannel::nsContentEncodings" != nullptr))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("\"HttpBaseChannel::nsContentEncodings\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 1749); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("HttpBaseChannel::nsContentEncodings" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"HttpBaseChannel::nsContentEncodings"), (uint32_t)(sizeof(*this
))); return count; } MozExternalRefCountType HttpBaseChannel::
nsContentEncodings::Release(void) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(int32_t(mRefCnt)
> 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1749
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel::nsContentEncodings" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("HttpBaseChannel::nsContentEncodings" != nullptr))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("\"HttpBaseChannel::nsContentEncodings\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 1749); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("HttpBaseChannel::nsContentEncodings" " not thread-safe"
); const char* const nametmp = "HttpBaseChannel::nsContentEncodings"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult HttpBaseChannel::nsContentEncodings
::QueryInterface(const nsIID& aIID, void** aInstancePtr) {
do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1749
); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(2 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<HttpBaseChannel::nsContentEncodings, nsIUTF8StringEnumerator
>, int32_t( reinterpret_cast<char*>(static_cast<nsIUTF8StringEnumerator
*>((HttpBaseChannel::nsContentEncodings*)0x1000)) - reinterpret_cast
<char*>((HttpBaseChannel::nsContentEncodings*)0x1000))}
, {&mozilla::detail::kImplementedIID<HttpBaseChannel::
nsContentEncodings, nsIStringEnumerator>, int32_t( reinterpret_cast
<char*>(static_cast<nsIStringEnumerator*>((HttpBaseChannel
::nsContentEncodings*)0x1000)) - reinterpret_cast<char*>
((HttpBaseChannel::nsContentEncodings*)0x1000))}, {&mozilla
::detail::kImplementedIID<HttpBaseChannel::nsContentEncodings
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIUTF8StringEnumerator*
>((HttpBaseChannel::nsContentEncodings*)0x1000))) - reinterpret_cast
<char*>((HttpBaseChannel::nsContentEncodings*)0x1000))}
, { nullptr, 0 } } ; static_assert(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
1749 nsIStringEnumerator)MozExternalRefCountType HttpBaseChannel::nsContentEncodings::
AddRef(void) { static_assert(!std::is_destructible_v<HttpBaseChannel
::nsContentEncodings>, "Reference-counted class " "HttpBaseChannel::nsContentEncodings"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1749
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel::nsContentEncodings" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("HttpBaseChannel::nsContentEncodings" != nullptr))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("\"HttpBaseChannel::nsContentEncodings\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 1749); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("HttpBaseChannel::nsContentEncodings" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"HttpBaseChannel::nsContentEncodings"), (uint32_t)(sizeof(*this
))); return count; } MozExternalRefCountType HttpBaseChannel::
nsContentEncodings::Release(void) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(int32_t(mRefCnt)
> 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1749
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel::nsContentEncodings" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("HttpBaseChannel::nsContentEncodings" != nullptr))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("\"HttpBaseChannel::nsContentEncodings\" != nullptr"
" (" "Must specify a name" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 1749); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("HttpBaseChannel::nsContentEncodings" " not thread-safe"
); const char* const nametmp = "HttpBaseChannel::nsContentEncodings"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult HttpBaseChannel::nsContentEncodings
::QueryInterface(const nsIID& aIID, void** aInstancePtr) {
do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1749
); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(2 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<HttpBaseChannel::nsContentEncodings, nsIUTF8StringEnumerator
>, int32_t( reinterpret_cast<char*>(static_cast<nsIUTF8StringEnumerator
*>((HttpBaseChannel::nsContentEncodings*)0x1000)) - reinterpret_cast
<char*>((HttpBaseChannel::nsContentEncodings*)0x1000))}
, {&mozilla::detail::kImplementedIID<HttpBaseChannel::
nsContentEncodings, nsIStringEnumerator>, int32_t( reinterpret_cast
<char*>(static_cast<nsIStringEnumerator*>((HttpBaseChannel
::nsContentEncodings*)0x1000)) - reinterpret_cast<char*>
((HttpBaseChannel::nsContentEncodings*)0x1000))}, {&mozilla
::detail::kImplementedIID<HttpBaseChannel::nsContentEncodings
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIUTF8StringEnumerator*
>((HttpBaseChannel::nsContentEncodings*)0x1000))) - reinterpret_cast
<char*>((HttpBaseChannel::nsContentEncodings*)0x1000))}
, { nullptr, 0 } } ; static_assert(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
1750
1751//-----------------------------------------------------------------------------
1752// HttpBaseChannel::nsContentEncodings <private>
1753//-----------------------------------------------------------------------------
1754
1755nsresult HttpBaseChannel::nsContentEncodings::PrepareForNext(void) {
1756 MOZ_ASSERT(mCurStart == mCurEnd, "Indeterminate state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCurStart == mCurEnd)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCurStart == mCurEnd))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mCurStart == mCurEnd"
" (" "Indeterminate state" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1756); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurStart == mCurEnd"
") (" "Indeterminate state" ")"); do { MOZ_CrashSequence(__null
, 1756); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
1757
1758 // At this point both mCurStart and mCurEnd point to somewhere
1759 // past the end of the next thing we want to return
1760
1761 while (mCurEnd != mEncodingHeader) {
1762 --mCurEnd;
1763 if (*mCurEnd != ',' && !nsCRT::IsAsciiSpace(*mCurEnd)) break;
1764 }
1765 if (mCurEnd == mEncodingHeader) {
1766 return NS_ERROR_NOT_AVAILABLE; // no more encodings
1767 }
1768 ++mCurEnd;
1769
1770 // At this point mCurEnd points to the first char _after_ the
1771 // header we want. Furthermore, mCurEnd - 1 != mEncodingHeader
1772
1773 mCurStart = mCurEnd - 1;
1774 while (mCurStart != mEncodingHeader && *mCurStart != ',' &&
1775 !nsCRT::IsAsciiSpace(*mCurStart)) {
1776 --mCurStart;
1777 }
1778 if (*mCurStart == ',' || nsCRT::IsAsciiSpace(*mCurStart)) {
1779 ++mCurStart; // we stopped because of a weird char, so move up one
1780 }
1781
1782 // At this point mCurStart and mCurEnd bracket the encoding string
1783 // we want. Check that it's not "identity"
1784 if (Substring(mCurStart, mCurEnd)
1785 .Equals("identity", nsCaseInsensitiveCStringComparator)) {
1786 mCurEnd = mCurStart;
1787 return PrepareForNext();
1788 }
1789
1790 mReady = true;
1791 return NS_OK;
1792}
1793
1794//-----------------------------------------------------------------------------
1795// HttpBaseChannel::nsIHttpChannel
1796//-----------------------------------------------------------------------------
1797
1798NS_IMETHODIMPnsresult
1799HttpBaseChannel::GetChannelId(uint64_t* aChannelId) {
1800 NS_ENSURE_ARG_POINTER(aChannelId)do { if ((__builtin_expect(!!(!(aChannelId)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aChannelId" ") failed",
nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1800); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1801 *aChannelId = mChannelId;
1802 return NS_OK;
1803}
1804
1805NS_IMETHODIMPnsresult
1806HttpBaseChannel::SetChannelId(uint64_t aChannelId) {
1807 mChannelId = aChannelId;
1808 return NS_OK;
1809}
1810
1811NS_IMETHODIMPnsresult HttpBaseChannel::GetTopLevelContentWindowId(uint64_t* aWindowId) {
1812 if (!mContentWindowId) {
1813 nsCOMPtr<nsILoadContext> loadContext;
1814 GetCallback(loadContext);
1815 if (loadContext) {
1816 nsCOMPtr<mozIDOMWindowProxy> topWindow;
1817 loadContext->GetTopWindow(getter_AddRefs(topWindow));
1818 if (topWindow) {
1819 if (nsPIDOMWindowInner* inner =
1820 nsPIDOMWindowOuter::From(topWindow)->GetCurrentInnerWindow()) {
1821 mContentWindowId = inner->WindowID();
1822 }
1823 }
1824 }
1825 }
1826 *aWindowId = mContentWindowId;
1827 return NS_OK;
1828}
1829
1830NS_IMETHODIMPnsresult HttpBaseChannel::SetBrowserId(uint64_t aId) {
1831 mBrowserId = aId;
1832 return NS_OK;
1833}
1834
1835NS_IMETHODIMPnsresult HttpBaseChannel::GetBrowserId(uint64_t* aId) {
1836 EnsureBrowserId();
1837 *aId = mBrowserId;
1838 return NS_OK;
1839}
1840
1841NS_IMETHODIMPnsresult HttpBaseChannel::SetTopLevelContentWindowId(uint64_t aWindowId) {
1842 mContentWindowId = aWindowId;
1843 return NS_OK;
1844}
1845
1846NS_IMETHODIMPnsresult
1847HttpBaseChannel::IsThirdPartyTrackingResource(bool* aIsTrackingResource) {
1848 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags)"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1849
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags)"
")"); do { MOZ_CrashSequence(__null, 1849); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1849 !(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags)"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1849
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags)"
")"); do { MOZ_CrashSequence(__null, 1849); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1850 *aIsTrackingResource = ChannelClassifierUtils::IsTrackingClassificationFlag(
1851 mThirdPartyClassificationFlags,
1852 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing());
1853 return NS_OK;
1854}
1855
1856NS_IMETHODIMPnsresult
1857HttpBaseChannel::IsThirdPartySocialTrackingResource(
1858 bool* aIsThirdPartySocialTrackingResource) {
1859 MOZ_ASSERT(!mFirstPartyClassificationFlags ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1860
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { MOZ_CrashSequence(__null, 1860); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1860 !mThirdPartyClassificationFlags)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1860
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { MOZ_CrashSequence(__null, 1860); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1861 *aIsThirdPartySocialTrackingResource =
1862 ChannelClassifierUtils::IsSocialTrackingClassificationFlag(
1863 mThirdPartyClassificationFlags);
1864 return NS_OK;
1865}
1866
1867NS_IMETHODIMPnsresult
1868HttpBaseChannel::GetClassificationFlags(uint32_t* aFlags) {
1869 if (mThirdPartyClassificationFlags) {
1870 *aFlags = mThirdPartyClassificationFlags;
1871 } else {
1872 *aFlags = mFirstPartyClassificationFlags;
1873 }
1874 return NS_OK;
1875}
1876
1877NS_IMETHODIMPnsresult
1878HttpBaseChannel::GetFirstPartyClassificationFlags(uint32_t* aFlags) {
1879 *aFlags = mFirstPartyClassificationFlags;
1880 return NS_OK;
1881}
1882
1883NS_IMETHODIMPnsresult
1884HttpBaseChannel::GetThirdPartyClassificationFlags(uint32_t* aFlags) {
1885 *aFlags = mThirdPartyClassificationFlags;
1886 return NS_OK;
1887}
1888
1889NS_IMETHODIMPnsresult
1890HttpBaseChannel::GetTransferSize(uint64_t* aTransferSize) {
1891 *aTransferSize = mTransferSize;
1892 return NS_OK;
1893}
1894
1895NS_IMETHODIMPnsresult
1896HttpBaseChannel::GetRequestSize(uint64_t* aRequestSize) {
1897 *aRequestSize = mRequestSize;
1898 return NS_OK;
1899}
1900
1901NS_IMETHODIMPnsresult
1902HttpBaseChannel::GetDecodedBodySize(uint64_t* aDecodedBodySize) {
1903 *aDecodedBodySize = mDecodedBodySize;
1904 return NS_OK;
1905}
1906
1907NS_IMETHODIMPnsresult
1908HttpBaseChannel::GetEncodedBodySize(uint64_t* aEncodedBodySize) {
1909 *aEncodedBodySize = mEncodedBodySize;
1910 return NS_OK;
1911}
1912
1913NS_IMETHODIMPnsresult
1914HttpBaseChannel::GetSupportsHTTP3(bool* aSupportsHTTP3) {
1915 *aSupportsHTTP3 = mSupportsHTTP3;
1916 return NS_OK;
1917}
1918
1919NS_IMETHODIMPnsresult
1920HttpBaseChannel::GetHasHTTPSRR(bool* aHasHTTPSRR) {
1921 *aHasHTTPSRR = LoadHasHTTPSRR();
1922 return NS_OK;
1923}
1924
1925NS_IMETHODIMPnsresult
1926HttpBaseChannel::GetRequestMethod(nsACString& aMethod) {
1927 mRequestHead.Method(aMethod);
1928 return NS_OK;
1929}
1930
1931NS_IMETHODIMPnsresult
1932HttpBaseChannel::SetRequestMethod(const nsACString& aMethod) {
1933 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1933); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1933, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1933); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1933
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 1933); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
1934
1935 mLoadInfo->SetIsGETRequest(aMethod.Equals("GET"));
1936
1937 const nsCString& flatMethod = PromiseFlatCStringTPromiseFlatString<char>(aMethod);
1938
1939 // Method names are restricted to valid HTTP tokens.
1940 if (!nsHttp::IsValidToken(flatMethod)) return NS_ERROR_INVALID_ARG;
1941
1942 mRequestHead.SetMethod(flatMethod);
1943 return NS_OK;
1944}
1945
1946NS_IMETHODIMPnsresult
1947HttpBaseChannel::GetReferrerInfo(nsIReferrerInfo** aReferrerInfo) {
1948 NS_ENSURE_ARG_POINTER(aReferrerInfo)do { if ((__builtin_expect(!!(!(aReferrerInfo)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aReferrerInfo" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1948); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1949 *aReferrerInfo = do_AddRef(mReferrerInfo).take();
1950 return NS_OK;
1951}
1952
1953nsresult HttpBaseChannel::SetReferrerInfoInternal(
1954 nsIReferrerInfo* aReferrerInfo, bool aClone, bool aCompute,
1955 bool aRespectBeforeConnect) {
1956 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetReferrerInfoInternal [this=%p aClone(%d) "
"aCompute(%d)]\n", this, aClone, aCompute); } } while (0)
1957 ("HttpBaseChannel::SetReferrerInfoInternal [this=%p aClone(%d) "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetReferrerInfoInternal [this=%p aClone(%d) "
"aCompute(%d)]\n", this, aClone, aCompute); } } while (0)
1958 "aCompute(%d)]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetReferrerInfoInternal [this=%p aClone(%d) "
"aCompute(%d)]\n", this, aClone, aCompute); } } while (0)
1959 this, aClone, aCompute))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetReferrerInfoInternal [this=%p aClone(%d) "
"aCompute(%d)]\n", this, aClone, aCompute); } } while (0)
;
1960 if (aRespectBeforeConnect) {
1961 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1961); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1961, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1961); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 1961
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 1961); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
1962 }
1963
1964 mReferrerInfo = aReferrerInfo;
1965
1966 // clear existing referrer, if any
1967 nsresult rv = ClearReferrerHeader();
1968 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1968)
) {
1969 return rv;
1970 }
1971
1972 if (!mReferrerInfo) {
1973 return NS_OK;
1974 }
1975
1976 if (aClone) {
1977 mReferrerInfo = static_cast<dom::ReferrerInfo*>(aReferrerInfo)->Clone();
1978 }
1979
1980 dom::ReferrerInfo* referrerInfo =
1981 static_cast<dom::ReferrerInfo*>(mReferrerInfo.get());
1982
1983 // Don't set referrerInfo if it has not been initialized.
1984 if (!referrerInfo->IsInitialized()) {
1985 mReferrerInfo = nullptr;
1986 return NS_ERROR_NOT_INITIALIZED;
1987 }
1988
1989 if (aCompute) {
1990 rv = referrerInfo->ComputeReferrer(this);
1991 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 1991)
) {
1992 return rv;
1993 }
1994 }
1995
1996 nsCOMPtr<nsIURI> computedReferrer = mReferrerInfo->GetComputedReferrer();
1997 if (!computedReferrer) {
1998 return NS_OK;
1999 }
2000
2001 nsAutoCString spec;
2002 rv = computedReferrer->GetSpec(spec);
2003 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2003)
) {
2004 return rv;
2005 }
2006
2007 return SetReferrerHeader(spec, aRespectBeforeConnect);
2008}
2009
2010NS_IMETHODIMPnsresult
2011HttpBaseChannel::SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
2012 return SetReferrerInfoInternal(aReferrerInfo, true, true, true);
2013}
2014
2015NS_IMETHODIMPnsresult
2016HttpBaseChannel::SetReferrerInfoWithoutClone(nsIReferrerInfo* aReferrerInfo) {
2017 return SetReferrerInfoInternal(aReferrerInfo, false, true, true);
2018}
2019
2020// Return the channel's proxy URI, or if it doesn't exist, the
2021// channel's main URI.
2022NS_IMETHODIMPnsresult
2023HttpBaseChannel::GetProxyURI(nsIURI** aOut) {
2024 NS_ENSURE_ARG_POINTER(aOut)do { if ((__builtin_expect(!!(!(aOut)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOut" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2024
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2025 nsCOMPtr<nsIURI> result(mProxyURI);
2026 result.forget(aOut);
2027 return NS_OK;
2028}
2029
2030NS_IMETHODIMPnsresult
2031HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
2032 nsACString& aValue) {
2033 aValue.Truncate();
2034
2035 // XXX might be better to search the header list directly instead of
2036 // hitting the http atom hash table.
2037 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
2038 if (!atom) return NS_ERROR_NOT_AVAILABLE;
2039
2040 return mRequestHead.GetHeader(atom, aValue);
2041}
2042
2043NS_IMETHODIMPnsresult
2044HttpBaseChannel::SetRequestHeader(const nsACString& aHeader,
2045 const nsACString& aValue, bool aMerge) {
2046 return SetRequestHeaderInternal(aHeader, aValue, aMerge,
2047 nsHttpHeaderArray::eVarietyRequestOverride);
2048}
2049
2050nsresult HttpBaseChannel::SetRequestHeaderInternal(
2051 const nsACString& aHeader, const nsACString& aValue, bool aMerge,
2052 nsHttpHeaderArray::HeaderVariety aVariety) {
2053 const nsCString& flatHeader = PromiseFlatCStringTPromiseFlatString<char>(aHeader);
2054 const nsCString& flatValue = PromiseFlatCStringTPromiseFlatString<char>(aValue);
2055
2056 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, flatHeader.get(), flatValue.get(), aMerge
); } } while (0)
2057 ("HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, flatHeader.get(), flatValue.get(), aMerge
); } } while (0)
2058 "merge=%u]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, flatHeader.get(), flatValue.get(), aMerge
); } } while (0)
2059 this, flatHeader.get(), flatValue.get(), aMerge))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, flatHeader.get(), flatValue.get(), aMerge
); } } while (0)
;
2060
2061 // Verify header names are valid HTTP tokens and header values are reasonably
2062 // close to whats allowed in RFC 2616.
2063 if (!nsHttp::IsValidToken(flatHeader) ||
2064 !nsHttp::IsReasonableHeaderValue(flatValue)) {
2065 return NS_ERROR_INVALID_ARG;
2066 }
2067
2068 // Mark that the User-Agent header has been modified.
2069 if (nsHttp::ResolveAtom(aHeader) == nsHttp::User_Agent) {
2070 StoreIsUserAgentHeaderModified(true);
2071 }
2072
2073 return mRequestHead.SetHeader(aHeader, flatValue, aMerge, aVariety);
2074}
2075
2076NS_IMETHODIMPnsresult
2077HttpBaseChannel::SetNewReferrerInfo(const nsACString& aUrl,
2078 nsIReferrerInfo::ReferrerPolicyIDL aPolicy,
2079 bool aSendReferrer) {
2080 nsresult rv;
2081 // Create URI from string
2082 nsCOMPtr<nsIURI> aURI;
2083 rv = NS_NewURI(getter_AddRefs(aURI), aUrl);
2084 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2084); return rv; } } while (false)
;
2085 // Create new ReferrerInfo and initialize it.
2086 nsCOMPtr<nsIReferrerInfo> referrerInfo = new mozilla::dom::ReferrerInfo();
2087 rv = referrerInfo->Init(aPolicy, aSendReferrer, aURI);
2088 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2088); return rv; } } while (false)
;
2089 // Set ReferrerInfo
2090 return SetReferrerInfo(referrerInfo);
2091}
2092
2093NS_IMETHODIMPnsresult
2094HttpBaseChannel::SetEmptyRequestHeader(const nsACString& aHeader) {
2095 const nsCString& flatHeader = PromiseFlatCStringTPromiseFlatString<char>(aHeader);
2096
2097 LOG(("HttpBaseChannel::SetEmptyRequestHeader [this=%p header=\"%s\"]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetEmptyRequestHeader [this=%p header=\"%s\"]\n"
, this, flatHeader.get()); } } while (0)
2098 flatHeader.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetEmptyRequestHeader [this=%p header=\"%s\"]\n"
, this, flatHeader.get()); } } while (0)
;
2099
2100 // Verify header names are valid HTTP tokens and header values are reasonably
2101 // close to whats allowed in RFC 2616.
2102 if (!nsHttp::IsValidToken(flatHeader)) {
2103 return NS_ERROR_INVALID_ARG;
2104 }
2105
2106 // Mark that the User-Agent header has been modified.
2107 if (nsHttp::ResolveAtom(aHeader) == nsHttp::User_Agent) {
2108 StoreIsUserAgentHeaderModified(true);
2109 }
2110
2111 return mRequestHead.SetEmptyHeader(aHeader);
2112}
2113
2114NS_IMETHODIMPnsresult
2115HttpBaseChannel::VisitRequestHeaders(nsIHttpHeaderVisitor* visitor) {
2116 return mRequestHead.VisitHeaders(visitor);
2117}
2118
2119NS_IMETHODIMPnsresult
2120HttpBaseChannel::VisitNonDefaultRequestHeaders(nsIHttpHeaderVisitor* visitor) {
2121 return mRequestHead.VisitHeaders(visitor,
2122 nsHttpHeaderArray::eFilterSkipDefault);
2123}
2124
2125NS_IMETHODIMPnsresult
2126HttpBaseChannel::GetResponseHeader(const nsACString& header,
2127 nsACString& value) {
2128 value.Truncate();
2129
2130 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2131
2132 nsHttpAtom atom = nsHttp::ResolveAtom(header);
2133 if (!atom) return NS_ERROR_NOT_AVAILABLE;
2134
2135 return mResponseHead->GetHeader(atom, value);
2136}
2137
2138NS_IMETHODIMPnsresult
2139HttpBaseChannel::SetResponseHeader(const nsACString& header,
2140 const nsACString& value, bool merge) {
2141 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, TPromiseFlatString<char>(header).
get(), TPromiseFlatString<char>(value).get(), merge); }
} while (0)
2142 ("HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, TPromiseFlatString<char>(header).
get(), TPromiseFlatString<char>(value).get(), merge); }
} while (0)
2143 "merge=%u]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, TPromiseFlatString<char>(header).
get(), TPromiseFlatString<char>(value).get(), merge); }
} while (0)
2144 this, PromiseFlatCString(header).get(), PromiseFlatCString(value).get(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, TPromiseFlatString<char>(header).
get(), TPromiseFlatString<char>(value).get(), merge); }
} while (0)
2145 merge))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, TPromiseFlatString<char>(header).
get(), TPromiseFlatString<char>(value).get(), merge); }
} while (0)
;
2146
2147 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2148
2149 nsHttpAtom atom = nsHttp::ResolveAtom(header);
2150 if (!atom) return NS_ERROR_NOT_AVAILABLE;
2151
2152 // these response headers must not be changed
2153 if (atom == nsHttp::Content_Type || atom == nsHttp::Content_Length ||
2154 atom == nsHttp::Content_Encoding || atom == nsHttp::Trailer ||
2155 atom == nsHttp::Transfer_Encoding) {
2156 return NS_ERROR_ILLEGAL_VALUE;
2157 }
2158
2159 StoreResponseHeadersModified(true);
2160
2161 return mResponseHead->SetHeader(header, value, merge);
2162}
2163
2164NS_IMETHODIMPnsresult
2165HttpBaseChannel::VisitResponseHeaders(nsIHttpHeaderVisitor* visitor) {
2166 if (!mResponseHead) {
2167 return NS_ERROR_NOT_AVAILABLE;
2168 }
2169 return mResponseHead->VisitHeaders(visitor,
2170 nsHttpHeaderArray::eFilterResponse);
2171}
2172
2173NS_IMETHODIMPnsresult
2174HttpBaseChannel::GetOriginalResponseHeader(const nsACString& aHeader,
2175 nsIHttpHeaderVisitor* aVisitor) {
2176 if (!mResponseHead) {
2177 return NS_ERROR_NOT_AVAILABLE;
2178 }
2179
2180 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
2181 if (!atom) {
2182 return NS_ERROR_NOT_AVAILABLE;
2183 }
2184
2185 return mResponseHead->GetOriginalHeader(atom, aVisitor);
2186}
2187
2188NS_IMETHODIMPnsresult
2189HttpBaseChannel::VisitOriginalResponseHeaders(nsIHttpHeaderVisitor* aVisitor) {
2190 if (!mResponseHead) {
2191 return NS_ERROR_NOT_AVAILABLE;
2192 }
2193
2194 return mResponseHead->VisitHeaders(
2195 aVisitor, nsHttpHeaderArray::eFilterResponseOriginal);
2196}
2197
2198NS_IMETHODIMPnsresult
2199HttpBaseChannel::GetAllowSTS(bool* value) {
2200 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2200
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2201 *value = LoadAllowSTS();
2202 return NS_OK;
2203}
2204
2205NS_IMETHODIMPnsresult
2206HttpBaseChannel::SetAllowSTS(bool value) {
2207 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2207); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2207, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2207); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2207
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 2207); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2208 StoreAllowSTS(value);
2209 return NS_OK;
2210}
2211
2212NS_IMETHODIMPnsresult
2213HttpBaseChannel::GetIsOCSP(bool* value) {
2214 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2214
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2215 *value = LoadIsOCSP();
2216 return NS_OK;
2217}
2218
2219NS_IMETHODIMPnsresult
2220HttpBaseChannel::SetIsOCSP(bool value) {
2221 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2221); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2221, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2221); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2221
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 2221); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2222 StoreIsOCSP(value);
2223 return NS_OK;
2224}
2225
2226NS_IMETHODIMPnsresult
2227HttpBaseChannel::GetIsUserAgentHeaderModified(bool* value) {
2228 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2228
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2229 *value = LoadIsUserAgentHeaderModified();
2230 return NS_OK;
2231}
2232
2233NS_IMETHODIMPnsresult
2234HttpBaseChannel::SetIsUserAgentHeaderModified(bool value) {
2235 StoreIsUserAgentHeaderModified(value);
2236 return NS_OK;
2237}
2238
2239NS_IMETHODIMPnsresult
2240HttpBaseChannel::GetRedirectionLimit(uint32_t* value) {
2241 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2241
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2242 *value = mRedirectionLimit;
2243 return NS_OK;
2244}
2245
2246NS_IMETHODIMPnsresult
2247HttpBaseChannel::SetRedirectionLimit(uint32_t value) {
2248 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2248); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2248, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2248); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2248
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 2248); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2249
2250 mRedirectionLimit = std::min<uint32_t>(value, 0xff);
2251 return NS_OK;
2252}
2253
2254nsresult HttpBaseChannel::OverrideSecurityInfo(
2255 nsITransportSecurityInfo* aSecurityInfo) {
2256 MOZ_ASSERT(!mSecurityInfo,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mSecurityInfo))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mSecurityInfo"
" (" "This can only be called when we don't have a security info "
"object already" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2258); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { MOZ_CrashSequence(__null, 2258);
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
2257 "This can only be called when we don't have a security info "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mSecurityInfo))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mSecurityInfo"
" (" "This can only be called when we don't have a security info "
"object already" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2258); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { MOZ_CrashSequence(__null, 2258);
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
2258 "object already")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mSecurityInfo))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mSecurityInfo"
" (" "This can only be called when we don't have a security info "
"object already" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2258); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { MOZ_CrashSequence(__null, 2258);
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
2259 MOZ_RELEASE_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSecurityInfo))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aSecurityInfo" " ("
"This can only be called with a valid security info object" ")"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2261
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { MOZ_CrashSequence(__null, 2261); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2260 aSecurityInfo,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSecurityInfo))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aSecurityInfo" " ("
"This can only be called with a valid security info object" ")"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2261
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { MOZ_CrashSequence(__null, 2261); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2261 "This can only be called with a valid security info object")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSecurityInfo))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aSecurityInfo" " ("
"This can only be called with a valid security info object" ")"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2261
); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { MOZ_CrashSequence(__null, 2261); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2262 MOZ_ASSERT(!BypassServiceWorker(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!BypassServiceWorker())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!BypassServiceWorker()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!BypassServiceWorker()"
" (" "This can only be called on channels that are not bypassing "
"interception" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2264); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { MOZ_CrashSequence(__null, 2264); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2263 "This can only be called on channels that are not bypassing "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!BypassServiceWorker())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!BypassServiceWorker()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!BypassServiceWorker()"
" (" "This can only be called on channels that are not bypassing "
"interception" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2264); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { MOZ_CrashSequence(__null, 2264); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2264 "interception")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!BypassServiceWorker())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!BypassServiceWorker()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!BypassServiceWorker()"
" (" "This can only be called on channels that are not bypassing "
"interception" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2264); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { MOZ_CrashSequence(__null, 2264); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
2265 MOZ_ASSERT(LoadResponseCouldBeSynthesized(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadResponseCouldBeSynthesized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadResponseCouldBeSynthesized
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("LoadResponseCouldBeSynthesized()" " (" "This can only be called on channels that can be intercepted"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2266); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadResponseCouldBeSynthesized()"
") (" "This can only be called on channels that can be intercepted"
")"); do { MOZ_CrashSequence(__null, 2266); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2266 "This can only be called on channels that can be intercepted")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadResponseCouldBeSynthesized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadResponseCouldBeSynthesized
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("LoadResponseCouldBeSynthesized()" " (" "This can only be called on channels that can be intercepted"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2266); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadResponseCouldBeSynthesized()"
") (" "This can only be called on channels that can be intercepted"
")"); do { MOZ_CrashSequence(__null, 2266); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2267 if (mSecurityInfo) {
2268 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::OverrideSecurityInfo mSecurityInfo is null! "
"[this=%p]\n", this); } } while (0)
2269 ("HttpBaseChannel::OverrideSecurityInfo mSecurityInfo is null! "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::OverrideSecurityInfo mSecurityInfo is null! "
"[this=%p]\n", this); } } while (0)
2270 "[this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::OverrideSecurityInfo mSecurityInfo is null! "
"[this=%p]\n", this); } } while (0)
2271 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::OverrideSecurityInfo mSecurityInfo is null! "
"[this=%p]\n", this); } } while (0)
;
2272 return NS_ERROR_UNEXPECTED;
2273 }
2274 if (!LoadResponseCouldBeSynthesized()) {
2275 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::OverrideSecurityInfo channel cannot be intercepted! "
"[this=%p]\n", this); } } while (0)
2276 ("HttpBaseChannel::OverrideSecurityInfo channel cannot be intercepted! "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::OverrideSecurityInfo channel cannot be intercepted! "
"[this=%p]\n", this); } } while (0)
2277 "[this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::OverrideSecurityInfo channel cannot be intercepted! "
"[this=%p]\n", this); } } while (0)
2278 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::OverrideSecurityInfo channel cannot be intercepted! "
"[this=%p]\n", this); } } while (0)
;
2279 return NS_ERROR_UNEXPECTED;
2280 }
2281
2282 mSecurityInfo = aSecurityInfo;
2283 return NS_OK;
2284}
2285
2286NS_IMETHODIMPnsresult
2287HttpBaseChannel::IsNoStoreResponse(bool* value) {
2288 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2289 *value = mResponseHead->NoStore();
2290 return NS_OK;
2291}
2292
2293NS_IMETHODIMPnsresult
2294HttpBaseChannel::IsNoCacheResponse(bool* value) {
2295 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2296 *value = mResponseHead->NoCache();
2297 if (!*value) *value = mResponseHead->ExpiresInPast();
2298 return NS_OK;
2299}
2300
2301NS_IMETHODIMPnsresult
2302HttpBaseChannel::GetResponseStatus(uint32_t* aValue) {
2303 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2304 *aValue = mResponseHead->Status();
2305 return NS_OK;
2306}
2307
2308NS_IMETHODIMPnsresult
2309HttpBaseChannel::GetResponseStatusText(nsACString& aValue) {
2310 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2311 nsAutoCString version;
2312 // https://fetch.spec.whatwg.org :
2313 // Responses over an HTTP/2 connection will always have the empty byte
2314 // sequence as status message as HTTP/2 does not support them.
2315 if (NS_WARN_IF(NS_FAILED(GetProtocolVersion(version)))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(GetProtocolVersion
(version))), 0))), "NS_FAILED(GetProtocolVersion(version))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2315)
||
2316 !version.EqualsLiteral("h2")) {
2317 mResponseHead->StatusText(aValue);
2318 }
2319 return NS_OK;
2320}
2321
2322NS_IMETHODIMPnsresult
2323HttpBaseChannel::GetRequestSucceeded(bool* aValue) {
2324 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2325 uint32_t status = mResponseHead->Status();
2326 *aValue = (status / 100 == 2);
2327 return NS_OK;
2328}
2329
2330NS_IMETHODIMPnsresult
2331HttpBaseChannel::RedirectTo(nsIURI* targetURI) {
2332 NS_ENSURE_ARG(targetURI)do { if ((__builtin_expect(!!(!(targetURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "targetURI" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2332
); return NS_ERROR_INVALID_ARG; } } while (false)
;
2333
2334 nsAutoCString spec;
2335 targetURI->GetAsciiSpec(spec);
2336 LOG(("HttpBaseChannel::RedirectTo [this=%p, uri=%s]", this, spec.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::RedirectTo [this=%p, uri=%s]", this, spec
.get()); } } while (0)
;
2337 LogCallingScriptLocation(this);
2338
2339 // We cannot redirect after OnStartRequest of the listener
2340 // has been called, since to redirect we have to switch channels
2341 // and the dance with OnStartRequest et al has to start over.
2342 // This would break the nsIStreamListener contract.
2343 NS_ENSURE_FALSE(LoadOnStartRequestCalled(), NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(!(LoadOnStartRequestCalled())
)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!(LoadOnStartRequestCalled())"
") failed", nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2343); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2344
2345 // The first parameter is the URI we would like to redirect to
2346 // The second parameter should default to false if normal redirect
2347 mAPIRedirectTo =
2348 Some(mozilla::MakeCompactPair(nsCOMPtr<nsIURI>(targetURI), false));
2349
2350 // Only Web Extensions are allowed to redirect a channel to a data:
2351 // URI. To avoid any bypasses after the channel was flagged by
2352 // the WebRequst API, we are dropping the flag here.
2353 mLoadInfo->SetAllowInsecureRedirectToDataURI(false);
2354
2355 // We may want to rewrite origin allowance, hence we need an
2356 // artificial response head.
2357 if (!mResponseHead) {
2358 mResponseHead.reset(new nsHttpResponseHead());
2359 }
2360 return NS_OK;
2361}
2362
2363NS_IMETHODIMPnsresult
2364HttpBaseChannel::TransparentRedirectTo(nsIURI* targetURI) {
2365 LOG(("HttpBaseChannel::TransparentRedirectTo [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::TransparentRedirectTo [this=%p]", this); }
} while (0)
;
2366 RedirectTo(targetURI);
2367 MOZ_ASSERT(mAPIRedirectTo, "How did this happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAPIRedirectTo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAPIRedirectTo))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mAPIRedirectTo"
" (" "How did this happen?" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2367); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAPIRedirectTo"
") (" "How did this happen?" ")"); do { MOZ_CrashSequence(__null
, 2367); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
2368 mAPIRedirectTo->second() = true;
2369 return NS_OK;
2370}
2371
2372NS_IMETHODIMPnsresult
2373HttpBaseChannel::UpgradeToSecure() {
2374 // Upgrades are handled internally between http-on-modify-request and
2375 // http-on-before-connect, which means upgrades are only possible during
2376 // on-modify, or WebRequest.onBeforeRequest in Web Extensions. Once we are
2377 // past the code path where upgrades are handled, attempting an upgrade
2378 // will throw an error.
2379 NS_ENSURE_TRUE(LoadUpgradableToSecure(), NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(LoadUpgradableToSecure())), 0
))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "LoadUpgradableToSecure()"
") failed", nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2379); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2380
2381 StoreUpgradeToSecure(true);
2382 // todo: Currently UpgradeToSecure() is called only by web extensions, if
2383 // that ever changes, we need to update the following telemetry collection
2384 // to reflect any future changes.
2385 mLoadInfo->SetHttpsUpgradeTelemetry(nsILoadInfo::WEB_EXTENSION_UPGRADE);
2386
2387 return NS_OK;
2388}
2389
2390NS_IMETHODIMPnsresult
2391HttpBaseChannel::GetRequestObserversCalled(bool* aCalled) {
2392 NS_ENSURE_ARG_POINTER(aCalled)do { if ((__builtin_expect(!!(!(aCalled)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCalled" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2392
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2393 *aCalled = LoadRequestObserversCalled();
2394 return NS_OK;
2395}
2396
2397NS_IMETHODIMPnsresult
2398HttpBaseChannel::SetRequestObserversCalled(bool aCalled) {
2399 StoreRequestObserversCalled(aCalled);
2400 return NS_OK;
2401}
2402
2403NS_IMETHODIMPnsresult
2404HttpBaseChannel::GetRequestContextID(uint64_t* aRCID) {
2405 NS_ENSURE_ARG_POINTER(aRCID)do { if ((__builtin_expect(!!(!(aRCID)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aRCID" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2405
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2406 *aRCID = mRequestContextID;
2407 return NS_OK;
2408}
2409
2410NS_IMETHODIMPnsresult
2411HttpBaseChannel::SetRequestContextID(uint64_t aRCID) {
2412 mRequestContextID = aRCID;
2413 return NS_OK;
2414}
2415
2416NS_IMETHODIMPnsresult
2417HttpBaseChannel::GetIsMainDocumentChannel(bool* aValue) {
2418 NS_ENSURE_ARG_POINTER(aValue)do { if ((__builtin_expect(!!(!(aValue)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aValue" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2418
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2419 *aValue = IsNavigation();
2420 return NS_OK;
2421}
2422
2423NS_IMETHODIMPnsresult
2424HttpBaseChannel::SetIsMainDocumentChannel(bool aValue) {
2425 StoreForceMainDocumentChannel(aValue);
2426 return NS_OK;
2427}
2428
2429NS_IMETHODIMPnsresult
2430HttpBaseChannel::GetIsUserAgentHeaderOutdated(bool* aValue) {
2431 NS_ENSURE_ARG_POINTER(aValue)do { if ((__builtin_expect(!!(!(aValue)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aValue" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2431
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2432 *aValue = LoadIsUserAgentHeaderOutdated();
2433 return NS_OK;
2434}
2435
2436NS_IMETHODIMPnsresult
2437HttpBaseChannel::SetIsUserAgentHeaderOutdated(bool aValue) {
2438 StoreIsUserAgentHeaderOutdated(aValue);
2439 return NS_OK;
2440}
2441
2442NS_IMETHODIMPnsresult
2443HttpBaseChannel::GetProtocolVersion(nsACString& aProtocolVersion) {
2444 // Try to use ALPN if available and if it is not for a proxy, i.e if an
2445 // https proxy was not used or if https proxy was used but the connection to
2446 // the origin server is also https. In the case, an https proxy was used and
2447 // the connection to the origin server was http, mSecurityInfo will be from
2448 // the proxy.
2449 if (!mConnectionInfo || !mConnectionInfo->UsingHttpsProxy() ||
2450 mConnectionInfo->EndToEndSSL()) {
2451 nsAutoCString protocol;
2452 if (mSecurityInfo &&
2453 NS_SUCCEEDED(mSecurityInfo->GetNegotiatedNPN(protocol))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mSecurityInfo->
GetNegotiatedNPN(protocol))), 1)))
&&
2454 !protocol.IsEmpty()) {
2455 // The negotiated protocol was not empty so we can use it.
2456 aProtocolVersion = std::move(protocol);
2457 return NS_OK;
2458 }
2459 }
2460
2461 if (mResponseHead) {
2462 HttpVersion version = mResponseHead->Version();
2463 aProtocolVersion.Assign(nsHttp::GetProtocolVersion(version));
2464 return NS_OK;
2465 }
2466
2467 return NS_ERROR_NOT_AVAILABLE;
2468}
2469
2470//-----------------------------------------------------------------------------
2471// HttpBaseChannel::nsIHttpChannelInternal
2472//-----------------------------------------------------------------------------
2473
2474NS_IMETHODIMPnsresult
2475HttpBaseChannel::SetTopWindowURIIfUnknown(nsIURI* aTopWindowURI) {
2476 if (!aTopWindowURI) {
2477 return NS_ERROR_INVALID_ARG;
2478 }
2479
2480 if (mTopWindowURI) {
2481 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "mTopWindowURI is already set.\n"
, this); } } while (0)
2482 ("HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "mTopWindowURI is already set.\n"
, this); } } while (0)
2483 "mTopWindowURI is already set.\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "mTopWindowURI is already set.\n"
, this); } } while (0)
2484 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "mTopWindowURI is already set.\n"
, this); } } while (0)
;
2485 return NS_ERROR_FAILURE;
2486 }
2487
2488 nsCOMPtr<nsIURI> topWindowURI;
2489 (void)GetTopWindowURI(getter_AddRefs(topWindowURI));
2490
2491 // Don't modify |mTopWindowURI| if we can get one from GetTopWindowURI().
2492 if (topWindowURI) {
2493 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "Return an error since we got a top window uri.\n"
, this); } } while (0)
2494 ("HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "Return an error since we got a top window uri.\n"
, this); } } while (0)
2495 "Return an error since we got a top window uri.\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "Return an error since we got a top window uri.\n"
, this); } } while (0)
2496 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "Return an error since we got a top window uri.\n"
, this); } } while (0)
;
2497 return NS_ERROR_FAILURE;
2498 }
2499
2500 mTopWindowURI = aTopWindowURI;
2501 return NS_OK;
2502}
2503
2504NS_IMETHODIMPnsresult
2505HttpBaseChannel::GetTopWindowURI(nsIURI** aTopWindowURI) {
2506 nsCOMPtr<nsIURI> uriBeingLoaded =
2507 AntiTrackingUtils::MaybeGetDocumentURIBeingLoaded(this);
2508 return GetTopWindowURI(uriBeingLoaded, aTopWindowURI);
2509}
2510
2511nsresult HttpBaseChannel::GetTopWindowURI(nsIURI* aURIBeingLoaded,
2512 nsIURI** aTopWindowURI) {
2513 nsresult rv = NS_OK;
2514 nsCOMPtr<mozIThirdPartyUtil> util;
2515 // Only compute the top window URI once. In e10s, this must be computed in the
2516 // child. The parent gets the top window URI through HttpChannelOpenArgs.
2517 if (!mTopWindowURI) {
2518 util = components::ThirdPartyUtil::Service();
2519 if (!util) {
2520 return NS_ERROR_NOT_AVAILABLE;
2521 }
2522 nsCOMPtr<mozIDOMWindowProxy> win;
2523 rv = util->GetTopWindowForChannel(this, aURIBeingLoaded,
2524 getter_AddRefs(win));
2525 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2526 rv = util->GetURIFromWindow(win, getter_AddRefs(mTopWindowURI));
2527#if DEBUG1
2528 if (mTopWindowURI) {
2529 nsCString spec;
2530 if (NS_SUCCEEDED(mTopWindowURI->GetSpec(spec))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mTopWindowURI->
GetSpec(spec))), 1)))
) {
2531 LOG(("HttpChannelBase::Setting topwindow URI spec %s [this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpChannelBase::Setting topwindow URI spec %s [this=%p]\n"
, spec.get(), this); } } while (0)
2532 spec.get(), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpChannelBase::Setting topwindow URI spec %s [this=%p]\n"
, spec.get(), this); } } while (0)
;
2533 }
2534 }
2535#endif
2536 }
2537 }
2538 *aTopWindowURI = do_AddRef(mTopWindowURI).take();
2539 return rv;
2540}
2541
2542NS_IMETHODIMPnsresult
2543HttpBaseChannel::GetDocumentURI(nsIURI** aDocumentURI) {
2544 NS_ENSURE_ARG_POINTER(aDocumentURI)do { if ((__builtin_expect(!!(!(aDocumentURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aDocumentURI" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2544); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2545 *aDocumentURI = do_AddRef(mDocumentURI).take();
2546 return NS_OK;
2547}
2548
2549NS_IMETHODIMPnsresult
2550HttpBaseChannel::SetDocumentURI(nsIURI* aDocumentURI) {
2551 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2551); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2551, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2551); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2551
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 2551); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2552 mDocumentURI = aDocumentURI;
2553 return NS_OK;
2554}
2555
2556NS_IMETHODIMPnsresult
2557HttpBaseChannel::GetRequestVersion(uint32_t* major, uint32_t* minor) {
2558 HttpVersion version = mRequestHead.Version();
2559
2560 if (major) {
2561 *major = static_cast<uint32_t>(version) / 10;
2562 }
2563 if (minor) {
2564 *minor = static_cast<uint32_t>(version) % 10;
2565 }
2566
2567 return NS_OK;
2568}
2569
2570NS_IMETHODIMPnsresult
2571HttpBaseChannel::GetResponseVersion(uint32_t* major, uint32_t* minor) {
2572 if (!mResponseHead) {
2573 *major = *minor = 0; // we should at least be kind about it
2574 return NS_ERROR_NOT_AVAILABLE;
2575 }
2576
2577 HttpVersion version = mResponseHead->Version();
2578
2579 if (major) {
2580 *major = static_cast<uint32_t>(version) / 10;
2581 }
2582 if (minor) {
2583 *minor = static_cast<uint32_t>(version) % 10;
2584 }
2585
2586 return NS_OK;
2587}
2588
2589bool HttpBaseChannel::IsBrowsingContextDiscarded() const {
2590 // If there is no loadGroup attached to the current channel, we check the
2591 // global private browsing state for the private channel instead. For
2592 // non-private channel, we will always return false here.
2593 //
2594 // Note that we can only access the global private browsing state in the
2595 // parent process. So, we will fallback to just return false in the content
2596 // process.
2597 if (!mLoadGroup) {
2598 if (!XRE_IsParentProcess()) {
2599 return false;
2600 }
2601
2602 return mLoadInfo->GetOriginAttributes().IsPrivateBrowsing() &&
2603 !dom::CanonicalBrowsingContext::IsPrivateBrowsingActive();
2604 }
2605
2606 return mLoadGroup->GetIsBrowsingContextDiscarded();
2607}
2608
2609// https://mikewest.github.io/corpp/#process-navigation-response
2610nsresult HttpBaseChannel::ProcessCrossOriginEmbedderPolicyHeader() {
2611 nsresult rv;
2612 if (!StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2613 return NS_OK;
2614 }
2615
2616 // Only consider Cross-Origin-Embedder-Policy for document loads.
2617 if (mLoadInfo->GetExternalContentPolicyType() !=
2618 ExtContentPolicy::TYPE_DOCUMENT &&
2619 mLoadInfo->GetExternalContentPolicyType() !=
2620 ExtContentPolicy::TYPE_SUBDOCUMENT) {
2621 return NS_OK;
2622 }
2623
2624 nsILoadInfo::CrossOriginEmbedderPolicy resultPolicy =
2625 nsILoadInfo::EMBEDDER_POLICY_NULL;
2626 bool isCoepCredentiallessEnabled;
2627 rv = mLoadInfo->GetIsOriginTrialCoepCredentiallessEnabledForTopLevel(
2628 &isCoepCredentiallessEnabled);
2629 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2629); return rv; } } while (false)
;
2630 rv = GetResponseEmbedderPolicy(isCoepCredentiallessEnabled, &resultPolicy);
2631 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2632 return NS_OK;
2633 }
2634
2635 // https://html.spec.whatwg.org/multipage/origin.html#coep
2636 if (mLoadInfo->GetExternalContentPolicyType() ==
2637 ExtContentPolicy::TYPE_SUBDOCUMENT &&
2638 !nsHttpChannel::IsRedirectStatus(mResponseHead->Status()) &&
2639 mLoadInfo->GetLoadingEmbedderPolicy() !=
2640 nsILoadInfo::EMBEDDER_POLICY_NULL &&
2641 resultPolicy != nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP &&
2642 resultPolicy != nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
2643 return NS_ERROR_DOM_COEP_FAILED;
2644 }
2645
2646 return NS_OK;
2647}
2648
2649// https://mikewest.github.io/corpp/#corp-check
2650nsresult HttpBaseChannel::ProcessCrossOriginResourcePolicyHeader() {
2651 // Fetch 4.5.9
2652 dom::RequestMode requestMode;
2653 MOZ_ALWAYS_SUCCEEDS(GetRequestMode(&requestMode))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(GetRequestMode(&requestMode))), 1)))), 1))) { } else { do
{ do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(GetRequestMode(&requestMode))"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2653
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(GetRequestMode(&requestMode))"
")"); do { MOZ_CrashSequence(__null, 2653); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
2654 // XXX this seems wrong per spec? What about navigate
2655 if (requestMode != RequestMode::No_cors) {
2656 return NS_OK;
2657 }
2658
2659 // We only apply this for resources.
2660 auto extContentPolicyType = mLoadInfo->GetExternalContentPolicyType();
2661 if (extContentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
2662 extContentPolicyType == ExtContentPolicy::TYPE_WEBSOCKET ||
2663 extContentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
2664 return NS_OK;
2665 }
2666
2667 if (extContentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
2668 // COEP pref off, skip CORP checking for subdocument.
2669 if (!StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2670 return NS_OK;
2671 }
2672 // COEP 3.2.1.2 when request targets a nested browsing context then embedder
2673 // policy value is "unsafe-none", then return allowed.
2674 if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2675 nsILoadInfo::EMBEDDER_POLICY_NULL) {
2676 return NS_OK;
2677 }
2678 }
2679
2680 MOZ_ASSERT(mLoadInfo->GetLoadingPrincipal(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetLoadingPrincipal())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetLoadingPrincipal
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLoadInfo->GetLoadingPrincipal()" " (" "Resources should always have a LoadingPrincipal"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2681); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetLoadingPrincipal()"
") (" "Resources should always have a LoadingPrincipal" ")")
; do { MOZ_CrashSequence(__null, 2681); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2681 "Resources should always have a LoadingPrincipal")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetLoadingPrincipal())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetLoadingPrincipal
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLoadInfo->GetLoadingPrincipal()" " (" "Resources should always have a LoadingPrincipal"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 2681); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetLoadingPrincipal()"
") (" "Resources should always have a LoadingPrincipal" ")")
; do { MOZ_CrashSequence(__null, 2681); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2682 if (!mResponseHead) {
2683 return NS_OK;
2684 }
2685
2686 if (mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()) {
2687 return NS_OK;
2688 }
2689
2690 nsAutoCString content;
2691 (void)mResponseHead->GetHeader(nsHttp::Cross_Origin_Resource_Policy, content);
2692
2693 if (StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2694 if (content.IsEmpty()) {
2695 if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2696 nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
2697 bool requestIncludesCredentials = false;
2698 nsresult rv = GetCorsIncludeCredentials(&requestIncludesCredentials);
2699 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2700 return NS_OK;
2701 }
2702 // COEP: Set policy to `same-origin` if: response’s
2703 // request-includes-credentials is true, or forNavigation is true.
2704 if (requestIncludesCredentials ||
2705 extContentPolicyType == ExtContentPolicyType::TYPE_SUBDOCUMENT) {
2706 content = "same-origin"_ns;
2707 }
2708 } else if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2709 nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP) {
2710 // COEP 3.2.1.6 If policy is null, and embedder policy is
2711 // "require-corp", set policy to "same-origin". Note that we treat
2712 // invalid value as "cross-origin", which spec indicates. We might want
2713 // to make that stricter.
2714 content = "same-origin"_ns;
2715 }
2716 }
2717 }
2718
2719 if (content.IsEmpty()) {
2720 return NS_OK;
2721 }
2722
2723 nsCOMPtr<nsIPrincipal> channelOrigin;
2724 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
2725 this, getter_AddRefs(channelOrigin));
2726
2727 // Cross-Origin-Resource-Policy = %s"same-origin" / %s"same-site" /
2728 // %s"cross-origin"
2729 if (content.EqualsLiteral("same-origin")) {
2730 if (!channelOrigin->Equals(mLoadInfo->GetLoadingPrincipal())) {
2731 return NS_ERROR_DOM_CORP_FAILED;
2732 }
2733 return NS_OK;
2734 }
2735 if (content.EqualsLiteral("same-site")) {
2736 nsAutoCString documentBaseDomain;
2737 nsAutoCString resourceBaseDomain;
2738 mLoadInfo->GetLoadingPrincipal()->GetBaseDomain(documentBaseDomain);
2739 channelOrigin->GetBaseDomain(resourceBaseDomain);
2740 if (documentBaseDomain != resourceBaseDomain) {
2741 return NS_ERROR_DOM_CORP_FAILED;
2742 }
2743
2744 nsCOMPtr<nsIURI> resourceURI = channelOrigin->GetURI();
2745 if (!mLoadInfo->GetLoadingPrincipal()->SchemeIs("https") &&
2746 resourceURI->SchemeIs("https")) {
2747 return NS_ERROR_DOM_CORP_FAILED;
2748 }
2749
2750 return NS_OK;
2751 }
2752
2753 return NS_OK;
2754}
2755
2756// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
2757// This method runs steps 1-4 of the algorithm to compare
2758// cross-origin-opener policies
2759static bool CompareCrossOriginOpenerPolicies(
2760 nsILoadInfo::CrossOriginOpenerPolicy documentPolicy,
2761 nsIPrincipal* documentOrigin,
2762 nsILoadInfo::CrossOriginOpenerPolicy resultPolicy,
2763 nsIPrincipal* resultOrigin) {
2764 if (documentPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE &&
2765 resultPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2766 return true;
2767 }
2768
2769 if (documentPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE ||
2770 resultPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2771 return false;
2772 }
2773
2774 if (documentPolicy == resultPolicy && documentOrigin->Equals(resultOrigin)) {
2775 return true;
2776 }
2777
2778 return false;
2779}
2780
2781// This runs steps 1-5 of the algorithm when navigating a top level document.
2782// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
2783nsresult HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch() {
2784 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 2784
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 2784); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2785
2786 StoreHasCrossOriginOpenerPolicyMismatch(false);
2787 if (!StaticPrefs::browser_tabs_remote_useCrossOriginOpenerPolicy()) {
2788 return NS_OK;
2789 }
2790
2791 // Only consider Cross-Origin-Opener-Policy for toplevel document loads.
2792 if (mLoadInfo->GetExternalContentPolicyType() !=
2793 ExtContentPolicy::TYPE_DOCUMENT) {
2794 return NS_OK;
2795 }
2796
2797 // Maybe the channel failed and we have no response head?
2798 if (!mResponseHead) {
2799 // Not having a response head is not a hard failure at the point where
2800 // this method is called.
2801 return NS_OK;
2802 }
2803
2804 RefPtr<mozilla::dom::BrowsingContext> ctx;
2805 mLoadInfo->GetBrowsingContext(getter_AddRefs(ctx));
2806
2807 // In xpcshell-tests we don't always have a browsingContext
2808 if (!ctx) {
2809 return NS_OK;
2810 }
2811
2812 nsCOMPtr<nsIPrincipal> resultOrigin;
2813 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
2814 this, getter_AddRefs(resultOrigin));
2815
2816 // Get the policy of the active document, and the policy for the result.
2817 nsILoadInfo::CrossOriginOpenerPolicy documentPolicy = ctx->GetOpenerPolicy();
2818 nsILoadInfo::CrossOriginOpenerPolicy resultPolicy =
2819 nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
2820 (void)ComputeCrossOriginOpenerPolicy(documentPolicy, &resultPolicy);
2821 mComputedCrossOriginOpenerPolicy = resultPolicy;
2822
2823 // Add a permission to mark this site as high-value into the permission DB.
2824 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2825 mozilla::dom::AddHighValuePermission(
2826 resultOrigin, mozilla::dom::kHighValueCOOPPermission);
2827 }
2828
2829 // If bc's popup sandboxing flag set is not empty and potentialCOOP is
2830 // non-null, then navigate bc to a network error and abort these steps.
2831 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE &&
2832 mLoadInfo->GetSandboxFlags()) {
2833 LOG((do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch network error "
"for non empty sandboxing and non null COOP"); } } while (0)
2834 "HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch network error "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch network error "
"for non empty sandboxing and non null COOP"); } } while (0)
2835 "for non empty sandboxing and non null COOP"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch network error "
"for non empty sandboxing and non null COOP"); } } while (0)
;
2836 return NS_ERROR_DOM_COOP_FAILED;
2837 }
2838
2839 // In xpcshell-tests we don't always have a current window global
2840 RefPtr<mozilla::dom::WindowGlobalParent> currentWindowGlobal =
2841 ctx->Canonical()->GetCurrentWindowGlobal();
2842 if (!currentWindowGlobal) {
2843 return NS_OK;
2844 }
2845
2846 // We use the top window principal as the documentOrigin
2847 nsCOMPtr<nsIPrincipal> documentOrigin =
2848 currentWindowGlobal->DocumentPrincipal();
2849
2850 bool compareResult = CompareCrossOriginOpenerPolicies(
2851 documentPolicy, documentOrigin, resultPolicy, resultOrigin);
2852
2853 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
2854 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch - " "doc:%d result:%d - compare:%d\n"
, documentPolicy, resultPolicy, compareResult); } } while (0)
2855 ("HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch - "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch - " "doc:%d result:%d - compare:%d\n"
, documentPolicy, resultPolicy, compareResult); } } while (0)
2856 "doc:%d result:%d - compare:%d\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch - " "doc:%d result:%d - compare:%d\n"
, documentPolicy, resultPolicy, compareResult); } } while (0)
2857 documentPolicy, resultPolicy, compareResult))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch - " "doc:%d result:%d - compare:%d\n"
, documentPolicy, resultPolicy, compareResult); } } while (0)
;
2858 nsAutoCString docOrigin("(null)");
2859 nsCOMPtr<nsIURI> uri = documentOrigin->GetURI();
2860 if (uri) {
2861 uri->GetSpec(docOrigin);
2862 }
2863 nsAutoCString resOrigin("(null)");
2864 uri = resultOrigin->GetURI();
2865 if (uri) {
2866 uri->GetSpec(resOrigin);
2867 }
2868 LOG(("doc origin:%s - res origin: %s\n", docOrigin.get(), resOrigin.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "doc origin:%s - res origin: %s\n", docOrigin.get(), resOrigin
.get()); } } while (0)
;
2869 }
2870
2871 if (compareResult) {
2872 return NS_OK;
2873 }
2874
2875 // If one of the following is false:
2876 // - document's policy is same-origin-allow-popups
2877 // - resultPolicy is null
2878 // - doc is the initial about:blank document
2879 // then we have a mismatch.
2880
2881 if (documentPolicy != nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_ALLOW_POPUPS) {
2882 StoreHasCrossOriginOpenerPolicyMismatch(true);
2883 return NS_OK;
2884 }
2885
2886 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2887 StoreHasCrossOriginOpenerPolicyMismatch(true);
2888 return NS_OK;
2889 }
2890
2891 if (!currentWindowGlobal->IsInitialDocument()) {
2892 StoreHasCrossOriginOpenerPolicyMismatch(true);
2893 return NS_OK;
2894 }
2895
2896 return NS_OK;
2897}
2898
2899nsresult HttpBaseChannel::ProcessCrossOriginSecurityHeaders() {
2900 StoreProcessCrossOriginSecurityHeadersCalled(true);
2901 nsresult rv = ProcessCrossOriginEmbedderPolicyHeader();
2902 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2903 return rv;
2904 }
2905 rv = ProcessCrossOriginResourcePolicyHeader();
2906 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2907 return rv;
2908 }
2909 return ComputeCrossOriginOpenerPolicyMismatch();
2910}
2911
2912enum class Report { Error, Warning };
2913
2914// Helper Function to report messages to the console when the loaded
2915// script had a wrong MIME type.
2916void ReportMimeTypeMismatch(HttpBaseChannel* aChannel, const char* aMessageName,
2917 nsIURI* aURI, const nsACString& aContentType,
2918 Report report) {
2919 NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
2920 NS_ConvertUTF8toUTF16 contentType(aContentType);
2921
2922 aChannel->LogMimeTypeMismatch(nsCString(aMessageName),
2923 report == Report::Warning, spec, contentType);
2924}
2925
2926// Check and potentially enforce X-Content-Type-Options: nosniff
2927nsresult ProcessXCTO(HttpBaseChannel* aChannel, nsIURI* aURI,
2928 nsHttpResponseHead* aResponseHead,
2929 nsILoadInfo* aLoadInfo) {
2930 if (!aURI || !aResponseHead || !aLoadInfo) {
2931 // if there is no uri, no response head or no loadInfo, then there is
2932 // nothing to do
2933 return NS_OK;
2934 }
2935
2936 // 1) Query the XCTO header and check if 'nosniff' is the first value.
2937 nsAutoCString contentTypeOptionsHeader;
2938 if (!aResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader)) {
2939 // if failed to get XCTO header, then there is nothing to do.
2940 return NS_OK;
2941 }
2942
2943 // let's compare the header (ignoring case)
2944 // e.g. "NoSniFF" -> "nosniff"
2945 // if it's not 'nosniff' then there is nothing to do here
2946 if (!contentTypeOptionsHeader.EqualsIgnoreCase("nosniff")) {
2947 // since we are getting here, the XCTO header was sent;
2948 // a non matching value most likely means a mistake happenend;
2949 // e.g. sending 'nosnif' instead of 'nosniff', let's log a warning.
2950 AutoTArray<nsString, 1> params;
2951 CopyUTF8toUTF16(contentTypeOptionsHeader, *params.AppendElement());
2952 RefPtr<dom::Document> doc;
2953 aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
2954 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "XCTO"_ns, doc,
2955 PropertiesFile::SECURITY_PROPERTIES,
2956 "XCTOHeaderValueMissing", params);
2957 return NS_OK;
2958 }
2959
2960 // 2) Query the content type from the channel
2961 nsAutoCString contentType;
2962 aResponseHead->ContentType(contentType);
2963
2964 // 3) Compare the expected MIME type with the actual type
2965 if (aLoadInfo->GetExternalContentPolicyType() ==
2966 ExtContentPolicy::TYPE_STYLESHEET) {
2967 if (contentType.EqualsLiteral(TEXT_CSS"text/css")) {
2968 return NS_OK;
2969 }
2970 ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
2971 Report::Error);
2972 return NS_ERROR_CORRUPTED_CONTENT;
2973 }
2974
2975 if (aLoadInfo->GetExternalContentPolicyType() ==
2976 ExtContentPolicy::TYPE_SCRIPT) {
2977 if (nsContentUtils::IsJavascriptMIMEType(
2978 NS_ConvertUTF8toUTF16(contentType))) {
2979 return NS_OK;
2980 }
2981 ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
2982 Report::Error);
2983 return NS_ERROR_CORRUPTED_CONTENT;
2984 }
2985
2986 auto policyType = aLoadInfo->GetExternalContentPolicyType();
2987 if (policyType == ExtContentPolicy::TYPE_DOCUMENT ||
2988 policyType == ExtContentPolicy::TYPE_SUBDOCUMENT ||
2989 policyType == ExtContentPolicy::TYPE_OBJECT) {
2990 // If the header XCTO nosniff is set for any browsing context, then
2991 // we set the skipContentSniffing flag on the Loadinfo. Within
2992 // GetMIMETypeFromContent we then bail early and do not do any sniffing.
2993 aLoadInfo->SetSkipContentSniffing(true);
2994 return NS_OK;
2995 }
2996
2997 return NS_OK;
2998}
2999
3000nsresult EnsureMIMEOfJSONModule(HttpBaseChannel* aChannel, nsIURI* aURI,
3001 nsHttpResponseHead* aResponseHead,
3002 nsILoadInfo* aLoadInfo) {
3003 if (!aURI || !aResponseHead || !aLoadInfo) {
3004 // if there is no uri, no response head or no loadInfo, then there is
3005 // nothing to do
3006 return NS_OK;
3007 }
3008
3009 if (aLoadInfo->GetExternalContentPolicyType() !=
3010 ExtContentPolicy::TYPE_JSON) {
3011 // if this is not a JSON load, then there is nothing to do
3012 return NS_OK;
3013 }
3014
3015 nsAutoCString contentType;
3016 aResponseHead->ContentType(contentType);
3017 NS_ConvertUTF8toUTF16 typeString(contentType);
3018
3019 if (nsContentUtils::IsJsonMimeType(typeString)) {
3020 return NS_OK;
3021 }
3022
3023 ReportMimeTypeMismatch(aChannel, "BlockJsonModuleWithWrongMimeType", aURI,
3024 contentType, Report::Error);
3025 return NS_ERROR_CORRUPTED_CONTENT;
3026}
3027
3028// Ensure that a load of type script has correct MIME type
3029nsresult EnsureMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
3030 nsHttpResponseHead* aResponseHead,
3031 nsILoadInfo* aLoadInfo) {
3032 if (!aURI || !aResponseHead || !aLoadInfo) {
3033 // if there is no uri, no response head or no loadInfo, then there is
3034 // nothing to do
3035 return NS_OK;
3036 }
3037
3038 if (aLoadInfo->GetExternalContentPolicyType() !=
3039 ExtContentPolicy::TYPE_SCRIPT) {
3040 // if this is not a script load, then there is nothing to do
3041 return NS_OK;
3042 }
3043
3044 nsAutoCString contentType;
3045 aResponseHead->ContentType(contentType);
3046 NS_ConvertUTF8toUTF16 typeString(contentType);
3047
3048 if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
3049 // script load has type script
3050 glean::http::script_block_incorrect_mime
3051 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eJavascript)
3052 .Add();
3053 return NS_OK;
3054 }
3055
3056 const auto internalPolicyType = aLoadInfo->InternalContentPolicyType();
3057 if (internalPolicyType ==
3058 nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE &&
3059 nsContentUtils::IsJsonMimeType(typeString)) {
3060 // script and json are both allowed
3061 glean::http::script_block_incorrect_mime
3062 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eTextJson)
3063 .Add();
3064 return NS_OK;
3065 }
3066
3067 switch (aLoadInfo->InternalContentPolicyType()) {
3068 case nsIContentPolicy::TYPE_SCRIPT:
3069 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
3070 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
3071 case nsIContentPolicy::TYPE_INTERNAL_MODULE:
3072 case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
3073 case nsIContentPolicy::TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT:
3074 case nsIContentPolicy::TYPE_INTERNAL_FRAME_MESSAGEMANAGER_SCRIPT:
3075 glean::http::script_block_incorrect_mime
3076 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eScriptLoad)
3077 .Add();
3078 break;
3079 case nsIContentPolicy::TYPE_INTERNAL_WORKER:
3080 case nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE:
3081 case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
3082 glean::http::script_block_incorrect_mime
3083 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eWorkerLoad)
3084 .Add();
3085 break;
3086 case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
3087 glean::http::script_block_incorrect_mime
3088 .EnumGet(
3089 glean::http::ScriptBlockIncorrectMimeLabel::eServiceworkerLoad)
3090 .Add();
3091 break;
3092 case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
3093 glean::http::script_block_incorrect_mime
3094 .EnumGet(
3095 glean::http::ScriptBlockIncorrectMimeLabel::eImportscriptLoad)
3096 .Add();
3097 break;
3098 case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
3099 case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
3100 glean::http::script_block_incorrect_mime
3101 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eWorkletLoad)
3102 .Add();
3103 break;
3104 default:
3105 MOZ_ASSERT_UNREACHABLE("unexpected script type")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"unexpected script type" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3105); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "unexpected script type" ")"); do
{ MOZ_CrashSequence(__null, 3105); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
3106 break;
3107 }
3108
3109 if (aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(aURI)) {
3110 // same origin
3111 glean::http::script_block_incorrect_mime
3112 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eSameOrigin)
3113 .Add();
3114 } else {
3115 bool cors = false;
3116 nsAutoCString corsOrigin;
3117 nsresult rv = aResponseHead->GetHeader(
3118 nsHttp::ResolveAtom("Access-Control-Allow-Origin"_ns), corsOrigin);
3119 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3120 if (corsOrigin.Equals("*")) {
3121 cors = true;
3122 } else {
3123 nsCOMPtr<nsIURI> corsOriginURI;
3124 rv = NS_NewURI(getter_AddRefs(corsOriginURI), corsOrigin);
3125 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3126 if (aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(corsOriginURI)) {
3127 cors = true;
3128 }
3129 }
3130 }
3131 }
3132 if (cors) {
3133 // cors origin
3134 glean::http::script_block_incorrect_mime
3135 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eCorsOrigin)
3136 .Add();
3137 } else {
3138 // cross origin
3139 glean::http::script_block_incorrect_mime
3140 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eCrossOrigin)
3141 .Add();
3142 }
3143 }
3144
3145 bool block = false;
3146 if (StringBeginsWith(contentType, "image/"_ns)) {
3147 // script load has type image
3148 glean::http::script_block_incorrect_mime
3149 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eImage)
3150 .Add();
3151 block = true;
3152 } else if (StringBeginsWith(contentType, "audio/"_ns)) {
3153 // script load has type audio
3154 glean::http::script_block_incorrect_mime
3155 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eAudio)
3156 .Add();
3157 block = true;
3158 } else if (StringBeginsWith(contentType, "video/"_ns)) {
3159 // script load has type video
3160 glean::http::script_block_incorrect_mime
3161 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eVideo)
3162 .Add();
3163 block = true;
3164 } else if (StringBeginsWith(contentType, "text/csv"_ns)) {
3165 // script load has type text/csv
3166 glean::http::script_block_incorrect_mime
3167 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eTextCsv)
3168 .Add();
3169 block = true;
3170 }
3171
3172 if (block) {
3173 ReportMimeTypeMismatch(aChannel, "BlockScriptWithWrongMimeType2", aURI,
3174 contentType, Report::Error);
3175 return NS_ERROR_CORRUPTED_CONTENT;
3176 }
3177
3178 if (StringBeginsWith(contentType, "text/plain"_ns)) {
3179 // script load has type text/plain
3180 glean::http::script_block_incorrect_mime
3181 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eTextPlain)
3182 .Add();
3183 } else if (StringBeginsWith(contentType, "text/xml"_ns)) {
3184 // script load has type text/xml
3185 glean::http::script_block_incorrect_mime
3186 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eTextXml)
3187 .Add();
3188 } else if (StringBeginsWith(contentType, "application/octet-stream"_ns)) {
3189 // script load has type application/octet-stream
3190 glean::http::script_block_incorrect_mime
3191 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eAppOctetStream)
3192 .Add();
3193 } else if (StringBeginsWith(contentType, "application/xml"_ns)) {
3194 // script load has type application/xml
3195 glean::http::script_block_incorrect_mime
3196 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eAppXml)
3197 .Add();
3198 } else if (StringBeginsWith(contentType, "application/json"_ns)) {
3199 // script load has type application/json
3200 glean::http::script_block_incorrect_mime
3201 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eAppJson)
3202 .Add();
3203 } else if (StringBeginsWith(contentType, "text/json"_ns)) {
3204 // script load has type text/json
3205 glean::http::script_block_incorrect_mime
3206 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eTextJson)
3207 .Add();
3208 } else if (StringBeginsWith(contentType, "text/html"_ns)) {
3209 // script load has type text/html
3210 glean::http::script_block_incorrect_mime
3211 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eTextHtml)
3212 .Add();
3213 } else if (contentType.IsEmpty()) {
3214 // script load has no type
3215 glean::http::script_block_incorrect_mime
3216 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eEmpty)
3217 .Add();
3218 } else {
3219 // script load has unknown type
3220 glean::http::script_block_incorrect_mime
3221 .EnumGet(glean::http::ScriptBlockIncorrectMimeLabel::eUnknown)
3222 .Add();
3223 }
3224
3225 nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
3226
3227 // We restrict importScripts() in worker code to JavaScript MIME types.
3228 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS) {
3229 ReportMimeTypeMismatch(aChannel, "BlockImportScriptsWithWrongMimeType",
3230 aURI, contentType, Report::Error);
3231 return NS_ERROR_CORRUPTED_CONTENT;
3232 }
3233
3234 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE) {
3235#ifdef NIGHTLY_BUILD1
3236 if (StaticPrefs::javascript_options_experimental_wasm_esm_integration()) {
3237 if (nsContentUtils::HasWasmMimeTypeEssence(typeString)) {
3238 return NS_OK;
3239 }
3240 }
3241#endif
3242 ReportMimeTypeMismatch(aChannel, "BlockModuleWithWrongMimeType", aURI,
3243 contentType, Report::Error);
3244 return NS_ERROR_CORRUPTED_CONTENT;
3245 }
3246
3247 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
3248 internalType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
3249 // Do not block the load if the feature is not enabled.
3250 if (!StaticPrefs::security_block_Worker_with_wrong_mime()) {
3251 return NS_OK;
3252 }
3253
3254#ifdef NIGHTLY_BUILD1
3255 if (StaticPrefs::javascript_options_experimental_wasm_esm_integration()) {
3256 if (nsContentUtils::HasWasmMimeTypeEssence(typeString)) {
3257 return NS_OK;
3258 }
3259 }
3260#endif
3261
3262 ReportMimeTypeMismatch(aChannel, "BlockWorkerWithWrongMimeType", aURI,
3263 contentType, Report::Error);
3264 return NS_ERROR_CORRUPTED_CONTENT;
3265 }
3266
3267 // ES6 modules require a strict MIME type check.
3268 if (internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
3269 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD) {
3270#ifdef NIGHTLY_BUILD1
3271 if (StaticPrefs::javascript_options_experimental_wasm_esm_integration()) {
3272 if (nsContentUtils::HasWasmMimeTypeEssence(typeString)) {
3273 return NS_OK;
3274 }
3275 }
3276#endif
3277
3278 ReportMimeTypeMismatch(aChannel, "BlockModuleWithWrongMimeType", aURI,
3279 contentType, Report::Error);
3280 return NS_ERROR_CORRUPTED_CONTENT;
3281 }
3282
3283 return NS_OK;
3284}
3285
3286// Warn when a load of type script uses a wrong MIME type and
3287// wasn't blocked by EnsureMIMEOfScript or ProcessXCTO.
3288void WarnWrongMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
3289 nsHttpResponseHead* aResponseHead,
3290 nsILoadInfo* aLoadInfo) {
3291 if (!aURI || !aResponseHead || !aLoadInfo) {
3292 // If there is no uri, no response head or no loadInfo, then there is
3293 // nothing to do.
3294 return;
3295 }
3296
3297 if (aLoadInfo->GetExternalContentPolicyType() !=
3298 ExtContentPolicy::TYPE_SCRIPT) {
3299 // If this is not a script load, then there is nothing to do.
3300 return;
3301 }
3302
3303 bool succeeded;
3304 MOZ_ALWAYS_SUCCEEDS(aChannel->GetRequestSucceeded(&succeeded))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aChannel->GetRequestSucceeded(&succeeded))), 1)))), 1
))) { } else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(aChannel->GetRequestSucceeded(&succeeded))"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3304
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(aChannel->GetRequestSucceeded(&succeeded))"
")"); do { MOZ_CrashSequence(__null, 3304); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
3305 if (!succeeded) {
3306 // Do not warn for failed loads: HTTP error pages are usually in HTML.
3307 return;
3308 }
3309
3310 nsAutoCString contentType;
3311 aResponseHead->ContentType(contentType);
3312 NS_ConvertUTF8toUTF16 typeString(contentType);
3313
3314 if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
3315 return;
3316 }
3317
3318#ifdef NIGHTLY_BUILD1
3319 if (StaticPrefs::javascript_options_experimental_wasm_esm_integration()) {
3320 if (nsContentUtils::HasWasmMimeTypeEssence(typeString)) {
3321 return;
3322 }
3323 }
3324#endif
3325
3326 ReportMimeTypeMismatch(aChannel, "WarnScriptWithWrongMimeType", aURI,
3327 contentType, Report::Warning);
3328}
3329
3330nsresult HttpBaseChannel::ValidateMIMEType() {
3331 nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
3332 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3333 return rv;
3334 }
3335
3336 rv = EnsureMIMEOfJSONModule(this, mURI, mResponseHead.get(), mLoadInfo);
3337 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3338 return rv;
3339 }
3340
3341 rv = ProcessXCTO(this, mURI, mResponseHead.get(), mLoadInfo);
3342 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3343 return rv;
3344 }
3345
3346 WarnWrongMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
3347 return NS_OK;
3348}
3349
3350bool HttpBaseChannel::ShouldFilterOpaqueResponse(
3351 OpaqueResponseFilterFetch aFilterType) const {
3352 MOZ_ASSERT(ShouldBlockOpaqueResponse())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ShouldBlockOpaqueResponse())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(ShouldBlockOpaqueResponse())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("ShouldBlockOpaqueResponse()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3352
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ShouldBlockOpaqueResponse()"
")"); do { MOZ_CrashSequence(__null, 3352); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3353
3354 if (!mLoadInfo || ConfiguredFilterFetchResponseBehaviour() != aFilterType) {
3355 return false;
3356 }
3357
3358 // We should filter a response in the parent if it is opaque and is the result
3359 // of a fetch() function from the Fetch specification.
3360 return mLoadInfo->InternalContentPolicyType() == nsIContentPolicy::TYPE_FETCH;
3361}
3362
3363bool HttpBaseChannel::ShouldBlockOpaqueResponse() const {
3364 if (!mURI || !mResponseHead || !mLoadInfo) {
3365 // if there is no uri, no response head or no loadInfo, then there is
3366 // nothing to do
3367 LOGORB("No block: no mURI, mResponseHead, or mLoadInfo");
3368 return false;
3369 }
3370
3371 nsCOMPtr<nsIPrincipal> principal = mLoadInfo->GetLoadingPrincipal();
3372 if (!principal || principal->IsSystemPrincipal()) {
3373 // If it's a top-level load or a system principal, then there is nothing to
3374 // do.
3375 LOGORB("No block: top-level load or system principal");
3376 return false;
3377 }
3378
3379 // Check if the response is a opaque response, which means requestMode should
3380 // be RequestMode::No_cors and responseType should be ResponseType::Opaque.
3381 nsContentPolicyType contentPolicy = mLoadInfo->InternalContentPolicyType();
3382
3383 // Skip the RequestMode would be RequestMode::Navigate
3384 if (contentPolicy == nsIContentPolicy::TYPE_DOCUMENT ||
3385 contentPolicy == nsIContentPolicy::TYPE_SUBDOCUMENT ||
3386 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_FRAME ||
3387 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_IFRAME ||
3388 // Skip the RequestMode would be RequestMode::Same_origin
3389 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
3390 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
3391 return false;
3392 }
3393
3394 uint32_t securityMode = mLoadInfo->GetSecurityMode();
3395 // Skip when RequestMode would not be RequestMode::no_cors
3396 if (securityMode !=
3397 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT &&
3398 securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL) {
3399 LOGORB("No block: not no_cors requests");
3400 return false;
3401 }
3402
3403 // Only continue when ResponseType would be ResponseType::Opaque
3404 if (mLoadInfo->GetTainting() != mozilla::LoadTainting::Opaque) {
3405 LOGORB("No block: not opaque response");
3406 return false;
3407 }
3408
3409 auto extContentPolicyType = mLoadInfo->GetExternalContentPolicyType();
3410 if (extContentPolicyType == ExtContentPolicy::TYPE_OBJECT ||
3411 extContentPolicyType == ExtContentPolicy::TYPE_WEBSOCKET ||
3412 extContentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
3413 LOGORB("No block: object || websocket request || save as download");
3414 return false;
3415 }
3416
3417 // Ignore the request from object or embed elements
3418 if (mLoadInfo->GetIsFromObjectOrEmbed()) {
3419 LOGORB("No block: Request From <object> or <embed>");
3420 return false;
3421 }
3422
3423 // Exclude no_cors System XHR
3424 if (extContentPolicyType == ExtContentPolicy::TYPE_XMLHTTPREQUEST) {
3425 if (securityMode ==
3426 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT) {
3427 LOGORB("No block: System XHR");
3428 return false;
3429 }
3430 }
3431
3432 // Exclude no_cors web-identity
3433 if (extContentPolicyType == ExtContentPolicy::TYPE_WEB_IDENTITY) {
3434 if (securityMode ==
3435 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT) {
3436 printf("Allowing ORB for web-identity\n");
3437 LOGORB("No block: System web-identity");
3438 return false;
3439 }
3440 }
3441
3442 uint32_t httpsOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
3443 if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_BYPASS_ORB) {
3444 LOGORB("No block: HTTPS_ONLY_BYPASS_ORB");
3445 return false;
3446 }
3447
3448 return true;
3449}
3450
3451OpaqueResponse HttpBaseChannel::BlockOrFilterOpaqueResponse(
3452 OpaqueResponseBlocker* aORB, const nsAString& aReason,
3453 const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
3454 const char* aFormat, ...) {
3455 NimbusFeatures::RecordExposureEvent("opaqueResponseBlocking"_ns, true);
3456
3457 const bool shouldFilter =
3458 ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::BlockedByORB);
3459
3460 if (MOZ_UNLIKELY(MOZ_LOG_TEST(GetORBLog(), LogLevel::Debug))(__builtin_expect(!!((__builtin_expect(!!(mozilla::detail::log_test
(GetORBLog(), LogLevel::Debug)), 0))), 0))
) {
3461 va_list ap;
3462 va_start(ap, aFormat)__builtin_va_start(ap, aFormat);
3463 nsVprintfCString logString(aFormat, ap);
3464 va_end(ap)__builtin_va_end(ap);
3465
3466 LOGORB("%s: %s", shouldFilter ? "Filtered" : "Blocked", logString.get());
3467 }
3468
3469 if (shouldFilter) {
3470 glean::orb::block_initiator
3471 .EnumGet(glean::orb::BlockInitiatorLabel::eFilteredFetch)
3472 .Add();
3473 // The existence of `mORB` depends on `BlockOrFilterOpaqueResponse` being
3474 // called before or after sniffing has completed.
3475 // Another requirement is that `OpaqueResponseFilter` must come after
3476 // `OpaqueResponseBlocker`, which is why in the case of having an
3477 // `OpaqueResponseBlocker` we let it handle creating an
3478 // `OpaqueResponseFilter`.
3479 if (aORB) {
3480 MOZ_DIAGNOSTIC_ASSERT(!mORB || aORB == mORB)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mORB || aORB == mORB)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mORB || aORB == mORB))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!mORB || aORB == mORB"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3480
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mORB || aORB == mORB"
")"); do { MOZ_CrashSequence(__null, 3480); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3481 aORB->FilterResponse();
3482 } else {
3483 mListener = new OpaqueResponseFilter(mListener);
3484 }
3485 return OpaqueResponse::Allow;
3486 }
3487
3488 LogORBError(aReason, aTelemetryReason);
3489 return OpaqueResponse::Block;
3490}
3491
3492dom::NoCorsMediaRequestState HttpBaseChannel::NoCorsMediaRequestState() {
3493 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3493
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 3493); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3494
3495 if (!mLoadInfo->GetIsMediaRequest()) {
3496 return dom::NoCorsMediaRequestState::NotAvailable;
3497 }
3498
3499 RefPtr<dom::WindowGlobalParent> wgp =
3500 dom::WindowGlobalParent::GetByInnerWindowId(
3501 mLoadInfo->GetInnerWindowID());
3502 if (!wgp || wgp->IsDiscarded()) {
3503 return dom::NoCorsMediaRequestState::NotAvailable;
3504 }
3505
3506 return wgp->NoCorsMediaRequestState(mURI);
3507}
3508
3509void HttpBaseChannel::RecordSubsequentNoCorsRequestState() {
3510 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3510
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 3510); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3511 MOZ_ASSERT(mLoadInfo->GetIsMediaRequest())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetIsMediaRequest())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetIsMediaRequest
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLoadInfo->GetIsMediaRequest()", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3511); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetIsMediaRequest()"
")"); do { MOZ_CrashSequence(__null, 3511); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3512
3513 RefPtr<dom::WindowGlobalParent> wgp =
3514 dom::WindowGlobalParent::GetByInnerWindowId(
3515 mLoadInfo->GetInnerWindowID());
3516 if (!wgp || wgp->IsDiscarded()) {
3517 return;
3518 }
3519
3520 wgp->RecordSubsequentNoCorsRequestState(mURI);
3521}
3522
3523// The specification for ORB is currently being written:
3524// https://whatpr.org/fetch/1442.html#orb-algorithm
3525// The `opaque-response-safelist check` is implemented in:
3526// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
3527// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3528// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
3529// * `OpaqueResponseBlocker::ValidateJavaScript`
3530OpaqueResponse
3531HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff() {
3532 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3532
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 3532); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3533
3534 // https://whatpr.org/fetch/1442.html#http-fetch, step 6.4
3535 if (!ShouldBlockOpaqueResponse()) {
3536 return OpaqueResponse::Allow;
3537 }
3538
3539 // Regardless of if ORB is enabled or not, we check if we should filter the
3540 // response in the parent. This way data won't reach a content process that
3541 // will create a filtered `Response` object. This is enabled when
3542 // 'browser.opaqueResponseBlocking.filterFetchResponse' is
3543 // `OpaqueResponseFilterFetch::All`.
3544 // See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
3545 if (ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::All)) {
3546 mListener = new OpaqueResponseFilter(mListener);
3547
3548 // If we're filtering a response in the parent, there will be no data to
3549 // determine if it should be blocked or not so the only option we have is to
3550 // allow it.
3551 return OpaqueResponse::Allow;
3552 }
3553
3554 if (!mCachedOpaqueResponseBlockingPref) {
3555 return OpaqueResponse::Allow;
3556 }
3557
3558 // If ORB is enabled, we check if we should filter the response in the parent.
3559 // This way data won't reach a content process that will create a filtered
3560 // `Response` object. We allow ORB to determine if the response should be
3561 // blocked or filtered, but regardless no data should reach the content
3562 // process. This is enabled when
3563 // 'browser.opaqueResponseBlocking.filterFetchResponse' is
3564 // `OpaqueResponseFilterFetch::AllowedByORB`.
3565 // See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
3566 if (ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::AllowedByORB)) {
3567 mListener = new OpaqueResponseFilter(mListener);
3568 }
3569
3570 glean::opaque_response_blocking::cross_origin_opaque_response_count.Add(1);
3571
3572 PROFILER_MARKER_TEXT("ORB safelist check", NETWORK, {}, "Before sniff"_ns)do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("ORB safelist check", ::geckoprofiler::category::NETWORK, {}
, ::geckoprofiler::markers::TextMarker{}, "Before sniff"_ns);
} } while (false); } while (false)
;
3573
3574 // https://whatpr.org/fetch/1442.html#orb-algorithm
3575 // Step 1
3576 nsAutoCString contentType;
3577 mResponseHead->ContentType(contentType);
3578
3579 // Step 2
3580 nsAutoCString contentTypeOptionsHeader;
3581 bool nosniff =
3582 mResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader) &&
3583 contentTypeOptionsHeader.EqualsIgnoreCase("nosniff");
3584
3585 // Step 3
3586 switch (GetOpaqueResponseBlockedReason(contentType, mResponseHead->Status(),
3587 nosniff)) {
3588 case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED:
3589 // Step 3.1
3590 return OpaqueResponse::Allow;
3591 case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED_SPEC_BREAKING:
3592 LOGORB("Allowed %s in a spec breaking way", contentType.get());
3593 return OpaqueResponse::Allow;
3594 case OpaqueResponseBlockedReason::BLOCKED_BLOCKLISTED_NEVER_SNIFFED:
3595 return BlockOrFilterOpaqueResponse(
3596 mORB, u"mimeType is an opaque-blocklisted-never-sniffed MIME type"_ns,
3597 OpaqueResponseBlockedTelemetryReason::eMimeNeverSniffed,
3598 "BLOCKED_BLOCKLISTED_NEVER_SNIFFED");
3599 case OpaqueResponseBlockedReason::BLOCKED_206_AND_BLOCKLISTED:
3600 // Step 3.3
3601 return BlockOrFilterOpaqueResponse(
3602 mORB,
3603 u"response's status is 206 and mimeType is an opaque-blocklisted MIME type"_ns,
3604 OpaqueResponseBlockedTelemetryReason::eResp206Blclisted,
3605 "BLOCKED_206_AND_BLOCKEDLISTED");
3606 case OpaqueResponseBlockedReason::
3607 BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN:
3608 // Step 3.4
3609 return BlockOrFilterOpaqueResponse(
3610 mORB,
3611 u"nosniff is true and mimeType is an opaque-blocklisted MIME type or its essence is 'text/plain'"_ns,
3612 OpaqueResponseBlockedTelemetryReason::eNosniffBlcOrTextp,
3613 "BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN");
3614 default:
3615 break;
3616 }
3617
3618 // Step 4
3619 // If it's a media subsequent request, we assume that it will only be made
3620 // after a successful initial request.
3621 if (NoCorsMediaRequestState() == dom::NoCorsMediaRequestState::Subsequent) {
3622 return OpaqueResponse::Allow;
3623 }
3624
3625 // Step 5
3626 if (mResponseHead->Status() == 206 &&
3627 !IsFirstPartialResponse(*mResponseHead)) {
3628 return BlockOrFilterOpaqueResponse(
3629 mORB, u"response status is 206 and not first partial response"_ns,
3630 OpaqueResponseBlockedTelemetryReason::eResp206Blclisted,
3631 "Is not a valid partial response given 0");
3632 }
3633
3634 // Setup for steps 6, 7, 8 and 10.
3635 // Steps 6 and 7 are handled by the sniffer framework.
3636 // Steps 8 and 10 by are handled by
3637 // `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3638 if (mLoadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS) {
3639 mSnifferCategoryType = SnifferCategoryType::All;
3640 } else {
3641 mSnifferCategoryType = SnifferCategoryType::OpaqueResponseBlocking;
3642 }
3643
3644 mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
3645 nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
3646
3647 // Install an input stream listener that performs ORB checks that depend on
3648 // inspecting the incoming data. It is crucial that `OnStartRequest` is called
3649 // on this listener either after sniffing is completed or that we skip
3650 // sniffing, otherwise `OpaqueResponseBlocker` will allow responses that it
3651 // shouldn't.
3652 mORB = new OpaqueResponseBlocker(mListener, this, contentType, nosniff);
3653 mListener = mORB;
3654
3655 nsAutoCString contentEncoding;
3656 nsresult rv =
3657 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
3658
3659 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !contentEncoding.IsEmpty()) {
3660 return OpaqueResponse::SniffCompressed;
3661 }
3662 mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
3663 nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
3664 return OpaqueResponse::Sniff;
3665}
3666
3667// The specification for ORB is currently being written:
3668// https://whatpr.org/fetch/1442.html#orb-algorithm
3669// The `opaque-response-safelist check` is implemented in:
3670// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
3671// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3672// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
3673// * `OpaqueResponseBlocker::ValidateJavaScript`
3674OpaqueResponse HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff(
3675 const nsACString& aContentType, bool aNoSniff) {
3676 PROFILER_MARKER_TEXT("ORB safelist check", NETWORK, {}, "After sniff"_ns)do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("ORB safelist check", ::geckoprofiler::category::NETWORK, {}
, ::geckoprofiler::markers::TextMarker{}, "After sniff"_ns); }
} while (false); } while (false)
;
3677
3678 // https://whatpr.org/fetch/1442.html#orb-algorithm
3679 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3679
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 3679); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3680 MOZ_ASSERT(mCachedOpaqueResponseBlockingPref)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCachedOpaqueResponseBlockingPref)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCachedOpaqueResponseBlockingPref
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mCachedOpaqueResponseBlockingPref", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3680); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedOpaqueResponseBlockingPref"
")"); do { MOZ_CrashSequence(__null, 3680); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3681
3682 // Step 9
3683 if (NoCorsMediaRequestState() != dom::NoCorsMediaRequestState::NotAvailable) {
3684 return BlockOrFilterOpaqueResponse(
3685 mORB, u"after sniff: media request"_ns,
3686 OpaqueResponseBlockedTelemetryReason::eAfterSniffMedia,
3687 "media request");
3688 }
3689
3690 // Step 11
3691 if (aNoSniff) {
3692 return BlockOrFilterOpaqueResponse(
3693 mORB, u"after sniff: nosniff is true"_ns,
3694 OpaqueResponseBlockedTelemetryReason::eAfterSniffNosniff, "nosniff");
3695 }
3696
3697 // Step 12
3698 if (mResponseHead &&
3699 (mResponseHead->Status() < 200 || mResponseHead->Status() > 299)) {
3700 return BlockOrFilterOpaqueResponse(
3701 mORB, u"after sniff: status code is not in allowed range"_ns,
3702 OpaqueResponseBlockedTelemetryReason::eAfterSniffStaCode,
3703 "status code (%d) is not allowed", mResponseHead->Status());
3704 }
3705
3706 // Step 13
3707 if (!mResponseHead || aContentType.IsEmpty()) {
3708 LOGORB("Allowed: mimeType is failure");
3709 return OpaqueResponse::Allow;
3710 }
3711
3712 // Step 14
3713 if (StringBeginsWith(aContentType, "image/"_ns) ||
3714 StringBeginsWith(aContentType, "video/"_ns) ||
3715 StringBeginsWith(aContentType, "audio/"_ns)) {
3716 return BlockOrFilterOpaqueResponse(
3717 mORB,
3718 u"after sniff: content-type declares image/video/audio, but sniffing fails"_ns,
3719 OpaqueResponseBlockedTelemetryReason::eAfterSniffCtFail,
3720 "ContentType is image/video/audio");
3721 }
3722
3723 return OpaqueResponse::Sniff;
3724}
3725
3726bool HttpBaseChannel::NeedOpaqueResponseAllowedCheckAfterSniff() const {
3727 RefPtr<OpaqueResponseBlocker> orb(mORB);
3728 return orb ? orb->IsSniffing() : false;
3729}
3730
3731void HttpBaseChannel::BlockOpaqueResponseAfterSniff(
3732 const nsAString& aReason,
3733 const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
3734 MOZ_DIAGNOSTIC_ASSERT(mORB)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mORB)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mORB))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mORB", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3734); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { MOZ_CrashSequence(__null, 3734); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3735 LogORBError(aReason, aTelemetryReason);
3736 RefPtr<OpaqueResponseBlocker> orb(mORB);
3737 orb->BlockResponse(this, NS_ERROR_DOM_NETWORK_ERR);
3738}
3739
3740void HttpBaseChannel::AllowOpaqueResponseAfterSniff() {
3741 MOZ_DIAGNOSTIC_ASSERT(mORB)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mORB)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mORB))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mORB", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3741); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { MOZ_CrashSequence(__null, 3741); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3742 RefPtr<OpaqueResponseBlocker> orb(mORB);
3743 orb->AllowResponse();
3744}
3745
3746void HttpBaseChannel::SetChannelBlockedByOpaqueResponse() {
3747 mChannelBlockedByOpaqueResponse = true;
3748
3749 RefPtr<dom::BrowsingContext> browsingContext =
3750 dom::BrowsingContext::GetCurrentTopByBrowserId(mBrowserId);
3751 if (!browsingContext) {
3752 return;
3753 }
3754
3755 dom::WindowContext* windowContext = browsingContext->GetTopWindowContext();
3756 if (windowContext) {
3757 windowContext->Canonical()->SetShouldReportHasBlockedOpaqueResponse(
3758 mLoadInfo->InternalContentPolicyType());
3759 }
3760}
3761
3762NS_IMETHODIMPnsresult
3763HttpBaseChannel::SetCookieHeaders(const nsTArray<nsCString>& aCookieHeaders) {
3764 if (mLoadFlags & LOAD_ANONYMOUS) return NS_OK;
3765
3766 // The loadGroup of the channel in the parent process could be null in the
3767 // XPCShell content process test, see test_cookiejars_wrap.js. In this case,
3768 // we cannot explicitly set the loadGroup for the parent channel because it's
3769 // created from the content process. To workaround this, we add a testing pref
3770 // to skip this check.
3771 if (!StaticPrefs::
3772 network_cookie_skip_browsing_context_check_in_parent_for_testing() &&
3773 IsBrowsingContextDiscarded()) {
3774 return NS_OK;
3775 }
3776
3777 // empty header isn't an error
3778 if (aCookieHeaders.IsEmpty()) {
3779 return NS_OK;
3780 }
3781
3782 nsICookieService* cs = gHttpHandler->GetCookieService();
3783 NS_ENSURE_TRUE(cs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(cs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "cs" ") failed", nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3783); return NS_ERROR_FAILURE; } } while (false)
;
3784
3785 for (const nsCString& cookieHeader : aCookieHeaders) {
3786 nsresult rv = cs->SetCookieStringFromHttp(mURI, cookieHeader, this);
3787 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3787); return rv; } } while (false)
;
3788 }
3789
3790 return NS_OK;
3791}
3792
3793NS_IMETHODIMPnsresult
3794HttpBaseChannel::GetThirdPartyFlags(uint32_t* aFlags) {
3795 *aFlags = LoadThirdPartyFlags();
3796 return NS_OK;
3797}
3798
3799NS_IMETHODIMPnsresult
3800HttpBaseChannel::SetThirdPartyFlags(uint32_t aFlags) {
3801 ENSURE_CALLED_BEFORE_ASYNC_OPEN()do { if (LoadIsPending() || LoadWasOpened()) { nsPrintfCString
msg("'%s' called after AsyncOpen: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3801); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3801, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3801); } } while (0); } do { if ((__builtin_expect(!!(!(!LoadIsPending
())), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE("
"!LoadIsPending()" ") failed", nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3801); return NS_ERROR_IN_PROGRESS; } } while (false); do {
if ((__builtin_expect(!!(!(!LoadWasOpened())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!LoadWasOpened()" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3801); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
3802
3803 StoreThirdPartyFlags(aFlags);
3804 return NS_OK;
3805}
3806
3807NS_IMETHODIMPnsresult
3808HttpBaseChannel::GetForceAllowThirdPartyCookie(bool* aForce) {
3809 *aForce = !!(LoadThirdPartyFlags() &
3810 nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3811 return NS_OK;
3812}
3813
3814NS_IMETHODIMPnsresult
3815HttpBaseChannel::SetForceAllowThirdPartyCookie(bool aForce) {
3816 ENSURE_CALLED_BEFORE_ASYNC_OPEN()do { if (LoadIsPending() || LoadWasOpened()) { nsPrintfCString
msg("'%s' called after AsyncOpen: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3816); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3816, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3816); } } while (0); } do { if ((__builtin_expect(!!(!(!LoadIsPending
())), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE("
"!LoadIsPending()" ") failed", nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3816); return NS_ERROR_IN_PROGRESS; } } while (false); do {
if ((__builtin_expect(!!(!(!LoadWasOpened())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!LoadWasOpened()" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3816); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
3817
3818 if (aForce) {
3819 StoreThirdPartyFlags(LoadThirdPartyFlags() |
3820 nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3821 } else {
3822 StoreThirdPartyFlags(LoadThirdPartyFlags() &
3823 ~nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3824 }
3825
3826 return NS_OK;
3827}
3828
3829NS_IMETHODIMPnsresult
3830HttpBaseChannel::GetCanceled(bool* aCanceled) {
3831 *aCanceled = mCanceled;
3832 return NS_OK;
3833}
3834
3835NS_IMETHODIMPnsresult
3836HttpBaseChannel::GetChannelIsForDownload(bool* aChannelIsForDownload) {
3837 *aChannelIsForDownload = LoadChannelIsForDownload();
3838 return NS_OK;
3839}
3840
3841NS_IMETHODIMPnsresult
3842HttpBaseChannel::SetChannelIsForDownload(bool aChannelIsForDownload) {
3843 StoreChannelIsForDownload(aChannelIsForDownload);
3844 return NS_OK;
3845}
3846
3847NS_IMETHODIMPnsresult
3848HttpBaseChannel::SetCacheKeysRedirectChain(nsTArray<nsCString>* cacheKeys) {
3849 auto RedirectedCachekeys = mRedirectedCachekeys.Lock();
3850 auto& ref = RedirectedCachekeys.ref();
3851 ref = WrapUnique(cacheKeys);
3852 return NS_OK;
3853}
3854
3855NS_IMETHODIMPnsresult
3856HttpBaseChannel::GetLocalAddress(nsACString& addr) {
3857 if (mSelfAddr.raw.family == PR_AF_UNSPEC0) return NS_ERROR_NOT_AVAILABLE;
3858
3859 mSelfAddr.ToString(addr);
3860
3861 return NS_OK;
3862}
3863
3864NS_IMETHODIMPnsresult
3865HttpBaseChannel::TakeAllSecurityMessages(
3866 nsCOMArray<nsISecurityConsoleMessage>& aMessages) {
3867 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3867
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3867); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3868
3869 aMessages.Clear();
3870 for (const auto& pair : mSecurityConsoleMessages) {
3871 nsresult rv;
3872 nsCOMPtr<nsISecurityConsoleMessage> message =
3873 do_CreateInstance(NS_SECURITY_CONSOLE_MESSAGE_CONTRACTID"@mozilla.org/securityconsole/message;1", &rv);
3874 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3874); return rv; } } while (false)
;
3875
3876 message->SetTag(pair.first);
3877 message->SetCategory(pair.second);
3878 aMessages.AppendElement(message);
3879 }
3880
3881 MOZ_ASSERT(mSecurityConsoleMessages.Length() == aMessages.Length())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSecurityConsoleMessages.Length() == aMessages.Length
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mSecurityConsoleMessages.Length() == aMessages.Length
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mSecurityConsoleMessages.Length() == aMessages.Length()", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3881); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSecurityConsoleMessages.Length() == aMessages.Length()"
")"); do { MOZ_CrashSequence(__null, 3881); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3882 mSecurityConsoleMessages.Clear();
3883
3884 return NS_OK;
3885}
3886
3887/* Please use this method with care. This can cause the message
3888 * queue to grow large and cause the channel to take up a lot
3889 * of memory. Use only static string messages and do not add
3890 * server side data to the queue, as that can be large.
3891 * Add only a limited number of messages to the queue to keep
3892 * the channel size down and do so only in rare erroneous situations.
3893 * More information can be found here:
3894 * https://bugzilla.mozilla.org/show_bug.cgi?id=846918
3895 */
3896nsresult HttpBaseChannel::AddSecurityMessage(
3897 const nsAString& aMessageTag, const nsAString& aMessageCategory) {
3898 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3898
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 3898); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3899
3900 nsresult rv;
3901
3902 // nsSecurityConsoleMessage is not thread-safe refcounted.
3903 // Delay the object construction until requested.
3904 // See TakeAllSecurityMessages()
3905 std::pair<nsString, nsString> pair(aMessageTag, aMessageCategory);
3906 mSecurityConsoleMessages.AppendElement(std::move(pair));
3907
3908 nsCOMPtr<nsIConsoleService> console(
3909 do_GetService(NS_CONSOLESERVICE_CONTRACTID"@mozilla.org/consoleservice;1"));
3910 if (!console) {
3911 return NS_ERROR_FAILURE;
3912 }
3913
3914 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
3915
3916 auto innerWindowID = loadInfo->GetInnerWindowID();
3917
3918 nsAutoString errorText;
3919 rv = nsContentUtils::GetLocalizedString(
3920 PropertiesFile::SECURITY_PROPERTIES,
3921 NS_ConvertUTF16toUTF8(aMessageTag).get(), errorText);
3922 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3922); return rv; } } while (false)
;
3923
3924 nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID"@mozilla.org/scripterror;1"));
3925 error->InitWithSourceURI(errorText, mURI, 0, 0, nsIScriptError::warningFlag,
3926 NS_ConvertUTF16toUTF8(aMessageCategory),
3927 innerWindowID);
3928
3929 console->LogMessage(error);
3930
3931 return NS_OK;
3932}
3933
3934NS_IMETHODIMPnsresult
3935HttpBaseChannel::GetLocalPort(int32_t* port) {
3936 NS_ENSURE_ARG_POINTER(port)do { if ((__builtin_expect(!!(!(port)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "port" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3936
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3937
3938 if (mSelfAddr.raw.family == PR_AF_INET2) {
3939 *port = (int32_t)ntohs(mSelfAddr.inet.port)__bswap_16 (mSelfAddr.inet.port);
3940 } else if (mSelfAddr.raw.family == PR_AF_INET610) {
3941 *port = (int32_t)ntohs(mSelfAddr.inet6.port)__bswap_16 (mSelfAddr.inet6.port);
3942 } else {
3943 return NS_ERROR_NOT_AVAILABLE;
3944 }
3945
3946 return NS_OK;
3947}
3948
3949NS_IMETHODIMPnsresult
3950HttpBaseChannel::GetRemoteAddress(nsACString& addr) {
3951 if (mPeerAddr.raw.family == PR_AF_UNSPEC0) return NS_ERROR_NOT_AVAILABLE;
3952
3953 mPeerAddr.ToString(addr);
3954
3955 return NS_OK;
3956}
3957
3958NS_IMETHODIMPnsresult
3959HttpBaseChannel::GetRemotePort(int32_t* port) {
3960 NS_ENSURE_ARG_POINTER(port)do { if ((__builtin_expect(!!(!(port)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "port" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3960
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3961
3962 if (mPeerAddr.raw.family == PR_AF_INET2) {
3963 *port = (int32_t)ntohs(mPeerAddr.inet.port)__bswap_16 (mPeerAddr.inet.port);
3964 } else if (mPeerAddr.raw.family == PR_AF_INET610) {
3965 *port = (int32_t)ntohs(mPeerAddr.inet6.port)__bswap_16 (mPeerAddr.inet6.port);
3966 } else {
3967 return NS_ERROR_NOT_AVAILABLE;
3968 }
3969
3970 return NS_OK;
3971}
3972
3973NS_IMETHODIMPnsresult
3974HttpBaseChannel::HTTPUpgrade(const nsACString& aProtocolName,
3975 nsIHttpUpgradeListener* aListener) {
3976 NS_ENSURE_ARG(!aProtocolName.IsEmpty())do { if ((__builtin_expect(!!(!(!aProtocolName.IsEmpty())), 0
))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!aProtocolName.IsEmpty()"
") failed", nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3976); return NS_ERROR_INVALID_ARG; } } while (false)
;
3977 NS_ENSURE_ARG_POINTER(aListener)do { if ((__builtin_expect(!!(!(aListener)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aListener" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 3977
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3978
3979 // The protocol name is emitted verbatim into the Upgrade request header, so
3980 // reject anything that could inject additional headers or requests (e.g. an
3981 // embedded CRLF from a compromised child process).
3982 if (!nsHttp::IsReasonableHeaderValue(aProtocolName)) {
3983 return NS_ERROR_ILLEGAL_VALUE;
3984 }
3985
3986 mUpgradeProtocol = aProtocolName;
3987 mUpgradeProtocolCallback = aListener;
3988 return NS_OK;
3989}
3990
3991NS_IMETHODIMPnsresult
3992HttpBaseChannel::GetOnlyConnect(bool* aOnlyConnect) {
3993 NS_ENSURE_ARG_POINTER(aOnlyConnect)do { if ((__builtin_expect(!!(!(aOnlyConnect)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOnlyConnect" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 3993); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3994
3995 *aOnlyConnect = mCaps & NS_HTTP_CONNECT_ONLY(1 << 16);
3996 return NS_OK;
3997}
3998
3999NS_IMETHODIMPnsresult
4000HttpBaseChannel::SetConnectOnly(bool aTlsTunnel) {
4001 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4001); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4001, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4001); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4001
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 4001); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
4002
4003 if (!mUpgradeProtocolCallback) {
4004 return NS_ERROR_FAILURE;
4005 }
4006
4007 mCaps |= NS_HTTP_CONNECT_ONLY(1 << 16);
4008 if (aTlsTunnel) {
4009 mCaps |= NS_HTTP_TLS_TUNNEL(1 << 29);
4010 }
4011 mProxyResolveFlags = nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY |
4012 nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL;
4013 return SetLoadFlags(nsIRequest::INHIBIT_CACHING | nsIChannel::LOAD_ANONYMOUS |
4014 nsIRequest::LOAD_BYPASS_CACHE |
4015 nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
4016}
4017
4018NS_IMETHODIMPnsresult
4019HttpBaseChannel::GetAllowSpdy(bool* aAllowSpdy) {
4020 NS_ENSURE_ARG_POINTER(aAllowSpdy)do { if ((__builtin_expect(!!(!(aAllowSpdy)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowSpdy" ") failed",
nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4020); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4021
4022 *aAllowSpdy = LoadAllowSpdy();
4023 return NS_OK;
4024}
4025
4026NS_IMETHODIMPnsresult
4027HttpBaseChannel::SetAllowSpdy(bool aAllowSpdy) {
4028 StoreAllowSpdy(aAllowSpdy);
4029 return NS_OK;
4030}
4031
4032NS_IMETHODIMPnsresult
4033HttpBaseChannel::GetAllowHttp3(bool* aAllowHttp3) {
4034 NS_ENSURE_ARG_POINTER(aAllowHttp3)do { if ((__builtin_expect(!!(!(aAllowHttp3)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowHttp3" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4034); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4035
4036 *aAllowHttp3 = LoadAllowHttp3();
4037 return NS_OK;
4038}
4039
4040NS_IMETHODIMPnsresult
4041HttpBaseChannel::SetAllowHttp3(bool aAllowHttp3) {
4042 StoreAllowHttp3(aAllowHttp3);
4043 return NS_OK;
4044}
4045
4046NS_IMETHODIMPnsresult
4047HttpBaseChannel::GetAllowAltSvc(bool* aAllowAltSvc) {
4048 NS_ENSURE_ARG_POINTER(aAllowAltSvc)do { if ((__builtin_expect(!!(!(aAllowAltSvc)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowAltSvc" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4048); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4049
4050 *aAllowAltSvc = LoadAllowAltSvc();
4051 return NS_OK;
4052}
4053
4054NS_IMETHODIMPnsresult
4055HttpBaseChannel::SetAllowAltSvc(bool aAllowAltSvc) {
4056 StoreAllowAltSvc(aAllowAltSvc);
4057 return NS_OK;
4058}
4059
4060NS_IMETHODIMPnsresult
4061HttpBaseChannel::GetBeConservative(bool* aBeConservative) {
4062 NS_ENSURE_ARG_POINTER(aBeConservative)do { if ((__builtin_expect(!!(!(aBeConservative)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aBeConservative" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4062); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4063
4064 *aBeConservative = LoadBeConservative();
4065 return NS_OK;
4066}
4067
4068NS_IMETHODIMPnsresult
4069HttpBaseChannel::SetBeConservative(bool aBeConservative) {
4070 StoreBeConservative(aBeConservative);
4071 return NS_OK;
4072}
4073
4074bool HttpBaseChannel::BypassProxy() {
4075 return StaticPrefs::network_proxy_allow_bypass() && LoadBypassProxy();
4076}
4077
4078NS_IMETHODIMPnsresult
4079HttpBaseChannel::GetBypassProxy(bool* aBypassProxy) {
4080 NS_ENSURE_ARG_POINTER(aBypassProxy)do { if ((__builtin_expect(!!(!(aBypassProxy)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aBypassProxy" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4080); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4081
4082 *aBypassProxy = BypassProxy();
4083 return NS_OK;
4084}
4085
4086NS_IMETHODIMPnsresult
4087HttpBaseChannel::SetBypassProxy(bool aBypassProxy) {
4088 if (StaticPrefs::network_proxy_allow_bypass()) {
4089 StoreBypassProxy(aBypassProxy);
4090 } else {
4091 NS_WARNING("bypassProxy set but network.proxy.allow_bypass is disabled")NS_DebugBreak(NS_DEBUG_WARNING, "bypassProxy set but network.proxy.allow_bypass is disabled"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4091)
;
4092 return NS_ERROR_FAILURE;
4093 }
4094 return NS_OK;
4095}
4096
4097NS_IMETHODIMPnsresult
4098HttpBaseChannel::GetProxyDNSStrategy(
4099 nsIHttpChannelInternal::ProxyDNSStrategy* aStrategy) {
4100 NS_ENSURE_ARG_POINTER(aStrategy)do { if ((__builtin_expect(!!(!(aStrategy)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aStrategy" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4100
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4101 *aStrategy = nsIHttpChannelInternal::PROXY_DNS_STRATEGY_ORIGIN;
4102 return NS_OK;
4103}
4104
4105NS_IMETHODIMPnsresult
4106HttpBaseChannel::GetIsTRRServiceChannel(bool* aIsTRRServiceChannel) {
4107 NS_ENSURE_ARG_POINTER(aIsTRRServiceChannel)do { if ((__builtin_expect(!!(!(aIsTRRServiceChannel)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aIsTRRServiceChannel"
") failed", nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4107); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4108
4109 *aIsTRRServiceChannel = LoadIsTRRServiceChannel();
4110 return NS_OK;
4111}
4112
4113NS_IMETHODIMPnsresult
4114HttpBaseChannel::SetIsTRRServiceChannel(bool aIsTRRServiceChannel) {
4115 StoreIsTRRServiceChannel(aIsTRRServiceChannel);
4116 return NS_OK;
4117}
4118
4119NS_IMETHODIMPnsresult
4120HttpBaseChannel::GetIsResolvedByTRR(bool* aResolvedByTRR) {
4121 NS_ENSURE_ARG_POINTER(aResolvedByTRR)do { if ((__builtin_expect(!!(!(aResolvedByTRR)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResolvedByTRR" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4121); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4122 *aResolvedByTRR = LoadResolvedByTRR();
4123 return NS_OK;
4124}
4125
4126NS_IMETHODIMPnsresult
4127HttpBaseChannel::GetEffectiveTRRMode(nsIRequest::TRRMode* aEffectiveTRRMode) {
4128 *aEffectiveTRRMode = mEffectiveTRRMode;
4129 return NS_OK;
4130}
4131
4132NS_IMETHODIMPnsresult
4133HttpBaseChannel::GetTrrSkipReason(nsITRRSkipReason::value* aTrrSkipReason) {
4134 *aTrrSkipReason = mTRRSkipReason;
4135 return NS_OK;
4136}
4137
4138NS_IMETHODIMPnsresult
4139HttpBaseChannel::GetIsLoadedBySocketProcess(bool* aResult) {
4140 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4140
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4141 *aResult = LoadLoadedBySocketProcess();
4142 return NS_OK;
4143}
4144
4145NS_IMETHODIMPnsresult
4146HttpBaseChannel::GetTlsFlags(uint32_t* aTlsFlags) {
4147 NS_ENSURE_ARG_POINTER(aTlsFlags)do { if ((__builtin_expect(!!(!(aTlsFlags)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aTlsFlags" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4147
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4148
4149 *aTlsFlags = mTlsFlags;
4150 return NS_OK;
4151}
4152
4153NS_IMETHODIMPnsresult
4154HttpBaseChannel::SetTlsFlags(uint32_t aTlsFlags) {
4155 mTlsFlags = aTlsFlags;
4156 return NS_OK;
4157}
4158
4159NS_IMETHODIMPnsresult
4160HttpBaseChannel::GetApiRedirectToURI(nsIURI** aResult) {
4161 if (!mAPIRedirectTo) {
4162 return NS_ERROR_NOT_AVAILABLE;
4163 }
4164 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4164
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4165 *aResult = do_AddRef(mAPIRedirectTo->first()).take();
4166 return NS_OK;
4167}
4168
4169NS_IMETHODIMPnsresult
4170HttpBaseChannel::GetResponseTimeoutEnabled(bool* aEnable) {
4171 if (NS_WARN_IF(!aEnable)NS_warn_if_impl(!aEnable, "!aEnable", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4171)
) {
4172 return NS_ERROR_NULL_POINTER;
4173 }
4174 *aEnable = LoadResponseTimeoutEnabled();
4175 return NS_OK;
4176}
4177
4178NS_IMETHODIMPnsresult
4179HttpBaseChannel::SetResponseTimeoutEnabled(bool aEnable) {
4180 StoreResponseTimeoutEnabled(aEnable);
4181 return NS_OK;
4182}
4183
4184NS_IMETHODIMPnsresult
4185HttpBaseChannel::GetInitialRwin(uint32_t* aRwin) {
4186 if (NS_WARN_IF(!aRwin)NS_warn_if_impl(!aRwin, "!aRwin", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4186)
) {
4187 return NS_ERROR_NULL_POINTER;
4188 }
4189 *aRwin = mInitialRwin;
4190 return NS_OK;
4191}
4192
4193NS_IMETHODIMPnsresult
4194HttpBaseChannel::SetInitialRwin(uint32_t aRwin) {
4195 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4195); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4195, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4195); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4195
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 4195); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
4196 mInitialRwin = aRwin;
4197 return NS_OK;
4198}
4199
4200NS_IMETHODIMPnsresult
4201HttpBaseChannel::ForcePending(bool aForcePending) {
4202 StoreForcePending(aForcePending);
4203 return NS_OK;
4204}
4205
4206NS_IMETHODIMPnsresult
4207HttpBaseChannel::GetLastModifiedTime(PRTime* lastModifiedTime) {
4208 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
4209 uint32_t lastMod;
4210 nsresult rv = mResponseHead->GetLastModifiedValue(&lastMod);
4211 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4211); return rv; } } while (false)
;
4212 *lastModifiedTime = lastMod;
4213 return NS_OK;
4214}
4215
4216NS_IMETHODIMPnsresult
4217HttpBaseChannel::GetCorsIncludeCredentials(bool* aInclude) {
4218 *aInclude = LoadCorsIncludeCredentials();
4219 return NS_OK;
4220}
4221
4222NS_IMETHODIMPnsresult
4223HttpBaseChannel::SetCorsIncludeCredentials(bool aInclude) {
4224 StoreCorsIncludeCredentials(aInclude);
4225 return NS_OK;
4226}
4227
4228NS_IMETHODIMPnsresult
4229HttpBaseChannel::GetRequestMode(RequestMode* aMode) {
4230 *aMode = mRequestMode;
4231 return NS_OK;
4232}
4233
4234NS_IMETHODIMPnsresult
4235HttpBaseChannel::SetRequestMode(RequestMode aMode) {
4236 mRequestMode = aMode;
4237 return NS_OK;
4238}
4239
4240NS_IMETHODIMPnsresult
4241HttpBaseChannel::GetRedirectMode(uint32_t* aMode) {
4242 *aMode = mRedirectMode;
4243 return NS_OK;
4244}
4245
4246NS_IMETHODIMPnsresult
4247HttpBaseChannel::SetRedirectMode(uint32_t aMode) {
4248 mRedirectMode = aMode;
4249 return NS_OK;
4250}
4251
4252namespace {
4253
4254bool ContainsAllFlags(uint32_t aLoadFlags, uint32_t aMask) {
4255 return (aLoadFlags & aMask) == aMask;
4256}
4257
4258} // anonymous namespace
4259
4260NS_IMETHODIMPnsresult
4261HttpBaseChannel::GetFetchCacheMode(uint32_t* aFetchCacheMode) {
4262 NS_ENSURE_ARG_POINTER(aFetchCacheMode)do { if ((__builtin_expect(!!(!(aFetchCacheMode)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aFetchCacheMode" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4262); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4263
4264 // Otherwise try to guess an appropriate cache mode from the load flags.
4265 if (ContainsAllFlags(mLoadFlags, INHIBIT_CACHING | LOAD_BYPASS_CACHE)) {
4266 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE;
4267 } else if (ContainsAllFlags(mLoadFlags, LOAD_BYPASS_CACHE)) {
4268 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD;
4269 } else if (ContainsAllFlags(mLoadFlags, VALIDATE_ALWAYS) ||
4270 LoadForceValidateCacheContent()) {
4271 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE;
4272 } else if (ContainsAllFlags(
4273 mLoadFlags,
4274 VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE)) {
4275 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED;
4276 } else if (ContainsAllFlags(mLoadFlags, VALIDATE_NEVER)) {
4277 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE;
4278 } else {
4279 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT;
4280 }
4281
4282 return NS_OK;
4283}
4284
4285namespace {
4286
4287void SetCacheFlags(Atomic<uint32_t, Relaxed>& aLoadFlags, uint32_t aFlags) {
4288 // First, clear any possible cache related flags
4289 uint32_t allPossibleFlags =
4290 nsIRequest::INHIBIT_CACHING | nsIRequest::LOAD_BYPASS_CACHE |
4291 nsIRequest::VALIDATE_ALWAYS | nsIRequest::LOAD_FROM_CACHE |
4292 nsICachingChannel::LOAD_ONLY_FROM_CACHE;
4293 aLoadFlags &= ~allPossibleFlags;
4294
4295 // Then set the new flags
4296 aLoadFlags |= aFlags;
4297}
4298
4299} // anonymous namespace
4300
4301NS_IMETHODIMPnsresult
4302HttpBaseChannel::SetFetchCacheMode(uint32_t aFetchCacheMode) {
4303 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4303); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4303, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4303); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4303
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 4303); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
4304
4305 // Now, set the load flags that implement each cache mode.
4306 switch (aFetchCacheMode) {
4307 case nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT:
4308 // The "default" mode means to use the http cache normally and
4309 // respect any http cache-control headers. We effectively want
4310 // to clear our cache related load flags.
4311 SetCacheFlags(mLoadFlags, 0);
4312 break;
4313 case nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE:
4314 // no-store means don't consult the cache on the way to the network, and
4315 // don't store the response in the cache even if it's cacheable.
4316 SetCacheFlags(mLoadFlags, INHIBIT_CACHING | LOAD_BYPASS_CACHE);
4317 break;
4318 case nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD:
4319 // reload means don't consult the cache on the way to the network, but
4320 // do store the response in the cache if possible.
4321 SetCacheFlags(mLoadFlags, LOAD_BYPASS_CACHE);
4322 break;
4323 case nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE:
4324 // no-cache means always validate what's in the cache.
4325 SetCacheFlags(mLoadFlags, VALIDATE_ALWAYS);
4326 break;
4327 case nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE:
4328 // force-cache means don't validate unless if the response would vary.
4329 SetCacheFlags(mLoadFlags, VALIDATE_NEVER);
4330 break;
4331 case nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED:
4332 // only-if-cached means only from cache, no network, no validation,
4333 // generate a network error if the document was't in the cache. The
4334 // privacy implications of these flags (making it fast/easy to check if
4335 // the user has things in their cache without any network traffic side
4336 // effects) are addressed in the Request constructor which
4337 // enforces/requires same-origin request mode.
4338 SetCacheFlags(mLoadFlags,
4339 VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE);
4340 break;
4341 }
4342
4343#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED1
4344 uint32_t finalMode = 0;
4345 MOZ_ALWAYS_SUCCEEDS(GetFetchCacheMode(&finalMode))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(GetFetchCacheMode(&finalMode))), 1)))), 1))) { } else { do
{ do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(GetFetchCacheMode(&finalMode))"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4345
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(GetFetchCacheMode(&finalMode))"
")"); do { MOZ_CrashSequence(__null, 4345); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
4346 MOZ_DIAGNOSTIC_ASSERT(finalMode == aFetchCacheMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(finalMode == aFetchCacheMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(finalMode == aFetchCacheMode
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"finalMode == aFetchCacheMode", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4346); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "finalMode == aFetchCacheMode"
")"); do { MOZ_CrashSequence(__null, 4346); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4347#endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED
4348
4349 return NS_OK;
4350}
4351
4352//-----------------------------------------------------------------------------
4353// HttpBaseChannel::nsISupportsPriority
4354//-----------------------------------------------------------------------------
4355
4356NS_IMETHODIMPnsresult
4357HttpBaseChannel::GetPriority(int32_t* value) {
4358 *value = mPriority;
4359 return NS_OK;
4360}
4361
4362NS_IMETHODIMPnsresult
4363HttpBaseChannel::AdjustPriority(int32_t delta) {
4364 return SetPriority(mPriority + delta);
4365}
4366
4367//-----------------------------------------------------------------------------
4368// HttpBaseChannel::nsIResumableChannel
4369//-----------------------------------------------------------------------------
4370
4371NS_IMETHODIMPnsresult
4372HttpBaseChannel::GetEntityID(nsACString& aEntityID) {
4373 // Don't return an entity ID for Non-GET requests which require
4374 // additional data
4375 if (!mRequestHead.IsGet()) {
4376 return NS_ERROR_NOT_RESUMABLE;
4377 }
4378
4379 uint64_t size = UINT64_MAX(18446744073709551615UL);
4380 nsAutoCString etag, lastmod;
4381 if (mResponseHead) {
4382 // Don't return an entity if the server sent the following header:
4383 // Accept-Ranges: none
4384 // Not sending the Accept-Ranges header means we can still try
4385 // sending range requests.
4386 nsAutoCString acceptRanges;
4387 (void)mResponseHead->GetHeader(nsHttp::Accept_Ranges, acceptRanges);
4388 if (!acceptRanges.IsEmpty() &&
4389 !nsHttp::FindToken(acceptRanges.get(), "bytes",
4390 HTTP_HEADER_VALUE_SEPS" \t" ",")) {
4391 return NS_ERROR_NOT_RESUMABLE;
4392 }
4393
4394 size = mResponseHead->TotalEntitySize();
4395 (void)mResponseHead->GetHeader(nsHttp::Last_Modified, lastmod);
4396 (void)mResponseHead->GetHeader(nsHttp::ETag, etag);
4397 }
4398 nsCString entityID;
4399 NS_EscapeURL(etag.BeginReading(), etag.Length(),
4400 esc_AlwaysCopy | esc_FileBaseName | esc_Forced, entityID);
4401 entityID.Append('/');
4402 entityID.AppendInt(int64_t(size));
4403 entityID.Append('/');
4404 entityID.Append(lastmod);
4405 // NOTE: Appending lastmod as the last part avoids having to escape it
4406
4407 aEntityID = std::move(entityID);
4408
4409 return NS_OK;
4410}
4411
4412//-----------------------------------------------------------------------------
4413// HttpBaseChannel::nsIConsoleReportCollector
4414//-----------------------------------------------------------------------------
4415
4416void HttpBaseChannel::AddConsoleReport(
4417 uint32_t aErrorFlags, const nsACString& aCategory,
4418 PropertiesFile aPropertiesFile, const nsACString& aSourceFileURI,
4419 uint32_t aLineNumber, uint32_t aColumnNumber,
4420 const nsACString& aMessageName, const nsTArray<nsString>& aStringParams) {
4421 mReportCollector->AddConsoleReport(aErrorFlags, aCategory, aPropertiesFile,
4422 aSourceFileURI, aLineNumber, aColumnNumber,
4423 aMessageName, aStringParams);
4424
4425 // If this channel is already part of a loadGroup, we can flush this console
4426 // report immediately.
4427 HttpBaseChannel::MaybeFlushConsoleReports();
4428}
4429
4430void HttpBaseChannel::FlushReportsToConsole(uint64_t aInnerWindowID,
4431 ReportAction aAction) {
4432 mReportCollector->FlushReportsToConsole(aInnerWindowID, aAction);
4433}
4434
4435void HttpBaseChannel::FlushReportsToConsoleForServiceWorkerScope(
4436 const nsACString& aScope, ReportAction aAction) {
4437 mReportCollector->FlushReportsToConsoleForServiceWorkerScope(aScope, aAction);
4438}
4439
4440void HttpBaseChannel::FlushConsoleReports(dom::Document* aDocument,
4441 ReportAction aAction) {
4442 mReportCollector->FlushConsoleReports(aDocument, aAction);
4443}
4444
4445void HttpBaseChannel::FlushConsoleReports(nsILoadGroup* aLoadGroup,
4446 ReportAction aAction) {
4447 mReportCollector->FlushConsoleReports(aLoadGroup, aAction);
4448}
4449
4450void HttpBaseChannel::FlushConsoleReports(
4451 nsIConsoleReportCollector* aCollector) {
4452 mReportCollector->FlushConsoleReports(aCollector);
4453}
4454
4455void HttpBaseChannel::StealConsoleReports(
4456 nsTArray<net::ConsoleReportCollected>& aReports) {
4457 mReportCollector->StealConsoleReports(aReports);
4458}
4459
4460void HttpBaseChannel::ClearConsoleReports() {
4461 mReportCollector->ClearConsoleReports();
4462}
4463
4464bool HttpBaseChannel::IsNavigation() {
4465 return LoadForceMainDocumentChannel() || (mLoadFlags & LOAD_DOCUMENT_URI);
4466}
4467
4468bool HttpBaseChannel::BypassServiceWorker() const {
4469 return mLoadFlags & LOAD_BYPASS_SERVICE_WORKER;
4470}
4471
4472bool HttpBaseChannel::ShouldIntercept(nsIURI* aURI) {
4473 nsCOMPtr<nsINetworkInterceptController> controller;
4474 GetCallback(controller);
4475 bool shouldIntercept = false;
4476
4477 if (!StaticPrefs::dom_serviceWorkers_enabled()) {
4478 return false;
4479 }
4480
4481 // We should never intercept internal redirects. The ServiceWorker code
4482 // can trigger interntal redirects as the result of a FetchEvent. If
4483 // we re-intercept then an infinite loop can occur.
4484 //
4485 // Its also important that we do not set the LOAD_BYPASS_SERVICE_WORKER
4486 // flag because an internal redirect occurs. Its possible that another
4487 // interception should occur after the internal redirect. For example,
4488 // if the ServiceWorker chooses not to call respondWith() the channel
4489 // will be reset with an internal redirect. If the request is a navigation
4490 // and the network then triggers a redirect its possible the new URL
4491 // should be intercepted again.
4492 //
4493 // Note, HSTS upgrade redirects are often treated the same as internal
4494 // redirects. In this case, however, we intentionally allow interception
4495 // of HSTS upgrade redirects. This matches the expected spec behavior and
4496 // does not run the risk of infinite loops as described above.
4497 bool internalRedirect =
4498 mLastRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL;
4499
4500 if (controller && mLoadInfo && !BypassServiceWorker() && !internalRedirect) {
4501 nsresult rv = controller->ShouldPrepareForIntercept(
4502 aURI ? aURI : mURI.get(), this, &shouldIntercept);
4503 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4504 return false;
4505 }
4506 }
4507 return shouldIntercept;
4508}
4509
4510void HttpBaseChannel::AddAsNonTailRequest() {
4511 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4511
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 4511); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4512
4513 if (EnsureRequestContext()) {
4514 LOG((do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::AddAsNonTailRequest this=%p, rc=%p, already added=%d"
, this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
4515 "HttpBaseChannel::AddAsNonTailRequest this=%p, rc=%p, already added=%d",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::AddAsNonTailRequest this=%p, rc=%p, already added=%d"
, this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
4516 this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::AddAsNonTailRequest this=%p, rc=%p, already added=%d"
, this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
;
4517
4518 if (!LoadAddedAsNonTailRequest()) {
4519 mRequestContext->AddNonTailRequest();
4520 StoreAddedAsNonTailRequest(true);
4521 }
4522 }
4523}
4524
4525void HttpBaseChannel::RemoveAsNonTailRequest() {
4526 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4526
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 4526); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4527
4528 if (mRequestContext) {
4529 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::RemoveAsNonTailRequest this=%p, rc=%p, already "
"added=%d", this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
4530 ("HttpBaseChannel::RemoveAsNonTailRequest this=%p, rc=%p, already "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::RemoveAsNonTailRequest this=%p, rc=%p, already "
"added=%d", this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
4531 "added=%d",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::RemoveAsNonTailRequest this=%p, rc=%p, already "
"added=%d", this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
4532 this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::RemoveAsNonTailRequest this=%p, rc=%p, already "
"added=%d", this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
;
4533
4534 if (LoadAddedAsNonTailRequest()) {
4535 mRequestContext->RemoveNonTailRequest();
4536 StoreAddedAsNonTailRequest(false);
4537 }
4538 }
4539}
4540
4541#ifdef DEBUG1
4542void HttpBaseChannel::AssertPrivateBrowsingId() {
4543 nsCOMPtr<nsILoadContext> loadContext;
4544 NS_QueryNotificationCallbacks(this, loadContext);
4545
4546 if (!loadContext) {
4547 return;
4548 }
4549
4550 // We skip testing of favicon loading here since it could be triggered by XUL
4551 // image which uses SystemPrincipal. The SystemPrincpal doesn't have
4552 // mPrivateBrowsingId.
4553 if (mLoadInfo->GetLoadingPrincipal() &&
4554 mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal() &&
4555 mLoadInfo->InternalContentPolicyType() ==
4556 nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
4557 return;
4558 }
4559
4560 OriginAttributes docShellAttrs;
4561 loadContext->GetOriginAttributes(docShellAttrs);
4562 MOZ_ASSERT(mLoadInfo->GetOriginAttributes().mPrivateBrowsingId ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetOriginAttributes().mPrivateBrowsingId
== docShellAttrs.mPrivateBrowsingId)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetOriginAttributes
().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
" (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4565); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { MOZ_CrashSequence(__null, 4565); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4563 docShellAttrs.mPrivateBrowsingId,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetOriginAttributes().mPrivateBrowsingId
== docShellAttrs.mPrivateBrowsingId)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetOriginAttributes
().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
" (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4565); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { MOZ_CrashSequence(__null, 4565); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4564 "PrivateBrowsingId values are not the same between LoadInfo and "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetOriginAttributes().mPrivateBrowsingId
== docShellAttrs.mPrivateBrowsingId)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetOriginAttributes
().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
" (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4565); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { MOZ_CrashSequence(__null, 4565); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4565 "LoadContext.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetOriginAttributes().mPrivateBrowsingId
== docShellAttrs.mPrivateBrowsingId)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetOriginAttributes
().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
" (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4565); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { MOZ_CrashSequence(__null, 4565); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
4566}
4567#endif
4568
4569already_AddRefed<nsILoadInfo> HttpBaseChannel::CloneLoadInfoForRedirect(
4570 nsIURI* aNewURI, uint32_t aRedirectFlags) {
4571 // make a copy of the loadinfo, append to the redirectchain
4572 // this will be set on the newly created channel for the redirect target.
4573 nsCOMPtr<nsILoadInfo> newLoadInfo =
4574 static_cast<mozilla::net::LoadInfo*>(mLoadInfo.get())->Clone();
4575
4576 ExtContentPolicyType contentPolicyType =
4577 mLoadInfo->GetExternalContentPolicyType();
4578 if (contentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
4579 contentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
4580 // Reset PrincipalToInherit to a null principal. We'll credit the the
4581 // redirecting resource's result principal as the new principal's precursor.
4582 // This means that a data: URI will end up loading in a process based on the
4583 // redirected-from URI.
4584 nsCOMPtr<nsIPrincipal> redirectPrincipal;
4585 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
4586 this, getter_AddRefs(redirectPrincipal));
4587 nsCOMPtr<nsIPrincipal> nullPrincipalToInherit =
4588 NullPrincipal::CreateWithInheritedAttributes(redirectPrincipal);
4589 newLoadInfo->SetPrincipalToInherit(nullPrincipalToInherit);
4590 }
4591
4592 bool isTopLevelDoc = newLoadInfo->GetExternalContentPolicyType() ==
4593 ExtContentPolicy::TYPE_DOCUMENT;
4594
4595 if (isTopLevelDoc) {
4596 // re-compute the origin attributes of the loadInfo if it's top-level load.
4597 nsCOMPtr<nsILoadContext> loadContext;
4598 NS_QueryNotificationCallbacks(this, loadContext);
4599 OriginAttributes attrs;
4600 if (loadContext) {
4601 loadContext->GetOriginAttributes(attrs);
4602 }
4603
4604 OriginAttributes channelAttrs = newLoadInfo->GetOriginAttributes();
4605
4606 // Preserve the container from the channel attributes, as it could
4607 // legitimately differ from the loadContext.
4608 attrs.mUserContextId = channelAttrs.mUserContextId;
4609
4610 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId"
" (" "docshell and necko should have the same privateBrowsingId attribute."
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4612); AnnotateMozCrashReason("MOZ_ASSERT" "(" "attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { MOZ_CrashSequence(__null, 4612); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4611 attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId"
" (" "docshell and necko should have the same privateBrowsingId attribute."
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4612); AnnotateMozCrashReason("MOZ_ASSERT" "(" "attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { MOZ_CrashSequence(__null, 4612); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4612 "docshell and necko should have the same privateBrowsingId attribute.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId"
" (" "docshell and necko should have the same privateBrowsingId attribute."
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4612); AnnotateMozCrashReason("MOZ_ASSERT" "(" "attrs.mPrivateBrowsingId == channelAttrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { MOZ_CrashSequence(__null, 4612); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4613 MOZ_ASSERT(attrs.mGeckoViewSessionContextId ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { MOZ_CrashSequence(__null, 4616); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4614 channelAttrs.mGeckoViewSessionContextId,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { MOZ_CrashSequence(__null, 4616); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4615 "docshell and necko should have the same "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { MOZ_CrashSequence(__null, 4616); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4616 "geckoViewSessionContextId attribute")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "attrs.mGeckoViewSessionContextId == channelAttrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { MOZ_CrashSequence(__null, 4616); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4617
4618 attrs.SetFirstPartyDomain(true, aNewURI);
4619
4620 newLoadInfo->SetOriginAttributes(attrs);
4621
4622 // re-compute the upgrade insecure requests bit for document navigations
4623 // since it should only apply to same-origin navigations (redirects).
4624 // we only do this if the CSP of the triggering element (the cspToInherit)
4625 // uses 'upgrade-insecure-requests', otherwise UIR does not apply.
4626 nsCOMPtr<nsIPolicyContainer> policyContainer =
4627 newLoadInfo->GetPolicyContainerToInherit();
4628 nsCOMPtr<nsIContentSecurityPolicy> csp =
4629 PolicyContainer::GetCSP(policyContainer);
4630 if (csp) {
4631 bool upgradeInsecureRequests = false;
4632 csp->GetUpgradeInsecureRequests(&upgradeInsecureRequests);
4633 if (upgradeInsecureRequests) {
4634 nsCOMPtr<nsIPrincipal> resultPrincipal =
4635 BasePrincipal::CreateContentPrincipal(
4636 aNewURI, newLoadInfo->GetOriginAttributes());
4637 bool isConsideredSameOriginforUIR =
4638 nsContentSecurityUtils::IsConsideredSameOriginForUIR(
4639 newLoadInfo->TriggeringPrincipal(), resultPrincipal);
4640 static_cast<mozilla::net::LoadInfo*>(newLoadInfo.get())
4641 ->SetUpgradeInsecureRequests(isConsideredSameOriginforUIR);
4642 }
4643 }
4644 }
4645
4646 // Clone a new cookieJarSettings from the old one for the new channel.
4647 // Otherwise, updating the new cookieJarSettings will affect the old one.
4648 nsCOMPtr<nsICookieJarSettings> oldCookieJarSettings;
4649 mLoadInfo->GetCookieJarSettings(getter_AddRefs(oldCookieJarSettings));
4650
4651 RefPtr<CookieJarSettings> newCookieJarSettings;
4652 newCookieJarSettings = CookieJarSettings::Cast(oldCookieJarSettings)->Clone();
4653
4654 newLoadInfo->SetCookieJarSettings(newCookieJarSettings);
4655
4656 // Clear the isThirdPartyContextToTopWindow flag for the new channel so that
4657 // it will be computed again when the new channel is opened.
4658 static_cast<net::LoadInfo*>(newLoadInfo.get())
4659 ->ClearIsThirdPartyContextToTopWindow();
4660
4661 // Leave empty, we want a 'clean ground' when creating the new channel.
4662 // This will be ensured to be either set by the protocol handler or set
4663 // to the redirect target URI properly after the channel creation.
4664 newLoadInfo->SetResultPrincipalURI(nullptr);
4665
4666 bool isInternalRedirect =
4667 (aRedirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
4668 nsIChannelEventSink::REDIRECT_STS_UPGRADE));
4669
4670 // Reset our sandboxed null principal ID when cloning loadInfo for an
4671 // externally visible redirect.
4672 if (!isInternalRedirect) {
4673 // If we've redirected from http to something that isn't, clear
4674 // the "external" flag, as loads that now go to other apps should be
4675 // allowed to go ahead and not trip infinite-loop protection
4676 // (see bug 1717314 for context).
4677 if (!net::SchemeIsHttpOrHttps(aNewURI)) {
4678 newLoadInfo->SetLoadTriggeredFromExternal(false);
4679 }
4680 newLoadInfo->ResetSandboxedNullPrincipalID();
4681
4682 if (isTopLevelDoc) {
4683 // Reset HTTPS-first and -only status on http redirect. To not
4684 // unexpectedly downgrade requests that weren't upgraded via HTTPS-First
4685 // (Bug 1904238).
4686 (void)newLoadInfo->SetHttpsOnlyStatus(
4687 nsILoadInfo::HTTPS_ONLY_UNINITIALIZED);
4688
4689 // Reset schemeless status flag to prevent schemeless HTTPS-First from
4690 // repeatedly trying to upgrade loads that get downgraded again from the
4691 // server by a redirect (Bug 1937386).
4692 (void)newLoadInfo->SetSchemelessInput(
4693 nsILoadInfo::SchemelessInputTypeUnset);
4694 }
4695 }
4696
4697 newLoadInfo->AppendRedirectHistoryEntry(this, isInternalRedirect);
4698
4699 return newLoadInfo.forget();
4700}
4701
4702//-----------------------------------------------------------------------------
4703// nsHttpChannel::nsITraceableChannel
4704//-----------------------------------------------------------------------------
4705
4706NS_IMETHODIMPnsresult
4707HttpBaseChannel::SetNewListener(nsIStreamListener* aListener,
4708 bool aMustApplyContentConversion,
4709 nsIStreamListener** _retval) {
4710 LOG((do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetNewListener [this=%p, mListener=%p, newListener=%p]"
, this, mListener.get(), aListener); } } while (0)
4711 "HttpBaseChannel::SetNewListener [this=%p, mListener=%p, newListener=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetNewListener [this=%p, mListener=%p, newListener=%p]"
, this, mListener.get(), aListener); } } while (0)
4712 this, mListener.get(), aListener))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetNewListener [this=%p, mListener=%p, newListener=%p]"
, this, mListener.get(), aListener); } } while (0)
;
4713
4714 if (!LoadTracingEnabled()) return NS_ERROR_FAILURE;
4715
4716 NS_ENSURE_STATE(mListener)do { if ((__builtin_expect(!!(!(mListener)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mListener" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4716
); return NS_ERROR_UNEXPECTED; } } while (false)
;
4717 NS_ENSURE_ARG_POINTER(aListener)do { if ((__builtin_expect(!!(!(aListener)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aListener" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 4717
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4718
4719 nsCOMPtr<nsIStreamListener> wrapper = new nsStreamListenerWrapper(mListener);
4720
4721 wrapper.forget(_retval);
4722 mListener = aListener;
4723 if (aMustApplyContentConversion) {
4724 StoreListenerRequiresContentConversion(true);
4725 }
4726 return NS_OK;
4727}
4728
4729//-----------------------------------------------------------------------------
4730// HttpBaseChannel helpers
4731//-----------------------------------------------------------------------------
4732
4733void HttpBaseChannel::ReleaseListeners() {
4734 MOZ_ASSERT(mCurrentThread->IsOnCurrentThread(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCurrentThread->IsOnCurrentThread())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mCurrentThread->IsOnCurrentThread()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mCurrentThread->IsOnCurrentThread()"
" (" "Should only be called on the current thread" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4735); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentThread->IsOnCurrentThread()"
") (" "Should only be called on the current thread" ")"); do
{ MOZ_CrashSequence(__null, 4735); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
4735 "Should only be called on the current thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCurrentThread->IsOnCurrentThread())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mCurrentThread->IsOnCurrentThread()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mCurrentThread->IsOnCurrentThread()"
" (" "Should only be called on the current thread" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 4735); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentThread->IsOnCurrentThread()"
") (" "Should only be called on the current thread" ")"); do
{ MOZ_CrashSequence(__null, 4735); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
4736
4737 mListener = nullptr;
4738 mCallbacks = nullptr;
4739 mProgressSink = nullptr;
4740 mCompressListener = nullptr;
4741 mORB = nullptr;
4742}
4743
4744void HttpBaseChannel::DoNotifyListener() {
4745 LOG(("HttpBaseChannel::DoNotifyListener this=%p", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::DoNotifyListener this=%p", this); } } while
(0)
;
4746
4747 // In case nsHttpChannel::OnStartRequest wasn't called (e.g. due to flag
4748 // LOAD_ONLY_IF_MODIFIED) we want to set AfterOnStartRequestBegun to true
4749 // before notifying listener.
4750 if (!LoadAfterOnStartRequestBegun()) {
4751 StoreAfterOnStartRequestBegun(true);
4752 }
4753
4754 if (mListener && !LoadOnStartRequestCalled()) {
4755 nsCOMPtr<nsIStreamListener> listener = mListener;
4756 StoreOnStartRequestCalled(true);
4757 listener->OnStartRequest(this);
4758 }
4759 StoreOnStartRequestCalled(true);
4760
4761 // Make sure IsPending is set to false. At this moment we are done from
4762 // the point of view of our consumer and we have to report our self
4763 // as not-pending.
4764 StoreIsPending(false);
4765
4766 // notify "http-on-before-stop-request" observers
4767 gHttpHandler->OnBeforeStopRequest(this);
4768
4769 if (mListener && !LoadOnStopRequestCalled()) {
4770 nsCOMPtr<nsIStreamListener> listener = mListener;
4771 StoreOnStopRequestCalled(true);
4772 listener->OnStopRequest(this, mStatus);
4773 }
4774 StoreOnStopRequestCalled(true);
4775
4776 // notify "http-on-stop-request" observers
4777 gHttpHandler->OnStopRequest(this);
4778
4779 // This channel has finished its job, potentially release any tail-blocked
4780 // requests with this.
4781 RemoveAsNonTailRequest();
4782
4783 // We have to make sure to drop the references to listeners and callbacks
4784 // no longer needed.
4785 ReleaseListeners();
4786
4787 DoNotifyListenerCleanup();
4788
4789 // If this is a navigation, then we must let the docshell flush the reports
4790 // to the console later. The LoadDocument() is pointing at the detached
4791 // document that started the navigation. We want to show the reports on the
4792 // new document. Otherwise the console is wiped and the user never sees
4793 // the information.
4794 if (!IsNavigation()) {
4795 if (mLoadGroup) {
4796 FlushConsoleReports(mLoadGroup);
4797 } else {
4798 RefPtr<dom::Document> doc;
4799 mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
4800 FlushConsoleReports(doc);
4801 }
4802 }
4803}
4804
4805void HttpBaseChannel::AddCookiesToRequest() {
4806 if (mLoadFlags & LOAD_ANONYMOUS) {
4807 return;
4808 }
4809
4810 bool useCookieService = (XRE_IsParentProcess());
4811 nsAutoCString cookie;
4812 if (useCookieService) {
4813 nsICookieService* cs = gHttpHandler->GetCookieService();
4814 if (cs) {
4815 cs->GetCookieStringFromHttp(mURI, this, cookie);
4816 }
4817
4818 if (cookie.IsEmpty()) {
4819 cookie = mUserSetCookieHeader;
4820 } else if (!mUserSetCookieHeader.IsEmpty()) {
4821 cookie.AppendLiteral("; ");
4822 cookie.Append(mUserSetCookieHeader);
4823 }
4824 } else {
4825 cookie = mUserSetCookieHeader;
4826 }
4827
4828 // If we are in the child process, we want the parent seeing any
4829 // cookie headers that might have been set by SetRequestHeader()
4830 SetRequestHeader(nsHttp::Cookie.val(), cookie, false);
4831}
4832
4833/* static */
4834void HttpBaseChannel::PropagateReferenceIfNeeded(
4835 nsIURI* aURI, nsCOMPtr<nsIURI>& aRedirectURI) {
4836 bool hasRef = false;
4837 nsresult rv = aRedirectURI->GetHasRef(&hasRef);
4838 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !hasRef) {
4839 nsAutoCString ref;
4840 aURI->GetRef(ref);
4841 if (!ref.IsEmpty()) {
4842 // NOTE: SetRef will fail if mRedirectURI is immutable
4843 // (e.g. an about: URI)... Oh well.
4844 (void)NS_MutateURI(aRedirectURI).SetRef(ref).Finalize(aRedirectURI);
4845 }
4846 }
4847}
4848
4849bool HttpBaseChannel::ShouldRewriteRedirectToGET(
4850 uint32_t httpStatus, nsHttpRequestHead::ParsedMethodType method) {
4851 // for 301 and 302, only rewrite POST
4852 if (httpStatus == 301 || httpStatus == 302) {
4853 return method == nsHttpRequestHead::kMethod_Post;
4854 }
4855
4856 // rewrite for 303 unless it was HEAD
4857 if (httpStatus == 303) return method != nsHttpRequestHead::kMethod_Head;
4858
4859 // otherwise, such as for 307, do not rewrite
4860 return false;
4861}
4862
4863NS_IMETHODIMPnsresult
4864HttpBaseChannel::ShouldStripRequestBodyHeader(const nsACString& aMethod,
4865 bool* aResult) {
4866 *aResult = false;
4867 uint32_t httpStatus = 0;
4868 if (NS_FAILED(GetResponseStatus(&httpStatus))((bool)(__builtin_expect(!!(NS_FAILED_impl(GetResponseStatus(
&httpStatus))), 0)))
) {
4869 return NS_OK;
4870 }
4871
4872 nsAutoCString method(aMethod);
4873 nsHttpRequestHead::ParsedMethodType parsedMethod;
4874 nsHttpRequestHead::ParseMethod(method, parsedMethod);
4875 // Fetch 4.4.11, which is slightly different than the perserved method
4876 // algrorithm: strip request-body-header for GET->GET redirection for 303.
4877 *aResult =
4878 ShouldRewriteRedirectToGET(httpStatus, parsedMethod) &&
4879 !(httpStatus == 303 && parsedMethod == nsHttpRequestHead::kMethod_Get);
4880
4881 return NS_OK;
4882}
4883
4884HttpBaseChannel::ReplacementChannelConfig
4885HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod,
4886 uint32_t aRedirectFlags,
4887 ReplacementReason aReason) {
4888 ReplacementChannelConfig config;
4889 config.redirectFlags = aRedirectFlags;
4890 config.classOfService = mClassOfService;
4891
4892 if (mPrivateBrowsingOverriden) {
4893 config.privateBrowsing = Some(mPrivateBrowsing);
4894 }
4895
4896 if (mReferrerInfo) {
4897 // When cloning for a document channel replacement (parent process
4898 // copying values for a new content process channel), this happens after
4899 // OnStartRequest so we have the headers for the response available.
4900 // We don't want to apply them to the referrer for the channel though,
4901 // since that is the referrer for the current document, and the header
4902 // should only apply to navigations from the current document.
4903 if (aReason == ReplacementReason::DocumentChannel) {
4904 config.referrerInfo = mReferrerInfo;
4905 } else {
4906 dom::ReferrerPolicy referrerPolicy = dom::ReferrerPolicy::_empty;
4907 nsAutoCString tRPHeaderCValue;
4908 (void)GetResponseHeader("referrer-policy"_ns, tRPHeaderCValue);
4909 NS_ConvertUTF8toUTF16 tRPHeaderValue(tRPHeaderCValue);
4910
4911 if (!tRPHeaderValue.IsEmpty()) {
4912 referrerPolicy =
4913 dom::ReferrerInfo::ReferrerPolicyFromHeaderString(tRPHeaderValue);
4914 }
4915
4916 // In case we are here because an upgrade happened through mixed content
4917 // upgrading, CSP upgrade-insecure-requests, HTTPS-Only or HTTPS-First, we
4918 // have to recalculate the referrer based on the original referrer to
4919 // account for the different scheme. This does NOT apply to HSTS.
4920 // See Bug 1857894 and order of https://fetch.spec.whatwg.org/#main-fetch.
4921 // Otherwise, if we have a new referrer policy, we want to recalculate the
4922 // referrer based on the old computed referrer (Bug 1678545).
4923 bool wasNonHSTSUpgrade =
4924 (aRedirectFlags & nsIChannelEventSink::REDIRECT_STS_UPGRADE) &&
4925 (!mLoadInfo->GetHstsStatus());
4926 if (wasNonHSTSUpgrade) {
4927 nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetOriginalReferrer();
4928 config.referrerInfo =
4929 new dom::ReferrerInfo(referrer, mReferrerInfo->ReferrerPolicy(),
4930 mReferrerInfo->GetSendReferrer());
4931 } else if (referrerPolicy != dom::ReferrerPolicy::_empty) {
4932 nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetComputedReferrer();
4933 config.referrerInfo = new dom::ReferrerInfo(
4934 referrer, referrerPolicy, mReferrerInfo->GetSendReferrer());
4935 } else {
4936 config.referrerInfo = mReferrerInfo;
4937 }
4938 }
4939 }
4940
4941 nsCOMPtr<nsITimedChannel> oldTimedChannel(
4942 do_QueryInterface(static_cast<nsIHttpChannel*>(this)));
4943 if (oldTimedChannel) {
4944 config.timedChannelInfo = Some(dom::TimedChannelInfo());
4945 config.timedChannelInfo->redirectCount() = mRedirectCount;
4946 config.timedChannelInfo->internalRedirectCount() = mInternalRedirectCount;
4947 config.timedChannelInfo->asyncOpen() = mAsyncOpenTime;
4948 config.timedChannelInfo->channelCreation() = mChannelCreationTimestamp;
4949 config.timedChannelInfo->redirectStart() = mRedirectStartTimeStamp;
4950 config.timedChannelInfo->redirectEnd() = mRedirectEndTimeStamp;
4951 config.timedChannelInfo->initiatorType() = mInitiatorType;
4952 config.timedChannelInfo->allRedirectsSameOrigin() =
4953 LoadAllRedirectsSameOrigin();
4954 config.timedChannelInfo->allRedirectsSameOriginIgnoringInternal() =
4955 LoadAllRedirectsSameOriginIgnoringInternal();
4956 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() =
4957 LoadAllRedirectsPassTimingAllowCheck();
4958 // Execute the timing allow check to determine whether
4959 // to report the redirect timing info
4960 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
4961 // TYPE_DOCUMENT loads don't have a loadingPrincipal, so we can't set
4962 // AllRedirectsPassTimingAllowCheck on them.
4963 if (loadInfo->GetExternalContentPolicyType() !=
4964 ExtContentPolicy::TYPE_DOCUMENT) {
4965 nsCOMPtr<nsIPrincipal> principal = loadInfo->GetLoadingPrincipal();
4966 config.timedChannelInfo->timingAllowCheckForPrincipal() =
4967 Some(oldTimedChannel->TimingAllowCheck(principal));
4968 }
4969
4970 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() =
4971 LoadAllRedirectsPassTimingAllowCheck();
4972 config.timedChannelInfo->launchServiceWorkerStart() =
4973 mLaunchServiceWorkerStart;
4974 config.timedChannelInfo->launchServiceWorkerEnd() = mLaunchServiceWorkerEnd;
4975 config.timedChannelInfo->dispatchFetchEventStart() =
4976 mDispatchFetchEventStart;
4977 config.timedChannelInfo->dispatchFetchEventEnd() = mDispatchFetchEventEnd;
4978 config.timedChannelInfo->handleFetchEventStart() = mHandleFetchEventStart;
4979 config.timedChannelInfo->handleFetchEventEnd() = mHandleFetchEventEnd;
4980 config.timedChannelInfo->responseStart() =
4981 mTransactionTimings.responseStart;
4982 config.timedChannelInfo->responseEnd() = mTransactionTimings.responseEnd;
4983 }
4984
4985 if (aPreserveMethod) {
4986 // since preserveMethod is true, we need to ensure that the appropriate
4987 // request method gets set on the channel, regardless of whether or not
4988 // we set the upload stream above. This means SetRequestMethod() will
4989 // be called twice if ExplicitSetUploadStream() gets called above.
4990
4991 nsAutoCString method;
4992 mRequestHead.Method(method);
4993 config.method = Some(method);
4994
4995 if (mUploadStream) {
4996 // rewind upload stream
4997 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
4998 if (seekable) {
4999 seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
5000 }
5001 config.uploadStream = mUploadStream;
5002 }
5003 config.uploadStreamLength = mReqContentLength;
5004
5005 nsAutoCString contentType;
5006 nsresult rv = mRequestHead.GetHeader(nsHttp::Content_Type, contentType);
5007 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5008 config.contentType = Some(contentType);
5009 }
5010
5011 nsAutoCString contentLength;
5012 rv = mRequestHead.GetHeader(nsHttp::Content_Length, contentLength);
5013 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5014 config.contentLength = Some(contentLength);
5015 }
5016 }
5017
5018 return config;
5019}
5020
5021/* static */ void HttpBaseChannel::ConfigureReplacementChannel(
5022 nsIChannel* newChannel, const ReplacementChannelConfig& config,
5023 ReplacementReason aReason) {
5024 nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(newChannel));
5025 if (cos) {
5026 cos->SetClassOfService(config.classOfService);
5027 }
5028
5029 // Try to preserve the privacy bit if it has been overridden
5030 if (config.privateBrowsing) {
5031 nsCOMPtr<nsIPrivateBrowsingChannel> newPBChannel =
5032 do_QueryInterface(newChannel);
5033 if (newPBChannel) {
5034 newPBChannel->SetPrivate(*config.privateBrowsing);
5035 }
5036 }
5037
5038 // Transfer the timing data (if we are dealing with an nsITimedChannel).
5039 nsCOMPtr<nsITimedChannel> newTimedChannel(do_QueryInterface(newChannel));
5040 if (config.timedChannelInfo && newTimedChannel) {
5041 // If we're an internal redirect, or a document channel replacement,
5042 // then we shouldn't record any new timing for this and just copy
5043 // over the existing values.
5044 bool shouldHideTiming = aReason != ReplacementReason::Redirect;
5045 if (shouldHideTiming) {
5046 newTimedChannel->SetRedirectCount(
5047 config.timedChannelInfo->redirectCount());
5048 int32_t newCount = config.timedChannelInfo->internalRedirectCount() + 1;
5049 newTimedChannel->SetInternalRedirectCount(std::max(
5050 newCount, static_cast<int32_t>(
5051 config.timedChannelInfo->internalRedirectCount())));
5052 } else {
5053 int32_t newCount = config.timedChannelInfo->redirectCount() + 1;
5054 newTimedChannel->SetRedirectCount(std::max(
5055 newCount,
5056 static_cast<int32_t>(config.timedChannelInfo->redirectCount())));
5057 newTimedChannel->SetInternalRedirectCount(
5058 config.timedChannelInfo->internalRedirectCount());
5059 }
5060
5061 if (shouldHideTiming) {
5062 if (!config.timedChannelInfo->channelCreation().IsNull()) {
5063 newTimedChannel->SetChannelCreation(
5064 config.timedChannelInfo->channelCreation());
5065 }
5066
5067 if (!config.timedChannelInfo->asyncOpen().IsNull()) {
5068 newTimedChannel->SetAsyncOpen(config.timedChannelInfo->asyncOpen());
5069 }
5070 }
5071
5072 // If the RedirectStart is null, we will use the AsyncOpen value of the
5073 // previous channel (this is the first redirect in the redirects chain).
5074 if (config.timedChannelInfo->redirectStart().IsNull()) {
5075 // Only do this for real redirects. Internal redirects should be hidden.
5076 if (!shouldHideTiming) {
5077 newTimedChannel->SetRedirectStart(config.timedChannelInfo->asyncOpen());
5078 }
5079 } else {
5080 newTimedChannel->SetRedirectStart(
5081 config.timedChannelInfo->redirectStart());
5082 }
5083
5084 // For internal redirects just propagate the last redirect end time
5085 // forward. Otherwise the new redirect end time is the last response
5086 // end time.
5087 TimeStamp newRedirectEnd;
5088 if (shouldHideTiming) {
5089 newRedirectEnd = config.timedChannelInfo->redirectEnd();
5090 } else if (!config.timedChannelInfo->responseEnd().IsNull()) {
5091 newRedirectEnd = config.timedChannelInfo->responseEnd();
5092 } else {
5093 newRedirectEnd = TimeStamp::Now();
5094 }
5095 newTimedChannel->SetRedirectEnd(newRedirectEnd);
5096
5097 newTimedChannel->SetInitiatorType(config.timedChannelInfo->initiatorType());
5098
5099 nsCOMPtr<nsILoadInfo> loadInfo = newChannel->LoadInfo();
5100 MOZ_ASSERT(loadInfo)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(loadInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(loadInfo))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("loadInfo", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5100); AnnotateMozCrashReason("MOZ_ASSERT" "(" "loadInfo" ")"
); do { MOZ_CrashSequence(__null, 5100); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5101
5102 newTimedChannel->SetAllRedirectsSameOrigin(
5103 config.timedChannelInfo->allRedirectsSameOrigin());
5104 newTimedChannel->SetAllRedirectsSameOriginIgnoringInternal(
5105 config.timedChannelInfo->allRedirectsSameOriginIgnoringInternal());
5106
5107 if (config.timedChannelInfo->timingAllowCheckForPrincipal()) {
5108 newTimedChannel->SetAllRedirectsPassTimingAllowCheck(
5109 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() &&
5110 *config.timedChannelInfo->timingAllowCheckForPrincipal());
5111 }
5112
5113 // Propagate service worker measurements across redirects. The
5114 // PeformanceResourceTiming.workerStart API expects to see the
5115 // worker start time after a redirect.
5116 newTimedChannel->SetLaunchServiceWorkerStart(
5117 config.timedChannelInfo->launchServiceWorkerStart());
5118 newTimedChannel->SetLaunchServiceWorkerEnd(
5119 config.timedChannelInfo->launchServiceWorkerEnd());
5120 newTimedChannel->SetDispatchFetchEventStart(
5121 config.timedChannelInfo->dispatchFetchEventStart());
5122 newTimedChannel->SetDispatchFetchEventEnd(
5123 config.timedChannelInfo->dispatchFetchEventEnd());
5124 newTimedChannel->SetHandleFetchEventStart(
5125 config.timedChannelInfo->handleFetchEventStart());
5126 newTimedChannel->SetHandleFetchEventEnd(
5127 config.timedChannelInfo->handleFetchEventEnd());
5128 }
5129
5130 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
5131 if (!httpChannel) {
5132 return; // no other options to set
5133 }
5134
5135 if (config.uploadStream) {
5136 nsCOMPtr<nsIUploadChannel2> uploadChannel2 = do_QueryInterface(httpChannel);
5137 // replicate original call to SetUploadStream...
5138 if (uploadChannel2) {
5139 const nsACString& ctype =
5140 config.contentType ? *config.contentType : VoidCString();
5141 // If header is not present mRequestHead.HasHeaderValue will truncated
5142 // it. But we want to end up with a void string, not an empty string,
5143 // because ExplicitSetUploadStream treats the former as "no header" and
5144 // the latter as "header with empty string value".
5145 const nsACString& method = config.method ? *config.method : VoidCString();
5146 uploadChannel2->ExplicitSetUploadStream(
5147 config.uploadStream, ctype, config.uploadStreamLength, method);
5148 } else if (nsCOMPtr<nsIUploadChannel> uploadChannel =
5149 do_QueryInterface(httpChannel)) {
5150 MOZ_ASSERT(false,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Should not QI to nsIUploadChannel but not nsIUploadChannel2"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5151); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Should not QI to nsIUploadChannel but not nsIUploadChannel2"
")"); do { MOZ_CrashSequence(__null, 5151); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5151 "Should not QI to nsIUploadChannel but not nsIUploadChannel2")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Should not QI to nsIUploadChannel but not nsIUploadChannel2"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5151); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Should not QI to nsIUploadChannel but not nsIUploadChannel2"
")"); do { MOZ_CrashSequence(__null, 5151); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5152 }
5153 }
5154
5155 if (config.referrerInfo) {
5156 DebugOnly<nsresult> success{};
5157 success = httpChannel->SetReferrerInfo(config.referrerInfo);
5158 MOZ_ASSERT(NS_SUCCEEDED(success))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)
), 1))))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)
), 1)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)), 1)))"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 5158
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5158); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5159 }
5160
5161 if (config.method) {
5162 DebugOnly<nsresult> rv = httpChannel->SetRequestMethod(*config.method);
5163 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5163); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5163); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5164 }
5165}
5166
5167HttpBaseChannel::ReplacementChannelConfig::ReplacementChannelConfig(
5168 const dom::ReplacementChannelConfigInit& aInit) {
5169 redirectFlags = aInit.redirectFlags();
5170 classOfService = aInit.classOfService();
5171 privateBrowsing = aInit.privateBrowsing();
5172 method = aInit.method();
5173 referrerInfo = aInit.referrerInfo();
5174 timedChannelInfo = aInit.timedChannelInfo();
5175 uploadStream = aInit.uploadStream();
5176 uploadStreamLength = aInit.uploadStreamLength();
5177 contentType = aInit.contentType();
5178 contentLength = aInit.contentLength();
5179}
5180
5181dom::ReplacementChannelConfigInit
5182HttpBaseChannel::ReplacementChannelConfig::Serialize() {
5183 dom::ReplacementChannelConfigInit config;
5184 config.redirectFlags() = redirectFlags;
5185 config.classOfService() = classOfService;
5186 config.privateBrowsing() = privateBrowsing;
5187 config.method() = method;
5188 config.referrerInfo() = referrerInfo;
5189 config.timedChannelInfo() = timedChannelInfo;
5190 config.uploadStream() =
5191 uploadStream ? RemoteLazyInputStream::WrapStream(uploadStream) : nullptr;
5192 config.uploadStreamLength() = uploadStreamLength;
5193 config.contentType() = contentType;
5194 config.contentLength() = contentLength;
5195
5196 return config;
5197}
5198
5199nsresult HttpBaseChannel::SetupReplacementChannel(nsIURI* newURI,
5200 nsIChannel* newChannel,
5201 bool preserveMethod,
5202 uint32_t redirectFlags) {
5203 nsresult rv;
5204
5205 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
5206 ("HttpBaseChannel::SetupReplacementChannel "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
5207 "[this=%p newChannel=%p preserveMethod=%d]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
5208 this, newChannel, preserveMethod))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
;
5209
5210 // Ensure the channel's loadInfo's result principal URI so that it's
5211 // either non-null or updated to the redirect target URI.
5212 // We must do this because in case the loadInfo's result principal URI
5213 // is null, it would be taken from OriginalURI of the channel. But we
5214 // overwrite it with the whole redirect chain first URI before opening
5215 // the target channel, hence the information would be lost.
5216 // If the protocol handler that created the channel wants to use
5217 // the originalURI of the channel as the principal URI, this fulfills
5218 // that request - newURI is the original URI of the channel.
5219 nsCOMPtr<nsILoadInfo> newLoadInfo = newChannel->LoadInfo();
5220 nsCOMPtr<nsIURI> resultPrincipalURI;
5221 rv = newLoadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
5222 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5222); return rv; } } while (false)
;
5223 if (!resultPrincipalURI) {
5224 rv = newLoadInfo->SetResultPrincipalURI(newURI);
5225 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5225); return rv; } } while (false)
;
5226 }
5227
5228 nsLoadFlags loadFlags = mLoadFlags;
5229 loadFlags |= LOAD_REPLACE;
5230
5231 // if the original channel was using SSL and this channel is not using
5232 // SSL, then no need to inhibit persistent caching. however, if the
5233 // original channel was not using SSL and has INHIBIT_PERSISTENT_CACHING
5234 // set, then allow the flag to apply to the redirected channel as well.
5235 // since we force set INHIBIT_PERSISTENT_CACHING on all HTTPS channels,
5236 // we only need to check if the original channel was using SSL.
5237 if (mURI->SchemeIs("https")) {
5238 loadFlags &= ~INHIBIT_PERSISTENT_CACHING;
5239 }
5240
5241 newChannel->SetLoadFlags(loadFlags);
5242
5243 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
5244
5245 ReplacementReason redirectType =
5246 redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
5247 nsIChannelEventSink::REDIRECT_TRANSPARENT)
5248 ? ReplacementReason::InternalRedirect
5249 : ReplacementReason::Redirect;
5250 ReplacementChannelConfig config = CloneReplacementChannelConfig(
5251 preserveMethod, redirectFlags, redirectType);
5252 ConfigureReplacementChannel(newChannel, config, redirectType);
5253
5254 // Check whether or not this was a cross-domain redirect.
5255 nsCOMPtr<nsITimedChannel> newTimedChannel(do_QueryInterface(newChannel));
5256 bool sameOriginWithOriginalUri = SameOriginWithOriginalUri(newURI);
5257 if (config.timedChannelInfo && newTimedChannel) {
5258 newTimedChannel->SetAllRedirectsSameOrigin(
5259 config.timedChannelInfo->allRedirectsSameOrigin() &&
5260 sameOriginWithOriginalUri);
5261 // Internal redirects (e.g. a service worker serving a response from a
5262 // different URL) are not real cross-origin network hops, so they must not
5263 // count as cross-origin for canvas/CSS/media tainting.
5264 newTimedChannel->SetAllRedirectsSameOriginIgnoringInternal(
5265 config.timedChannelInfo->allRedirectsSameOriginIgnoringInternal() &&
5266 (redirectType == ReplacementReason::InternalRedirect ||
5267 sameOriginWithOriginalUri));
5268 }
5269
5270 newChannel->SetLoadGroup(mLoadGroup);
5271 newChannel->SetNotificationCallbacks(mCallbacks);
5272 // TODO: create tests for cross-origin redirect in bug 1662896.
5273 if (sameOriginWithOriginalUri) {
5274 newChannel->SetContentDisposition(mContentDispositionHint);
5275 if (mContentDispositionFilename) {
5276 newChannel->SetContentDispositionFilename(*mContentDispositionFilename);
5277 }
5278 }
5279
5280 if (!httpChannel) return NS_OK; // no other options to set
5281
5282 // Preserve the CORS preflight information.
5283 nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(newChannel);
5284 if (httpInternal) {
5285 httpInternal->SetLastRedirectFlags(redirectFlags);
5286
5287 if (LoadRequireCORSPreflight()) {
5288 httpInternal->SetCorsPreflightParameters(mUnsafeHeaders, false, false);
5289 }
5290 }
5291
5292 // convey the LoadAllowSTS() flags
5293 rv = httpChannel->SetAllowSTS(LoadAllowSTS());
5294 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5294); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5294); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5295
5296 // convey the Accept header value
5297 {
5298 nsAutoCString oldAcceptValue;
5299 nsresult hasHeader = mRequestHead.GetHeader(nsHttp::Accept, oldAcceptValue);
5300 if (NS_SUCCEEDED(hasHeader)((bool)(__builtin_expect(!!(!NS_FAILED_impl(hasHeader)), 1)))) {
5301 rv = httpChannel->SetRequestHeader("Accept"_ns, oldAcceptValue, false);
5302 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5302); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5302); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5303 }
5304 }
5305
5306 // convey the User-Agent header value
5307 // since we might be setting custom user agent from DevTools.
5308 if (httpInternal && mRequestMode == RequestMode::No_cors &&
5309 redirectType == ReplacementReason::Redirect) {
5310 nsAutoCString oldUserAgent;
5311 nsresult hasHeader =
5312 mRequestHead.GetHeader(nsHttp::User_Agent, oldUserAgent);
5313 if (NS_SUCCEEDED(hasHeader)((bool)(__builtin_expect(!!(!NS_FAILED_impl(hasHeader)), 1)))) {
5314 rv = httpChannel->SetRequestHeader("User-Agent"_ns, oldUserAgent, false);
5315 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5315); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5315); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5316 }
5317 }
5318
5319 // convery the IsUserAgentHeaderModified value.
5320 if (httpInternal) {
5321 rv = httpInternal->SetIsUserAgentHeaderModified(
5322 LoadIsUserAgentHeaderModified());
5323 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5323); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5323); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5324 }
5325
5326 // share the request context - see bug 1236650
5327 rv = httpChannel->SetRequestContextID(mRequestContextID);
5328 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5328); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5328); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5329
5330 // When on the parent process, the channel can't attempt to get it itself.
5331 // When on the child process, it would be waste to query it again.
5332 rv = httpChannel->SetBrowserId(mBrowserId);
5333 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5333); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5333); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5334
5335 // Not setting this flag would break carrying permissions down to the child
5336 // process when the channel is artificially forced to be a main document load.
5337 rv = httpChannel->SetIsMainDocumentChannel(LoadForceMainDocumentChannel());
5338 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5338); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5338); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5339
5340 // Preserve the loading order
5341 nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(newChannel);
5342 if (p) {
5343 p->SetPriority(mPriority);
5344 }
5345
5346 if (httpInternal) {
5347 // Convey third party cookie, conservative, and spdy flags.
5348 rv = httpInternal->SetThirdPartyFlags(LoadThirdPartyFlags());
5349 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5349); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5350 rv = httpInternal->SetAllowSpdy(LoadAllowSpdy());
5351 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5351); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5351); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5352 rv = httpInternal->SetAllowHttp3(LoadAllowHttp3());
5353 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5353); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5353); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5354 rv = httpInternal->SetAllowAltSvc(LoadAllowAltSvc());
5355 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5355); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5355); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5356 rv = httpInternal->SetBeConservative(LoadBeConservative());
5357 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5357); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5357); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5358 rv = httpInternal->SetIsTRRServiceChannel(LoadIsTRRServiceChannel());
5359 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5359); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5359); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5360 rv = httpInternal->SetTlsFlags(mTlsFlags);
5361 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5361); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5361); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5362
5363 // Ensure the type of realChannel involves all types it may redirect to.
5364 // Such as nsHttpChannel and InterceptedChannel.
5365 // Even thought InterceptedChannel itself doesn't require these information,
5366 // it may still be necessary for the following redirections.
5367 // E.g. nsHttpChannel -> InterceptedChannel -> nsHttpChannel
5368 RefPtr<HttpBaseChannel> realChannel;
5369 CallQueryInterface(newChannel, realChannel.StartAssignment());
5370 if (realChannel) {
5371 realChannel->SetTopWindowURI(mTopWindowURI);
5372
5373 realChannel->StoreTaintedOriginFlag(
5374 ShouldTaintReplacementChannelOrigin(newChannel, redirectFlags));
5375 }
5376
5377 // update the DocumentURI indicator since we are being redirected.
5378 // if this was a top-level document channel, then the new channel
5379 // should have its mDocumentURI point to newURI; otherwise, we
5380 // just need to pass along our mDocumentURI to the new channel.
5381 if (newURI && (mURI == mDocumentURI)) {
5382 rv = httpInternal->SetDocumentURI(newURI);
5383 } else {
5384 rv = httpInternal->SetDocumentURI(mDocumentURI);
5385 }
5386 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5386); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5386); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5387
5388 // if there is a chain of keys for redirect-responses we transfer it to
5389 // the new channel (see bug #561276)
5390 {
5391 auto redirectedCachekeys = mRedirectedCachekeys.Lock();
5392 auto& ref = redirectedCachekeys.ref();
5393 if (ref) {
5394 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p] transferring chain of redirect cache-keys"
, this); } } while (0)
5395 ("HttpBaseChannel::SetupReplacementChannel "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p] transferring chain of redirect cache-keys"
, this); } } while (0)
5396 "[this=%p] transferring chain of redirect cache-keys",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p] transferring chain of redirect cache-keys"
, this); } } while (0)
5397 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p] transferring chain of redirect cache-keys"
, this); } } while (0)
;
5398 rv = httpInternal->SetCacheKeysRedirectChain(ref.release());
5399 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5399); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5399); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5400 }
5401 }
5402
5403 // Preserve Request mode.
5404 rv = httpInternal->SetRequestMode(mRequestMode);
5405 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5405); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5405); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5406
5407 // Preserve Redirect mode flag.
5408 rv = httpInternal->SetRedirectMode(mRedirectMode);
5409 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5409); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5409); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5410
5411 httpInternal->SetAltDataForChild(LoadAltDataForChild());
5412 if (LoadDisableAltDataCache()) {
5413 httpInternal->DisableAltDataCache();
5414 }
5415 }
5416
5417 // transfer any properties
5418 nsCOMPtr<nsIWritablePropertyBag> bag(do_QueryInterface(newChannel));
5419 if (bag) {
5420 for (const auto& entry : mPropertyHash) {
5421 bag->SetProperty(entry.GetKey(), entry.GetWeak());
5422 }
5423 }
5424
5425 // Pass the preferred alt-data type on to the new channel.
5426 nsCOMPtr<nsICacheInfoChannel> cacheInfoChan(do_QueryInterface(newChannel));
5427 if (cacheInfoChan) {
5428 for (auto& data : mPreferredCachedAltDataTypes) {
5429 cacheInfoChan->PreferAlternativeDataType(data.type(), data.contentType(),
5430 data.deliverAltData());
5431 }
5432
5433 if (LoadForceValidateCacheContent()) {
5434 (void)cacheInfoChan->SetForceValidateCacheContent(true);
5435 }
5436 }
5437
5438 if (redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
5439 nsIChannelEventSink::REDIRECT_STS_UPGRADE)) {
5440 // Copy non-origin related headers to the new channel.
5441 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
5442 new AddHeadersToChannelVisitor(httpChannel);
5443 rv = mRequestHead.VisitHeaders(visitor);
5444 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5444); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5444); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5445 }
5446
5447 // we need to strip Authentication headers for cross-origin requests
5448 // Ref: https://fetch.spec.whatwg.org/#http-redirect-fetch
5449 nsAutoCString authHeader;
5450 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetRequestHeader
("Authorization"_ns, authHeader))), 1)))
5451 httpChannel->GetRequestHeader("Authorization"_ns, authHeader))((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetRequestHeader
("Authorization"_ns, authHeader))), 1)))
&&
5452 NS_ShouldRemoveAuthHeaderOnRedirect(static_cast<nsIChannel*>(this),
5453 newChannel, redirectFlags)) {
5454 rv = httpChannel->SetRequestHeader("Authorization"_ns, ""_ns, false);
5455 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5455); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 5455); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5456 }
5457
5458 return NS_OK;
5459}
5460
5461// check whether the new channel is of same origin as the current channel
5462bool HttpBaseChannel::IsNewChannelSameOrigin(nsIChannel* aNewChannel) {
5463 bool isSameOrigin = false;
5464 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5465
5466 if (!ssm) {
5467 return false;
5468 }
5469
5470 nsCOMPtr<nsIURI> newURI;
5471 NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
5472
5473 nsresult rv = ssm->CheckSameOriginURI(newURI, mURI, false, false);
5474 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5475 isSameOrigin = true;
5476 }
5477
5478 return isSameOrigin;
5479}
5480
5481bool HttpBaseChannel::ShouldTaintReplacementChannelOrigin(
5482 nsIChannel* aNewChannel, uint32_t aRedirectFlags) {
5483 if (LoadTaintedOriginFlag()) {
5484 return true;
5485 }
5486
5487 if (NS_IsInternalSameURIRedirect(this, aNewChannel, aRedirectFlags) ||
5488 NS_IsHSTSUpgradeRedirect(this, aNewChannel, aRedirectFlags)) {
5489 return false;
5490 }
5491
5492 // Fetch spec "compute redirect-taint":
5493 // Taint if url's origin is not same-origin with lastURL's origin AND
5494 // request's origin is not same-origin with lastURL's origin.
5495 // Condition 1: same-origin redirect never taints.
5496 if (IsNewChannelSameOrigin(aNewChannel)) {
5497 return false;
5498 }
5499
5500 // Condition 2: cross-origin redirect — taint if the origin that initiated
5501 // the request is not same-origin with the current URL (mURI).
5502 //
5503 // Bug 1965430: For top-level navigational loads (e.g., form POST),
5504 // LoadingPrincipal is null. TriggeringPrincipal correctly represents the
5505 // origin that initiated the request in all cases. The old code using
5506 // LoadingPrincipal fell through to comparing mOriginalURI with mURI, which
5507 // are equal for the first redirect, incorrectly skipping the taint.
5508 if (StaticPrefs::network_http_origin_useTriggeringPrincipal()) {
5509 nsIPrincipal* triggeringPrincipal = mLoadInfo->TriggeringPrincipal();
5510 if (!triggeringPrincipal) {
5511 return true;
5512 }
5513 bool sameOrigin = false;
5514 nsresult rv = triggeringPrincipal->IsSameOrigin(mURI, &sameOrigin);
5515 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5516 return true;
5517 }
5518 return !sameOrigin;
5519 }
5520
5521 // Old code path (Bug 1965430): retained behind pref for safety.
5522 // Uses LoadingPrincipal which is null for top-level navigations,
5523 // falling back to mOriginalURI vs mURI comparison.
5524 nsresult rv;
5525 if (mLoadInfo->GetLoadingPrincipal()) {
5526 bool sameOrigin = false;
5527 rv = mLoadInfo->GetLoadingPrincipal()->IsSameOrigin(mURI, &sameOrigin);
5528 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5529 return true;
5530 }
5531 return !sameOrigin;
5532 }
5533 if (!mOriginalURI) {
5534 return true;
5535 }
5536
5537 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5538 if (!ssm) {
5539 return true;
5540 }
5541
5542 rv = ssm->CheckSameOriginURI(mOriginalURI, mURI, false, false);
5543 return NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)));
5544}
5545
5546// Redirect Tracking
5547bool HttpBaseChannel::SameOriginWithOriginalUri(nsIURI* aURI) {
5548 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5549 bool isPrivateWin = mLoadInfo->GetOriginAttributes().IsPrivateBrowsing();
5550 nsresult rv =
5551 ssm->CheckSameOriginURI(aURI, mOriginalURI, false, isPrivateWin);
5552 return (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))));
5553}
5554
5555//-----------------------------------------------------------------------------
5556// HttpBaseChannel::nsIClassifiedChannel
5557
5558NS_IMETHODIMPnsresult
5559HttpBaseChannel::GetMatchedList(nsACString& aList) {
5560 aList = mMatchedList;
5561 return NS_OK;
5562}
5563
5564NS_IMETHODIMPnsresult
5565HttpBaseChannel::GetMatchedProvider(nsACString& aProvider) {
5566 aProvider = mMatchedProvider;
5567 return NS_OK;
5568}
5569
5570NS_IMETHODIMPnsresult
5571HttpBaseChannel::GetMatchedFullHash(nsACString& aFullHash) {
5572 aFullHash = mMatchedFullHash;
5573 return NS_OK;
5574}
5575
5576NS_IMETHODIMPnsresult
5577HttpBaseChannel::SetMatchedInfo(const nsACString& aList,
5578 const nsACString& aProvider,
5579 const nsACString& aFullHash) {
5580 NS_ENSURE_ARG(!aList.IsEmpty())do { if ((__builtin_expect(!!(!(!aList.IsEmpty())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!aList.IsEmpty()" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5580); return NS_ERROR_INVALID_ARG; } } while (false)
;
5581
5582 mMatchedList = aList;
5583 mMatchedProvider = aProvider;
5584 mMatchedFullHash = aFullHash;
5585 return NS_OK;
5586}
5587
5588NS_IMETHODIMPnsresult
5589HttpBaseChannel::GetMatchedTrackingLists(nsTArray<nsCString>& aLists) {
5590 aLists = mMatchedTrackingLists.Clone();
5591 return NS_OK;
5592}
5593
5594NS_IMETHODIMPnsresult
5595HttpBaseChannel::GetMatchedTrackingFullHashes(
5596 nsTArray<nsCString>& aFullHashes) {
5597 aFullHashes = mMatchedTrackingFullHashes.Clone();
5598 return NS_OK;
5599}
5600
5601NS_IMETHODIMPnsresult
5602HttpBaseChannel::SetMatchedTrackingInfo(
5603 const nsTArray<nsCString>& aLists, const nsTArray<nsCString>& aFullHashes) {
5604 NS_ENSURE_ARG(!aLists.IsEmpty())do { if ((__builtin_expect(!!(!(!aLists.IsEmpty())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!aLists.IsEmpty()" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5604); return NS_ERROR_INVALID_ARG; } } while (false)
;
5605 // aFullHashes can be empty for non hash-matching algorithm, for example,
5606 // host based test entries in preference.
5607
5608 mMatchedTrackingLists = aLists.Clone();
5609 mMatchedTrackingFullHashes = aFullHashes.Clone();
5610 return NS_OK;
5611}
5612//-----------------------------------------------------------------------------
5613// HttpBaseChannel::nsITimedChannel
5614//-----------------------------------------------------------------------------
5615
5616NS_IMETHODIMPnsresult
5617HttpBaseChannel::GetChannelCreation(TimeStamp* _retval) {
5618 *_retval = mChannelCreationTimestamp;
5619 return NS_OK;
5620}
5621
5622NS_IMETHODIMPnsresult
5623HttpBaseChannel::SetChannelCreation(TimeStamp aValue) {
5624 MOZ_DIAGNOSTIC_ASSERT(!aValue.IsNull())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aValue.IsNull())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aValue.IsNull()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!aValue.IsNull()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 5624
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!aValue.IsNull()"
")"); do { MOZ_CrashSequence(__null, 5624); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5625 TimeDuration adjust = aValue - mChannelCreationTimestamp;
5626 mChannelCreationTimestamp = aValue;
5627 mChannelCreationTime += (PRTime)adjust.ToMicroseconds();
5628 return NS_OK;
5629}
5630
5631NS_IMETHODIMPnsresult
5632HttpBaseChannel::GetAsyncOpen(TimeStamp* _retval) {
5633 *_retval = mAsyncOpenTime;
5634 return NS_OK;
5635}
5636
5637NS_IMETHODIMPnsresult
5638HttpBaseChannel::SetAsyncOpen(TimeStamp aValue) {
5639 MOZ_DIAGNOSTIC_ASSERT(!aValue.IsNull())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aValue.IsNull())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aValue.IsNull()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!aValue.IsNull()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 5639
); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!aValue.IsNull()"
")"); do { MOZ_CrashSequence(__null, 5639); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5640 mAsyncOpenTime = aValue;
5641 StoreAsyncOpenTimeOverriden(true);
5642 return NS_OK;
5643}
5644
5645/**
5646 * @return the number of redirects. There is no check for cross-domain
5647 * redirects. This check must be done by the consumers.
5648 */
5649NS_IMETHODIMPnsresult
5650HttpBaseChannel::GetRedirectCount(uint8_t* aRedirectCount) {
5651 *aRedirectCount = mRedirectCount;
5652 return NS_OK;
5653}
5654
5655NS_IMETHODIMPnsresult
5656HttpBaseChannel::SetRedirectCount(uint8_t aRedirectCount) {
5657 mRedirectCount = aRedirectCount;
5658 return NS_OK;
5659}
5660
5661NS_IMETHODIMPnsresult
5662HttpBaseChannel::GetInternalRedirectCount(uint8_t* aRedirectCount) {
5663 *aRedirectCount = mInternalRedirectCount;
5664 return NS_OK;
5665}
5666
5667NS_IMETHODIMPnsresult
5668HttpBaseChannel::SetInternalRedirectCount(uint8_t aRedirectCount) {
5669 mInternalRedirectCount = aRedirectCount;
5670 return NS_OK;
5671}
5672
5673NS_IMETHODIMPnsresult
5674HttpBaseChannel::GetRedirectStart(TimeStamp* _retval) {
5675 *_retval = mRedirectStartTimeStamp;
5676 return NS_OK;
5677}
5678
5679NS_IMETHODIMPnsresult
5680HttpBaseChannel::SetRedirectStart(TimeStamp aRedirectStart) {
5681 mRedirectStartTimeStamp = aRedirectStart;
5682 return NS_OK;
5683}
5684
5685NS_IMETHODIMPnsresult
5686HttpBaseChannel::GetRedirectEnd(TimeStamp* _retval) {
5687 *_retval = mRedirectEndTimeStamp;
5688 return NS_OK;
5689}
5690
5691NS_IMETHODIMPnsresult
5692HttpBaseChannel::SetRedirectEnd(TimeStamp aRedirectEnd) {
5693 mRedirectEndTimeStamp = aRedirectEnd;
5694 return NS_OK;
5695}
5696
5697NS_IMETHODIMPnsresult
5698HttpBaseChannel::GetAllRedirectsSameOrigin(bool* aAllRedirectsSameOrigin) {
5699 *aAllRedirectsSameOrigin = LoadAllRedirectsSameOrigin();
5700 return NS_OK;
5701}
5702
5703NS_IMETHODIMPnsresult
5704HttpBaseChannel::SetAllRedirectsSameOrigin(bool aAllRedirectsSameOrigin) {
5705 StoreAllRedirectsSameOrigin(aAllRedirectsSameOrigin);
5706 return NS_OK;
5707}
5708
5709NS_IMETHODIMPnsresult
5710HttpBaseChannel::GetAllRedirectsSameOriginIgnoringInternal(
5711 bool* aAllRedirectsSameOriginIgnoringInternal) {
5712 *aAllRedirectsSameOriginIgnoringInternal =
5713 LoadAllRedirectsSameOriginIgnoringInternal();
5714 return NS_OK;
5715}
5716
5717NS_IMETHODIMPnsresult
5718HttpBaseChannel::SetAllRedirectsSameOriginIgnoringInternal(
5719 bool aAllRedirectsSameOriginIgnoringInternal) {
5720 StoreAllRedirectsSameOriginIgnoringInternal(
5721 aAllRedirectsSameOriginIgnoringInternal);
5722 return NS_OK;
5723}
5724
5725NS_IMETHODIMPnsresult
5726HttpBaseChannel::GetAllRedirectsPassTimingAllowCheck(bool* aPassesCheck) {
5727 *aPassesCheck = LoadAllRedirectsPassTimingAllowCheck();
5728 return NS_OK;
5729}
5730
5731NS_IMETHODIMPnsresult
5732HttpBaseChannel::SetAllRedirectsPassTimingAllowCheck(bool aPassesCheck) {
5733 StoreAllRedirectsPassTimingAllowCheck(aPassesCheck);
5734 return NS_OK;
5735}
5736
5737// https://fetch.spec.whatwg.org/#cors-check
5738bool HttpBaseChannel::PerformCORSCheck() {
5739 // Step 1
5740 // Let origin be the result of getting `Access-Control-Allow-Origin`
5741 // from response’s header list.
5742 nsAutoCString origin;
5743 nsresult rv = GetResponseHeader("Access-Control-Allow-Origin"_ns, origin);
5744
5745 // Step 2
5746 // If origin is null, then return failure. (Note: null, not 'null').
5747 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || origin.IsVoid()) {
5748 return false;
5749 }
5750
5751 // Step 3
5752 // If request’s credentials mode is not "include"
5753 // and origin is `*`, then return success.
5754 uint32_t cookiePolicy = mLoadInfo->GetCookiePolicy();
5755 if (cookiePolicy != nsILoadInfo::SEC_COOKIES_INCLUDE &&
5756 origin.EqualsLiteral("*")) {
5757 return true;
5758 }
5759
5760 // Step 4
5761 // If the result of byte-serializing a request origin
5762 // with request is not origin, then return failure.
5763 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5764 nsCOMPtr<nsIPrincipal> resourcePrincipal;
5765 rv = ssm->GetChannelURIPrincipal(this, getter_AddRefs(resourcePrincipal));
5766 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !resourcePrincipal) {
5767 return false;
5768 }
5769 nsAutoCString serializedOrigin;
5770 nsContentSecurityManager::GetSerializedOrigin(
5771 mLoadInfo->TriggeringPrincipal(), resourcePrincipal, serializedOrigin,
5772 mLoadInfo);
5773 if (!serializedOrigin.Equals(origin)) {
5774 return false;
5775 }
5776
5777 // Step 5
5778 // If request’s credentials mode is not "include", then return success.
5779 if (cookiePolicy != nsILoadInfo::SEC_COOKIES_INCLUDE) {
5780 return true;
5781 }
5782
5783 // Step 6
5784 // Let credentials be the result of getting
5785 // `Access-Control-Allow-Credentials` from response’s header list.
5786 nsAutoCString credentials;
5787 rv = GetResponseHeader("Access-Control-Allow-Credentials"_ns, credentials);
5788
5789 // Step 7 and 8
5790 // If credentials is `true`, then return success.
5791 // (else) return failure.
5792 return NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && credentials.EqualsLiteral("true");
5793}
5794
5795NS_IMETHODIMPnsresult
5796HttpBaseChannel::BodyInfoAccessAllowedCheck(nsIPrincipal* aOrigin,
5797 BodyInfoAccess* _retval) {
5798 // Per the Fetch spec, https://fetch.spec.whatwg.org/#response-body-info,
5799 // the bodyInfo for Resource Timing and Navigation Timing info consists of
5800 // encoded size, decoded size, and content type. It is however made opaque
5801 // whenever the response is turned into a network error, which sets its
5802 // bodyInfo to its default values (sizes=0, content-type="").
5803
5804 // Case 1:
5805 // "no-cors" -> Upon success, fetch will return an opaque filtered response.
5806 // An opaque(-redirect) filtered response is a filtered response
5807 // whose ... body info is a new response body info.
5808 auto tainting = mLoadInfo->GetTainting();
5809 if (tainting == mozilla::LoadTainting::Opaque) {
5810 *_retval = BodyInfoAccess::DISALLOWED;
5811 return NS_OK;
5812 }
5813
5814 // Case 2:
5815 // If request’s response tainting is "cors" and a CORS check for request
5816 // and response returns failure, then return a network error.
5817 if (tainting == mozilla::LoadTainting::CORS && !PerformCORSCheck()) {
5818 *_retval = BodyInfoAccess::DISALLOWED;
5819 return NS_OK;
5820 }
5821
5822 // Otherwise:
5823 // The fetch response handover, given a fetch params fetchParams
5824 // and a response response, run these steps:
5825 // processResponseEndOfBody:
5826 // - If fetchParams’s request’s mode is not "navigate" or response’s
5827 // has-cross-origin-redirects is false:
5828 // - Let mimeType be the result of extracting a MIME type from
5829 // response’s header list.
5830 // - If mimeType is not failure, then set bodyInfo’s content type to the
5831 // result of minimizing a supported MIME type given mimeType.
5832 dom::RequestMode requestMode;
5833 MOZ_ALWAYS_SUCCEEDS(GetRequestMode(&requestMode))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(GetRequestMode(&requestMode))), 1)))), 1))) { } else { do
{ do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(GetRequestMode(&requestMode))"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 5833
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(GetRequestMode(&requestMode))"
")"); do { MOZ_CrashSequence(__null, 5833); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5834 if (requestMode != RequestMode::Navigate || LoadAllRedirectsSameOrigin()) {
5835 *_retval = BodyInfoAccess::ALLOW_ALL;
5836 return NS_OK;
5837 }
5838
5839 *_retval = BodyInfoAccess::ALLOW_SIZES;
5840 return NS_OK;
5841}
5842
5843// https://fetch.spec.whatwg.org/#tao-check
5844NS_IMETHODIMPnsresult
5845HttpBaseChannel::TimingAllowCheck(nsIPrincipal* aOrigin, bool* _retval) {
5846 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5847 nsCOMPtr<nsIPrincipal> resourcePrincipal;
5848 nsresult rv =
5849 ssm->GetChannelURIPrincipal(this, getter_AddRefs(resourcePrincipal));
5850 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !resourcePrincipal || !aOrigin) {
5851 *_retval = false;
5852 return NS_OK;
5853 }
5854
5855 bool sameOrigin = false;
5856 rv = resourcePrincipal->Equals(aOrigin, &sameOrigin);
5857
5858 nsAutoCString serializedOrigin;
5859 nsContentSecurityManager::GetSerializedOrigin(aOrigin, resourcePrincipal,
5860 serializedOrigin, mLoadInfo);
5861
5862 // All redirects are same origin
5863 if (sameOrigin && (!serializedOrigin.IsEmpty() &&
5864 !serializedOrigin.EqualsLiteral("null"))) {
5865 *_retval = true;
5866 return NS_OK;
5867 }
5868
5869 nsAutoCString headerValue;
5870 rv = GetResponseHeader("Timing-Allow-Origin"_ns, headerValue);
5871 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5872 *_retval = false;
5873 return NS_OK;
5874 }
5875
5876 Tokenizer p(headerValue);
5877 Tokenizer::Token t;
5878
5879 p.Record();
5880 nsAutoCString headerItem;
5881 while (p.Next(t)) {
5882 if (t.Type() == Tokenizer::TOKEN_EOF ||
5883 t.Equals(Tokenizer::Token::Char(','))) {
5884 p.Claim(headerItem);
5885 nsHttp::TrimHTTPWhitespace(headerItem, headerItem);
5886 // If the list item contains a case-sensitive match for the value of the
5887 // origin, or a wildcard, return pass
5888 if (headerItem == serializedOrigin || headerItem == "*") {
5889 *_retval = true;
5890 return NS_OK;
5891 }
5892 // We start recording again for the following items in the list
5893 p.Record();
5894 }
5895 }
5896
5897 *_retval = false;
5898 return NS_OK;
5899}
5900
5901NS_IMETHODIMPnsresult
5902HttpBaseChannel::GetLaunchServiceWorkerStart(TimeStamp* _retval) {
5903 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5903); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { MOZ_CrashSequence(__null, 5903); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5904 *_retval = mLaunchServiceWorkerStart;
5905 return NS_OK;
5906}
5907
5908NS_IMETHODIMPnsresult
5909HttpBaseChannel::SetLaunchServiceWorkerStart(TimeStamp aTimeStamp) {
5910 mLaunchServiceWorkerStart = aTimeStamp;
5911 return NS_OK;
5912}
5913
5914NS_IMETHODIMPnsresult
5915HttpBaseChannel::GetLaunchServiceWorkerEnd(TimeStamp* _retval) {
5916 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5916); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { MOZ_CrashSequence(__null, 5916); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5917 *_retval = mLaunchServiceWorkerEnd;
5918 return NS_OK;
5919}
5920
5921NS_IMETHODIMPnsresult
5922HttpBaseChannel::SetLaunchServiceWorkerEnd(TimeStamp aTimeStamp) {
5923 mLaunchServiceWorkerEnd = aTimeStamp;
5924 return NS_OK;
5925}
5926
5927NS_IMETHODIMPnsresult
5928HttpBaseChannel::GetDispatchFetchEventStart(TimeStamp* _retval) {
5929 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5929); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { MOZ_CrashSequence(__null, 5929); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5930 *_retval = mDispatchFetchEventStart;
5931 return NS_OK;
5932}
5933
5934NS_IMETHODIMPnsresult
5935HttpBaseChannel::SetDispatchFetchEventStart(TimeStamp aTimeStamp) {
5936 mDispatchFetchEventStart = aTimeStamp;
5937 return NS_OK;
5938}
5939
5940NS_IMETHODIMPnsresult
5941HttpBaseChannel::GetDispatchFetchEventEnd(TimeStamp* _retval) {
5942 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { MOZ_CrashSequence(__null, 5942); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5943 *_retval = mDispatchFetchEventEnd;
5944 return NS_OK;
5945}
5946
5947NS_IMETHODIMPnsresult
5948HttpBaseChannel::SetDispatchFetchEventEnd(TimeStamp aTimeStamp) {
5949 mDispatchFetchEventEnd = aTimeStamp;
5950 return NS_OK;
5951}
5952
5953NS_IMETHODIMPnsresult
5954HttpBaseChannel::GetHandleFetchEventStart(TimeStamp* _retval) {
5955 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5955); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { MOZ_CrashSequence(__null, 5955); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5956 *_retval = mHandleFetchEventStart;
5957 return NS_OK;
5958}
5959
5960NS_IMETHODIMPnsresult
5961HttpBaseChannel::SetHandleFetchEventStart(TimeStamp aTimeStamp) {
5962 mHandleFetchEventStart = aTimeStamp;
5963 return NS_OK;
5964}
5965
5966NS_IMETHODIMPnsresult
5967HttpBaseChannel::GetHandleFetchEventEnd(TimeStamp* _retval) {
5968 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 5968); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { MOZ_CrashSequence(__null, 5968); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5969 *_retval = mHandleFetchEventEnd;
5970 return NS_OK;
5971}
5972
5973NS_IMETHODIMPnsresult
5974HttpBaseChannel::SetHandleFetchEventEnd(TimeStamp aTimeStamp) {
5975 mHandleFetchEventEnd = aTimeStamp;
5976 return NS_OK;
5977}
5978
5979NS_IMETHODIMPnsresult
5980HttpBaseChannel::GetDomainLookupStart(TimeStamp* _retval) {
5981 *_retval = mTransactionTimings.domainLookupStart;
5982 return NS_OK;
5983}
5984
5985NS_IMETHODIMPnsresult
5986HttpBaseChannel::GetDomainLookupEnd(TimeStamp* _retval) {
5987 *_retval = mTransactionTimings.domainLookupEnd;
5988 return NS_OK;
5989}
5990
5991NS_IMETHODIMPnsresult
5992HttpBaseChannel::GetConnectStart(TimeStamp* _retval) {
5993 *_retval = mTransactionTimings.connectStart;
5994 return NS_OK;
5995}
5996
5997NS_IMETHODIMPnsresult
5998HttpBaseChannel::GetTcpConnectEnd(TimeStamp* _retval) {
5999 *_retval = mTransactionTimings.tcpConnectEnd;
6000 return NS_OK;
6001}
6002
6003NS_IMETHODIMPnsresult
6004HttpBaseChannel::GetSecureConnectionStart(TimeStamp* _retval) {
6005 *_retval = mTransactionTimings.secureConnectionStart;
6006 return NS_OK;
6007}
6008
6009NS_IMETHODIMPnsresult
6010HttpBaseChannel::GetConnectEnd(TimeStamp* _retval) {
6011 *_retval = mTransactionTimings.connectEnd;
6012 return NS_OK;
6013}
6014
6015NS_IMETHODIMPnsresult
6016HttpBaseChannel::GetRequestStart(TimeStamp* _retval) {
6017 *_retval = mTransactionTimings.requestStart;
6018 return NS_OK;
6019}
6020
6021NS_IMETHODIMPnsresult
6022HttpBaseChannel::GetResponseStart(TimeStamp* _retval) {
6023 *_retval = mTransactionTimings.responseStart;
6024 return NS_OK;
6025}
6026
6027NS_IMETHODIMPnsresult
6028HttpBaseChannel::GetFirstInterimResponseStart(TimeStamp* _retval) {
6029 *_retval = mTransactionTimings.firstInterimResponseStart;
6030 return NS_OK;
6031}
6032
6033NS_IMETHODIMPnsresult
6034HttpBaseChannel::GetFinalResponseHeadersStart(TimeStamp* _retval) {
6035 *_retval = mTransactionTimings.finalResponseHeadersStart;
6036 return NS_OK;
6037}
6038
6039NS_IMETHODIMPnsresult
6040HttpBaseChannel::GetResponseEnd(TimeStamp* _retval) {
6041 *_retval = mTransactionTimings.responseEnd;
6042 return NS_OK;
6043}
6044
6045NS_IMETHODIMPnsresult
6046HttpBaseChannel::GetCacheReadStart(TimeStamp* _retval) {
6047 *_retval = mCacheReadStart;
6048 return NS_OK;
6049}
6050
6051NS_IMETHODIMPnsresult
6052HttpBaseChannel::GetCacheReadEnd(TimeStamp* _retval) {
6053 *_retval = mCacheReadEnd;
6054 return NS_OK;
6055}
6056
6057NS_IMETHODIMPnsresult
6058HttpBaseChannel::GetTransactionPending(TimeStamp* _retval) {
6059 *_retval = mTransactionTimings.transactionPending;
6060 return NS_OK;
6061}
6062
6063NS_IMETHODIMPnsresult
6064HttpBaseChannel::GetInitiatorType(nsAString& aInitiatorType) {
6065 aInitiatorType = mInitiatorType;
6066 return NS_OK;
6067}
6068
6069NS_IMETHODIMPnsresult
6070HttpBaseChannel::SetInitiatorType(const nsAString& aInitiatorType) {
6071 mInitiatorType = aInitiatorType;
6072 return NS_OK;
6073}
6074
6075#define IMPL_TIMING_ATTR(name) \
6076 NS_IMETHODIMPnsresult \
6077 HttpBaseChannel::Get##name##Time(PRTime* _retval) { \
6078 TimeStamp stamp; \
6079 Get##name(&stamp); \
6080 if (stamp.IsNull()) { \
6081 *_retval = 0; \
6082 return NS_OK; \
6083 } \
6084 *_retval = \
6085 mChannelCreationTime + \
6086 (PRTime)((stamp - mChannelCreationTimestamp).ToSeconds() * 1e6); \
6087 return NS_OK; \
6088 }
6089
6090IMPL_TIMING_ATTR(ChannelCreation)
6091IMPL_TIMING_ATTR(AsyncOpen)
6092IMPL_TIMING_ATTR(LaunchServiceWorkerStart)
6093IMPL_TIMING_ATTR(LaunchServiceWorkerEnd)
6094IMPL_TIMING_ATTR(DispatchFetchEventStart)
6095IMPL_TIMING_ATTR(DispatchFetchEventEnd)
6096IMPL_TIMING_ATTR(HandleFetchEventStart)
6097IMPL_TIMING_ATTR(HandleFetchEventEnd)
6098IMPL_TIMING_ATTR(DomainLookupStart)
6099IMPL_TIMING_ATTR(DomainLookupEnd)
6100IMPL_TIMING_ATTR(ConnectStart)
6101IMPL_TIMING_ATTR(TcpConnectEnd)
6102IMPL_TIMING_ATTR(SecureConnectionStart)
6103IMPL_TIMING_ATTR(ConnectEnd)
6104IMPL_TIMING_ATTR(RequestStart)
6105IMPL_TIMING_ATTR(ResponseStart)
6106IMPL_TIMING_ATTR(FirstInterimResponseStart)
6107IMPL_TIMING_ATTR(FinalResponseHeadersStart)
6108IMPL_TIMING_ATTR(ResponseEnd)
6109IMPL_TIMING_ATTR(CacheReadStart)
6110IMPL_TIMING_ATTR(CacheReadEnd)
6111IMPL_TIMING_ATTR(RedirectStart)
6112IMPL_TIMING_ATTR(RedirectEnd)
6113IMPL_TIMING_ATTR(TransactionPending)
6114
6115#undef IMPL_TIMING_ATTR
6116
6117void HttpBaseChannel::MaybeReportTimingData() {
6118 // There is no point in continuing, since the performance object in the parent
6119 // isn't the same as the one in the child which will be reporting resource
6120 // performance.
6121 if (XRE_IsE10sParentProcess()) {
6122 return;
6123 }
6124
6125 // Devtools can create fetch requests on behalf the content document.
6126 // If we don't exclude these requests, they'd also be reported
6127 // to the content document.
6128 bool isInDevToolsContext;
6129 mLoadInfo->GetIsInDevToolsContext(&isInDevToolsContext);
6130 if (isInDevToolsContext) {
6131 return;
6132 }
6133
6134 mozilla::dom::PerformanceStorage* documentPerformance =
6135 mLoadInfo->GetPerformanceStorage();
6136 if (documentPerformance) {
6137 documentPerformance->AddEntry(this, this);
6138 return;
6139 }
6140
6141 if (!nsGlobalWindowInner::GetInnerWindowWithId(
6142 mLoadInfo->GetInnerWindowID())) {
6143 // The inner window is in a different process.
6144 dom::ContentChild* child = dom::ContentChild::GetSingleton();
6145
6146 if (!child) {
6147 return;
6148 }
6149 nsAutoString initiatorType;
6150 nsAutoString entryName;
6151
6152 UniquePtr<dom::PerformanceTimingData> performanceTimingData(
6153 dom::PerformanceTimingData::Create(this, this, 0, initiatorType,
6154 entryName));
6155 if (!performanceTimingData) {
6156 return;
6157 }
6158
6159 LoadInfoArgs loadInfoArgs;
6160 mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &loadInfoArgs);
6161 child->SendReportFrameTimingData(loadInfoArgs, entryName, initiatorType,
6162 std::move(performanceTimingData));
6163 }
6164}
6165
6166NS_IMETHODIMPnsresult
6167HttpBaseChannel::SetReportResourceTiming(bool enabled) {
6168 StoreReportTiming(enabled);
6169 return NS_OK;
6170}
6171
6172NS_IMETHODIMPnsresult
6173HttpBaseChannel::GetReportResourceTiming(bool* _retval) {
6174 *_retval = LoadReportTiming();
6175 return NS_OK;
6176}
6177
6178nsIURI* HttpBaseChannel::GetReferringPage() {
6179 nsCOMPtr<nsPIDOMWindowInner> pDomWindow = GetInnerDOMWindow();
6180 if (!pDomWindow) {
6181 return nullptr;
6182 }
6183 return pDomWindow->GetDocumentURI();
6184}
6185
6186nsPIDOMWindowInner* HttpBaseChannel::GetInnerDOMWindow() {
6187 nsCOMPtr<nsILoadContext> loadContext;
6188 NS_QueryNotificationCallbacks(this, loadContext);
6189 if (!loadContext) {
6190 return nullptr;
6191 }
6192 nsCOMPtr<mozIDOMWindowProxy> domWindow;
6193 loadContext->GetAssociatedWindow(getter_AddRefs(domWindow));
6194 if (!domWindow) {
6195 return nullptr;
6196 }
6197 auto* pDomWindow = nsPIDOMWindowOuter::From(domWindow);
6198 if (!pDomWindow) {
6199 return nullptr;
6200 }
6201 nsCOMPtr<nsPIDOMWindowInner> innerWindow =
6202 pDomWindow->GetCurrentInnerWindow();
6203 if (!innerWindow) {
6204 return nullptr;
6205 }
6206
6207 return innerWindow;
6208}
6209
6210//-----------------------------------------------------------------------------
6211// HttpBaseChannel::nsIThrottledInputChannel
6212//-----------------------------------------------------------------------------
6213
6214NS_IMETHODIMPnsresult
6215HttpBaseChannel::SetThrottleQueue(nsIInputChannelThrottleQueue* aQueue) {
6216 if (!XRE_IsParentProcess()) {
6217 return NS_ERROR_FAILURE;
6218 }
6219
6220 mThrottleQueue = aQueue;
6221 return NS_OK;
6222}
6223
6224NS_IMETHODIMPnsresult
6225HttpBaseChannel::GetThrottleQueue(nsIInputChannelThrottleQueue** aQueue) {
6226 NS_ENSURE_ARG_POINTER(aQueue)do { if ((__builtin_expect(!!(!(aQueue)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aQueue" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 6226
); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6227 nsCOMPtr<nsIInputChannelThrottleQueue> queue = mThrottleQueue;
6228 queue.forget(aQueue);
6229 return NS_OK;
6230}
6231
6232//------------------------------------------------------------------------------
6233
6234bool HttpBaseChannel::EnsureRequestContextID() {
6235 if (mRequestContextID) {
6236 // Already have a request context ID, no need to do the rest of this work
6237 LOG(("HttpBaseChannel::EnsureRequestContextID this=%p id=%" PRIx64, this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::EnsureRequestContextID this=%p id=%" "l" "x"
, this, mRequestContextID); } } while (0)
6238 mRequestContextID))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::EnsureRequestContextID this=%p id=%" "l" "x"
, this, mRequestContextID); } } while (0)
;
6239 return true;
6240 }
6241
6242 // Find the loadgroup at the end of the chain in order
6243 // to make sure all channels derived from the load group
6244 // use the same connection scope.
6245 nsCOMPtr<nsILoadGroupChild> childLoadGroup = do_QueryInterface(mLoadGroup);
6246 if (!childLoadGroup) {
6247 return false;
6248 }
6249
6250 nsCOMPtr<nsILoadGroup> rootLoadGroup;
6251 childLoadGroup->GetRootLoadGroup(getter_AddRefs(rootLoadGroup));
6252 if (!rootLoadGroup) {
6253 return false;
6254 }
6255
6256 // Set the load group connection scope on this channel and its transaction
6257 rootLoadGroup->GetRequestContextID(&mRequestContextID);
6258
6259 LOG(("HttpBaseChannel::EnsureRequestContextID this=%p id=%" PRIx64, this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::EnsureRequestContextID this=%p id=%" "l" "x"
, this, mRequestContextID); } } while (0)
6260 mRequestContextID))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::EnsureRequestContextID this=%p id=%" "l" "x"
, this, mRequestContextID); } } while (0)
;
6261
6262 return true;
6263}
6264
6265bool HttpBaseChannel::EnsureRequestContext() {
6266 if (mRequestContext) {
6267 // Already have a request context, no need to do the rest of this work
6268 return true;
6269 }
6270
6271 if (!EnsureRequestContextID()) {
6272 return false;
6273 }
6274
6275 nsIRequestContextService* rcsvc = gHttpHandler->GetRequestContextService();
6276 if (!rcsvc) {
6277 return false;
6278 }
6279
6280 rcsvc->GetRequestContext(mRequestContextID, getter_AddRefs(mRequestContext));
6281 return static_cast<bool>(mRequestContext);
6282}
6283
6284void HttpBaseChannel::EnsureBrowserId() {
6285 if (mBrowserId) {
6286 return;
6287 }
6288
6289 RefPtr<dom::BrowsingContext> bc;
6290 MOZ_ALWAYS_SUCCEEDS(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))), 1)))
), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 6290
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
")"); do { MOZ_CrashSequence(__null, 6290); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
6291
6292 if (bc) {
6293 mBrowserId = bc->GetBrowserId();
6294 }
6295}
6296
6297void HttpBaseChannel::SetCorsPreflightParameters(
6298 const nsTArray<nsCString>& aUnsafeHeaders,
6299 bool aShouldStripRequestBodyHeader, bool aShouldStripAuthHeader) {
6300 MOZ_RELEASE_ASSERT(!LoadRequestObserversCalled())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadRequestObserversCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadRequestObserversCalled(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadRequestObserversCalled()", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6300); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequestObserversCalled()"
")"); do { MOZ_CrashSequence(__null, 6300); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6301
6302 StoreRequireCORSPreflight(true);
6303 mUnsafeHeaders = aUnsafeHeaders.Clone();
6304 if (aShouldStripRequestBodyHeader || aShouldStripAuthHeader) {
6305 mUnsafeHeaders.RemoveElementsBy([&](const nsCString& aHeader) {
6306 return (aShouldStripRequestBodyHeader &&
6307 (aHeader.LowerCaseEqualsASCII("content-type") ||
6308 aHeader.LowerCaseEqualsASCII("content-encoding") ||
6309 aHeader.LowerCaseEqualsASCII("content-language") ||
6310 aHeader.LowerCaseEqualsASCII("content-location"))) ||
6311 (aShouldStripAuthHeader &&
6312 aHeader.LowerCaseEqualsASCII("authorization"));
6313 });
6314 }
6315}
6316
6317void HttpBaseChannel::SetAltDataForChild(bool aIsForChild) {
6318 StoreAltDataForChild(aIsForChild);
6319}
6320
6321NS_IMETHODIMPnsresult
6322HttpBaseChannel::GetBlockAuthPrompt(bool* aValue) {
6323 if (!aValue) {
6324 return NS_ERROR_FAILURE;
6325 }
6326
6327 *aValue = LoadBlockAuthPrompt();
6328 return NS_OK;
6329}
6330
6331NS_IMETHODIMPnsresult
6332HttpBaseChannel::SetBlockAuthPrompt(bool aValue) {
6333 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6333); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6333, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6333); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 6333
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()" ")"
); do { MOZ_CrashSequence(__null, 6333); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
6334
6335 StoreBlockAuthPrompt(aValue);
6336 return NS_OK;
6337}
6338
6339NS_IMETHODIMPnsresult
6340HttpBaseChannel::GetConnectionInfoHashKey(nsACString& aConnectionInfoHashKey) {
6341 if (!mConnectionInfo) {
6342 return NS_ERROR_FAILURE;
6343 }
6344 aConnectionInfoHashKey.Assign(mConnectionInfo->HashKey());
6345 return NS_OK;
6346}
6347
6348NS_IMETHODIMPnsresult
6349HttpBaseChannel::GetLastRedirectFlags(uint32_t* aValue) {
6350 NS_ENSURE_ARG(aValue)do { if ((__builtin_expect(!!(!(aValue)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aValue" ") failed", nullptr
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 6350
); return NS_ERROR_INVALID_ARG; } } while (false)
;
6351 *aValue = mLastRedirectFlags;
6352 return NS_OK;
6353}
6354
6355NS_IMETHODIMPnsresult
6356HttpBaseChannel::SetLastRedirectFlags(uint32_t aValue) {
6357 mLastRedirectFlags = aValue;
6358 return NS_OK;
6359}
6360
6361NS_IMETHODIMPnsresult
6362HttpBaseChannel::GetNavigationStartTimeStamp(TimeStamp* aTimeStamp) {
6363 return NS_ERROR_NOT_IMPLEMENTED;
6364}
6365
6366NS_IMETHODIMPnsresult
6367HttpBaseChannel::SetNavigationStartTimeStamp(TimeStamp aTimeStamp) {
6368 return NS_ERROR_NOT_IMPLEMENTED;
6369}
6370
6371nsresult HttpBaseChannel::CheckRedirectLimit(nsIURI* aNewURI,
6372 uint32_t aRedirectFlags) const {
6373 if (aRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
6374 // for internal redirect due to auth retry we do not have any limit
6375 // as we might restrict the number of times a user might retry
6376 // authentication
6377 if (aRedirectFlags & nsIChannelEventSink::REDIRECT_AUTH_RETRY) {
6378 return NS_OK;
6379 }
6380 // Some platform features, like Service Workers, depend on internal
6381 // redirects. We should allow some number of internal redirects above
6382 // and beyond the normal redirect limit so these features continue
6383 // to work.
6384 static const int8_t kMinInternalRedirects = 5;
6385
6386 if (mInternalRedirectCount >= (mRedirectionLimit + kMinInternalRedirects)) {
6387 LOG(("internal redirection limit reached!\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "internal redirection limit reached!\n"); } } while (0)
;
6388 return NS_ERROR_REDIRECT_LOOP;
6389 }
6390 return NS_OK;
6391 }
6392
6393 MOZ_ASSERT(aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY |do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY
| nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink
::REDIRECT_STS_UPGRADE))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aRedirectFlags & (nsIChannelEventSink
::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT
| nsIChannelEventSink::REDIRECT_STS_UPGRADE)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 6395
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { MOZ_CrashSequence(__null, 6395); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6394 nsIChannelEventSink::REDIRECT_PERMANENT |do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY
| nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink
::REDIRECT_STS_UPGRADE))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aRedirectFlags & (nsIChannelEventSink
::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT
| nsIChannelEventSink::REDIRECT_STS_UPGRADE)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 6395
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { MOZ_CrashSequence(__null, 6395); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6395 nsIChannelEventSink::REDIRECT_STS_UPGRADE))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY
| nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink
::REDIRECT_STS_UPGRADE))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aRedirectFlags & (nsIChannelEventSink
::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT
| nsIChannelEventSink::REDIRECT_STS_UPGRADE)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 6395
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { MOZ_CrashSequence(__null, 6395); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6396
6397 if (mRedirectCount >= mRedirectionLimit) {
6398 LOG(("redirection limit reached!\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "redirection limit reached!\n"); } } while (0)
;
6399 return NS_ERROR_REDIRECT_LOOP;
6400 }
6401
6402 // in case https-only mode is enabled which upgrades top-level requests to
6403 // https and the page answers with a redirect (meta, 302, win.location, ...)
6404 // then this method can break the cycle which causes the https-only exception
6405 // page to appear. Note that https-first mode breaks upgrade downgrade endless
6406 // loops within ShouldUpgradeHttpsFirstRequest because https-first does not
6407 // display an exception page but needs a soft fallback/downgrade.
6408 if (nsHTTPSOnlyUtils::IsUpgradeDowngradeEndlessLoop(
6409 mURI, aNewURI, mLoadInfo,
6410 {nsHTTPSOnlyUtils::UpgradeDowngradeEndlessLoopOptions::
6411 EnforceForHTTPSOnlyMode})) {
6412 // Mark that we didn't upgrade to https due to loop detection in https-only
6413 // mode to show https-only error page. We know that we are in https-only
6414 // mode, because we passed `EnforceForHTTPSOnlyMode` to
6415 // `IsUpgradeDowngradeEndlessLoop`. In other words we upgrade the request
6416 // with https-only mode, but then immediately cancel the request.
6417 uint32_t httpsOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
6418 if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_UNINITIALIZED) {
6419 httpsOnlyStatus ^= nsILoadInfo::HTTPS_ONLY_UNINITIALIZED;
6420 httpsOnlyStatus |=
6421 nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_NOT_REGISTERED;
6422 mLoadInfo->SetHttpsOnlyStatus(httpsOnlyStatus);
6423 }
6424
6425 LOG(("upgrade downgrade redirect loop!\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "upgrade downgrade redirect loop!\n"); } } while (0)
;
6426 return NS_ERROR_REDIRECT_LOOP;
6427 }
6428 // in case of http-first mode we want to add an exception to disable the
6429 // upgrade behavior if we have upgrade-downgrade loop to break the loop and
6430 // load the http request next
6431 if (mozilla::StaticPrefs::
6432 dom_security_https_first_add_exception_on_failure() &&
6433 nsHTTPSOnlyUtils::IsUpgradeDowngradeEndlessLoop(
6434 mURI, aNewURI, mLoadInfo,
6435 {nsHTTPSOnlyUtils::UpgradeDowngradeEndlessLoopOptions::
6436 EnforceForHTTPSFirstMode})) {
6437 nsHTTPSOnlyUtils::AddHTTPSFirstException(mURI, mLoadInfo);
6438 }
6439
6440 return NS_OK;
6441}
6442
6443// NOTE: This function duplicates code from nsBaseChannel. This will go away
6444// once HTTP uses nsBaseChannel (part of bug 312760)
6445/* static */
6446void HttpBaseChannel::CallTypeSniffers(void* aClosure, const uint8_t* aData,
6447 uint32_t aCount) {
6448 nsIChannel* chan = static_cast<nsIChannel*>(aClosure);
6449 const char* snifferType = [chan]() {
6450 if (RefPtr<nsHttpChannel> httpChannel = do_QueryObject(chan)) {
6451 switch (httpChannel->GetSnifferCategoryType()) {
6452 case SnifferCategoryType::NetContent:
6453 return NS_CONTENT_SNIFFER_CATEGORY"net-content-sniffers";
6454 case SnifferCategoryType::OpaqueResponseBlocking:
6455 return NS_ORB_SNIFFER_CATEGORY"orb-content-sniffers";
6456 case SnifferCategoryType::All:
6457 return NS_CONTENT_AND_ORB_SNIFFER_CATEGORY"net-and-orb-content-sniffers";
6458 default:
6459 MOZ_ASSERT_UNREACHABLE("Unexpected SnifferCategoryType!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Unexpected SnifferCategoryType!" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6459); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected SnifferCategoryType!"
")"); do { MOZ_CrashSequence(__null, 6459); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6460 }
6461 }
6462
6463 return NS_CONTENT_SNIFFER_CATEGORY"net-content-sniffers";
6464 }();
6465
6466 nsAutoCString newType;
6467 NS_SniffContent(snifferType, chan, aData, aCount, newType);
6468 if (!newType.IsEmpty()) {
6469 chan->SetContentType(newType);
6470 }
6471}
6472
6473template <class T>
6474static void ParseServerTimingHeader(
6475 const UniquePtr<T>& aHeader, nsTArray<nsCOMPtr<nsIServerTiming>>& aOutput) {
6476 if (!aHeader) {
6477 return;
6478 }
6479
6480 nsAutoCString serverTimingHeader;
6481 (void)aHeader->GetHeader(nsHttp::Server_Timing, serverTimingHeader);
6482 if (serverTimingHeader.IsEmpty()) {
6483 return;
6484 }
6485
6486 ServerTimingParser parser(serverTimingHeader);
6487 parser.Parse();
6488
6489 nsTArray<nsCOMPtr<nsIServerTiming>> array = parser.TakeServerTimingHeaders();
6490 aOutput.AppendElements(array);
6491}
6492
6493NS_IMETHODIMPnsresult
6494HttpBaseChannel::GetServerTiming(nsIArray** aServerTiming) {
6495 nsresult rv;
6496 NS_ENSURE_ARG_POINTER(aServerTiming)do { if ((__builtin_expect(!!(!(aServerTiming)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aServerTiming" ") failed"
, nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6496); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6497
6498 nsCOMPtr<nsIMutableArray> array = do_CreateInstance(NS_ARRAY_CONTRACTID"@mozilla.org/array;1", &rv);
6499 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6499); return rv; } } while (false)
;
6500
6501 nsTArray<nsCOMPtr<nsIServerTiming>> data;
6502 rv = GetNativeServerTiming(data);
6503 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6503); return rv; } } while (false)
;
6504
6505 for (const auto& entry : data) {
6506 array->AppendElement(entry);
6507 }
6508
6509 array.forget(aServerTiming);
6510 return NS_OK;
6511}
6512
6513NS_IMETHODIMPnsresult
6514HttpBaseChannel::GetNativeServerTiming(
6515 nsTArray<nsCOMPtr<nsIServerTiming>>& aServerTiming) {
6516 aServerTiming.Clear();
6517
6518 if (nsContentUtils::ComputeIsSecureContext(this)) {
6519 ParseServerTimingHeader(mResponseHead, aServerTiming);
6520 ParseServerTimingHeader(mResponseTrailers, aServerTiming);
6521 }
6522
6523 return NS_OK;
6524}
6525
6526NS_IMETHODIMPnsresult
6527HttpBaseChannel::CancelByURLClassifier(nsresult aErrorCode) {
6528 MOZ_ASSERT(ChannelClassifierUtils::IsClassifierBlockingErrorCode(aErrorCode))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ChannelClassifierUtils::IsClassifierBlockingErrorCode
(aErrorCode))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(ChannelClassifierUtils::IsClassifierBlockingErrorCode
(aErrorCode)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("ChannelClassifierUtils::IsClassifierBlockingErrorCode(aErrorCode)"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 6528
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ChannelClassifierUtils::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { MOZ_CrashSequence(__null, 6528); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6529 return Cancel(aErrorCode);
6530}
6531
6532NS_IMETHODIMPnsresult HttpBaseChannel::SetIPv4Disabled() {
6533 mCaps |= NS_HTTP_DISABLE_IPV4(1 << 17);
6534 return NS_OK;
6535}
6536
6537NS_IMETHODIMPnsresult HttpBaseChannel::SetIPv6Disabled() {
6538 mCaps |= NS_HTTP_DISABLE_IPV6(1 << 18);
6539 return NS_OK;
6540}
6541
6542NS_IMETHODIMPnsresult HttpBaseChannel::GetResponseEmbedderPolicy(
6543 bool aIsOriginTrialCoepCredentiallessEnabled,
6544 nsILoadInfo::CrossOriginEmbedderPolicy* aOutPolicy) {
6545 *aOutPolicy = nsILoadInfo::EMBEDDER_POLICY_NULL;
6546 if (!mResponseHead) {
6547 return NS_ERROR_NOT_AVAILABLE;
6548 }
6549
6550 if (!nsContentUtils::ComputeIsSecureContext(this)) {
6551 // Feature is only available for secure contexts.
6552 return NS_OK;
6553 }
6554
6555 nsAutoCString content;
6556 (void)mResponseHead->GetHeader(nsHttp::Cross_Origin_Embedder_Policy, content);
6557 *aOutPolicy = NS_GetCrossOriginEmbedderPolicyFromHeader(
6558 content, aIsOriginTrialCoepCredentiallessEnabled);
6559 return NS_OK;
6560}
6561
6562// Obtain a cross-origin opener-policy from a response response and a
6563// cross-origin opener policy initiator.
6564// https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
6565NS_IMETHODIMPnsresult HttpBaseChannel::ComputeCrossOriginOpenerPolicy(
6566 nsILoadInfo::CrossOriginOpenerPolicy aInitiatorPolicy,
6567 nsILoadInfo::CrossOriginOpenerPolicy* aOutPolicy) {
6568 MOZ_ASSERT(aOutPolicy)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aOutPolicy)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aOutPolicy))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aOutPolicy", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6568); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOutPolicy"
")"); do { MOZ_CrashSequence(__null, 6568); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6569 *aOutPolicy = nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
6570
6571 if (!mResponseHead) {
6572 return NS_ERROR_NOT_AVAILABLE;
6573 }
6574
6575 // COOP headers are ignored for insecure-context loads.
6576 if (!nsContentUtils::ComputeIsSecureContext(this)) {
6577 return NS_OK;
6578 }
6579
6580 nsAutoCString openerPolicy;
6581 (void)mResponseHead->GetHeader(nsHttp::Cross_Origin_Opener_Policy,
6582 openerPolicy);
6583
6584 // Cross-Origin-Opener-Policy = %s"same-origin" /
6585 // %s"same-origin-allow-popups" /
6586 // %s"unsafe-none"; case-sensitive
6587
6588 nsresult rv = SFV::ParseItem<SFV::Token>(openerPolicy, openerPolicy);
6589 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6590 return rv;
6591 }
6592
6593 nsILoadInfo::CrossOriginOpenerPolicy policy =
6594 nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
6595
6596 if (openerPolicy.EqualsLiteral("same-origin")) {
6597 policy = nsILoadInfo::OPENER_POLICY_SAME_ORIGIN;
6598 } else if (openerPolicy.EqualsLiteral("same-origin-allow-popups")) {
6599 policy = nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_ALLOW_POPUPS;
6600 }
6601 if (policy == nsILoadInfo::OPENER_POLICY_SAME_ORIGIN) {
6602 nsILoadInfo::CrossOriginEmbedderPolicy coep =
6603 nsILoadInfo::EMBEDDER_POLICY_NULL;
6604 bool isCoepCredentiallessEnabled;
6605 rv = mLoadInfo->GetIsOriginTrialCoepCredentiallessEnabledForTopLevel(
6606 &isCoepCredentiallessEnabled);
6607 if (!isCoepCredentiallessEnabled) {
6608 nsAutoCString originTrialToken;
6609 (void)mResponseHead->GetHeader(nsHttp::OriginTrial, originTrialToken);
6610 if (!originTrialToken.IsEmpty()) {
6611 nsCOMPtr<nsIPrincipal> resultPrincipal;
6612 rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
6613 this, getter_AddRefs(resultPrincipal));
6614 if (!NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6614)
) {
6615 OriginTrials trials;
6616 trials.UpdateFromToken(NS_ConvertASCIItoUTF16(originTrialToken),
6617 resultPrincipal);
6618 if (trials.IsEnabled(OriginTrial::CoepCredentialless)) {
6619 isCoepCredentiallessEnabled = true;
6620 }
6621 }
6622 }
6623 }
6624
6625 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6625); return rv; } } while (false)
;
6626 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetResponseEmbedderPolicy
(isCoepCredentiallessEnabled, &coep))), 1)))
6627 GetResponseEmbedderPolicy(isCoepCredentiallessEnabled, &coep))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetResponseEmbedderPolicy
(isCoepCredentiallessEnabled, &coep))), 1)))
&&
6628 (coep == nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP ||
6629 coep == nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS)) {
6630 policy =
6631 nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP;
6632 }
6633 }
6634
6635 *aOutPolicy = policy;
6636 return NS_OK;
6637}
6638
6639NS_IMETHODIMPnsresult
6640HttpBaseChannel::GetCrossOriginOpenerPolicy(
6641 nsILoadInfo::CrossOriginOpenerPolicy* aPolicy) {
6642 MOZ_ASSERT(aPolicy)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPolicy)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPolicy))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aPolicy", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6642); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPolicy" ")"
); do { MOZ_CrashSequence(__null, 6642); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6643 if (!aPolicy) {
6644 return NS_ERROR_INVALID_ARG;
6645 }
6646 // If this method is called before OnStartRequest (ie. before we call
6647 // ComputeCrossOriginOpenerPolicy) or if we were unable to compute the
6648 // policy we'll throw an error.
6649 if (!LoadOnStartRequestCalled()) {
6650 return NS_ERROR_NOT_AVAILABLE;
6651 }
6652 *aPolicy = mComputedCrossOriginOpenerPolicy;
6653 return NS_OK;
6654}
6655
6656NS_IMETHODIMPnsresult
6657HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch(bool* aIsMismatch) {
6658 // This should only be called in parent process.
6659 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 6659
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 6659); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6660 *aIsMismatch = LoadHasCrossOriginOpenerPolicyMismatch();
6661 return NS_OK;
6662}
6663
6664NS_IMETHODIMPnsresult
6665HttpBaseChannel::GetOriginAgentClusterHeader(bool* aValue) {
6666 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp", 6666
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 6666); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6667 if (!mResponseHead) {
6668 return NS_ERROR_NOT_AVAILABLE;
6669 }
6670
6671 nsAutoCString content;
6672 nsresult rv = mResponseHead->GetHeader(nsHttp::OriginAgentCluster, content);
6673 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6674 return rv;
6675 }
6676
6677 // Origin-Agent-Cluster = <boolean>
6678 return SFV::ParseItem<SFV::SFVBool>(content, *aValue);
6679}
6680
6681void HttpBaseChannel::MaybeFlushConsoleReports() {
6682 // Flush if we have a known window ID.
6683 if (mLoadInfo->GetInnerWindowID() > 0) {
6684 FlushReportsToConsole(mLoadInfo->GetInnerWindowID());
6685 return;
6686 }
6687
6688 // If this channel is part of a loadGroup, we can flush the console reports
6689 // immediately.
6690 nsCOMPtr<nsILoadGroup> loadGroup;
6691 nsresult rv = GetLoadGroup(getter_AddRefs(loadGroup));
6692 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && loadGroup) {
6693 FlushConsoleReports(loadGroup);
6694 }
6695}
6696
6697void HttpBaseChannel::DoDiagnosticAssertWhenOnStopNotCalledOnDestroy() {}
6698
6699bool HttpBaseChannel::Http3Allowed() const {
6700 bool allowedProxyInfo =
6701 mProxyInfo ? (static_cast<nsProxyInfo*>(mProxyInfo.get())->IsDirect() ||
6702 static_cast<nsProxyInfo*>(mProxyInfo.get())->IsHttp3Proxy())
6703 : true;
6704 // TODO: When mUpgradeProtocolCallback is not null, we should allow HTTP/3 for
6705 // connect-udp.
6706 return !mUpgradeProtocolCallback && allowedProxyInfo &&
6707 !(mCaps & NS_HTTP_BE_CONSERVATIVE(1 << 11)) && !LoadBeConservative() &&
6708 LoadAllowHttp3();
6709}
6710
6711UniquePtr<nsHttpResponseHead>
6712HttpBaseChannel::MaybeCloneResponseHeadForCachedResource() {
6713 if (!mResponseHead) {
6714 return nullptr;
6715 }
6716
6717 return MakeUnique<nsHttpResponseHead>(*mResponseHead);
6718}
6719
6720void HttpBaseChannel::SetDummyChannelForCachedResource(
6721 const nsHttpResponseHead* aMaybeResponseHead /* = nullptr */) {
6722 mDummyChannelForCachedResource = true;
6723 MOZ_ASSERT(!mResponseHead,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mResponseHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mResponseHead))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mResponseHead"
" (" "SetDummyChannelForCachedResource should only be called once"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6724); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mResponseHead"
") (" "SetDummyChannelForCachedResource should only be called once"
")"); do { MOZ_CrashSequence(__null, 6724); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6724 "SetDummyChannelForCachedResource should only be called once")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mResponseHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mResponseHead))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mResponseHead"
" (" "SetDummyChannelForCachedResource should only be called once"
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6724); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mResponseHead"
") (" "SetDummyChannelForCachedResource should only be called once"
")"); do { MOZ_CrashSequence(__null, 6724); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6725 if (aMaybeResponseHead) {
6726 mResponseHead = MakeUnique<nsHttpResponseHead>(*aMaybeResponseHead);
6727 } else {
6728 mResponseHead = MakeUnique<nsHttpResponseHead>();
6729 }
6730}
6731
6732void HttpBaseChannel::SetEarlyHints(
6733 nsTArray<EarlyHintConnectArgs>&& aEarlyHints) {
6734 mEarlyHints = std::move(aEarlyHints);
6735}
6736
6737nsTArray<EarlyHintConnectArgs>&& HttpBaseChannel::TakeEarlyHints() {
6738 return std::move(mEarlyHints);
6739}
6740
6741NS_IMETHODIMPnsresult
6742HttpBaseChannel::SetEarlyHintPreloaderId(uint64_t aEarlyHintPreloaderId) {
6743 mEarlyHintPreloaderId = aEarlyHintPreloaderId;
6744 return NS_OK;
6745}
6746
6747NS_IMETHODIMPnsresult
6748HttpBaseChannel::GetEarlyHintPreloaderId(uint64_t* aEarlyHintPreloaderId) {
6749 NS_ENSURE_ARG_POINTER(aEarlyHintPreloaderId)do { if ((__builtin_expect(!!(!(aEarlyHintPreloaderId)), 0)))
{ NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aEarlyHintPreloaderId"
") failed", nullptr, "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6749); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6750 *aEarlyHintPreloaderId = mEarlyHintPreloaderId;
6751 return NS_OK;
6752}
6753
6754NS_IMETHODIMPnsresult
6755HttpBaseChannel::SetClassicScriptHintCharset(
6756 const nsAString& aClassicScriptHintCharset) {
6757 mClassicScriptHintCharset = aClassicScriptHintCharset;
6758 return NS_OK;
6759}
6760
6761NS_IMETHODIMPnsresult HttpBaseChannel::GetClassicScriptHintCharset(
6762 nsAString& aClassicScriptHintCharset) {
6763 aClassicScriptHintCharset = mClassicScriptHintCharset;
6764 return NS_OK;
6765}
6766
6767NS_IMETHODIMPnsresult HttpBaseChannel::SetDocumentCharacterSet(
6768 const nsAString& aDocumentCharacterSet) {
6769 mDocumentCharacterSet = aDocumentCharacterSet;
6770 return NS_OK;
6771}
6772
6773NS_IMETHODIMPnsresult HttpBaseChannel::GetDocumentCharacterSet(
6774 nsAString& aDocumentCharacterSet) {
6775 aDocumentCharacterSet = mDocumentCharacterSet;
6776 return NS_OK;
6777}
6778
6779void HttpBaseChannel::SetConnectionInfo(nsHttpConnectionInfo* aCI) {
6780 mConnectionInfo = aCI ? aCI->Clone() : nullptr;
6781}
6782
6783NS_IMETHODIMPnsresult
6784HttpBaseChannel::GetIsProxyUsed(bool* aIsProxyUsed) {
6785 if (mProxyInfo) {
6786 if (!static_cast<nsProxyInfo*>(mProxyInfo.get())->IsDirect()) {
6787 StoreIsProxyUsed(true);
6788 }
6789 }
6790 *aIsProxyUsed = LoadIsProxyUsed();
6791 return NS_OK;
6792}
6793
6794static void CollectORBBlockTelemetry(
6795 const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
6796 ExtContentPolicy aPolicy) {
6797 glean::orb::block_reason.EnumGet(aTelemetryReason).Add();
6798
6799 switch (aPolicy) {
6800 case ExtContentPolicy::TYPE_INVALID:
6801 glean::orb::block_initiator
6802 .EnumGet(glean::orb::BlockInitiatorLabel::eInvalid)
6803 .Add();
6804 break;
6805 case ExtContentPolicy::TYPE_OTHER:
6806 glean::orb::block_initiator
6807 .EnumGet(glean::orb::BlockInitiatorLabel::eOther)
6808 .Add();
6809 break;
6810 case ExtContentPolicy::TYPE_FETCH:
6811 glean::orb::block_initiator
6812 .EnumGet(glean::orb::BlockInitiatorLabel::eBlockedFetch)
6813 .Add();
6814 break;
6815 case ExtContentPolicy::TYPE_SCRIPT:
6816 glean::orb::block_initiator
6817 .EnumGet(glean::orb::BlockInitiatorLabel::eScript)
6818 .Add();
6819 break;
6820 case ExtContentPolicy::TYPE_JSON:
6821 glean::orb::block_initiator
6822 .EnumGet(glean::orb::BlockInitiatorLabel::eJson)
6823 .Add();
6824 break;
6825 case ExtContentPolicy::TYPE_IMAGE:
6826 glean::orb::block_initiator
6827 .EnumGet(glean::orb::BlockInitiatorLabel::eImage)
6828 .Add();
6829 break;
6830 case ExtContentPolicy::TYPE_STYLESHEET:
6831 glean::orb::block_initiator
6832 .EnumGet(glean::orb::BlockInitiatorLabel::eStylesheet)
6833 .Add();
6834 break;
6835 case ExtContentPolicy::TYPE_XMLHTTPREQUEST:
6836 glean::orb::block_initiator
6837 .EnumGet(glean::orb::BlockInitiatorLabel::eXmlhttprequest)
6838 .Add();
6839 break;
6840 case ExtContentPolicy::TYPE_DTD:
6841 glean::orb::block_initiator.EnumGet(glean::orb::BlockInitiatorLabel::eDtd)
6842 .Add();
6843 break;
6844 case ExtContentPolicy::TYPE_FONT:
6845 glean::orb::block_initiator
6846 .EnumGet(glean::orb::BlockInitiatorLabel::eFont)
6847 .Add();
6848 break;
6849 case ExtContentPolicy::TYPE_MEDIA:
6850 glean::orb::block_initiator
6851 .EnumGet(glean::orb::BlockInitiatorLabel::eMedia)
6852 .Add();
6853 break;
6854 case ExtContentPolicy::TYPE_CSP_REPORT:
6855 glean::orb::block_initiator
6856 .EnumGet(glean::orb::BlockInitiatorLabel::eCspReport)
6857 .Add();
6858 break;
6859 case ExtContentPolicy::TYPE_XSLT:
6860 glean::orb::block_initiator
6861 .EnumGet(glean::orb::BlockInitiatorLabel::eXslt)
6862 .Add();
6863 break;
6864 case ExtContentPolicy::TYPE_IMAGESET:
6865 glean::orb::block_initiator
6866 .EnumGet(glean::orb::BlockInitiatorLabel::eImageset)
6867 .Add();
6868 break;
6869 case ExtContentPolicy::TYPE_WEB_MANIFEST:
6870 glean::orb::block_initiator
6871 .EnumGet(glean::orb::BlockInitiatorLabel::eWebManifest)
6872 .Add();
6873 break;
6874 case ExtContentPolicy::TYPE_SPECULATIVE:
6875 glean::orb::block_initiator
6876 .EnumGet(glean::orb::BlockInitiatorLabel::eSpeculative)
6877 .Add();
6878 break;
6879 case ExtContentPolicy::TYPE_UA_FONT:
6880 glean::orb::block_initiator
6881 .EnumGet(glean::orb::BlockInitiatorLabel::eUaFont)
6882 .Add();
6883 break;
6884 case ExtContentPolicy::TYPE_PROXIED_WEBRTC_MEDIA:
6885 glean::orb::block_initiator
6886 .EnumGet(glean::orb::BlockInitiatorLabel::eProxiedWebrtcMedia)
6887 .Add();
6888 break;
6889 case ExtContentPolicy::TYPE_PING:
6890 glean::orb::block_initiator
6891 .EnumGet(glean::orb::BlockInitiatorLabel::ePing)
6892 .Add();
6893 break;
6894 case ExtContentPolicy::TYPE_BEACON:
6895 glean::orb::block_initiator
6896 .EnumGet(glean::orb::BlockInitiatorLabel::eBeacon)
6897 .Add();
6898 break;
6899 case ExtContentPolicy::TYPE_WEB_TRANSPORT:
6900 glean::orb::block_initiator
6901 .EnumGet(glean::orb::BlockInitiatorLabel::eWebTransport)
6902 .Add();
6903 break;
6904 case ExtContentPolicy::TYPE_WEB_IDENTITY:
6905 // Don't bother extending the telemetry for this.
6906 glean::orb::block_initiator
6907 .EnumGet(glean::orb::BlockInitiatorLabel::eOther)
6908 .Add();
6909 break;
6910 case ExtContentPolicy::TYPE_TEXT:
6911 glean::orb::block_initiator
6912 .EnumGet(glean::orb::BlockInitiatorLabel::eText)
6913 .Add();
6914 break;
6915 case ExtContentPolicy::TYPE_DOCUMENT:
6916 case ExtContentPolicy::TYPE_SUBDOCUMENT:
6917 case ExtContentPolicy::TYPE_OBJECT:
6918 case ExtContentPolicy::TYPE_WEBSOCKET:
6919 case ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD:
6920 MOZ_ASSERT_UNREACHABLE("Shouldn't block this type")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Shouldn't block this type" ")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 6920); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Shouldn't block this type" ")");
do { MOZ_CrashSequence(__null, 6920); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6921 // DOCUMENT, SUBDOCUMENT, OBJECT,
6922 // WEBSOCKET and SAVEAS_DOWNLOAD are excluded from ORB
6923 glean::orb::block_initiator
6924 .EnumGet(glean::orb::BlockInitiatorLabel::eExcluded)
6925 .Add();
6926 break;
6927 // Do not add default: so that compilers can catch the missing case.
6928 }
6929}
6930
6931void HttpBaseChannel::LogORBError(
6932 const nsAString& aReason,
6933 const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
6934 auto policy = mLoadInfo->GetExternalContentPolicyType();
6935 CollectORBBlockTelemetry(aTelemetryReason, policy);
6936
6937 // Blocking `ExtContentPolicy::TYPE_BEACON` isn't web observable, so keep
6938 // quiet in the console about blocking it.
6939 if (policy == ExtContentPolicy::TYPE_BEACON) {
6940 return;
6941 }
6942
6943 RefPtr<dom::Document> doc;
6944 mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
6945
6946 nsAutoCString uri;
6947 if (mURI->SchemeIs("data")) {
6948 uri.AssignLiteral("data:...");
6949 } else {
6950 nsCOMPtr<nsIURI> exposableURI = net::nsIOService::CreateExposableURI(mURI);
6951 exposableURI->GetSpec(uri);
6952 }
6953
6954 uint64_t contentWindowId;
6955 GetTopLevelContentWindowId(&contentWindowId);
6956 if (contentWindowId) {
6957 nsContentUtils::ReportToConsoleByWindowID(
6958 u"A resource is blocked by OpaqueResponseBlocking, please check browser console for details."_ns,
6959 nsIScriptError::warningFlag, "ORB"_ns, contentWindowId,
6960 SourceLocation(mURI.get()));
6961 }
6962
6963 AutoTArray<nsString, 2> params;
6964 params.AppendElement(NS_ConvertUTF8toUTF16(uri));
6965 params.AppendElement(aReason);
6966 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "ORB"_ns, doc,
6967 PropertiesFile::NECKO_PROPERTIES,
6968 "ResourceBlockedORB", params);
6969}
6970
6971NS_IMETHODIMPnsresult HttpBaseChannel::SetEarlyHintLinkType(
6972 uint32_t aEarlyHintLinkType) {
6973 mEarlyHintLinkType = aEarlyHintLinkType;
6974 return NS_OK;
6975}
6976
6977NS_IMETHODIMPnsresult HttpBaseChannel::GetEarlyHintLinkType(
6978 uint32_t* aEarlyHintLinkType) {
6979 *aEarlyHintLinkType = mEarlyHintLinkType;
6980 return NS_OK;
6981}
6982
6983NS_IMETHODIMPnsresult
6984HttpBaseChannel::SetHasContentDecompressed(bool aValue) {
6985 LOG(("HttpBaseChannel::SetHasContentDecompressed [this=%p value=%d]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetHasContentDecompressed [this=%p value=%d]\n"
, this, aValue); } } while (0)
6986 aValue))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetHasContentDecompressed [this=%p value=%d]\n"
, this, aValue); } } while (0)
;
6987 mHasContentDecompressed = aValue;
6988 return NS_OK;
6989}
6990NS_IMETHODIMPnsresult
6991HttpBaseChannel::GetHasContentDecompressed(bool* value) {
6992 *value = mHasContentDecompressed;
6993 return NS_OK;
6994}
6995
6996NS_IMETHODIMPnsresult
6997HttpBaseChannel::SetRenderBlocking(bool aRenderBlocking) {
6998 mRenderBlocking = aRenderBlocking;
6999 return NS_OK;
7000}
7001
7002NS_IMETHODIMPnsresult
7003HttpBaseChannel::GetRenderBlocking(bool* aRenderBlocking) {
7004 *aRenderBlocking = mRenderBlocking;
7005 return NS_OK;
7006}
7007
7008NS_IMETHODIMPnsresult HttpBaseChannel::GetLastTransportStatus(
7009 nsresult* aLastTransportStatus) {
7010 return NS_ERROR_NOT_IMPLEMENTED;
7011}
7012
7013void HttpBaseChannel::SetFetchPriorityDOM(
7014 mozilla::dom::FetchPriority aPriority) {
7015 switch (aPriority) {
7016 case mozilla::dom::FetchPriority::Auto:
7017 SetFetchPriority(nsIClassOfService::FETCHPRIORITY_AUTO);
7018 return;
7019 case mozilla::dom::FetchPriority::High:
7020 SetFetchPriority(nsIClassOfService::FETCHPRIORITY_HIGH);
7021 return;
7022 case mozilla::dom::FetchPriority::Low:
7023 SetFetchPriority(nsIClassOfService::FETCHPRIORITY_LOW);
7024 return;
7025 default:
7026 MOZ_ASSERT_UNREACHABLE()do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
")", "./../../../../netwerk/protocol/http/HttpBaseChannel.cpp"
, 7026); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " ")"); do { MOZ_CrashSequence(__null
, 7026); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
7027 }
7028}
7029
7030} // namespace net
7031} // namespace mozilla
7032#undef LOGORB