Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp
Warning:line 5597, column 3
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -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=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/netwerk/protocol/http -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/netwerk/protocol/http -resource-dir /usr/lib/llvm-19/lib/clang/19 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/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 /var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/netwerk/protocol/http -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/base -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/cookie -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/ipc -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/socket/neqo_glue -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/url-classifier -I /var/lib/jenkins/workspace/firefox-scan-build/extensions/auth -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -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-deprecated-this-capture -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 -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 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-09-22-115206-3586786-1 -x c++ Unified_cpp_protocol_http2.cpp
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set sw=2 ts=8 et tw=80 : */
3
4/* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8// HttpLog.h should generally be included first
9#include "mozilla/net/HttpBaseChannel.h"
10
11#include <algorithm>
12#include <utility>
13
14#include "HttpBaseChannel.h"
15#include "HttpLog.h"
16#include "LoadInfo.h"
17#include "ReferrerInfo.h"
18#include "mozIRemoteLazyInputStream.h"
19#include "mozIThirdPartyUtil.h"
20#include "mozilla/LoadInfo.h"
21#include "mozilla/AntiTrackingUtils.h"
22#include "mozilla/BasePrincipal.h"
23#include "mozilla/BinarySearch.h"
24#include "mozilla/ConsoleReportCollector.h"
25#include "mozilla/DebugOnly.h"
26#include "mozilla/InputStreamLengthHelper.h"
27#include "mozilla/Mutex.h"
28#include "mozilla/NullPrincipal.h"
29#include "mozilla/PermissionManager.h"
30#include "mozilla/Components.h"
31#include "mozilla/StaticPrefs_browser.h"
32#include "mozilla/StaticPrefs_fission.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/Document.h"
41#include "mozilla/dom/nsHTTPSOnlyUtils.h"
42#include "mozilla/dom/nsMixedContentBlocker.h"
43#include "mozilla/dom/Performance.h"
44#include "mozilla/dom/PerformanceStorage.h"
45#include "mozilla/dom/ProcessIsolation.h"
46#include "mozilla/dom/RequestBinding.h"
47#include "mozilla/dom/WindowGlobalParent.h"
48#include "mozilla/net/OpaqueResponseUtils.h"
49#include "mozilla/net/UrlClassifierCommon.h"
50#include "mozilla/net/UrlClassifierFeatureFactory.h"
51#include "nsBufferedStreams.h"
52#include "nsCOMPtr.h"
53#include "nsCRT.h"
54#include "nsContentSecurityManager.h"
55#include "nsContentSecurityUtils.h"
56#include "nsContentUtils.h"
57#include "nsDebug.h"
58#include "nsEscape.h"
59#include "nsGlobalWindowInner.h"
60#include "nsGlobalWindowOuter.h"
61#include "nsHttpChannel.h"
62#include "nsHTTPCompressConv.h"
63#include "nsHttpHandler.h"
64#include "nsICacheInfoChannel.h"
65#include "nsICachingChannel.h"
66#include "nsIChannelEventSink.h"
67#include "nsIConsoleService.h"
68#include "nsIContentPolicy.h"
69#include "nsICookieService.h"
70#include "nsIDOMWindowUtils.h"
71#include "nsIDocShell.h"
72#include "nsIDNSService.h"
73#include "nsIEncodedChannel.h"
74#include "nsIHttpHeaderVisitor.h"
75#include "nsILoadGroupChild.h"
76#include "nsIMIMEInputStream.h"
77#include "nsIMultiplexInputStream.h"
78#include "nsIMutableArray.h"
79#include "nsINetworkInterceptController.h"
80#include "nsIObserverService.h"
81#include "nsIPrincipal.h"
82#include "nsIProtocolProxyService.h"
83#include "nsIScriptError.h"
84#include "nsIScriptSecurityManager.h"
85#include "nsISecurityConsoleMessage.h"
86#include "nsISeekableStream.h"
87#include "nsIStorageStream.h"
88#include "nsIStreamConverterService.h"
89#include "nsITimedChannel.h"
90#include "nsITransportSecurityInfo.h"
91#include "nsIURIMutator.h"
92#include "nsMimeTypes.h"
93#include "nsNetCID.h"
94#include "nsNetUtil.h"
95#include "nsPIDOMWindow.h"
96#include "nsProxyRelease.h"
97#include "nsReadableUtils.h"
98#include "nsRedirectHistoryEntry.h"
99#include "nsServerTiming.h"
100#include "nsStreamListenerWrapper.h"
101#include "nsStreamUtils.h"
102#include "nsString.h"
103#include "nsThreadUtils.h"
104#include "nsURLHelper.h"
105#include "mozilla/RemoteLazyInputStreamChild.h"
106#include "mozilla/net/SFVService.h"
107#include "mozilla/dom/ContentChild.h"
108#include "nsQueryObject.h"
109
110using mozilla::dom::RequestMode;
111
112#define LOGORB(msg, ...)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, ...); } } while
(0)
\
113 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)
114 ("%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)
115
116namespace mozilla {
117namespace net {
118
119static bool IsHeaderBlacklistedForRedirectCopy(nsHttpAtom const& aHeader) {
120 // IMPORTANT: keep this list ASCII-code sorted
121 static nsHttpAtomLiteral const* blackList[] = {
122 &nsHttp::Accept,
123 &nsHttp::Accept_Encoding,
124 &nsHttp::Accept_Language,
125 &nsHttp::Alternate_Service_Used,
126 &nsHttp::Authentication,
127 &nsHttp::Authorization,
128 &nsHttp::Connection,
129 &nsHttp::Content_Length,
130 &nsHttp::Cookie,
131 &nsHttp::Host,
132 &nsHttp::If,
133 &nsHttp::If_Match,
134 &nsHttp::If_Modified_Since,
135 &nsHttp::If_None_Match,
136 &nsHttp::If_None_Match_Any,
137 &nsHttp::If_Range,
138 &nsHttp::If_Unmodified_Since,
139 &nsHttp::Proxy_Authenticate,
140 &nsHttp::Proxy_Authorization,
141 &nsHttp::Range,
142 &nsHttp::TE,
143 &nsHttp::Transfer_Encoding,
144 &nsHttp::Upgrade,
145 &nsHttp::User_Agent,
146 &nsHttp::WWW_Authenticate};
147
148 class HttpAtomComparator {
149 nsHttpAtom const& mTarget;
150
151 public:
152 explicit HttpAtomComparator(nsHttpAtom const& aTarget) : mTarget(aTarget) {}
153 int operator()(nsHttpAtom const* aVal) const {
154 if (mTarget == *aVal) {
155 return 0;
156 }
157 return strcmp(mTarget.get(), aVal->get());
158 }
159 int operator()(nsHttpAtomLiteral const* aVal) const {
160 if (mTarget == *aVal) {
161 return 0;
162 }
163 return strcmp(mTarget.get(), aVal->get());
164 }
165 };
166
167 size_t unused;
168 return BinarySearchIf(blackList, 0, ArrayLength(blackList),
169 HttpAtomComparator(aHeader), &unused);
170}
171
172class AddHeadersToChannelVisitor final : public nsIHttpHeaderVisitor {
173 public:
174 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:
175
176 explicit AddHeadersToChannelVisitor(nsIHttpChannel* aChannel)
177 : mChannel(aChannel) {}
178
179 NS_IMETHODvirtual nsresult VisitHeader(const nsACString& aHeader,
180 const nsACString& aValue) override {
181 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
182 if (!IsHeaderBlacklistedForRedirectCopy(atom)) {
183 DebugOnly<nsresult> rv =
184 mChannel->SetRequestHeader(aHeader, aValue, false);
185 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 185); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 185; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
186 }
187 return NS_OK;
188 }
189
190 private:
191 ~AddHeadersToChannelVisitor() = default;
192
193 nsCOMPtr<nsIHttpChannel> mChannel;
194};
195
196NS_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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 196); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
196; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 196); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"AddHeadersToChannelVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 196; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 196); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 196
; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 196); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"AddHeadersToChannelVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 196; __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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 196); 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((sizeof(table) /
sizeof(table[0])) > 1, "need at least 1 interface"); rv =
NS_TableDrivenQI(static_cast<void*>(this), aIID, aInstancePtr
, table); return rv; }
197
198static OpaqueResponseFilterFetch ConfiguredFilterFetchResponseBehaviour() {
199 uint32_t pref = StaticPrefs::
200 browser_opaqueResponseBlocking_filterFetchResponse_DoNotUseDirectly();
201 if (NS_WARN_IF(pref >NS_warn_if_impl(pref > static_cast<uint32_t>(OpaqueResponseFilterFetch
::All), "pref > static_cast<uint32_t>(OpaqueResponseFilterFetch::All)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 202)
202 static_cast<uint32_t>(OpaqueResponseFilterFetch::All))NS_warn_if_impl(pref > static_cast<uint32_t>(OpaqueResponseFilterFetch
::All), "pref > static_cast<uint32_t>(OpaqueResponseFilterFetch::All)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 202)
) {
203 return OpaqueResponseFilterFetch::All;
204 }
205
206 return static_cast<OpaqueResponseFilterFetch>(pref);
207}
208
209HttpBaseChannel::HttpBaseChannel()
210 : mReportCollector(new ConsoleReportCollector()),
211 mHttpHandler(gHttpHandler),
212 mChannelCreationTime(0),
213 mComputedCrossOriginOpenerPolicy(nsILoadInfo::OPENER_POLICY_UNSAFE_NONE),
214 mStartPos(UINT64_MAX(18446744073709551615UL)),
215 mTransferSize(0),
216 mRequestSize(0),
217 mDecodedBodySize(0),
218 mSupportsHTTP3(false),
219 mEncodedBodySize(0),
220 mRequestContextID(0),
221 mContentWindowId(0),
222 mBrowserId(0),
223 mAltDataLength(-1),
224 mChannelId(0),
225 mReqContentLength(0U),
226 mStatus(NS_OK),
227 mCanceled(false),
228 mFirstPartyClassificationFlags(0),
229 mThirdPartyClassificationFlags(0),
230 mLoadFlags(LOAD_NORMAL),
231 mCaps(0),
232 mClassOfService(0, false),
233 mTlsFlags(0),
234 mSuspendCount(0),
235 mInitialRwin(0),
236 mProxyResolveFlags(0),
237 mContentDispositionHint(UINT32_MAX(4294967295U)),
238 mRequestMode(RequestMode::No_cors),
239 mRedirectMode(nsIHttpChannelInternal::REDIRECT_MODE_FOLLOW),
240 mLastRedirectFlags(0),
241 mPriority(PRIORITY_NORMAL),
242 mRedirectionLimit(gHttpHandler->RedirectionLimit()),
243 mRedirectCount(0),
244 mInternalRedirectCount(0),
245 mCachedOpaqueResponseBlockingPref(
246 StaticPrefs::browser_opaqueResponseBlocking()),
247 mChannelBlockedByOpaqueResponse(false),
248 mDummyChannelForCachedResource(false),
249 mHasContentDecompressed(false),
250 mRenderBlocking(false) {
251 StoreApplyConversion(true);
252 StoreAllowSTS(true);
253 StoreTracingEnabled(true);
254 StoreReportTiming(true);
255 StoreAllowSpdy(true);
256 StoreAllowHttp3(true);
257 StoreAllowAltSvc(true);
258 StoreResponseTimeoutEnabled(true);
259 StoreAllRedirectsSameOrigin(true);
260 StoreAllRedirectsPassTimingAllowCheck(true);
261 StoreUpgradableToSecure(true);
262 StoreIsUserAgentHeaderModified(false);
263
264 this->mSelfAddr.inet = {};
265 this->mPeerAddr.inet = {};
266 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)
;
267
268 // Subfields of unions cannot be targeted in an initializer list.
269#ifdef MOZ_VALGRIND
270 // Zero the entire unions so that Valgrind doesn't complain when we send them
271 // to another process.
272 memset(&mSelfAddr, 0, sizeof(NetAddr));
273 memset(&mPeerAddr, 0, sizeof(NetAddr));
274#endif
275 mSelfAddr.raw.family = PR_AF_UNSPEC0;
276 mPeerAddr.raw.family = PR_AF_UNSPEC0;
277}
278
279HttpBaseChannel::~HttpBaseChannel() {
280 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)
;
281
282 // Make sure we don't leak
283 CleanRedirectCacheChainIfNecessary();
284
285 ReleaseMainThreadOnlyReferences();
286}
287
288namespace { // anon
289
290class NonTailRemover : public nsISupports {
291 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:
292
293 explicit NonTailRemover(nsIRequestContext* rc) : mRequestContext(rc) {}
294
295 private:
296 virtual ~NonTailRemover() {
297 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 297); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 297; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
298 mRequestContext->RemoveNonTailRequest();
299 }
300
301 nsCOMPtr<nsIRequestContext> mRequestContext;
302};
303
304NS_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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 304); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
304; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 304); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"NonTailRemover\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 304; __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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 304); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 304
; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 304); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"NonTailRemover\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 304; __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"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 304); 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((sizeof(table) /
sizeof(table[0])) > 1, "need at least 1 interface"); rv =
NS_TableDrivenQI(static_cast<void*>(this), aIID, aInstancePtr
, table); return rv; }
305
306} // namespace
307
308void HttpBaseChannel::ReleaseMainThreadOnlyReferences() {
309 if (NS_IsMainThread()) {
310 // Already on main thread, let dtor to
311 // take care of releasing references
312 RemoveAsNonTailRequest();
313 return;
314 }
315
316 nsTArray<nsCOMPtr<nsISupports>> arrayToRelease;
317 arrayToRelease.AppendElement(mLoadGroup.forget());
318 arrayToRelease.AppendElement(mLoadInfo.forget());
319 arrayToRelease.AppendElement(mCallbacks.forget());
320 arrayToRelease.AppendElement(mProgressSink.forget());
321 arrayToRelease.AppendElement(mPrincipal.forget());
322 arrayToRelease.AppendElement(mListener.forget());
323 arrayToRelease.AppendElement(mCompressListener.forget());
324 arrayToRelease.AppendElement(mORB.forget());
325
326 if (LoadAddedAsNonTailRequest()) {
327 // RemoveNonTailRequest() on our request context must be called on the main
328 // thread
329 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?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 330); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mRequestContext"
") (" "Someone released rc or set flags w/o having it?" ")")
; do { *((volatile int*)__null) = 330; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
330 "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?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 330); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mRequestContext"
") (" "Someone released rc or set flags w/o having it?" ")")
; do { *((volatile int*)__null) = 330; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
331
332 nsCOMPtr<nsISupports> nonTailRemover(new NonTailRemover(mRequestContext));
333 arrayToRelease.AppendElement(nonTailRemover.forget());
334 }
335
336 NS_DispatchToMainThread(new ProxyReleaseRunnable(std::move(arrayToRelease)));
337}
338
339void HttpBaseChannel::AddClassificationFlags(uint32_t aClassificationFlags,
340 bool aIsThirdParty) {
341 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)
342 ("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)
343 "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)
344 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)
;
345
346 if (aIsThirdParty) {
347 mThirdPartyClassificationFlags |= aClassificationFlags;
348 } else {
349 mFirstPartyClassificationFlags |= aClassificationFlags;
350 }
351}
352
353static bool isSecureOrTrustworthyURL(nsIURI* aURI) {
354 return aURI->SchemeIs("https") ||
355 (StaticPrefs::network_http_encoding_trustworthy_is_https() &&
356 nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(aURI));
357}
358
359nsresult HttpBaseChannel::Init(nsIURI* aURI, uint32_t aCaps,
360 nsProxyInfo* aProxyInfo,
361 uint32_t aProxyResolveFlags, nsIURI* aProxyURI,
362 uint64_t aChannelId,
363 ExtContentPolicyType aContentPolicyType,
364 nsILoadInfo* aLoadInfo) {
365 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)
;
366
367 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 367); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aURI" ") (" "null uri"
")"); do { *((volatile int*)__null) = 367; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
368
369 mURI = aURI;
370 mOriginalURI = aURI;
371 mDocumentURI = nullptr;
372 mCaps = aCaps;
373 mProxyResolveFlags = aProxyResolveFlags;
374 mProxyURI = aProxyURI;
375 mChannelId = aChannelId;
376 mLoadInfo = aLoadInfo;
377
378 // Construct connection info object
379 nsAutoCString host;
380 int32_t port = -1;
381 bool isHTTPS = isSecureOrTrustworthyURL(mURI);
382
383 nsresult rv = mURI->GetAsciiHost(host);
384 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
385
386 // Reject the URL if it doesn't specify a host
387 if (host.IsEmpty()) return NS_ERROR_MALFORMED_URI;
388
389 rv = mURI->GetPort(&port);
390 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
391
392 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)
;
393
394 rv = mURI->GetAsciiSpec(mSpec);
395 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
396 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)
;
397
398 // Assert default request method
399 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)",
"/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 399); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get)"
")"); do { *((volatile int*)__null) = 399; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
400
401 // Set request headers
402 nsAutoCString hostLine;
403 rv = nsHttpHandler::GenerateHostPort(host, port, hostLine);
404 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
405
406 rv = mRequestHead.SetHeader(nsHttp::Host, hostLine);
407 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
408
409 rv = gHttpHandler->AddStandardRequestHeaders(
410 &mRequestHead, isHTTPS, aContentPolicyType,
411 nsContentUtils::ShouldResistFingerprinting(this,
412 RFPTarget::HttpUserAgent));
413 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
414
415 nsAutoCString type;
416 if (aProxyInfo && NS_SUCCEEDED(aProxyInfo->GetType(type))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aProxyInfo->GetType
(type))), 1)))
&&
417 !type.EqualsLiteral("unknown")) {
418 mProxyInfo = aProxyInfo;
419 }
420
421 mCurrentThread = GetCurrentSerialEventTarget();
422 return rv;
423}
424
425//-----------------------------------------------------------------------------
426// HttpBaseChannel::nsISupports
427//-----------------------------------------------------------------------------
428
429NS_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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 429); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__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" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 429); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 429; __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; }
430NS_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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 430); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 430
; __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" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 430); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 430; __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
; }
431
432NS_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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 432); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
433 NS_INTERFACE_MAP_ENTRY(nsIRequest)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequest>)) foundInterface = static_cast
<nsIRequest*>(this); else
434 NS_INTERFACE_MAP_ENTRY(nsIChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIChannel>)) foundInterface = static_cast
<nsIChannel*>(this); else
435 NS_INTERFACE_MAP_ENTRY(nsIIdentChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIIdentChannel>)) foundInterface
= static_cast<nsIIdentChannel*>(this); else
436 NS_INTERFACE_MAP_ENTRY(nsIEncodedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIEncodedChannel>)) foundInterface
= static_cast<nsIEncodedChannel*>(this); else
437 NS_INTERFACE_MAP_ENTRY(nsIHttpChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpChannel>)) foundInterface =
static_cast<nsIHttpChannel*>(this); else
438 NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpChannelInternal>)) foundInterface
= static_cast<nsIHttpChannelInternal*>(this); else
439 NS_INTERFACE_MAP_ENTRY(nsIForcePendingChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIForcePendingChannel>)) foundInterface
= static_cast<nsIForcePendingChannel*>(this); else
440 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIUploadChannel>)) foundInterface
= static_cast<nsIUploadChannel*>(this); else
441 NS_INTERFACE_MAP_ENTRY(nsIFormPOSTActionChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIFormPOSTActionChannel>)) foundInterface
= static_cast<nsIFormPOSTActionChannel*>(this); else
442 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIUploadChannel2>)) foundInterface
= static_cast<nsIUploadChannel2*>(this); else
443 NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsPriority>)) foundInterface
= static_cast<nsISupportsPriority*>(this); else
444 NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsITraceableChannel>)) foundInterface
= static_cast<nsITraceableChannel*>(this); else
445 NS_INTERFACE_MAP_ENTRY(nsIPrivateBrowsingChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIPrivateBrowsingChannel>)) foundInterface
= static_cast<nsIPrivateBrowsingChannel*>(this); else
446 NS_INTERFACE_MAP_ENTRY(nsITimedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsITimedChannel>)) foundInterface
= static_cast<nsITimedChannel*>(this); else
447 NS_INTERFACE_MAP_ENTRY(nsIConsoleReportCollector)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIConsoleReportCollector>)) foundInterface
= static_cast<nsIConsoleReportCollector*>(this); else
448 NS_INTERFACE_MAP_ENTRY(nsIThrottledInputChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThrottledInputChannel>)) foundInterface
= static_cast<nsIThrottledInputChannel*>(this); else
449 NS_INTERFACE_MAP_ENTRY(nsIClassifiedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIClassifiedChannel>)) foundInterface
= static_cast<nsIClassifiedChannel*>(this); else
450 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
451NS_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; }
452
453//-----------------------------------------------------------------------------
454// HttpBaseChannel::nsIRequest
455//-----------------------------------------------------------------------------
456
457NS_IMETHODIMPnsresult
458HttpBaseChannel::GetName(nsACString& aName) {
459 aName = mSpec;
460 return NS_OK;
461}
462
463NS_IMETHODIMPnsresult
464HttpBaseChannel::IsPending(bool* aIsPending) {
465 NS_ENSURE_ARG_POINTER(aIsPending)do { if ((__builtin_expect(!!(!(aIsPending)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aIsPending" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 465); return NS_ERROR_INVALID_POINTER; } } while (false)
;
466 *aIsPending = LoadIsPending() || LoadForcePending();
467 return NS_OK;
468}
469
470NS_IMETHODIMPnsresult
471HttpBaseChannel::GetStatus(nsresult* aStatus) {
472 NS_ENSURE_ARG_POINTER(aStatus)do { if ((__builtin_expect(!!(!(aStatus)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aStatus" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 472); return NS_ERROR_INVALID_POINTER; } } while (false)
;
473 *aStatus = mStatus;
474 return NS_OK;
475}
476
477NS_IMETHODIMPnsresult
478HttpBaseChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) {
479 NS_ENSURE_ARG_POINTER(aLoadGroup)do { if ((__builtin_expect(!!(!(aLoadGroup)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aLoadGroup" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 479); return NS_ERROR_INVALID_POINTER; } } while (false)
;
480 *aLoadGroup = do_AddRef(mLoadGroup).take();
481 return NS_OK;
482}
483
484NS_IMETHODIMPnsresult
485HttpBaseChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) {
486 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." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should only be called on the main thread." ")"); do {
*((volatile int*)__null) = 486; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
487
488 if (!CanSetLoadGroup(aLoadGroup)) {
489 return NS_ERROR_FAILURE;
490 }
491
492 mLoadGroup = aLoadGroup;
493 mProgressSink = nullptr;
494 UpdatePrivateBrowsing();
495 return NS_OK;
496}
497
498NS_IMETHODIMPnsresult
499HttpBaseChannel::GetLoadFlags(nsLoadFlags* aLoadFlags) {
500 NS_ENSURE_ARG_POINTER(aLoadFlags)do { if ((__builtin_expect(!!(!(aLoadFlags)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aLoadFlags" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 500); return NS_ERROR_INVALID_POINTER; } } while (false)
;
501 *aLoadFlags = mLoadFlags;
502 return NS_OK;
503}
504
505NS_IMETHODIMPnsresult
506HttpBaseChannel::SetLoadFlags(nsLoadFlags aLoadFlags) {
507 mLoadFlags = aLoadFlags;
508 return NS_OK;
509}
510
511NS_IMETHODIMPnsresult
512HttpBaseChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
513 if (!LoadIsOCSP()) {
514 return GetTRRModeImpl(aTRRMode);
515 }
516
517 nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID"@mozilla.org/network/dns-service;1");
518 nsIDNSService::ResolverMode trrMode = nsIDNSService::MODE_NATIVEONLY;
519 // If this is an OCSP channel, and the global TRR mode is TRR_ONLY (3)
520 // then we set the mode for this channel as TRR_DISABLED_MODE.
521 // We do this to prevent a TRR service channel's OCSP validation from
522 // blocking DNS resolution completely.
523 if (dns && NS_SUCCEEDED(dns->GetCurrentTrrMode(&trrMode))((bool)(__builtin_expect(!!(!NS_FAILED_impl(dns->GetCurrentTrrMode
(&trrMode))), 1)))
&&
524 trrMode == nsIDNSService::MODE_TRRONLY) {
525 *aTRRMode = nsIRequest::TRR_DISABLED_MODE;
526 return NS_OK;
527 }
528
529 return GetTRRModeImpl(aTRRMode);
530}
531
532NS_IMETHODIMPnsresult
533HttpBaseChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
534 return SetTRRModeImpl(aTRRMode);
535}
536
537NS_IMETHODIMPnsresult
538HttpBaseChannel::SetDocshellUserAgentOverride() {
539 RefPtr<dom::BrowsingContext> bc;
540 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 { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 540); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
")"); do { *((volatile int*)__null) = 540; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
541 if (!bc) {
542 return NS_OK;
543 }
544
545 nsAutoString customUserAgent;
546 bc->GetCustomUserAgent(customUserAgent);
547 if (customUserAgent.IsEmpty() || customUserAgent.IsVoid()) {
548 return NS_OK;
549 }
550
551 NS_ConvertUTF16toUTF8 utf8CustomUserAgent(customUserAgent);
552 nsresult rv = SetRequestHeaderInternal(
553 "User-Agent"_ns, utf8CustomUserAgent, false,
554 nsHttpHeaderArray::eVarietyRequestEnforceDefault);
555 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
556 return rv;
557 }
558
559 return NS_OK;
560}
561
562//-----------------------------------------------------------------------------
563// HttpBaseChannel::nsIChannel
564//-----------------------------------------------------------------------------
565
566NS_IMETHODIMPnsresult
567HttpBaseChannel::GetOriginalURI(nsIURI** aOriginalURI) {
568 NS_ENSURE_ARG_POINTER(aOriginalURI)do { if ((__builtin_expect(!!(!(aOriginalURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOriginalURI" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 568); return NS_ERROR_INVALID_POINTER; } } while (false)
;
569 *aOriginalURI = do_AddRef(mOriginalURI).take();
570 return NS_OK;
571}
572
573NS_IMETHODIMPnsresult
574HttpBaseChannel::SetOriginalURI(nsIURI* aOriginalURI) {
575 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 575); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 575, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 575); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 575); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 575; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
576
577 NS_ENSURE_ARG_POINTER(aOriginalURI)do { if ((__builtin_expect(!!(!(aOriginalURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOriginalURI" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 577); return NS_ERROR_INVALID_POINTER; } } while (false)
;
578 mOriginalURI = aOriginalURI;
579 return NS_OK;
580}
581
582NS_IMETHODIMPnsresult
583HttpBaseChannel::GetURI(nsIURI** aURI) {
584 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 584); return NS_ERROR_INVALID_POINTER; } } while (false)
;
585 *aURI = do_AddRef(mURI).take();
586 return NS_OK;
587}
588
589NS_IMETHODIMPnsresult
590HttpBaseChannel::GetOwner(nsISupports** aOwner) {
591 NS_ENSURE_ARG_POINTER(aOwner)do { if ((__builtin_expect(!!(!(aOwner)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOwner" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 591); return NS_ERROR_INVALID_POINTER; } } while (false)
;
592 *aOwner = do_AddRef(mOwner).take();
593 return NS_OK;
594}
595
596NS_IMETHODIMPnsresult
597HttpBaseChannel::SetOwner(nsISupports* aOwner) {
598 mOwner = aOwner;
599 return NS_OK;
600}
601
602NS_IMETHODIMPnsresult
603HttpBaseChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
604 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 604); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aLoadInfo"
") (" "loadinfo can't be null" ")"); do { *((volatile int*)__null
) = 604; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
605 mLoadInfo = aLoadInfo;
606 return NS_OK;
607}
608
609NS_IMETHODIMPnsresult
610HttpBaseChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) {
611 *aLoadInfo = do_AddRef(mLoadInfo).take();
612 return NS_OK;
613}
614
615NS_IMETHODIMPnsresult
616HttpBaseChannel::GetIsDocument(bool* aIsDocument) {
617 return NS_GetIsDocumentChannel(this, aIsDocument);
618}
619
620NS_IMETHODIMPnsresult
621HttpBaseChannel::GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks) {
622 *aCallbacks = do_AddRef(mCallbacks).take();
623 return NS_OK;
624}
625
626NS_IMETHODIMPnsresult
627HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) {
628 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." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 628); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should only be called on the main thread." ")"); do {
*((volatile int*)__null) = 628; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
629
630 if (!CanSetCallbacks(aCallbacks)) {
631 return NS_ERROR_FAILURE;
632 }
633
634 mCallbacks = aCallbacks;
635 mProgressSink = nullptr;
636
637 UpdatePrivateBrowsing();
638 return NS_OK;
639}
640
641NS_IMETHODIMPnsresult
642HttpBaseChannel::GetContentType(nsACString& aContentType) {
643 if (!mResponseHead) {
644 aContentType.Truncate();
645 return NS_ERROR_NOT_AVAILABLE;
646 }
647
648 mResponseHead->ContentType(aContentType);
649 if (!aContentType.IsEmpty()) {
650 return NS_OK;
651 }
652
653 aContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE"application/x-unknown-content-type");
654 return NS_OK;
655}
656
657NS_IMETHODIMPnsresult
658HttpBaseChannel::SetContentType(const nsACString& aContentType) {
659 if (mListener || LoadWasOpened() || mDummyChannelForCachedResource) {
660 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
661
662 nsAutoCString contentTypeBuf, charsetBuf;
663 bool hadCharset;
664 net_ParseContentType(aContentType, contentTypeBuf, charsetBuf, &hadCharset);
665
666 mResponseHead->SetContentType(contentTypeBuf);
667
668 // take care not to stomp on an existing charset
669 if (hadCharset) mResponseHead->SetContentCharset(charsetBuf);
670
671 } else {
672 // We are being given a content-type hint.
673 bool dummy;
674 net_ParseContentType(aContentType, mContentTypeHint, mContentCharsetHint,
675 &dummy);
676 }
677
678 return NS_OK;
679}
680
681NS_IMETHODIMPnsresult
682HttpBaseChannel::GetContentCharset(nsACString& aContentCharset) {
683 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
684
685 mResponseHead->ContentCharset(aContentCharset);
686 return NS_OK;
687}
688
689NS_IMETHODIMPnsresult
690HttpBaseChannel::SetContentCharset(const nsACString& aContentCharset) {
691 if (mListener) {
692 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
693
694 mResponseHead->SetContentCharset(aContentCharset);
695 } else {
696 // Charset hint
697 mContentCharsetHint = aContentCharset;
698 }
699 return NS_OK;
700}
701
702NS_IMETHODIMPnsresult
703HttpBaseChannel::GetContentDisposition(uint32_t* aContentDisposition) {
704 // See bug 1658877. If mContentDispositionHint is already
705 // DISPOSITION_ATTACHMENT, it means this channel is created from a
706 // download attribute. In this case, we should prefer the value from the
707 // download attribute rather than the value in content disposition header.
708 // DISPOSITION_FORCE_INLINE is used to explicitly set inline, used by
709 // the pdf reader when loading a attachment pdf without having to
710 // download it.
711 if (mContentDispositionHint == nsIChannel::DISPOSITION_ATTACHMENT ||
712 mContentDispositionHint == nsIChannel::DISPOSITION_FORCE_INLINE) {
713 *aContentDisposition = mContentDispositionHint;
714 return NS_OK;
715 }
716
717 nsresult rv;
718 nsCString header;
719
720 rv = GetContentDispositionHeader(header);
721 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
722 if (mContentDispositionHint == UINT32_MAX(4294967295U)) return rv;
723
724 *aContentDisposition = mContentDispositionHint;
725 return NS_OK;
726 }
727
728 *aContentDisposition = NS_GetContentDispositionFromHeader(header, this);
729 return NS_OK;
730}
731
732NS_IMETHODIMPnsresult
733HttpBaseChannel::SetContentDisposition(uint32_t aContentDisposition) {
734 mContentDispositionHint = aContentDisposition;
735 return NS_OK;
736}
737
738NS_IMETHODIMPnsresult
739HttpBaseChannel::GetContentDispositionFilename(
740 nsAString& aContentDispositionFilename) {
741 aContentDispositionFilename.Truncate();
742 nsresult rv;
743 nsCString header;
744
745 rv = GetContentDispositionHeader(header);
746 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
747 rv = NS_GetFilenameFromDisposition(aContentDispositionFilename, header);
748 }
749
750 // If we failed to get the filename from header, we should use
751 // mContentDispositionFilename, since mContentDispositionFilename is set from
752 // the download attribute.
753 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
754 if (!mContentDispositionFilename) {
755 return rv;
756 }
757
758 aContentDispositionFilename = *mContentDispositionFilename;
759 return NS_OK;
760 }
761
762 return rv;
763}
764
765NS_IMETHODIMPnsresult
766HttpBaseChannel::SetContentDispositionFilename(
767 const nsAString& aContentDispositionFilename) {
768 mContentDispositionFilename =
769 MakeUnique<nsString>(aContentDispositionFilename);
770
771 // For safety reasons ensure the filename doesn't contain null characters and
772 // replace them with underscores. We may later pass the extension to system
773 // MIME APIs that expect null terminated strings.
774 mContentDispositionFilename->ReplaceChar(char16_t(0), '_');
775
776 return NS_OK;
777}
778
779NS_IMETHODIMPnsresult
780HttpBaseChannel::GetContentDispositionHeader(
781 nsACString& aContentDispositionHeader) {
782 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
783
784 nsresult rv = mResponseHead->GetHeader(nsHttp::Content_Disposition,
785 aContentDispositionHeader);
786 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || aContentDispositionHeader.IsEmpty()) {
787 return NS_ERROR_NOT_AVAILABLE;
788 }
789
790 return NS_OK;
791}
792
793NS_IMETHODIMPnsresult
794HttpBaseChannel::GetContentLength(int64_t* aContentLength) {
795 NS_ENSURE_ARG_POINTER(aContentLength)do { if ((__builtin_expect(!!(!(aContentLength)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aContentLength" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 795); return NS_ERROR_INVALID_POINTER; } } while (false)
;
796
797 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
798
799 if (LoadDeliveringAltData()) {
800 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 800); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mAvailableCachedAltDataType.IsEmpty()"
")"); do { *((volatile int*)__null) = 800; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
801 *aContentLength = mAltDataLength;
802 return NS_OK;
803 }
804
805 *aContentLength = mResponseHead->ContentLength();
806 return NS_OK;
807}
808
809NS_IMETHODIMPnsresult
810HttpBaseChannel::SetContentLength(int64_t value) {
811 if (!mDummyChannelForCachedResource) {
812 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 812); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "HttpBaseChannel::SetContentLength"
")"); do { *((volatile int*)__null) = 812; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
813 return NS_ERROR_NOT_IMPLEMENTED;
814 }
815 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",
"/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 815); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mResponseHead"
")"); do { *((volatile int*)__null) = 815; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
816 mResponseHead->SetContentLength(value);
817 return NS_OK;
818}
819
820NS_IMETHODIMPnsresult
821HttpBaseChannel::Open(nsIInputStream** aStream) {
822 if (!gHttpHandler->Active()) {
823 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)
;
824 return NS_ERROR_NOT_AVAILABLE;
825 }
826
827 nsCOMPtr<nsIStreamListener> listener;
828 nsresult rv =
829 nsContentSecurityManager::doContentSecurityCheck(this, listener);
830 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 830); return rv; } } while (false)
;
831
832 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 832); return NS_ERROR_IN_PROGRESS; } } while (false)
;
833
834 if (!gHttpHandler->Active()) {
835 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)
;
836 return NS_ERROR_NOT_AVAILABLE;
837 }
838
839 return NS_ImplementChannelOpen(this, aStream);
840}
841
842//-----------------------------------------------------------------------------
843// HttpBaseChannel::nsIUploadChannel
844//-----------------------------------------------------------------------------
845
846NS_IMETHODIMPnsresult
847HttpBaseChannel::GetUploadStream(nsIInputStream** stream) {
848 NS_ENSURE_ARG_POINTER(stream)do { if ((__builtin_expect(!!(!(stream)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stream" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 848); return NS_ERROR_INVALID_POINTER; } } while (false)
;
849 *stream = do_AddRef(mUploadStream).take();
850 return NS_OK;
851}
852
853NS_IMETHODIMPnsresult
854HttpBaseChannel::SetUploadStream(nsIInputStream* stream,
855 const nsACString& contentTypeArg,
856 int64_t contentLength) {
857 // NOTE: for backwards compatibility and for compatibility with old style
858 // plugins, |stream| may include headers, specifically Content-Type and
859 // Content-Length headers. in this case, |contentType| and |contentLength|
860 // would be unspecified. this is traditionally the case of a POST request,
861 // and so we select POST as the request method if contentType and
862 // contentLength are unspecified.
863
864 if (stream) {
865 nsAutoCString method;
866 bool hasHeaders = false;
867
868 // This method and ExplicitSetUploadStream mean different things by "empty
869 // content type string". This method means "no header", but
870 // ExplicitSetUploadStream means "header with empty value". So we have to
871 // massage the contentType argument into the form ExplicitSetUploadStream
872 // expects.
873 nsCOMPtr<nsIMIMEInputStream> mimeStream;
874 nsCString contentType(contentTypeArg);
875 if (contentType.IsEmpty()) {
876 contentType.SetIsVoid(true);
877 method = "POST"_ns;
878
879 // MIME streams are a special case, and include headers which need to be
880 // copied to the channel.
881 mimeStream = do_QueryInterface(stream);
882 if (mimeStream) {
883 // Copy non-origin related headers to the channel.
884 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
885 new AddHeadersToChannelVisitor(this);
886 mimeStream->VisitHeaders(visitor);
887
888 return ExplicitSetUploadStream(stream, contentType, contentLength,
889 method, hasHeaders);
890 }
891
892 hasHeaders = true;
893 } else {
894 method = "PUT"_ns;
895
896 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 898); 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 { *((volatile int*)__null) = 898; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
897 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 898); 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 { *((volatile int*)__null) = 898; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
898 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 898); 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 { *((volatile int*)__null) = 898; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
899 }
900 return ExplicitSetUploadStream(stream, contentType, contentLength, method,
901 hasHeaders);
902 }
903
904 // if stream is null, ExplicitSetUploadStream returns error.
905 // So we need special case for GET method.
906 StoreUploadStreamHasHeaders(false);
907 mRequestHead.SetMethod("GET"_ns); // revert to GET request
908 mUploadStream = nullptr;
909 return NS_OK;
910}
911
912namespace {
913
914class MIMEHeaderCopyVisitor final : public nsIHttpHeaderVisitor {
915 public:
916 explicit MIMEHeaderCopyVisitor(nsIMIMEInputStream* aDest) : mDest(aDest) {}
917
918 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:
919 NS_IMETHODvirtual nsresult VisitHeader(const nsACString& aName,
920 const nsACString& aValue) override {
921 return mDest->AddHeader(PromiseFlatCStringTPromiseFlatString<char>(aName).get(),
922 PromiseFlatCStringTPromiseFlatString<char>(aValue).get());
923 }
924
925 private:
926 ~MIMEHeaderCopyVisitor() = default;
927
928 nsCOMPtr<nsIMIMEInputStream> mDest;
929};
930
931NS_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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 931); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
931; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 931); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MIMEHeaderCopyVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 931; __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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 931); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 931
; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 931); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MIMEHeaderCopyVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 931; __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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 931); 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((sizeof(table) /
sizeof(table[0])) > 1, "need at least 1 interface"); rv =
NS_TableDrivenQI(static_cast<void*>(this), aIID, aInstancePtr
, table); return rv; }
932
933static void NormalizeCopyComplete(void* aClosure, nsresult aStatus) {
934#ifdef DEBUG1
935 // Called on the STS thread by NS_AsyncCopy
936 nsCOMPtr<nsIEventTarget> sts =
937 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/stream-transport-service;1");
938 bool result = false;
939 sts->IsOnCurrentThread(&result);
940 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."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 940); AnnotateMozCrashReason("MOZ_ASSERT" "(" "result" ") ("
"Should only be called on the STS thread." ")"); do { *((volatile
int*)__null) = 940; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
941#endif
942
943 RefPtr<GenericPromise::Private> ready =
944 already_AddRefed(static_cast<GenericPromise::Private*>(aClosure));
945 if (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)))) {
946 ready->Resolve(true, __func__);
947 } else {
948 ready->Reject(aStatus, __func__);
949 }
950}
951
952// Normalize the upload stream for a HTTP channel, so that is one of the
953// expected and compatible types. Components like WebExtensions and DevTools
954// expect that upload streams in the parent process are cloneable, seekable, and
955// synchronous to read, which this function helps guarantee somewhat efficiently
956// and without loss of information.
957//
958// If the replacement stream outparameter is not initialized to `nullptr`, the
959// returned stream should be used instead of `aUploadStream` as the upload
960// stream for the HTTP channel, and the previous stream should not be touched
961// again.
962//
963// If aReadyPromise is non-nullptr after the function is called, it is a promise
964// which should be awaited before continuing to `AsyncOpen` the HTTP channel,
965// as the replacement stream will not be ready until it is resolved.
966static nsresult NormalizeUploadStream(nsIInputStream* aUploadStream,
967 nsIInputStream** aReplacementStream,
968 GenericPromise** aReadyPromise) {
969 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 969); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 969; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
970
971 *aReplacementStream = nullptr;
972 *aReadyPromise = nullptr;
973
974 // Unwrap RemoteLazyInputStream and normalize the contents as we're in the
975 // parent process.
976 if (nsCOMPtr<mozIRemoteLazyInputStream> lazyStream =
977 do_QueryInterface(aUploadStream)) {
978 nsCOMPtr<nsIInputStream> internal;
979 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(lazyStream->TakeInternalStream
(getter_AddRefs(internal)))), 1)))
980 lazyStream->TakeInternalStream(getter_AddRefs(internal)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(lazyStream->TakeInternalStream
(getter_AddRefs(internal)))), 1)))
) {
981 nsCOMPtr<nsIInputStream> replacement;
982 nsresult rv = NormalizeUploadStream(internal, getter_AddRefs(replacement),
983 aReadyPromise);
984 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 984); return rv; } } while (false)
;
985
986 if (replacement) {
987 replacement.forget(aReplacementStream);
988 } else {
989 internal.forget(aReplacementStream);
990 }
991 return NS_OK;
992 }
993 }
994
995 // Preserve MIME information on the stream when normalizing.
996 if (nsCOMPtr<nsIMIMEInputStream> mime = do_QueryInterface(aUploadStream)) {
997 nsCOMPtr<nsIInputStream> data;
998 nsresult rv = mime->GetData(getter_AddRefs(data));
999 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 999); return rv; } } while (false)
;
1000
1001 nsCOMPtr<nsIInputStream> replacement;
1002 rv =
1003 NormalizeUploadStream(data, getter_AddRefs(replacement), aReadyPromise);
1004 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1004); return rv; } } while (false)
;
1005
1006 if (replacement) {
1007 nsCOMPtr<nsIMIMEInputStream> replacementMime(
1008 do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv));
1009 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1009); return rv; } } while (false)
;
1010
1011 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
1012 new MIMEHeaderCopyVisitor(replacementMime);
1013 rv = mime->VisitHeaders(visitor);
1014 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1014); return rv; } } while (false)
;
1015
1016 rv = replacementMime->SetData(replacement);
1017 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1017); return rv; } } while (false)
;
1018
1019 replacementMime.forget(aReplacementStream);
1020 }
1021 return NS_OK;
1022 }
1023
1024 // Preserve "real" buffered input streams which wrap data (i.e. are backed by
1025 // nsBufferedInputStream), but normalize the wrapped stream.
1026 if (nsCOMPtr<nsIBufferedInputStream> buffered =
1027 do_QueryInterface(aUploadStream)) {
1028 nsCOMPtr<nsIInputStream> data;
1029 if (NS_SUCCEEDED(buffered->GetData(getter_AddRefs(data)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(buffered->GetData
(getter_AddRefs(data)))), 1)))
) {
1030 nsCOMPtr<nsIInputStream> replacement;
1031 nsresult rv = NormalizeUploadStream(data, getter_AddRefs(replacement),
1032 aReadyPromise);
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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1033); return rv; } } while (false)
;
1034 if (replacement) {
1035 // This buffer size should be kept in sync with HTMLFormSubmission.
1036 rv = NS_NewBufferedInputStream(aReplacementStream, replacement.forget(),
1037 8192);
1038 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1038); return rv; } } while (false)
;
1039 }
1040 return NS_OK;
1041 }
1042 }
1043
1044 // Preserve multiplex input streams, normalizing each individual inner stream
1045 // to avoid unnecessary copying.
1046 if (nsCOMPtr<nsIMultiplexInputStream> multiplex =
1047 do_QueryInterface(aUploadStream)) {
1048 uint32_t count = multiplex->GetCount();
1049 nsTArray<nsCOMPtr<nsIInputStream>> streams(count);
1050 nsTArray<RefPtr<GenericPromise>> promises(count);
1051 bool replace = false;
1052 for (uint32_t i = 0; i < count; ++i) {
1053 nsCOMPtr<nsIInputStream> inner;
1054 nsresult rv = multiplex->GetStream(i, getter_AddRefs(inner));
1055 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1055); return rv; } } while (false)
;
1056
1057 RefPtr<GenericPromise> promise;
1058 nsCOMPtr<nsIInputStream> replacement;
1059 rv = NormalizeUploadStream(inner, getter_AddRefs(replacement),
1060 getter_AddRefs(promise));
1061 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1061); return rv; } } while (false)
;
1062 if (promise) {
1063 promises.AppendElement(promise);
1064 }
1065 if (replacement) {
1066 streams.AppendElement(replacement);
1067 replace = true;
1068 } else {
1069 streams.AppendElement(inner);
1070 }
1071 }
1072
1073 // If any of the inner streams needed to be replaced, replace the entire
1074 // nsIMultiplexInputStream.
1075 if (replace) {
1076 nsresult rv;
1077 nsCOMPtr<nsIMultiplexInputStream> replacement =
1078 do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1", &rv);
1079 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1079); return rv; } } while (false)
;
1080 for (auto& stream : streams) {
1081 rv = replacement->AppendStream(stream);
1082 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1082); return rv; } } while (false)
;
1083 }
1084
1085 MOZ_ALWAYS_SUCCEEDS(CallQueryInterface(replacement, aReplacementStream))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(CallQueryInterface(replacement, aReplacementStream))), 1))))
, 1))) { } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(CallQueryInterface(replacement, aReplacementStream))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1085); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(CallQueryInterface(replacement, aReplacementStream))"
")"); do { *((volatile int*)__null) = 1085; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1086 }
1087
1088 // Wait for all inner promises to settle before resolving the final promise.
1089 if (!promises.IsEmpty()) {
1090 RefPtr<GenericPromise> ready =
1091 GenericPromise::AllSettled(GetCurrentSerialEventTarget(), promises)
1092 ->Then(GetCurrentSerialEventTarget(), __func__,
1093 [](GenericPromise::AllSettledPromiseType::
1094 ResolveOrRejectValue&& aResults)
1095 -> RefPtr<GenericPromise> {
1096 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1097); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aResults.IsResolve()"
") (" "AllSettled never rejects" ")"); do { *((volatile int*
)__null) = 1097; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1097 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1097); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aResults.IsResolve()"
") (" "AllSettled never rejects" ")"); do { *((volatile int*
)__null) = 1097; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1098 for (auto& result : aResults.ResolveValue()) {
1099 if (result.IsReject()) {
1100 return GenericPromise::CreateAndReject(
1101 result.RejectValue(), __func__);
1102 }
1103 }
1104 return GenericPromise::CreateAndResolve(true, __func__);
1105 });
1106 ready.forget(aReadyPromise);
1107 }
1108 return NS_OK;
1109 }
1110
1111 // If the stream is cloneable, seekable and non-async, we can allow it. Async
1112 // input streams can cause issues, as various consumers of input streams
1113 // expect the payload to be synchronous and `Available()` to be the length of
1114 // the stream, which is not true for asynchronous streams.
1115 nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(aUploadStream);
1116 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(aUploadStream);
1117 if (NS_InputStreamIsCloneable(aUploadStream) && seekable && !async) {
1118 return NS_OK;
1119 }
1120
1121 // Asynchronously copy our non-normalized stream into a StorageStream so that
1122 // it is seekable, cloneable, and synchronous once the copy completes.
1123
1124 NS_WARNING("Upload Stream is being copied into StorageStream")NS_DebugBreak(NS_DEBUG_WARNING, "Upload Stream is being copied into StorageStream"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1124)
;
1125
1126 nsCOMPtr<nsIStorageStream> storageStream;
1127 nsresult rv =
1128 NS_NewStorageStream(4096, UINT32_MAX(4294967295U), getter_AddRefs(storageStream));
1129 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1129); return rv; } } while (false)
;
1130
1131 nsCOMPtr<nsIOutputStream> sink;
1132 rv = storageStream->GetOutputStream(0, getter_AddRefs(sink));
1133 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1133); return rv; } } while (false)
;
1134
1135 nsCOMPtr<nsIInputStream> replacementStream;
1136 rv = storageStream->NewInputStream(0, getter_AddRefs(replacementStream));
1137 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1137); return rv; } } while (false)
;
1138
1139 // Ensure the source stream is buffered before starting the copy so we can use
1140 // ReadSegments, as nsStorageStream doesn't implement WriteSegments.
1141 nsCOMPtr<nsIInputStream> source = aUploadStream;
1142 if (!NS_InputStreamIsBuffered(aUploadStream)) {
1143 nsCOMPtr<nsIInputStream> bufferedSource;
1144 rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedSource),
1145 source.forget(), 4096);
1146 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1146); return rv; } } while (false)
;
1147 source = bufferedSource.forget();
1148 }
1149
1150 // Perform an AsyncCopy into the input stream on the STS.
1151 nsCOMPtr<nsIEventTarget> target =
1152 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/stream-transport-service;1");
1153 RefPtr<GenericPromise::Private> ready = new GenericPromise::Private(__func__);
1154 rv = NS_AsyncCopy(source, sink, target, NS_ASYNCCOPY_VIA_READSEGMENTS, 4096,
1155 NormalizeCopyComplete, do_AddRef(ready).take());
1156 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1156)
) {
1157 ready.get()->Release();
1158 return rv;
1159 }
1160
1161 replacementStream.forget(aReplacementStream);
1162 ready.forget(aReadyPromise);
1163 return NS_OK;
1164}
1165
1166} // anonymous namespace
1167
1168NS_IMETHODIMPnsresult
1169HttpBaseChannel::CloneUploadStream(int64_t* aContentLength,
1170 nsIInputStream** aClonedStream) {
1171 NS_ENSURE_ARG_POINTER(aContentLength)do { if ((__builtin_expect(!!(!(aContentLength)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aContentLength" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1171); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1172 NS_ENSURE_ARG_POINTER(aClonedStream)do { if ((__builtin_expect(!!(!(aClonedStream)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aClonedStream" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1172); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1173 *aClonedStream = nullptr;
1174
1175 if (!XRE_IsParentProcess()) {
1176 NS_WARNING("CloneUploadStream is only supported in the parent process")NS_DebugBreak(NS_DEBUG_WARNING, "CloneUploadStream is only supported in the parent process"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1176)
;
1177 return NS_ERROR_NOT_AVAILABLE;
1178 }
1179
1180 if (!mUploadStream) {
1181 return NS_OK;
1182 }
1183
1184 nsCOMPtr<nsIInputStream> clonedStream;
1185 nsresult rv =
1186 NS_CloneInputStream(mUploadStream, getter_AddRefs(clonedStream));
1187 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1187); return rv; } } while (false)
;
1188
1189 clonedStream.forget(aClonedStream);
1190
1191 *aContentLength = mReqContentLength;
1192 return NS_OK;
1193}
1194
1195//-----------------------------------------------------------------------------
1196// HttpBaseChannel::nsIUploadChannel2
1197//-----------------------------------------------------------------------------
1198
1199NS_IMETHODIMPnsresult
1200HttpBaseChannel::ExplicitSetUploadStream(nsIInputStream* aStream,
1201 const nsACString& aContentType,
1202 int64_t aContentLength,
1203 const nsACString& aMethod,
1204 bool aStreamHasHeaders) {
1205 // Ensure stream is set and method is valid
1206 NS_ENSURE_TRUE(aStream, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(aStream)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aStream" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1206); return NS_ERROR_FAILURE; } } while (false)
;
1207
1208 {
1209 DebugOnly<nsCOMPtr<nsIMIMEInputStream>> mimeStream;
1210 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl
(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value
)))), 0))))>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(!aStreamHasHeaders || ((bool)(__builtin_expect
(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs
(mimeStream.value)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
" (" "nsIMIMEInputStream should not include headers" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1213); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
") (" "nsIMIMEInputStream should not include headers" ")"); do
{ *((volatile int*)__null) = 1213; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
1211 !aStreamHasHeaders || NS_FAILED(CallQueryInterface(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl
(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value
)))), 0))))>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(!aStreamHasHeaders || ((bool)(__builtin_expect
(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs
(mimeStream.value)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
" (" "nsIMIMEInputStream should not include headers" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1213); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
") (" "nsIMIMEInputStream should not include headers" ")"); do
{ *((volatile int*)__null) = 1213; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
1212 aStream, getter_AddRefs(mimeStream.value))),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl
(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value
)))), 0))))>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(!aStreamHasHeaders || ((bool)(__builtin_expect
(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs
(mimeStream.value)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
" (" "nsIMIMEInputStream should not include headers" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1213); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
") (" "nsIMIMEInputStream should not include headers" ")"); do
{ *((volatile int*)__null) = 1213; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
1213 "nsIMIMEInputStream should not include headers")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl
(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value
)))), 0))))>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(!aStreamHasHeaders || ((bool)(__builtin_expect
(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs
(mimeStream.value)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
" (" "nsIMIMEInputStream should not include headers" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1213); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
") (" "nsIMIMEInputStream should not include headers" ")"); do
{ *((volatile int*)__null) = 1213; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
1214 }
1215
1216 nsresult rv = SetRequestMethod(aMethod);
1217 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1217); return rv; } } while (false)
;
1218
1219 if (!aStreamHasHeaders && !aContentType.IsVoid()) {
1220 if (aContentType.IsEmpty()) {
1221 SetEmptyRequestHeader("Content-Type"_ns);
1222 } else {
1223 SetRequestHeader("Content-Type"_ns, aContentType, false);
1224 }
1225 }
1226
1227 StoreUploadStreamHasHeaders(aStreamHasHeaders);
1228
1229 return InternalSetUploadStream(aStream, aContentLength, !aStreamHasHeaders);
1230}
1231
1232nsresult HttpBaseChannel::InternalSetUploadStream(
1233 nsIInputStream* aUploadStream, int64_t aContentLength,
1234 bool aSetContentLengthHeader) {
1235 // If we're not on the main thread, such as for TRR, the content length must
1236 // be provided, as we can't normalize our upload stream.
1237 if (!NS_IsMainThread()) {
1238 if (aContentLength < 0) {
1239 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" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1240); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload content length must be explicit off-main-thread"
")"); do { *((volatile int*)__null) = 1240; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1240 "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" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1240); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload content length must be explicit off-main-thread"
")"); do { *((volatile int*)__null) = 1240; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1241 return NS_ERROR_INVALID_ARG;
1242 }
1243
1244 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(aUploadStream);
1245 if (!NS_InputStreamIsCloneable(aUploadStream) || !seekable) {
1246 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1247); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload stream must be cloneable & seekable off-main-thread"
")"); do { *((volatile int*)__null) = 1247; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1247 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1247); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload stream must be cloneable & seekable off-main-thread"
")"); do { *((volatile int*)__null) = 1247; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1248 return NS_ERROR_INVALID_ARG;
1249 }
1250
1251 mUploadStream = aUploadStream;
1252 ExplicitSetUploadStreamLength(aContentLength, aSetContentLengthHeader);
1253 return NS_OK;
1254 }
1255
1256 // Normalize the upload stream we're provided to ensure that it is cloneable,
1257 // seekable, and synchronous when in the parent process.
1258 //
1259 // This might be an async operation, in which case ready will be returned and
1260 // resolved when the operation is complete.
1261 nsCOMPtr<nsIInputStream> replacement;
1262 RefPtr<GenericPromise> ready;
1263 if (XRE_IsParentProcess()) {
1264 nsresult rv = NormalizeUploadStream(
1265 aUploadStream, getter_AddRefs(replacement), getter_AddRefs(ready));
1266 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1266); return rv; } } while (false)
;
1267 }
1268
1269 mUploadStream = replacement ? replacement.get() : aUploadStream;
1270
1271 // Once the upload stream is ready, fetch its length before proceeding with
1272 // AsyncOpen.
1273 auto onReady = [self = RefPtr{this}, aContentLength, aSetContentLengthHeader,
1274 stream = mUploadStream]() {
1275 auto setLengthAndResume = [self, aSetContentLengthHeader](int64_t aLength) {
1276 self->StorePendingUploadStreamNormalization(false);
1277 self->ExplicitSetUploadStreamLength(aLength >= 0 ? aLength : 0,
1278 aSetContentLengthHeader);
1279 self->MaybeResumeAsyncOpen();
1280 };
1281
1282 if (aContentLength >= 0) {
1283 setLengthAndResume(aContentLength);
1284 return;
1285 }
1286
1287 int64_t length;
1288 if (InputStreamLengthHelper::GetSyncLength(stream, &length)) {
1289 setLengthAndResume(length);
1290 return;
1291 }
1292
1293 InputStreamLengthHelper::GetAsyncLength(stream, setLengthAndResume);
1294 };
1295 StorePendingUploadStreamNormalization(true);
1296
1297 // Resolve onReady synchronously unless a promise is returned.
1298 if (ready) {
1299 ready->Then(GetCurrentSerialEventTarget(), __func__,
1300 [onReady = std::move(onReady)](
1301 GenericPromise::ResolveOrRejectValue&&) { onReady(); });
1302 } else {
1303 onReady();
1304 }
1305 return NS_OK;
1306}
1307
1308void HttpBaseChannel::ExplicitSetUploadStreamLength(
1309 uint64_t aContentLength, bool aSetContentLengthHeader) {
1310 // We already have the content length. We don't need to determinate it.
1311 mReqContentLength = aContentLength;
1312
1313 if (!aSetContentLengthHeader) {
1314 return;
1315 }
1316
1317 nsAutoCString header;
1318 header.AssignLiteral("Content-Length");
1319
1320 // Maybe the content-length header has been already set.
1321 nsAutoCString value;
1322 nsresult rv = GetRequestHeader(header, value);
1323 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !value.IsEmpty()) {
1324 return;
1325 }
1326
1327 nsAutoCString contentLengthStr;
1328 contentLengthStr.AppendInt(aContentLength);
1329 SetRequestHeader(header, contentLengthStr, false);
1330}
1331
1332NS_IMETHODIMPnsresult
1333HttpBaseChannel::GetUploadStreamHasHeaders(bool* hasHeaders) {
1334 NS_ENSURE_ARG(hasHeaders)do { if ((__builtin_expect(!!(!(hasHeaders)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "hasHeaders" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1334); return NS_ERROR_INVALID_ARG; } } while (false)
;
1335
1336 *hasHeaders = LoadUploadStreamHasHeaders();
1337 return NS_OK;
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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1342); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__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?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadAsyncOpenWaitingForStreamNormalization()"
") (" "AsyncOpen() called twice?" ")"); do { *((volatile int
*)__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?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadAsyncOpenWaitingForStreamNormalization()"
") (" "AsyncOpen() called twice?" ")"); do { *((volatile int
*)__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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1356); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1357); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadPendingUploadStreamNormalization()"
")"); do { *((volatile int*)__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)", "/var/lib/jenkins/workspace/firefox-scan-build/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 DoApplyContentConversions(aNextListener, aNewNextListener, nullptr);
1395}
1396
1397// create a listener chain that looks like this
1398// http-channel -> decompressor (n times) -> InterceptFailedOnSTop ->
1399// channel-creator-listener
1400//
1401// we need to do this because not every decompressor has fully streamed output
1402// so may need a call to OnStopRequest to identify its completion state.. and if
1403// it creates an error there the channel status code needs to be updated before
1404// calling the terminal listener. Having the decompress do it via cancel() means
1405// channels cannot effectively be used in two contexts (specifically this one
1406// and a peek context for sniffing)
1407//
1408class InterceptFailedOnStop : public nsIThreadRetargetableStreamListener {
1409 virtual ~InterceptFailedOnStop() = default;
1410 nsCOMPtr<nsIStreamListener> mNext;
1411 HttpBaseChannel* mChannel;
1412
1413 public:
1414 InterceptFailedOnStop(nsIStreamListener* arg, HttpBaseChannel* chan)
1415 : mNext(arg), mChannel(chan) {}
1416 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:
1417 NS_DECL_NSITHREADRETARGETABLESTREAMLISTENERvirtual nsresult CheckListenerChain(void) override; virtual nsresult
OnDataFinished(nsresult aStatusCode) override;
1418
1419 NS_IMETHODvirtual nsresult OnStartRequest(nsIRequest* aRequest) override {
1420 return mNext->OnStartRequest(aRequest);
1421 }
1422
1423 NS_IMETHODvirtual nsresult OnStopRequest(nsIRequest* aRequest,
1424 nsresult aStatusCode) override {
1425 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)))
) {
1426 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)
1427 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)
;
1428 mChannel->mStatus = aStatusCode;
1429 }
1430 return mNext->OnStopRequest(aRequest, aStatusCode);
1431 }
1432
1433 NS_IMETHODvirtual nsresult OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
1434 uint64_t aOffset, uint32_t aCount) override {
1435 return mNext->OnDataAvailable(aRequest, aInputStream, aOffset, aCount);
1436 }
1437};
1438
1439NS_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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1439); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1439; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1439); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"InterceptFailedOnStop\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1439; __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; }
1440NS_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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1440); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1440
; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1440); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"InterceptFailedOnStop\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1440; __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; }
1441
1442NS_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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1442); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
1443 NS_INTERFACE_MAP_ENTRY(nsIStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIStreamListener>)) foundInterface
= static_cast<nsIStreamListener*>(this); else
1444 NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequestObserver>)) foundInterface
= static_cast<nsIRequestObserver*>(this); else
1445 NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThreadRetargetableStreamListener>
)) foundInterface = static_cast<nsIThreadRetargetableStreamListener
*>(this); else
1446 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
1447NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::COMTypeInfo<nsISupports
, void>::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::COMTypeInfo
<nsISupports, void>::kIID))))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1447); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
")"); do { *((volatile int*)__null) = 1447; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
1448
1449NS_IMETHODIMPnsresult
1450InterceptFailedOnStop::CheckListenerChain() {
1451 nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
1452 do_QueryInterface(mNext);
1453 if (!listener) {
1454 return NS_ERROR_NO_INTERFACE;
1455 }
1456
1457 return listener->CheckListenerChain();
1458}
1459
1460NS_IMETHODIMPnsresult
1461InterceptFailedOnStop::OnDataFinished(nsresult aStatus) {
1462 nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
1463 do_QueryInterface(mNext);
1464 if (listener) {
1465 return listener->OnDataFinished(aStatus);
1466 }
1467
1468 return NS_OK;
1469}
1470
1471NS_IMETHODIMPnsresult
1472HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
1473 nsIStreamListener** aNewNextListener,
1474 nsISupports* aCtxt) {
1475 *aNewNextListener = nullptr;
1476 if (!mResponseHead || !aNextListener) {
1477 return NS_OK;
1478 }
1479
1480 LOG(("HttpBaseChannel::DoApplyContentConversions [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::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::DoApplyContentConversions [this=%p]\n", this
); } } while (0)
;
1481
1482 if (!LoadApplyConversion()) {
1483 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)
;
1484 return NS_OK;
1485 }
1486
1487 if (LoadHasAppliedConversion()) {
1488 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)
;
1489 return NS_OK;
1490 }
1491
1492 if (LoadDeliveringAltData()) {
1493 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1493); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mAvailableCachedAltDataType.IsEmpty()"
")"); do { *((volatile int*)__null) = 1493; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1494 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)
;
1495 return NS_OK;
1496 }
1497
1498 nsAutoCString contentEncoding;
1499 nsresult rv =
1500 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
1501 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || contentEncoding.IsEmpty()) return NS_OK;
1502
1503 nsCOMPtr<nsIStreamListener> nextListener =
1504 new InterceptFailedOnStop(aNextListener, this);
1505
1506 // The encodings are listed in the order they were applied
1507 // (see rfc 2616 section 14.11), so they need to removed in reverse
1508 // order. This is accomplished because the converter chain ends up
1509 // being a stack with the last converter created being the first one
1510 // to accept the raw network data.
1511
1512 char* cePtr = contentEncoding.BeginWriting();
1513 uint32_t count = 0;
1514 while (char* val = nsCRT::strtok(cePtr, HTTP_LWS" \t" ",", &cePtr)) {
1515 if (++count > 16) {
1516 // That's ridiculous. We only understand 2 different ones :)
1517 // but for compatibility with old code, we will just carry on without
1518 // removing the encodings
1519 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)
;
1520 break;
1521 }
1522
1523 if (gHttpHandler->IsAcceptableEncoding(val,
1524 isSecureOrTrustworthyURL(mURI))) {
1525 RefPtr<nsHTTPCompressConv> converter = new nsHTTPCompressConv();
1526 nsAutoCString from(val);
1527 ToLowerCase(from);
1528 rv = converter->AsyncConvertData(from.get(), "uncompressed", nextListener,
1529 aCtxt);
1530 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1531 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)
;
1532 return rv;
1533 }
1534
1535 LOG(("converter removed '%s' content-encoding\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
, "converter removed '%s' content-encoding\n", val); } } while
(0)
;
1536 if (Telemetry::CanRecordPrereleaseData()) {
1537 int mode = 0;
1538 if (from.EqualsLiteral("gzip") || from.EqualsLiteral("x-gzip")) {
1539 mode = 1;
1540 } else if (from.EqualsLiteral("deflate") ||
1541 from.EqualsLiteral("x-deflate")) {
1542 mode = 2;
1543 } else if (from.EqualsLiteral("br")) {
1544 mode = 3;
1545 } else if (from.EqualsLiteral("zstd")) {
1546 mode = 4;
1547 }
1548 Telemetry::Accumulate(Telemetry::HTTP_CONTENT_ENCODING, mode);
1549 }
1550 nextListener = converter;
1551 } else {
1552 if (val) LOG(("Unknown content encoding '%s', ignoring\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', ignoring\n", val); } } while
(0)
;
1553 }
1554 }
1555 *aNewNextListener = do_AddRef(nextListener).take();
1556 return NS_OK;
1557}
1558
1559NS_IMETHODIMPnsresult
1560HttpBaseChannel::GetContentEncodings(nsIUTF8StringEnumerator** aEncodings) {
1561 if (!mResponseHead) {
1562 *aEncodings = nullptr;
1563 return NS_OK;
1564 }
1565
1566 nsAutoCString encoding;
1567 Unused << mResponseHead->GetHeader(nsHttp::Content_Encoding, encoding);
1568 if (encoding.IsEmpty()) {
1569 *aEncodings = nullptr;
1570 return NS_OK;
1571 }
1572 RefPtr<nsContentEncodings> enumerator =
1573 new nsContentEncodings(this, encoding.get());
1574 enumerator.forget(aEncodings);
1575 return NS_OK;
1576}
1577
1578//-----------------------------------------------------------------------------
1579// HttpBaseChannel::nsContentEncodings <public>
1580//-----------------------------------------------------------------------------
1581
1582HttpBaseChannel::nsContentEncodings::nsContentEncodings(
1583 nsIHttpChannel* aChannel, const char* aEncodingHeader)
1584 : mEncodingHeader(aEncodingHeader), mChannel(aChannel), mReady(false) {
1585 mCurEnd = aEncodingHeader + strlen(aEncodingHeader);
1586 mCurStart = mCurEnd;
1587}
1588
1589//-----------------------------------------------------------------------------
1590// HttpBaseChannel::nsContentEncodings::nsISimpleEnumerator
1591//-----------------------------------------------------------------------------
1592
1593NS_IMETHODIMPnsresult
1594HttpBaseChannel::nsContentEncodings::HasMore(bool* aMoreEncodings) {
1595 if (mReady) {
1596 *aMoreEncodings = true;
1597 return NS_OK;
1598 }
1599
1600 nsresult rv = PrepareForNext();
1601 *aMoreEncodings = NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)));
1602 return NS_OK;
1603}
1604
1605NS_IMETHODIMPnsresult
1606HttpBaseChannel::nsContentEncodings::GetNext(nsACString& aNextEncoding) {
1607 aNextEncoding.Truncate();
1608 if (!mReady) {
1609 nsresult rv = PrepareForNext();
1610 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1611 return NS_ERROR_FAILURE;
1612 }
1613 }
1614
1615 const nsACString& encoding = Substring(mCurStart, mCurEnd);
1616
1617 nsACString::const_iterator start, end;
1618 encoding.BeginReading(start);
1619 encoding.EndReading(end);
1620
1621 bool haveType = false;
1622 if (CaseInsensitiveFindInReadable("gzip"_ns, start, end)) {
1623 aNextEncoding.AssignLiteral(APPLICATION_GZIP"application/x-gzip");
1624 haveType = true;
1625 }
1626
1627 if (!haveType) {
1628 encoding.BeginReading(start);
1629 if (CaseInsensitiveFindInReadable("compress"_ns, start, end)) {
1630 aNextEncoding.AssignLiteral(APPLICATION_COMPRESS"application/x-compress");
1631 haveType = true;
1632 }
1633 }
1634
1635 if (!haveType) {
1636 encoding.BeginReading(start);
1637 if (CaseInsensitiveFindInReadable("deflate"_ns, start, end)) {
1638 aNextEncoding.AssignLiteral(APPLICATION_ZIP"application/zip");
1639 haveType = true;
1640 }
1641 }
1642
1643 if (!haveType) {
1644 encoding.BeginReading(start);
1645 if (CaseInsensitiveFindInReadable("br"_ns, start, end)) {
1646 aNextEncoding.AssignLiteral(APPLICATION_BROTLI"application/brotli");
1647 haveType = true;
1648 }
1649 }
1650
1651 if (!haveType) {
1652 encoding.BeginReading(start);
1653 if (CaseInsensitiveFindInReadable("zstd"_ns, start, end)) {
1654 aNextEncoding.AssignLiteral(APPLICATION_ZSTD"application/zstd");
1655 haveType = true;
1656 }
1657 }
1658
1659 // Prepare to fetch the next encoding
1660 mCurEnd = mCurStart;
1661 mReady = false;
1662
1663 if (haveType) return NS_OK;
1664
1665 NS_WARNING("Unknown encoding type")NS_DebugBreak(NS_DEBUG_WARNING, "Unknown encoding type", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1665)
;
1666 return NS_ERROR_FAILURE;
1667}
1668
1669//-----------------------------------------------------------------------------
1670// HttpBaseChannel::nsContentEncodings::nsISupports
1671//-----------------------------------------------------------------------------
1672
1673NS_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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1674; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1674; __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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1674
; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1674; __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"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1674); 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((sizeof(table) / sizeof(table
[0])) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
1674 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1674; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1674; __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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1674
; __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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1674; __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"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1674); 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((sizeof(table) / sizeof(table
[0])) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
1675
1676//-----------------------------------------------------------------------------
1677// HttpBaseChannel::nsContentEncodings <private>
1678//-----------------------------------------------------------------------------
1679
1680nsresult HttpBaseChannel::nsContentEncodings::PrepareForNext(void) {
1681 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1681); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurStart == mCurEnd"
") (" "Indeterminate state" ")"); do { *((volatile int*)__null
) = 1681; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
1682
1683 // At this point both mCurStart and mCurEnd point to somewhere
1684 // past the end of the next thing we want to return
1685
1686 while (mCurEnd != mEncodingHeader) {
1687 --mCurEnd;
1688 if (*mCurEnd != ',' && !nsCRT::IsAsciiSpace(*mCurEnd)) break;
1689 }
1690 if (mCurEnd == mEncodingHeader) {
1691 return NS_ERROR_NOT_AVAILABLE; // no more encodings
1692 }
1693 ++mCurEnd;
1694
1695 // At this point mCurEnd points to the first char _after_ the
1696 // header we want. Furthermore, mCurEnd - 1 != mEncodingHeader
1697
1698 mCurStart = mCurEnd - 1;
1699 while (mCurStart != mEncodingHeader && *mCurStart != ',' &&
1700 !nsCRT::IsAsciiSpace(*mCurStart)) {
1701 --mCurStart;
1702 }
1703 if (*mCurStart == ',' || nsCRT::IsAsciiSpace(*mCurStart)) {
1704 ++mCurStart; // we stopped because of a weird char, so move up one
1705 }
1706
1707 // At this point mCurStart and mCurEnd bracket the encoding string
1708 // we want. Check that it's not "identity"
1709 if (Substring(mCurStart, mCurEnd)
1710 .Equals("identity", nsCaseInsensitiveCStringComparator)) {
1711 mCurEnd = mCurStart;
1712 return PrepareForNext();
1713 }
1714
1715 mReady = true;
1716 return NS_OK;
1717}
1718
1719//-----------------------------------------------------------------------------
1720// HttpBaseChannel::nsIHttpChannel
1721//-----------------------------------------------------------------------------
1722
1723NS_IMETHODIMPnsresult
1724HttpBaseChannel::GetChannelId(uint64_t* aChannelId) {
1725 NS_ENSURE_ARG_POINTER(aChannelId)do { if ((__builtin_expect(!!(!(aChannelId)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aChannelId" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1725); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1726 *aChannelId = mChannelId;
1727 return NS_OK;
1728}
1729
1730NS_IMETHODIMPnsresult
1731HttpBaseChannel::SetChannelId(uint64_t aChannelId) {
1732 mChannelId = aChannelId;
1733 return NS_OK;
1734}
1735
1736NS_IMETHODIMPnsresult HttpBaseChannel::GetTopLevelContentWindowId(uint64_t* aWindowId) {
1737 if (!mContentWindowId) {
1738 nsCOMPtr<nsILoadContext> loadContext;
1739 GetCallback(loadContext);
1740 if (loadContext) {
1741 nsCOMPtr<mozIDOMWindowProxy> topWindow;
1742 loadContext->GetTopWindow(getter_AddRefs(topWindow));
1743 if (topWindow) {
1744 if (nsPIDOMWindowInner* inner =
1745 nsPIDOMWindowOuter::From(topWindow)->GetCurrentInnerWindow()) {
1746 mContentWindowId = inner->WindowID();
1747 }
1748 }
1749 }
1750 }
1751 *aWindowId = mContentWindowId;
1752 return NS_OK;
1753}
1754
1755NS_IMETHODIMPnsresult HttpBaseChannel::SetBrowserId(uint64_t aId) {
1756 mBrowserId = aId;
1757 return NS_OK;
1758}
1759
1760NS_IMETHODIMPnsresult HttpBaseChannel::GetBrowserId(uint64_t* aId) {
1761 EnsureBrowserId();
1762 *aId = mBrowserId;
1763 return NS_OK;
1764}
1765
1766NS_IMETHODIMPnsresult HttpBaseChannel::SetTopLevelContentWindowId(uint64_t aWindowId) {
1767 mContentWindowId = aWindowId;
1768 return NS_OK;
1769}
1770
1771NS_IMETHODIMPnsresult
1772HttpBaseChannel::IsThirdPartyTrackingResource(bool* aIsTrackingResource) {
1773 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1774); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags)"
")"); do { *((volatile int*)__null) = 1774; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1774 !(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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1774); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags)"
")"); do { *((volatile int*)__null) = 1774; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1775 *aIsTrackingResource = UrlClassifierCommon::IsTrackingClassificationFlag(
1776 mThirdPartyClassificationFlags,
1777 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing());
1778 return NS_OK;
1779}
1780
1781NS_IMETHODIMPnsresult
1782HttpBaseChannel::IsThirdPartySocialTrackingResource(
1783 bool* aIsThirdPartySocialTrackingResource) {
1784 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1785); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { *((volatile int*)__null) = 1785; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1785 !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"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1785); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { *((volatile int*)__null) = 1785; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1786 *aIsThirdPartySocialTrackingResource =
1787 UrlClassifierCommon::IsSocialTrackingClassificationFlag(
1788 mThirdPartyClassificationFlags);
1789 return NS_OK;
1790}
1791
1792NS_IMETHODIMPnsresult
1793HttpBaseChannel::GetClassificationFlags(uint32_t* aFlags) {
1794 if (mThirdPartyClassificationFlags) {
1795 *aFlags = mThirdPartyClassificationFlags;
1796 } else {
1797 *aFlags = mFirstPartyClassificationFlags;
1798 }
1799 return NS_OK;
1800}
1801
1802NS_IMETHODIMPnsresult
1803HttpBaseChannel::GetFirstPartyClassificationFlags(uint32_t* aFlags) {
1804 *aFlags = mFirstPartyClassificationFlags;
1805 return NS_OK;
1806}
1807
1808NS_IMETHODIMPnsresult
1809HttpBaseChannel::GetThirdPartyClassificationFlags(uint32_t* aFlags) {
1810 *aFlags = mThirdPartyClassificationFlags;
1811 return NS_OK;
1812}
1813
1814NS_IMETHODIMPnsresult
1815HttpBaseChannel::GetTransferSize(uint64_t* aTransferSize) {
1816 MutexAutoLock lock(mOnDataFinishedMutex);
1817 *aTransferSize = mTransferSize;
1818 return NS_OK;
1819}
1820
1821NS_IMETHODIMPnsresult
1822HttpBaseChannel::GetRequestSize(uint64_t* aRequestSize) {
1823 *aRequestSize = mRequestSize;
1824 return NS_OK;
1825}
1826
1827NS_IMETHODIMPnsresult
1828HttpBaseChannel::GetDecodedBodySize(uint64_t* aDecodedBodySize) {
1829 *aDecodedBodySize = mDecodedBodySize;
1830 return NS_OK;
1831}
1832
1833NS_IMETHODIMPnsresult
1834HttpBaseChannel::GetEncodedBodySize(uint64_t* aEncodedBodySize) {
1835 MutexAutoLock lock(mOnDataFinishedMutex);
1836 *aEncodedBodySize = mEncodedBodySize;
1837 return NS_OK;
1838}
1839
1840NS_IMETHODIMPnsresult
1841HttpBaseChannel::GetSupportsHTTP3(bool* aSupportsHTTP3) {
1842 *aSupportsHTTP3 = mSupportsHTTP3;
1843 return NS_OK;
1844}
1845
1846NS_IMETHODIMPnsresult
1847HttpBaseChannel::GetHasHTTPSRR(bool* aHasHTTPSRR) {
1848 *aHasHTTPSRR = LoadHasHTTPSRR();
1849 return NS_OK;
1850}
1851
1852NS_IMETHODIMPnsresult
1853HttpBaseChannel::GetRequestMethod(nsACString& aMethod) {
1854 mRequestHead.Method(aMethod);
1855 return NS_OK;
1856}
1857
1858NS_IMETHODIMPnsresult
1859HttpBaseChannel::SetRequestMethod(const nsACString& aMethod) {
1860 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1860); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1860, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1860); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1860); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 1860; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
1861
1862 const nsCString& flatMethod = PromiseFlatCStringTPromiseFlatString<char>(aMethod);
1863
1864 // Method names are restricted to valid HTTP tokens.
1865 if (!nsHttp::IsValidToken(flatMethod)) return NS_ERROR_INVALID_ARG;
1866
1867 mRequestHead.SetMethod(flatMethod);
1868 return NS_OK;
1869}
1870
1871NS_IMETHODIMPnsresult
1872HttpBaseChannel::GetReferrerInfo(nsIReferrerInfo** aReferrerInfo) {
1873 NS_ENSURE_ARG_POINTER(aReferrerInfo)do { if ((__builtin_expect(!!(!(aReferrerInfo)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aReferrerInfo" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1873); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1874 *aReferrerInfo = do_AddRef(mReferrerInfo).take();
1875 return NS_OK;
1876}
1877
1878nsresult HttpBaseChannel::SetReferrerInfoInternal(
1879 nsIReferrerInfo* aReferrerInfo, bool aClone, bool aCompute,
1880 bool aRespectBeforeConnect) {
1881 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)
1882 ("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)
1883 "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)
1884 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)
;
1885 if (aRespectBeforeConnect) {
1886 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1886); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1886, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1886); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1886); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 1886; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
1887 }
1888
1889 mReferrerInfo = aReferrerInfo;
1890
1891 // clear existing referrer, if any
1892 nsresult rv = ClearReferrerHeader();
1893 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1893)
) {
1894 return rv;
1895 }
1896
1897 if (!mReferrerInfo) {
1898 return NS_OK;
1899 }
1900
1901 if (aClone) {
1902 mReferrerInfo = static_cast<dom::ReferrerInfo*>(aReferrerInfo)->Clone();
1903 }
1904
1905 dom::ReferrerInfo* referrerInfo =
1906 static_cast<dom::ReferrerInfo*>(mReferrerInfo.get());
1907
1908 // Don't set referrerInfo if it has not been initialized.
1909 if (!referrerInfo->IsInitialized()) {
1910 mReferrerInfo = nullptr;
1911 return NS_ERROR_NOT_INITIALIZED;
1912 }
1913
1914 if (aClone) {
1915 // Record the telemetry once we set the referrer info to the channel
1916 // successfully.
1917 referrerInfo->RecordTelemetry(this);
1918 }
1919
1920 if (aCompute) {
1921 rv = referrerInfo->ComputeReferrer(this);
1922 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1922)
) {
1923 return rv;
1924 }
1925 }
1926
1927 nsCOMPtr<nsIURI> computedReferrer = mReferrerInfo->GetComputedReferrer();
1928 if (!computedReferrer) {
1929 return NS_OK;
1930 }
1931
1932 nsAutoCString spec;
1933 rv = computedReferrer->GetSpec(spec);
1934 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1934)
) {
1935 return rv;
1936 }
1937
1938 return SetReferrerHeader(spec, aRespectBeforeConnect);
1939}
1940
1941NS_IMETHODIMPnsresult
1942HttpBaseChannel::SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
1943 return SetReferrerInfoInternal(aReferrerInfo, true, true, true);
1944}
1945
1946NS_IMETHODIMPnsresult
1947HttpBaseChannel::SetReferrerInfoWithoutClone(nsIReferrerInfo* aReferrerInfo) {
1948 return SetReferrerInfoInternal(aReferrerInfo, false, true, true);
1949}
1950
1951// Return the channel's proxy URI, or if it doesn't exist, the
1952// channel's main URI.
1953NS_IMETHODIMPnsresult
1954HttpBaseChannel::GetProxyURI(nsIURI** aOut) {
1955 NS_ENSURE_ARG_POINTER(aOut)do { if ((__builtin_expect(!!(!(aOut)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOut" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1955); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1956 nsCOMPtr<nsIURI> result(mProxyURI);
1957 result.forget(aOut);
1958 return NS_OK;
1959}
1960
1961NS_IMETHODIMPnsresult
1962HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
1963 nsACString& aValue) {
1964 aValue.Truncate();
1965
1966 // XXX might be better to search the header list directly instead of
1967 // hitting the http atom hash table.
1968 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
1969 if (!atom) return NS_ERROR_NOT_AVAILABLE;
1970
1971 return mRequestHead.GetHeader(atom, aValue);
1972}
1973
1974NS_IMETHODIMPnsresult
1975HttpBaseChannel::SetRequestHeader(const nsACString& aHeader,
1976 const nsACString& aValue, bool aMerge) {
1977 return SetRequestHeaderInternal(aHeader, aValue, aMerge,
1978 nsHttpHeaderArray::eVarietyRequestOverride);
1979}
1980
1981nsresult HttpBaseChannel::SetRequestHeaderInternal(
1982 const nsACString& aHeader, const nsACString& aValue, bool aMerge,
1983 nsHttpHeaderArray::HeaderVariety aVariety) {
1984 const nsCString& flatHeader = PromiseFlatCStringTPromiseFlatString<char>(aHeader);
1985 const nsCString& flatValue = PromiseFlatCStringTPromiseFlatString<char>(aValue);
1986
1987 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)
1988 ("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)
1989 "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)
1990 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)
;
1991
1992 // Verify header names are valid HTTP tokens and header values are reasonably
1993 // close to whats allowed in RFC 2616.
1994 if (!nsHttp::IsValidToken(flatHeader) ||
1995 !nsHttp::IsReasonableHeaderValue(flatValue)) {
1996 return NS_ERROR_INVALID_ARG;
1997 }
1998
1999 // Mark that the User-Agent header has been modified.
2000 if (nsHttp::ResolveAtom(aHeader) == nsHttp::User_Agent) {
2001 StoreIsUserAgentHeaderModified(true);
2002 }
2003
2004 return mRequestHead.SetHeader(aHeader, flatValue, aMerge);
2005}
2006
2007NS_IMETHODIMPnsresult
2008HttpBaseChannel::SetNewReferrerInfo(const nsACString& aUrl,
2009 nsIReferrerInfo::ReferrerPolicyIDL aPolicy,
2010 bool aSendReferrer) {
2011 nsresult rv;
2012 // Create URI from string
2013 nsCOMPtr<nsIURI> aURI;
2014 rv = NS_NewURI(getter_AddRefs(aURI), aUrl);
2015 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2015); return rv; } } while (false)
;
2016 // Create new ReferrerInfo and initialize it.
2017 nsCOMPtr<nsIReferrerInfo> referrerInfo = new mozilla::dom::ReferrerInfo();
2018 rv = referrerInfo->Init(aPolicy, aSendReferrer, aURI);
2019 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2019); return rv; } } while (false)
;
2020 // Set ReferrerInfo
2021 return SetReferrerInfo(referrerInfo);
2022}
2023
2024NS_IMETHODIMPnsresult
2025HttpBaseChannel::SetEmptyRequestHeader(const nsACString& aHeader) {
2026 const nsCString& flatHeader = PromiseFlatCStringTPromiseFlatString<char>(aHeader);
2027
2028 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)
2029 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)
;
2030
2031 // Verify header names are valid HTTP tokens and header values are reasonably
2032 // close to whats allowed in RFC 2616.
2033 if (!nsHttp::IsValidToken(flatHeader)) {
2034 return NS_ERROR_INVALID_ARG;
2035 }
2036
2037 // Mark that the User-Agent header has been modified.
2038 if (nsHttp::ResolveAtom(aHeader) == nsHttp::User_Agent) {
2039 StoreIsUserAgentHeaderModified(true);
2040 }
2041
2042 return mRequestHead.SetEmptyHeader(aHeader);
2043}
2044
2045NS_IMETHODIMPnsresult
2046HttpBaseChannel::VisitRequestHeaders(nsIHttpHeaderVisitor* visitor) {
2047 return mRequestHead.VisitHeaders(visitor);
2048}
2049
2050NS_IMETHODIMPnsresult
2051HttpBaseChannel::VisitNonDefaultRequestHeaders(nsIHttpHeaderVisitor* visitor) {
2052 return mRequestHead.VisitHeaders(visitor,
2053 nsHttpHeaderArray::eFilterSkipDefault);
2054}
2055
2056NS_IMETHODIMPnsresult
2057HttpBaseChannel::GetResponseHeader(const nsACString& header,
2058 nsACString& value) {
2059 value.Truncate();
2060
2061 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2062
2063 nsHttpAtom atom = nsHttp::ResolveAtom(header);
2064 if (!atom) return NS_ERROR_NOT_AVAILABLE;
2065
2066 return mResponseHead->GetHeader(atom, value);
2067}
2068
2069NS_IMETHODIMPnsresult
2070HttpBaseChannel::SetResponseHeader(const nsACString& header,
2071 const nsACString& value, bool merge) {
2072 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)
2073 ("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)
2074 "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)
2075 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)
2076 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)
;
2077
2078 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2079
2080 nsHttpAtom atom = nsHttp::ResolveAtom(header);
2081 if (!atom) return NS_ERROR_NOT_AVAILABLE;
2082
2083 // these response headers must not be changed
2084 if (atom == nsHttp::Content_Type || atom == nsHttp::Content_Length ||
2085 atom == nsHttp::Content_Encoding || atom == nsHttp::Trailer ||
2086 atom == nsHttp::Transfer_Encoding) {
2087 return NS_ERROR_ILLEGAL_VALUE;
2088 }
2089
2090 StoreResponseHeadersModified(true);
2091
2092 return mResponseHead->SetHeader(header, value, merge);
2093}
2094
2095NS_IMETHODIMPnsresult
2096HttpBaseChannel::VisitResponseHeaders(nsIHttpHeaderVisitor* visitor) {
2097 if (!mResponseHead) {
2098 return NS_ERROR_NOT_AVAILABLE;
2099 }
2100 return mResponseHead->VisitHeaders(visitor,
2101 nsHttpHeaderArray::eFilterResponse);
2102}
2103
2104NS_IMETHODIMPnsresult
2105HttpBaseChannel::GetOriginalResponseHeader(const nsACString& aHeader,
2106 nsIHttpHeaderVisitor* aVisitor) {
2107 if (!mResponseHead) {
2108 return NS_ERROR_NOT_AVAILABLE;
2109 }
2110
2111 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
2112 if (!atom) {
2113 return NS_ERROR_NOT_AVAILABLE;
2114 }
2115
2116 return mResponseHead->GetOriginalHeader(atom, aVisitor);
2117}
2118
2119NS_IMETHODIMPnsresult
2120HttpBaseChannel::VisitOriginalResponseHeaders(nsIHttpHeaderVisitor* aVisitor) {
2121 if (!mResponseHead) {
2122 return NS_ERROR_NOT_AVAILABLE;
2123 }
2124
2125 return mResponseHead->VisitHeaders(
2126 aVisitor, nsHttpHeaderArray::eFilterResponseOriginal);
2127}
2128
2129NS_IMETHODIMPnsresult
2130HttpBaseChannel::GetAllowSTS(bool* value) {
2131 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2131); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2132 *value = LoadAllowSTS();
2133 return NS_OK;
2134}
2135
2136NS_IMETHODIMPnsresult
2137HttpBaseChannel::SetAllowSTS(bool value) {
2138 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2138); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2138, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2138); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2138); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2138; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2139 StoreAllowSTS(value);
2140 return NS_OK;
2141}
2142
2143NS_IMETHODIMPnsresult
2144HttpBaseChannel::GetIsOCSP(bool* value) {
2145 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2145); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2146 *value = LoadIsOCSP();
2147 return NS_OK;
2148}
2149
2150NS_IMETHODIMPnsresult
2151HttpBaseChannel::SetIsOCSP(bool value) {
2152 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2152); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2152, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2152); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2152); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2152; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2153 StoreIsOCSP(value);
2154 return NS_OK;
2155}
2156
2157NS_IMETHODIMPnsresult
2158HttpBaseChannel::GetIsUserAgentHeaderModified(bool* value) {
2159 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2159); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2160 *value = LoadIsUserAgentHeaderModified();
2161 return NS_OK;
2162}
2163
2164NS_IMETHODIMPnsresult
2165HttpBaseChannel::SetIsUserAgentHeaderModified(bool value) {
2166 StoreIsUserAgentHeaderModified(value);
2167 return NS_OK;
2168}
2169
2170NS_IMETHODIMPnsresult
2171HttpBaseChannel::GetRedirectionLimit(uint32_t* value) {
2172 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2172); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2173 *value = mRedirectionLimit;
2174 return NS_OK;
2175}
2176
2177NS_IMETHODIMPnsresult
2178HttpBaseChannel::SetRedirectionLimit(uint32_t value) {
2179 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2179); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2179, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2179); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2179; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2180
2181 mRedirectionLimit = std::min<uint32_t>(value, 0xff);
2182 return NS_OK;
2183}
2184
2185nsresult HttpBaseChannel::OverrideSecurityInfo(
2186 nsITransportSecurityInfo* aSecurityInfo) {
2187 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2189); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { *((volatile int*)__null) = 2189;
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
2188 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2189); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { *((volatile int*)__null) = 2189;
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
2189 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2189); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { *((volatile int*)__null) = 2189;
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
2190 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" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2192); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { *((volatile int*)__null) = 2192; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2191 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" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2192); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { *((volatile int*)__null) = 2192; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2192 "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" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2192); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { *((volatile int*)__null) = 2192; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2193 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2195); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { *((volatile int*)__null) = 2195; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2194 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2195); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { *((volatile int*)__null) = 2195; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2195 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2195); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { *((volatile int*)__null) = 2195; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
2196 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2197); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadResponseCouldBeSynthesized()"
") (" "This can only be called on channels that can be intercepted"
")"); do { *((volatile int*)__null) = 2197; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2197 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2197); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadResponseCouldBeSynthesized()"
") (" "This can only be called on channels that can be intercepted"
")"); do { *((volatile int*)__null) = 2197; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2198 if (mSecurityInfo) {
2199 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)
2200 ("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)
2201 "[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)
2202 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)
;
2203 return NS_ERROR_UNEXPECTED;
2204 }
2205 if (!LoadResponseCouldBeSynthesized()) {
2206 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)
2207 ("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)
2208 "[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)
2209 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)
;
2210 return NS_ERROR_UNEXPECTED;
2211 }
2212
2213 mSecurityInfo = aSecurityInfo;
2214 return NS_OK;
2215}
2216
2217NS_IMETHODIMPnsresult
2218HttpBaseChannel::IsNoStoreResponse(bool* value) {
2219 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2220 *value = mResponseHead->NoStore();
2221 return NS_OK;
2222}
2223
2224NS_IMETHODIMPnsresult
2225HttpBaseChannel::IsNoCacheResponse(bool* value) {
2226 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2227 *value = mResponseHead->NoCache();
2228 if (!*value) *value = mResponseHead->ExpiresInPast();
2229 return NS_OK;
2230}
2231
2232NS_IMETHODIMPnsresult
2233HttpBaseChannel::IsPrivateResponse(bool* value) {
2234 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2235 *value = mResponseHead->Private();
2236 return NS_OK;
2237}
2238
2239NS_IMETHODIMPnsresult
2240HttpBaseChannel::GetResponseStatus(uint32_t* aValue) {
2241 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2242 *aValue = mResponseHead->Status();
2243 return NS_OK;
2244}
2245
2246NS_IMETHODIMPnsresult
2247HttpBaseChannel::GetResponseStatusText(nsACString& aValue) {
2248 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2249 nsAutoCString version;
2250 // https://fetch.spec.whatwg.org :
2251 // Responses over an HTTP/2 connection will always have the empty byte
2252 // sequence as status message as HTTP/2 does not support them.
2253 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))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2253)
||
2254 !version.EqualsLiteral("h2")) {
2255 mResponseHead->StatusText(aValue);
2256 }
2257 return NS_OK;
2258}
2259
2260NS_IMETHODIMPnsresult
2261HttpBaseChannel::GetRequestSucceeded(bool* aValue) {
2262 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2263 uint32_t status = mResponseHead->Status();
2264 *aValue = (status / 100 == 2);
2265 return NS_OK;
2266}
2267
2268NS_IMETHODIMPnsresult
2269HttpBaseChannel::RedirectTo(nsIURI* targetURI) {
2270 NS_ENSURE_ARG(targetURI)do { if ((__builtin_expect(!!(!(targetURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "targetURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2270); return NS_ERROR_INVALID_ARG; } } while (false)
;
2271
2272 nsAutoCString spec;
2273 targetURI->GetAsciiSpec(spec);
2274 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)
;
2275 LogCallingScriptLocation(this);
2276
2277 // We cannot redirect after OnStartRequest of the listener
2278 // has been called, since to redirect we have to switch channels
2279 // and the dance with OnStartRequest et al has to start over.
2280 // This would break the nsIStreamListener contract.
2281 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2281); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2282
2283 mAPIRedirectToURI = targetURI;
2284 // Only Web Extensions are allowed to redirect a channel to a data:
2285 // URI. To avoid any bypasses after the channel was flagged by
2286 // the WebRequst API, we are dropping the flag here.
2287 mLoadInfo->SetAllowInsecureRedirectToDataURI(false);
2288
2289 // We may want to rewrite origin allowance, hence we need an
2290 // artificial response head.
2291 if (!mResponseHead) {
2292 mResponseHead.reset(new nsHttpResponseHead());
2293 }
2294 return NS_OK;
2295}
2296
2297NS_IMETHODIMPnsresult
2298HttpBaseChannel::UpgradeToSecure() {
2299 // Upgrades are handled internally between http-on-modify-request and
2300 // http-on-before-connect, which means upgrades are only possible during
2301 // on-modify, or WebRequest.onBeforeRequest in Web Extensions. Once we are
2302 // past the code path where upgrades are handled, attempting an upgrade
2303 // will throw an error.
2304 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2304); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2305
2306 StoreUpgradeToSecure(true);
2307 // todo: Currently UpgradeToSecure() is called only by web extensions, if
2308 // that ever changes, we need to update the following telemetry collection
2309 // to reflect any future changes.
2310 mLoadInfo->SetHttpsUpgradeTelemetry(nsILoadInfo::WEB_EXTENSION_UPGRADE);
2311
2312 return NS_OK;
2313}
2314
2315NS_IMETHODIMPnsresult
2316HttpBaseChannel::GetRequestObserversCalled(bool* aCalled) {
2317 NS_ENSURE_ARG_POINTER(aCalled)do { if ((__builtin_expect(!!(!(aCalled)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCalled" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2317); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2318 *aCalled = LoadRequestObserversCalled();
2319 return NS_OK;
2320}
2321
2322NS_IMETHODIMPnsresult
2323HttpBaseChannel::SetRequestObserversCalled(bool aCalled) {
2324 StoreRequestObserversCalled(aCalled);
2325 return NS_OK;
2326}
2327
2328NS_IMETHODIMPnsresult
2329HttpBaseChannel::GetRequestContextID(uint64_t* aRCID) {
2330 NS_ENSURE_ARG_POINTER(aRCID)do { if ((__builtin_expect(!!(!(aRCID)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aRCID" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2330); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2331 *aRCID = mRequestContextID;
2332 return NS_OK;
2333}
2334
2335NS_IMETHODIMPnsresult
2336HttpBaseChannel::SetRequestContextID(uint64_t aRCID) {
2337 mRequestContextID = aRCID;
2338 return NS_OK;
2339}
2340
2341NS_IMETHODIMPnsresult
2342HttpBaseChannel::GetIsMainDocumentChannel(bool* aValue) {
2343 NS_ENSURE_ARG_POINTER(aValue)do { if ((__builtin_expect(!!(!(aValue)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aValue" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2343); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2344 *aValue = IsNavigation();
2345 return NS_OK;
2346}
2347
2348NS_IMETHODIMPnsresult
2349HttpBaseChannel::SetIsMainDocumentChannel(bool aValue) {
2350 StoreForceMainDocumentChannel(aValue);
2351 return NS_OK;
2352}
2353
2354NS_IMETHODIMPnsresult
2355HttpBaseChannel::GetProtocolVersion(nsACString& aProtocolVersion) {
2356 // Try to use ALPN if available and if it is not for a proxy, i.e if an
2357 // https proxy was not used or if https proxy was used but the connection to
2358 // the origin server is also https. In the case, an https proxy was used and
2359 // the connection to the origin server was http, mSecurityInfo will be from
2360 // the proxy.
2361 if (!mConnectionInfo || !mConnectionInfo->UsingHttpsProxy() ||
2362 mConnectionInfo->EndToEndSSL()) {
2363 nsAutoCString protocol;
2364 if (mSecurityInfo &&
2365 NS_SUCCEEDED(mSecurityInfo->GetNegotiatedNPN(protocol))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mSecurityInfo->
GetNegotiatedNPN(protocol))), 1)))
&&
2366 !protocol.IsEmpty()) {
2367 // The negotiated protocol was not empty so we can use it.
2368 aProtocolVersion = protocol;
2369 return NS_OK;
2370 }
2371 }
2372
2373 if (mResponseHead) {
2374 HttpVersion version = mResponseHead->Version();
2375 aProtocolVersion.Assign(nsHttp::GetProtocolVersion(version));
2376 return NS_OK;
2377 }
2378
2379 return NS_ERROR_NOT_AVAILABLE;
2380}
2381
2382//-----------------------------------------------------------------------------
2383// HttpBaseChannel::nsIHttpChannelInternal
2384//-----------------------------------------------------------------------------
2385
2386NS_IMETHODIMPnsresult
2387HttpBaseChannel::SetTopWindowURIIfUnknown(nsIURI* aTopWindowURI) {
2388 if (!aTopWindowURI) {
2389 return NS_ERROR_INVALID_ARG;
2390 }
2391
2392 if (mTopWindowURI) {
2393 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)
2394 ("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)
2395 "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)
2396 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)
;
2397 return NS_ERROR_FAILURE;
2398 }
2399
2400 nsCOMPtr<nsIURI> topWindowURI;
2401 Unused << GetTopWindowURI(getter_AddRefs(topWindowURI));
2402
2403 // Don't modify |mTopWindowURI| if we can get one from GetTopWindowURI().
2404 if (topWindowURI) {
2405 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)
2406 ("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)
2407 "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)
2408 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)
;
2409 return NS_ERROR_FAILURE;
2410 }
2411
2412 mTopWindowURI = aTopWindowURI;
2413 return NS_OK;
2414}
2415
2416NS_IMETHODIMPnsresult
2417HttpBaseChannel::GetTopWindowURI(nsIURI** aTopWindowURI) {
2418 nsCOMPtr<nsIURI> uriBeingLoaded =
2419 AntiTrackingUtils::MaybeGetDocumentURIBeingLoaded(this);
2420 return GetTopWindowURI(uriBeingLoaded, aTopWindowURI);
2421}
2422
2423nsresult HttpBaseChannel::GetTopWindowURI(nsIURI* aURIBeingLoaded,
2424 nsIURI** aTopWindowURI) {
2425 nsresult rv = NS_OK;
2426 nsCOMPtr<mozIThirdPartyUtil> util;
2427 // Only compute the top window URI once. In e10s, this must be computed in the
2428 // child. The parent gets the top window URI through HttpChannelOpenArgs.
2429 if (!mTopWindowURI) {
2430 util = components::ThirdPartyUtil::Service();
2431 if (!util) {
2432 return NS_ERROR_NOT_AVAILABLE;
2433 }
2434 nsCOMPtr<mozIDOMWindowProxy> win;
2435 rv = util->GetTopWindowForChannel(this, aURIBeingLoaded,
2436 getter_AddRefs(win));
2437 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2438 rv = util->GetURIFromWindow(win, getter_AddRefs(mTopWindowURI));
2439#if DEBUG1
2440 if (mTopWindowURI) {
2441 nsCString spec;
2442 if (NS_SUCCEEDED(mTopWindowURI->GetSpec(spec))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mTopWindowURI->
GetSpec(spec))), 1)))
) {
2443 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)
2444 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)
;
2445 }
2446 }
2447#endif
2448 }
2449 }
2450 *aTopWindowURI = do_AddRef(mTopWindowURI).take();
2451 return rv;
2452}
2453
2454NS_IMETHODIMPnsresult
2455HttpBaseChannel::GetDocumentURI(nsIURI** aDocumentURI) {
2456 NS_ENSURE_ARG_POINTER(aDocumentURI)do { if ((__builtin_expect(!!(!(aDocumentURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aDocumentURI" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2456); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2457 *aDocumentURI = do_AddRef(mDocumentURI).take();
2458 return NS_OK;
2459}
2460
2461NS_IMETHODIMPnsresult
2462HttpBaseChannel::SetDocumentURI(nsIURI* aDocumentURI) {
2463 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2463); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2463, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2463); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2463); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2463; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2464 mDocumentURI = aDocumentURI;
2465 return NS_OK;
2466}
2467
2468NS_IMETHODIMPnsresult
2469HttpBaseChannel::GetRequestVersion(uint32_t* major, uint32_t* minor) {
2470 HttpVersion version = mRequestHead.Version();
2471
2472 if (major) {
2473 *major = static_cast<uint32_t>(version) / 10;
2474 }
2475 if (minor) {
2476 *minor = static_cast<uint32_t>(version) % 10;
2477 }
2478
2479 return NS_OK;
2480}
2481
2482NS_IMETHODIMPnsresult
2483HttpBaseChannel::GetResponseVersion(uint32_t* major, uint32_t* minor) {
2484 if (!mResponseHead) {
2485 *major = *minor = 0; // we should at least be kind about it
2486 return NS_ERROR_NOT_AVAILABLE;
2487 }
2488
2489 HttpVersion version = mResponseHead->Version();
2490
2491 if (major) {
2492 *major = static_cast<uint32_t>(version) / 10;
2493 }
2494 if (minor) {
2495 *minor = static_cast<uint32_t>(version) % 10;
2496 }
2497
2498 return NS_OK;
2499}
2500
2501bool HttpBaseChannel::IsBrowsingContextDiscarded() const {
2502 // If there is no loadGroup attached to the current channel, we check the
2503 // global private browsing state for the private channel instead. For
2504 // non-private channel, we will always return false here.
2505 //
2506 // Note that we can only access the global private browsing state in the
2507 // parent process. So, we will fallback to just return false in the content
2508 // process.
2509 if (!mLoadGroup) {
2510 if (!XRE_IsParentProcess()) {
2511 return false;
2512 }
2513
2514 return mLoadInfo->GetOriginAttributes().IsPrivateBrowsing() &&
2515 !dom::CanonicalBrowsingContext::IsPrivateBrowsingActive();
2516 }
2517
2518 return mLoadGroup->GetIsBrowsingContextDiscarded();
2519}
2520
2521// https://mikewest.github.io/corpp/#process-navigation-response
2522nsresult HttpBaseChannel::ProcessCrossOriginEmbedderPolicyHeader() {
2523 nsresult rv;
2524 if (!StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2525 return NS_OK;
2526 }
2527
2528 // Only consider Cross-Origin-Embedder-Policy for document loads.
2529 if (mLoadInfo->GetExternalContentPolicyType() !=
2530 ExtContentPolicy::TYPE_DOCUMENT &&
2531 mLoadInfo->GetExternalContentPolicyType() !=
2532 ExtContentPolicy::TYPE_SUBDOCUMENT) {
2533 return NS_OK;
2534 }
2535
2536 nsILoadInfo::CrossOriginEmbedderPolicy resultPolicy =
2537 nsILoadInfo::EMBEDDER_POLICY_NULL;
2538 bool isCoepCredentiallessEnabled;
2539 rv = mLoadInfo->GetIsOriginTrialCoepCredentiallessEnabledForTopLevel(
2540 &isCoepCredentiallessEnabled);
2541 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2541); return rv; } } while (false)
;
2542 rv = GetResponseEmbedderPolicy(isCoepCredentiallessEnabled, &resultPolicy);
2543 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2544 return NS_OK;
2545 }
2546
2547 // https://html.spec.whatwg.org/multipage/origin.html#coep
2548 if (mLoadInfo->GetExternalContentPolicyType() ==
2549 ExtContentPolicy::TYPE_SUBDOCUMENT &&
2550 !nsHttpChannel::IsRedirectStatus(mResponseHead->Status()) &&
2551 mLoadInfo->GetLoadingEmbedderPolicy() !=
2552 nsILoadInfo::EMBEDDER_POLICY_NULL &&
2553 resultPolicy != nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP &&
2554 resultPolicy != nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
2555 return NS_ERROR_DOM_COEP_FAILED;
2556 }
2557
2558 return NS_OK;
2559}
2560
2561// https://mikewest.github.io/corpp/#corp-check
2562nsresult HttpBaseChannel::ProcessCrossOriginResourcePolicyHeader() {
2563 // Fetch 4.5.9
2564 dom::RequestMode requestMode;
2565 MOZ_ALWAYS_SUCCEEDS(GetRequestMode(&requestMode))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(GetRequestMode(&requestMode))), 1)))), 1))) { } else { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(GetRequestMode(&requestMode))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2565); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(GetRequestMode(&requestMode))" ")");
do { *((volatile int*)__null) = 2565; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2566 // XXX this seems wrong per spec? What about navigate
2567 if (requestMode != RequestMode::No_cors) {
2568 return NS_OK;
2569 }
2570
2571 // We only apply this for resources.
2572 auto extContentPolicyType = mLoadInfo->GetExternalContentPolicyType();
2573 if (extContentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
2574 extContentPolicyType == ExtContentPolicy::TYPE_WEBSOCKET ||
2575 extContentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
2576 return NS_OK;
2577 }
2578
2579 if (extContentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
2580 // COEP pref off, skip CORP checking for subdocument.
2581 if (!StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2582 return NS_OK;
2583 }
2584 // COEP 3.2.1.2 when request targets a nested browsing context then embedder
2585 // policy value is "unsafe-none", then return allowed.
2586 if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2587 nsILoadInfo::EMBEDDER_POLICY_NULL) {
2588 return NS_OK;
2589 }
2590 }
2591
2592 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2593); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetLoadingPrincipal()"
") (" "Resources should always have a LoadingPrincipal" ")")
; do { *((volatile int*)__null) = 2593; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2593 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2593); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetLoadingPrincipal()"
") (" "Resources should always have a LoadingPrincipal" ")")
; do { *((volatile int*)__null) = 2593; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2594 if (!mResponseHead) {
2595 return NS_OK;
2596 }
2597
2598 if (mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()) {
2599 return NS_OK;
2600 }
2601
2602 nsAutoCString content;
2603 Unused << mResponseHead->GetHeader(nsHttp::Cross_Origin_Resource_Policy,
2604 content);
2605
2606 if (StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2607 if (content.IsEmpty()) {
2608 if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2609 nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
2610 bool requestIncludesCredentials = false;
2611 nsresult rv = GetCorsIncludeCredentials(&requestIncludesCredentials);
2612 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2613 return NS_OK;
2614 }
2615 // COEP: Set policy to `same-origin` if: response’s
2616 // request-includes-credentials is true, or forNavigation is true.
2617 if (requestIncludesCredentials ||
2618 extContentPolicyType == ExtContentPolicyType::TYPE_SUBDOCUMENT) {
2619 content = "same-origin"_ns;
2620 }
2621 } else if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2622 nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP) {
2623 // COEP 3.2.1.6 If policy is null, and embedder policy is
2624 // "require-corp", set policy to "same-origin". Note that we treat
2625 // invalid value as "cross-origin", which spec indicates. We might want
2626 // to make that stricter.
2627 content = "same-origin"_ns;
2628 }
2629 }
2630 }
2631
2632 if (content.IsEmpty()) {
2633 return NS_OK;
2634 }
2635
2636 nsCOMPtr<nsIPrincipal> channelOrigin;
2637 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
2638 this, getter_AddRefs(channelOrigin));
2639
2640 // Cross-Origin-Resource-Policy = %s"same-origin" / %s"same-site" /
2641 // %s"cross-origin"
2642 if (content.EqualsLiteral("same-origin")) {
2643 if (!channelOrigin->Equals(mLoadInfo->GetLoadingPrincipal())) {
2644 return NS_ERROR_DOM_CORP_FAILED;
2645 }
2646 return NS_OK;
2647 }
2648 if (content.EqualsLiteral("same-site")) {
2649 nsAutoCString documentBaseDomain;
2650 nsAutoCString resourceBaseDomain;
2651 mLoadInfo->GetLoadingPrincipal()->GetBaseDomain(documentBaseDomain);
2652 channelOrigin->GetBaseDomain(resourceBaseDomain);
2653 if (documentBaseDomain != resourceBaseDomain) {
2654 return NS_ERROR_DOM_CORP_FAILED;
2655 }
2656
2657 nsCOMPtr<nsIURI> resourceURI = channelOrigin->GetURI();
2658 if (!mLoadInfo->GetLoadingPrincipal()->SchemeIs("https") &&
2659 resourceURI->SchemeIs("https")) {
2660 return NS_ERROR_DOM_CORP_FAILED;
2661 }
2662
2663 return NS_OK;
2664 }
2665
2666 return NS_OK;
2667}
2668
2669// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
2670// This method runs steps 1-4 of the algorithm to compare
2671// cross-origin-opener policies
2672static bool CompareCrossOriginOpenerPolicies(
2673 nsILoadInfo::CrossOriginOpenerPolicy documentPolicy,
2674 nsIPrincipal* documentOrigin,
2675 nsILoadInfo::CrossOriginOpenerPolicy resultPolicy,
2676 nsIPrincipal* resultOrigin) {
2677 if (documentPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE &&
2678 resultPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2679 return true;
2680 }
2681
2682 if (documentPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE ||
2683 resultPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2684 return false;
2685 }
2686
2687 if (documentPolicy == resultPolicy && documentOrigin->Equals(resultOrigin)) {
2688 return true;
2689 }
2690
2691 return false;
2692}
2693
2694// This runs steps 1-5 of the algorithm when navigating a top level document.
2695// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
2696nsresult HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch() {
2697 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2697); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 2697; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2698
2699 StoreHasCrossOriginOpenerPolicyMismatch(false);
2700 if (!StaticPrefs::browser_tabs_remote_useCrossOriginOpenerPolicy()) {
2701 return NS_OK;
2702 }
2703
2704 // Only consider Cross-Origin-Opener-Policy for toplevel document loads.
2705 if (mLoadInfo->GetExternalContentPolicyType() !=
2706 ExtContentPolicy::TYPE_DOCUMENT) {
2707 return NS_OK;
2708 }
2709
2710 // Maybe the channel failed and we have no response head?
2711 if (!mResponseHead) {
2712 // Not having a response head is not a hard failure at the point where
2713 // this method is called.
2714 return NS_OK;
2715 }
2716
2717 RefPtr<mozilla::dom::BrowsingContext> ctx;
2718 mLoadInfo->GetBrowsingContext(getter_AddRefs(ctx));
2719
2720 // In xpcshell-tests we don't always have a browsingContext
2721 if (!ctx) {
2722 return NS_OK;
2723 }
2724
2725 nsCOMPtr<nsIPrincipal> resultOrigin;
2726 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
2727 this, getter_AddRefs(resultOrigin));
2728
2729 // Get the policy of the active document, and the policy for the result.
2730 nsILoadInfo::CrossOriginOpenerPolicy documentPolicy = ctx->GetOpenerPolicy();
2731 nsILoadInfo::CrossOriginOpenerPolicy resultPolicy =
2732 nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
2733 Unused << ComputeCrossOriginOpenerPolicy(documentPolicy, &resultPolicy);
2734 mComputedCrossOriginOpenerPolicy = resultPolicy;
2735
2736 // Add a permission to mark this site as high-value into the permission DB.
2737 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2738 mozilla::dom::AddHighValuePermission(
2739 resultOrigin, mozilla::dom::kHighValueCOOPPermission);
2740 }
2741
2742 // If bc's popup sandboxing flag set is not empty and potentialCOOP is
2743 // non-null, then navigate bc to a network error and abort these steps.
2744 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE &&
2745 mLoadInfo->GetSandboxFlags()) {
2746 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)
2747 "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)
2748 "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)
;
2749 return NS_ERROR_DOM_COOP_FAILED;
2750 }
2751
2752 // In xpcshell-tests we don't always have a current window global
2753 RefPtr<mozilla::dom::WindowGlobalParent> currentWindowGlobal =
2754 ctx->Canonical()->GetCurrentWindowGlobal();
2755 if (!currentWindowGlobal) {
2756 return NS_OK;
2757 }
2758
2759 // We use the top window principal as the documentOrigin
2760 nsCOMPtr<nsIPrincipal> documentOrigin =
2761 currentWindowGlobal->DocumentPrincipal();
2762
2763 bool compareResult = CompareCrossOriginOpenerPolicies(
2764 documentPolicy, documentOrigin, resultPolicy, resultOrigin);
2765
2766 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
2767 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)
2768 ("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)
2769 "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)
2770 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)
;
2771 nsAutoCString docOrigin("(null)");
2772 nsCOMPtr<nsIURI> uri = documentOrigin->GetURI();
2773 if (uri) {
2774 uri->GetSpec(docOrigin);
2775 }
2776 nsAutoCString resOrigin("(null)");
2777 uri = resultOrigin->GetURI();
2778 if (uri) {
2779 uri->GetSpec(resOrigin);
2780 }
2781 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)
;
2782 }
2783
2784 if (compareResult) {
2785 return NS_OK;
2786 }
2787
2788 // If one of the following is false:
2789 // - document's policy is same-origin-allow-popups
2790 // - resultPolicy is null
2791 // - doc is the initial about:blank document
2792 // then we have a mismatch.
2793
2794 if (documentPolicy != nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_ALLOW_POPUPS) {
2795 StoreHasCrossOriginOpenerPolicyMismatch(true);
2796 return NS_OK;
2797 }
2798
2799 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2800 StoreHasCrossOriginOpenerPolicyMismatch(true);
2801 return NS_OK;
2802 }
2803
2804 if (!currentWindowGlobal->IsInitialDocument()) {
2805 StoreHasCrossOriginOpenerPolicyMismatch(true);
2806 return NS_OK;
2807 }
2808
2809 return NS_OK;
2810}
2811
2812nsresult HttpBaseChannel::ProcessCrossOriginSecurityHeaders() {
2813 StoreProcessCrossOriginSecurityHeadersCalled(true);
2814 nsresult rv = ProcessCrossOriginEmbedderPolicyHeader();
2815 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2816 return rv;
2817 }
2818 rv = ProcessCrossOriginResourcePolicyHeader();
2819 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2820 return rv;
2821 }
2822 return ComputeCrossOriginOpenerPolicyMismatch();
2823}
2824
2825enum class Report { Error, Warning };
2826
2827// Helper Function to report messages to the console when the loaded
2828// script had a wrong MIME type.
2829void ReportMimeTypeMismatch(HttpBaseChannel* aChannel, const char* aMessageName,
2830 nsIURI* aURI, const nsACString& aContentType,
2831 Report report) {
2832 NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
2833 NS_ConvertUTF8toUTF16 contentType(aContentType);
2834
2835 aChannel->LogMimeTypeMismatch(nsCString(aMessageName),
2836 report == Report::Warning, spec, contentType);
2837}
2838
2839// Check and potentially enforce X-Content-Type-Options: nosniff
2840nsresult ProcessXCTO(HttpBaseChannel* aChannel, nsIURI* aURI,
2841 nsHttpResponseHead* aResponseHead,
2842 nsILoadInfo* aLoadInfo) {
2843 if (!aURI || !aResponseHead || !aLoadInfo) {
2844 // if there is no uri, no response head or no loadInfo, then there is
2845 // nothing to do
2846 return NS_OK;
2847 }
2848
2849 // 1) Query the XCTO header and check if 'nosniff' is the first value.
2850 nsAutoCString contentTypeOptionsHeader;
2851 if (!aResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader)) {
2852 // if failed to get XCTO header, then there is nothing to do.
2853 return NS_OK;
2854 }
2855
2856 // let's compare the header (ignoring case)
2857 // e.g. "NoSniFF" -> "nosniff"
2858 // if it's not 'nosniff' then there is nothing to do here
2859 if (!contentTypeOptionsHeader.EqualsIgnoreCase("nosniff")) {
2860 // since we are getting here, the XCTO header was sent;
2861 // a non matching value most likely means a mistake happenend;
2862 // e.g. sending 'nosnif' instead of 'nosniff', let's log a warning.
2863 AutoTArray<nsString, 1> params;
2864 CopyUTF8toUTF16(contentTypeOptionsHeader, *params.AppendElement());
2865 RefPtr<dom::Document> doc;
2866 aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
2867 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "XCTO"_ns, doc,
2868 nsContentUtils::eSECURITY_PROPERTIES,
2869 "XCTOHeaderValueMissing", params);
2870 return NS_OK;
2871 }
2872
2873 // 2) Query the content type from the channel
2874 nsAutoCString contentType;
2875 aResponseHead->ContentType(contentType);
2876
2877 // 3) Compare the expected MIME type with the actual type
2878 if (aLoadInfo->GetExternalContentPolicyType() ==
2879 ExtContentPolicy::TYPE_STYLESHEET) {
2880 if (contentType.EqualsLiteral(TEXT_CSS"text/css")) {
2881 return NS_OK;
2882 }
2883 ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
2884 Report::Error);
2885 return NS_ERROR_CORRUPTED_CONTENT;
2886 }
2887
2888 if (aLoadInfo->GetExternalContentPolicyType() ==
2889 ExtContentPolicy::TYPE_SCRIPT) {
2890 if (nsContentUtils::IsJavascriptMIMEType(
2891 NS_ConvertUTF8toUTF16(contentType))) {
2892 return NS_OK;
2893 }
2894 ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
2895 Report::Error);
2896 return NS_ERROR_CORRUPTED_CONTENT;
2897 }
2898
2899 auto policyType = aLoadInfo->GetExternalContentPolicyType();
2900 if (policyType == ExtContentPolicy::TYPE_DOCUMENT ||
2901 policyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
2902 // If the header XCTO nosniff is set for any browsing context, then
2903 // we set the skipContentSniffing flag on the Loadinfo. Within
2904 // GetMIMETypeFromContent we then bail early and do not do any sniffing.
2905 aLoadInfo->SetSkipContentSniffing(true);
2906 return NS_OK;
2907 }
2908
2909 return NS_OK;
2910}
2911
2912// Ensure that a load of type script has correct MIME type
2913nsresult EnsureMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
2914 nsHttpResponseHead* aResponseHead,
2915 nsILoadInfo* aLoadInfo) {
2916 if (!aURI || !aResponseHead || !aLoadInfo) {
2917 // if there is no uri, no response head or no loadInfo, then there is
2918 // nothing to do
2919 return NS_OK;
2920 }
2921
2922 if (aLoadInfo->GetExternalContentPolicyType() !=
2923 ExtContentPolicy::TYPE_SCRIPT) {
2924 // if this is not a script load, then there is nothing to do
2925 return NS_OK;
2926 }
2927
2928 nsAutoCString contentType;
2929 aResponseHead->ContentType(contentType);
2930 NS_ConvertUTF8toUTF16 typeString(contentType);
2931
2932 if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
2933 // script load has type script
2934 AccumulateCategorical(
2935 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
2936 return NS_OK;
2937 }
2938
2939 nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
2940 bool isModule =
2941 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
2942 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD;
2943
2944 if (isModule && nsContentUtils::IsJsonMimeType(typeString)) {
2945 AccumulateCategorical(
2946 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
2947 return NS_OK;
2948 }
2949
2950 switch (aLoadInfo->InternalContentPolicyType()) {
2951 case nsIContentPolicy::TYPE_SCRIPT:
2952 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
2953 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
2954 case nsIContentPolicy::TYPE_INTERNAL_MODULE:
2955 case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
2956 case nsIContentPolicy::TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT:
2957 case nsIContentPolicy::TYPE_INTERNAL_FRAME_MESSAGEMANAGER_SCRIPT:
2958 AccumulateCategorical(
2959 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::script_load);
2960 break;
2961 case nsIContentPolicy::TYPE_INTERNAL_WORKER:
2962 case nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE:
2963 case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
2964 AccumulateCategorical(
2965 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worker_load);
2966 break;
2967 case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
2968 AccumulateCategorical(
2969 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::serviceworker_load);
2970 break;
2971 case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
2972 AccumulateCategorical(
2973 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::importScript_load);
2974 break;
2975 case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
2976 case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
2977 AccumulateCategorical(
2978 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worklet_load);
2979 break;
2980 default:
2981 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2981); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "unexpected script type" ")"); do
{ *((volatile int*)__null) = 2981; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
2982 break;
2983 }
2984
2985 if (aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(aURI)) {
2986 // same origin
2987 AccumulateCategorical(
2988 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::same_origin);
2989 } else {
2990 bool cors = false;
2991 nsAutoCString corsOrigin;
2992 nsresult rv = aResponseHead->GetHeader(
2993 nsHttp::ResolveAtom("Access-Control-Allow-Origin"_ns), corsOrigin);
2994 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2995 if (corsOrigin.Equals("*")) {
2996 cors = true;
2997 } else {
2998 nsCOMPtr<nsIURI> corsOriginURI;
2999 rv = NS_NewURI(getter_AddRefs(corsOriginURI), corsOrigin);
3000 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3001 if (aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(corsOriginURI)) {
3002 cors = true;
3003 }
3004 }
3005 }
3006 }
3007 if (cors) {
3008 // cors origin
3009 AccumulateCategorical(
3010 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::CORS_origin);
3011 } else {
3012 // cross origin
3013 AccumulateCategorical(
3014 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::cross_origin);
3015 }
3016 }
3017
3018 bool block = false;
3019 if (StringBeginsWith(contentType, "image/"_ns)) {
3020 // script load has type image
3021 AccumulateCategorical(
3022 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::image);
3023 block = true;
3024 } else if (StringBeginsWith(contentType, "audio/"_ns)) {
3025 // script load has type audio
3026 AccumulateCategorical(
3027 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::audio);
3028 block = true;
3029 } else if (StringBeginsWith(contentType, "video/"_ns)) {
3030 // script load has type video
3031 AccumulateCategorical(
3032 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::video);
3033 block = true;
3034 } else if (StringBeginsWith(contentType, "text/csv"_ns)) {
3035 // script load has type text/csv
3036 AccumulateCategorical(
3037 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_csv);
3038 block = true;
3039 }
3040
3041 if (block) {
3042 ReportMimeTypeMismatch(aChannel, "BlockScriptWithWrongMimeType2", aURI,
3043 contentType, Report::Error);
3044 return NS_ERROR_CORRUPTED_CONTENT;
3045 }
3046
3047 if (StringBeginsWith(contentType, "text/plain"_ns)) {
3048 // script load has type text/plain
3049 AccumulateCategorical(
3050 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
3051 } else if (StringBeginsWith(contentType, "text/xml"_ns)) {
3052 // script load has type text/xml
3053 AccumulateCategorical(
3054 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_xml);
3055 } else if (StringBeginsWith(contentType, "application/octet-stream"_ns)) {
3056 // script load has type application/octet-stream
3057 AccumulateCategorical(
3058 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_octet_stream);
3059 } else if (StringBeginsWith(contentType, "application/xml"_ns)) {
3060 // script load has type application/xml
3061 AccumulateCategorical(
3062 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_xml);
3063 } else if (StringBeginsWith(contentType, "application/json"_ns)) {
3064 // script load has type application/json
3065 AccumulateCategorical(
3066 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_json);
3067 } else if (StringBeginsWith(contentType, "text/json"_ns)) {
3068 // script load has type text/json
3069 AccumulateCategorical(
3070 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_json);
3071 } else if (StringBeginsWith(contentType, "text/html"_ns)) {
3072 // script load has type text/html
3073 AccumulateCategorical(
3074 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_html);
3075 } else if (contentType.IsEmpty()) {
3076 // script load has no type
3077 AccumulateCategorical(
3078 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::empty);
3079 } else {
3080 // script load has unknown type
3081 AccumulateCategorical(
3082 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::unknown);
3083 }
3084
3085 // We restrict importScripts() in worker code to JavaScript MIME types.
3086 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS ||
3087 internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE) {
3088 ReportMimeTypeMismatch(aChannel, "BlockImportScriptsWithWrongMimeType",
3089 aURI, contentType, Report::Error);
3090 return NS_ERROR_CORRUPTED_CONTENT;
3091 }
3092
3093 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
3094 internalType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
3095 // Do not block the load if the feature is not enabled.
3096 if (!StaticPrefs::security_block_Worker_with_wrong_mime()) {
3097 return NS_OK;
3098 }
3099
3100 ReportMimeTypeMismatch(aChannel, "BlockWorkerWithWrongMimeType", aURI,
3101 contentType, Report::Error);
3102 return NS_ERROR_CORRUPTED_CONTENT;
3103 }
3104
3105 // ES6 modules require a strict MIME type check.
3106 if (isModule) {
3107 ReportMimeTypeMismatch(aChannel, "BlockModuleWithWrongMimeType", aURI,
3108 contentType, Report::Error);
3109 return NS_ERROR_CORRUPTED_CONTENT;
3110 }
3111
3112 return NS_OK;
3113}
3114
3115// Warn when a load of type script uses a wrong MIME type and
3116// wasn't blocked by EnsureMIMEOfScript or ProcessXCTO.
3117void WarnWrongMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
3118 nsHttpResponseHead* aResponseHead,
3119 nsILoadInfo* aLoadInfo) {
3120 if (!aURI || !aResponseHead || !aLoadInfo) {
3121 // If there is no uri, no response head or no loadInfo, then there is
3122 // nothing to do.
3123 return;
3124 }
3125
3126 if (aLoadInfo->GetExternalContentPolicyType() !=
3127 ExtContentPolicy::TYPE_SCRIPT) {
3128 // If this is not a script load, then there is nothing to do.
3129 return;
3130 }
3131
3132 bool succeeded;
3133 MOZ_ALWAYS_SUCCEEDS(aChannel->GetRequestSucceeded(&succeeded))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aChannel->GetRequestSucceeded(&succeeded))), 1)))), 1
))) { } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(aChannel->GetRequestSucceeded(&succeeded))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3133); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(aChannel->GetRequestSucceeded(&succeeded))"
")"); do { *((volatile int*)__null) = 3133; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3134 if (!succeeded) {
3135 // Do not warn for failed loads: HTTP error pages are usually in HTML.
3136 return;
3137 }
3138
3139 nsAutoCString contentType;
3140 aResponseHead->ContentType(contentType);
3141 NS_ConvertUTF8toUTF16 typeString(contentType);
3142
3143 if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
3144 return;
3145 }
3146
3147 nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
3148 bool isModule =
3149 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
3150 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD;
3151 if (isModule && nsContentUtils::IsJsonMimeType(typeString)) {
3152 return;
3153 }
3154
3155 ReportMimeTypeMismatch(aChannel, "WarnScriptWithWrongMimeType", aURI,
3156 contentType, Report::Warning);
3157}
3158
3159nsresult HttpBaseChannel::ValidateMIMEType() {
3160 nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
3161 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3162 return rv;
3163 }
3164
3165 rv = ProcessXCTO(this, mURI, mResponseHead.get(), mLoadInfo);
3166 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3167 return rv;
3168 }
3169
3170 WarnWrongMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
3171 return NS_OK;
3172}
3173
3174bool HttpBaseChannel::ShouldFilterOpaqueResponse(
3175 OpaqueResponseFilterFetch aFilterType) const {
3176 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3176); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ShouldBlockOpaqueResponse()"
")"); do { *((volatile int*)__null) = 3176; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3177
3178 if (!mLoadInfo || ConfiguredFilterFetchResponseBehaviour() != aFilterType) {
3179 return false;
3180 }
3181
3182 // We should filter a response in the parent if it is opaque and is the result
3183 // of a fetch() function from the Fetch specification.
3184 return mLoadInfo->InternalContentPolicyType() == nsIContentPolicy::TYPE_FETCH;
3185}
3186
3187bool HttpBaseChannel::ShouldBlockOpaqueResponse() const {
3188 if (!mURI || !mResponseHead || !mLoadInfo) {
3189 // if there is no uri, no response head or no loadInfo, then there is
3190 // nothing to do
3191 LOGORB("No block: no mURI, mResponseHead, or mLoadInfo")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 " "No block: no mURI, mResponseHead, or mLoadInfo"
, __func__, this); } } while (0)
;
3192 return false;
3193 }
3194
3195 nsCOMPtr<nsIPrincipal> principal = mLoadInfo->GetLoadingPrincipal();
3196 if (!principal || principal->IsSystemPrincipal()) {
3197 // If it's a top-level load or a system principal, then there is nothing to
3198 // do.
3199 LOGORB("No block: top-level load or system principal")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 " "No block: top-level load or system principal"
, __func__, this); } } while (0)
;
3200 return false;
3201 }
3202
3203 // Check if the response is a opaque response, which means requestMode should
3204 // be RequestMode::No_cors and responseType should be ResponseType::Opaque.
3205 nsContentPolicyType contentPolicy = mLoadInfo->InternalContentPolicyType();
3206
3207 // Skip the RequestMode would be RequestMode::Navigate
3208 if (contentPolicy == nsIContentPolicy::TYPE_DOCUMENT ||
3209 contentPolicy == nsIContentPolicy::TYPE_SUBDOCUMENT ||
3210 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_FRAME ||
3211 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_IFRAME ||
3212 // Skip the RequestMode would be RequestMode::Same_origin
3213 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
3214 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
3215 return false;
3216 }
3217
3218 uint32_t securityMode = mLoadInfo->GetSecurityMode();
3219 // Skip when RequestMode would not be RequestMode::no_cors
3220 if (securityMode !=
3221 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT &&
3222 securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL) {
3223 LOGORB("No block: not no_cors requests")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 " "No block: not no_cors requests"
, __func__, this); } } while (0)
;
3224 return false;
3225 }
3226
3227 // Only continue when ResponseType would be ResponseType::Opaque
3228 if (mLoadInfo->GetTainting() != mozilla::LoadTainting::Opaque) {
3229 LOGORB("No block: not opaque response")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 " "No block: not opaque response",
__func__, this); } } while (0)
;
3230 return false;
3231 }
3232
3233 auto extContentPolicyType = mLoadInfo->GetExternalContentPolicyType();
3234 if (extContentPolicyType == ExtContentPolicy::TYPE_OBJECT ||
3235 extContentPolicyType == ExtContentPolicy::TYPE_OBJECT_SUBREQUEST ||
3236 extContentPolicyType == ExtContentPolicy::TYPE_WEBSOCKET ||
3237 extContentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
3238 LOGORB("No block: object || websocket request || save as download")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 " "No block: object || websocket request || save as download"
, __func__, this); } } while (0)
;
3239 return false;
3240 }
3241
3242 // Ignore the request from object or embed elements
3243 if (mLoadInfo->GetIsFromObjectOrEmbed()) {
3244 LOGORB("No block: Request From <object> or <embed>")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 " "No block: Request From <object> or <embed>"
, __func__, this); } } while (0)
;
3245 return false;
3246 }
3247
3248 // Exclude no_cors System XHR
3249 if (extContentPolicyType == ExtContentPolicy::TYPE_XMLHTTPREQUEST) {
3250 if (securityMode ==
3251 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT) {
3252 LOGORB("No block: System XHR")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 " "No block: System XHR", __func__
, this); } } while (0)
;
3253 return false;
3254 }
3255 }
3256
3257 uint32_t httpsOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
3258 if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_BYPASS_ORB) {
3259 LOGORB("No block: HTTPS_ONLY_BYPASS_ORB")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 " "No block: HTTPS_ONLY_BYPASS_ORB"
, __func__, this); } } while (0)
;
3260 return false;
3261 }
3262
3263 bool isInDevToolsContext;
3264 mLoadInfo->GetIsInDevToolsContext(&isInDevToolsContext);
3265 if (isInDevToolsContext) {
3266 LOGORB("No block: Request created by devtools")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 " "No block: Request created by devtools"
, __func__, this); } } while (0)
;
3267 return false;
3268 }
3269
3270 return true;
3271}
3272
3273OpaqueResponse HttpBaseChannel::BlockOrFilterOpaqueResponse(
3274 OpaqueResponseBlocker* aORB, const nsAString& aReason,
3275 const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
3276 const char* aFormat, ...) {
3277 NimbusFeatures::RecordExposureEvent("opaqueResponseBlocking"_ns, true);
3278
3279 const bool shouldFilter =
3280 ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::BlockedByORB);
3281
3282 if (MOZ_UNLIKELY(MOZ_LOG_TEST(GetORBLog(), LogLevel::Debug))(__builtin_expect(!!((__builtin_expect(!!(mozilla::detail::log_test
(GetORBLog(), LogLevel::Debug)), 0))), 0))
) {
3283 va_list ap;
3284 va_start(ap, aFormat)__builtin_va_start(ap, aFormat);
3285 nsVprintfCString logString(aFormat, ap);
3286 va_end(ap)__builtin_va_end(ap);
3287
3288 LOGORB("%s: %s", shouldFilter ? "Filtered" : "Blocked", logString.get())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 " "%s: %s", __func__, this, shouldFilter
? "Filtered" : "Blocked", logString.get()); } } while (0)
;
3289 }
3290
3291 if (shouldFilter) {
3292 Telemetry::AccumulateCategorical(
3293 Telemetry::LABELS_ORB_BLOCK_INITIATOR::FILTERED_FETCH);
3294 // The existence of `mORB` depends on `BlockOrFilterOpaqueResponse` being
3295 // called before or after sniffing has completed.
3296 // Another requirement is that `OpaqueResponseFilter` must come after
3297 // `OpaqueResponseBlocker`, which is why in the case of having an
3298 // `OpaqueResponseBlocker` we let it handle creating an
3299 // `OpaqueResponseFilter`.
3300 if (aORB) {
3301 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"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3301); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mORB || aORB == mORB"
")"); do { *((volatile int*)__null) = 3301; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3302 aORB->FilterResponse();
3303 } else {
3304 mListener = new OpaqueResponseFilter(mListener);
3305 }
3306 return OpaqueResponse::Allow;
3307 }
3308
3309 LogORBError(aReason, aTelemetryReason);
3310 return OpaqueResponse::Block;
3311}
3312
3313// The specification for ORB is currently being written:
3314// https://whatpr.org/fetch/1442.html#orb-algorithm
3315// The `opaque-response-safelist check` is implemented in:
3316// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
3317// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3318// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
3319// * `OpaqueResponseBlocker::ValidateJavaScript`
3320OpaqueResponse
3321HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff() {
3322 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3322); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 3322; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3323
3324 // https://whatpr.org/fetch/1442.html#http-fetch, step 6.4
3325 if (!ShouldBlockOpaqueResponse()) {
3326 return OpaqueResponse::Allow;
3327 }
3328
3329 // Regardless of if ORB is enabled or not, we check if we should filter the
3330 // response in the parent. This way data won't reach a content process that
3331 // will create a filtered `Response` object. This is enabled when
3332 // 'browser.opaqueResponseBlocking.filterFetchResponse' is
3333 // `OpaqueResponseFilterFetch::All`.
3334 // See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
3335 if (ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::All)) {
3336 mListener = new OpaqueResponseFilter(mListener);
3337
3338 // If we're filtering a response in the parent, there will be no data to
3339 // determine if it should be blocked or not so the only option we have is to
3340 // allow it.
3341 return OpaqueResponse::Allow;
3342 }
3343
3344 if (!mCachedOpaqueResponseBlockingPref) {
3345 return OpaqueResponse::Allow;
3346 }
3347
3348 // If ORB is enabled, we check if we should filter the response in the parent.
3349 // This way data won't reach a content process that will create a filtered
3350 // `Response` object. We allow ORB to determine if the response should be
3351 // blocked or filtered, but regardless no data should reach the content
3352 // process. This is enabled when
3353 // 'browser.opaqueResponseBlocking.filterFetchResponse' is
3354 // `OpaqueResponseFilterFetch::AllowedByORB`.
3355 // See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
3356 if (ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::AllowedByORB)) {
3357 mListener = new OpaqueResponseFilter(mListener);
3358 }
3359
3360 Telemetry::ScalarAdd(
3361 Telemetry::ScalarID::
3362 OPAQUE_RESPONSE_BLOCKING_CROSS_ORIGIN_OPAQUE_RESPONSE_COUNT,
3363 1);
3364
3365 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)
;
3366
3367 // https://whatpr.org/fetch/1442.html#orb-algorithm
3368 // Step 1
3369 nsAutoCString contentType;
3370 mResponseHead->ContentType(contentType);
3371
3372 // Step 2
3373 nsAutoCString contentTypeOptionsHeader;
3374 bool nosniff =
3375 mResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader) &&
3376 contentTypeOptionsHeader.EqualsIgnoreCase("nosniff");
3377
3378 // Step 3
3379 switch (GetOpaqueResponseBlockedReason(contentType, mResponseHead->Status(),
3380 nosniff)) {
3381 case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED:
3382 // Step 3.1
3383 return OpaqueResponse::Allow;
3384 case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED_SPEC_BREAKING:
3385 LOGORB("Allowed %s in a spec breaking way", contentType.get())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 " "Allowed %s in a spec breaking way"
, __func__, this, contentType.get()); } } while (0)
;
3386 return OpaqueResponse::Allow;
3387 case OpaqueResponseBlockedReason::BLOCKED_BLOCKLISTED_NEVER_SNIFFED:
3388 return BlockOrFilterOpaqueResponse(
3389 mORB, u"mimeType is an opaque-blocklisted-never-sniffed MIME type"_ns,
3390 OpaqueResponseBlockedTelemetryReason::MIME_NEVER_SNIFFED,
3391 "BLOCKED_BLOCKLISTED_NEVER_SNIFFED");
3392 case OpaqueResponseBlockedReason::BLOCKED_206_AND_BLOCKLISTED:
3393 // Step 3.3
3394 return BlockOrFilterOpaqueResponse(
3395 mORB,
3396 u"response's status is 206 and mimeType is an opaque-blocklisted MIME type"_ns,
3397 OpaqueResponseBlockedTelemetryReason::RESP_206_BLCLISTED,
3398 "BLOCKED_206_AND_BLOCKEDLISTED");
3399 case OpaqueResponseBlockedReason::
3400 BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN:
3401 // Step 3.4
3402 return BlockOrFilterOpaqueResponse(
3403 mORB,
3404 u"nosniff is true and mimeType is an opaque-blocklisted MIME type or its essence is 'text/plain'"_ns,
3405 OpaqueResponseBlockedTelemetryReason::NOSNIFF_BLC_OR_TEXTP,
3406 "BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN");
3407 default:
3408 break;
3409 }
3410
3411 // Step 4
3412 // If it's a media subsequent request, we assume that it will only be made
3413 // after a successful initial request.
3414 bool isMediaRequest;
3415 mLoadInfo->GetIsMediaRequest(&isMediaRequest);
3416 if (isMediaRequest) {
3417 bool isMediaInitialRequest;
3418 mLoadInfo->GetIsMediaInitialRequest(&isMediaInitialRequest);
3419 if (!isMediaInitialRequest) {
3420 return OpaqueResponse::Allow;
3421 }
3422 }
3423
3424 // Step 5
3425 if (mResponseHead->Status() == 206 &&
3426 !IsFirstPartialResponse(*mResponseHead)) {
3427 return BlockOrFilterOpaqueResponse(
3428 mORB, u"response status is 206 and not first partial response"_ns,
3429 OpaqueResponseBlockedTelemetryReason::RESP_206_BLCLISTED,
3430 "Is not a valid partial response given 0");
3431 }
3432
3433 // Setup for steps 6, 7, 8 and 10.
3434 // Steps 6 and 7 are handled by the sniffer framework.
3435 // Steps 8 and 10 by are handled by
3436 // `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3437 if (mLoadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS) {
3438 mSnifferCategoryType = SnifferCategoryType::All;
3439 } else {
3440 mSnifferCategoryType = SnifferCategoryType::OpaqueResponseBlocking;
3441 }
3442
3443 mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
3444 nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
3445
3446 // Install an input stream listener that performs ORB checks that depend on
3447 // inspecting the incoming data. It is crucial that `OnStartRequest` is called
3448 // on this listener either after sniffing is completed or that we skip
3449 // sniffing, otherwise `OpaqueResponseBlocker` will allow responses that it
3450 // shouldn't.
3451 mORB = new OpaqueResponseBlocker(mListener, this, contentType, nosniff);
3452 mListener = mORB;
3453
3454 nsAutoCString contentEncoding;
3455 nsresult rv =
3456 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
3457
3458 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !contentEncoding.IsEmpty()) {
3459 return OpaqueResponse::SniffCompressed;
3460 }
3461 mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
3462 nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
3463 return OpaqueResponse::Sniff;
3464}
3465
3466// The specification for ORB is currently being written:
3467// https://whatpr.org/fetch/1442.html#orb-algorithm
3468// The `opaque-response-safelist check` is implemented in:
3469// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
3470// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3471// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
3472// * `OpaqueResponseBlocker::ValidateJavaScript`
3473OpaqueResponse HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff(
3474 const nsACString& aContentType, bool aNoSniff) {
3475 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)
;
3476
3477 // https://whatpr.org/fetch/1442.html#orb-algorithm
3478 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3478); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 3478; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3479 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3479); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedOpaqueResponseBlockingPref"
")"); do { *((volatile int*)__null) = 3479; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3480
3481 // Step 9
3482 bool isMediaRequest;
3483 mLoadInfo->GetIsMediaRequest(&isMediaRequest);
3484 if (isMediaRequest) {
3485 return BlockOrFilterOpaqueResponse(
3486 mORB, u"after sniff: media request"_ns,
3487 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_MEDIA,
3488 "media request");
3489 }
3490
3491 // Step 11
3492 if (aNoSniff) {
3493 return BlockOrFilterOpaqueResponse(
3494 mORB, u"after sniff: nosniff is true"_ns,
3495 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_NOSNIFF, "nosniff");
3496 }
3497
3498 // Step 12
3499 if (mResponseHead &&
3500 (mResponseHead->Status() < 200 || mResponseHead->Status() > 299)) {
3501 return BlockOrFilterOpaqueResponse(
3502 mORB, u"after sniff: status code is not in allowed range"_ns,
3503 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_STA_CODE,
3504 "status code (%d) is not allowed", mResponseHead->Status());
3505 }
3506
3507 // Step 13
3508 if (!mResponseHead || aContentType.IsEmpty()) {
3509 LOGORB("Allowed: mimeType is failure")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 " "Allowed: mimeType is failure", __func__
, this); } } while (0)
;
3510 return OpaqueResponse::Allow;
3511 }
3512
3513 // Step 14
3514 if (StringBeginsWith(aContentType, "image/"_ns) ||
3515 StringBeginsWith(aContentType, "video/"_ns) ||
3516 StringBeginsWith(aContentType, "audio/"_ns)) {
3517 return BlockOrFilterOpaqueResponse(
3518 mORB,
3519 u"after sniff: content-type declares image/video/audio, but sniffing fails"_ns,
3520 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_CT_FAIL,
3521 "ContentType is image/video/audio");
3522 }
3523
3524 return OpaqueResponse::Sniff;
3525}
3526
3527bool HttpBaseChannel::NeedOpaqueResponseAllowedCheckAfterSniff() const {
3528 return mORB ? mORB->IsSniffing() : false;
3529}
3530
3531void HttpBaseChannel::BlockOpaqueResponseAfterSniff(
3532 const nsAString& aReason,
3533 const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
3534 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3534); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { *((volatile int*)__null) = 3534; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3535 LogORBError(aReason, aTelemetryReason);
3536 mORB->BlockResponse(this, NS_BINDING_ABORTED);
3537}
3538
3539void HttpBaseChannel::AllowOpaqueResponseAfterSniff() {
3540 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3540); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { *((volatile int*)__null) = 3540; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3541 mORB->AllowResponse();
3542}
3543
3544void HttpBaseChannel::SetChannelBlockedByOpaqueResponse() {
3545 mChannelBlockedByOpaqueResponse = true;
3546
3547 RefPtr<dom::BrowsingContext> browsingContext =
3548 dom::BrowsingContext::GetCurrentTopByBrowserId(mBrowserId);
3549 if (!browsingContext) {
3550 return;
3551 }
3552
3553 dom::WindowContext* windowContext = browsingContext->GetTopWindowContext();
3554 if (windowContext) {
3555 windowContext->Canonical()->SetShouldReportHasBlockedOpaqueResponse(
3556 mLoadInfo->InternalContentPolicyType());
3557 }
3558}
3559
3560NS_IMETHODIMPnsresult
3561HttpBaseChannel::SetCookie(const nsACString& aCookieHeader) {
3562 if (mLoadFlags & LOAD_ANONYMOUS) return NS_OK;
3563
3564 if (IsBrowsingContextDiscarded()) {
3565 return NS_OK;
3566 }
3567
3568 // empty header isn't an error
3569 if (aCookieHeader.IsEmpty()) {
3570 return NS_OK;
3571 }
3572
3573 nsICookieService* cs = gHttpHandler->GetCookieService();
3574 NS_ENSURE_TRUE(cs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(cs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "cs" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3574); return NS_ERROR_FAILURE; } } while (false)
;
3575
3576 return cs->SetCookieStringFromHttp(mURI, aCookieHeader, this);
3577}
3578
3579NS_IMETHODIMPnsresult
3580HttpBaseChannel::GetThirdPartyFlags(uint32_t* aFlags) {
3581 *aFlags = LoadThirdPartyFlags();
3582 return NS_OK;
3583}
3584
3585NS_IMETHODIMPnsresult
3586HttpBaseChannel::SetThirdPartyFlags(uint32_t aFlags) {
3587 ENSURE_CALLED_BEFORE_ASYNC_OPEN()do { if (LoadIsPending() || LoadWasOpened()) { nsPrintfCString
msg("'%s' called after AsyncOpen: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3587); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3587, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3587); } } while (0); } do { if ((__builtin_expect(!!(!(!LoadIsPending
())), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE("
"!LoadIsPending()" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3587); return NS_ERROR_IN_PROGRESS; } } while (false); do {
if ((__builtin_expect(!!(!(!LoadWasOpened())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!LoadWasOpened()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3587); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
3588
3589 StoreThirdPartyFlags(aFlags);
3590 return NS_OK;
3591}
3592
3593NS_IMETHODIMPnsresult
3594HttpBaseChannel::GetForceAllowThirdPartyCookie(bool* aForce) {
3595 *aForce = !!(LoadThirdPartyFlags() &
3596 nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3597 return NS_OK;
3598}
3599
3600NS_IMETHODIMPnsresult
3601HttpBaseChannel::SetForceAllowThirdPartyCookie(bool aForce) {
3602 ENSURE_CALLED_BEFORE_ASYNC_OPEN()do { if (LoadIsPending() || LoadWasOpened()) { nsPrintfCString
msg("'%s' called after AsyncOpen: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3602); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3602, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3602); } } while (0); } do { if ((__builtin_expect(!!(!(!LoadIsPending
())), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE("
"!LoadIsPending()" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3602); return NS_ERROR_IN_PROGRESS; } } while (false); do {
if ((__builtin_expect(!!(!(!LoadWasOpened())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!LoadWasOpened()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3602); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
3603
3604 if (aForce) {
3605 StoreThirdPartyFlags(LoadThirdPartyFlags() |
3606 nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3607 } else {
3608 StoreThirdPartyFlags(LoadThirdPartyFlags() &
3609 ~nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3610 }
3611
3612 return NS_OK;
3613}
3614
3615NS_IMETHODIMPnsresult
3616HttpBaseChannel::GetCanceled(bool* aCanceled) {
3617 *aCanceled = mCanceled;
3618 return NS_OK;
3619}
3620
3621NS_IMETHODIMPnsresult
3622HttpBaseChannel::GetChannelIsForDownload(bool* aChannelIsForDownload) {
3623 *aChannelIsForDownload = LoadChannelIsForDownload();
3624 return NS_OK;
3625}
3626
3627NS_IMETHODIMPnsresult
3628HttpBaseChannel::SetChannelIsForDownload(bool aChannelIsForDownload) {
3629 StoreChannelIsForDownload(aChannelIsForDownload);
3630 return NS_OK;
3631}
3632
3633NS_IMETHODIMPnsresult
3634HttpBaseChannel::SetCacheKeysRedirectChain(nsTArray<nsCString>* cacheKeys) {
3635 auto RedirectedCachekeys = mRedirectedCachekeys.Lock();
3636 auto& ref = RedirectedCachekeys.ref();
3637 ref = WrapUnique(cacheKeys);
3638 return NS_OK;
3639}
3640
3641NS_IMETHODIMPnsresult
3642HttpBaseChannel::GetLocalAddress(nsACString& addr) {
3643 if (mSelfAddr.raw.family == PR_AF_UNSPEC0) return NS_ERROR_NOT_AVAILABLE;
3644
3645 addr.SetLength(kIPv6CStrBufSize);
3646 mSelfAddr.ToStringBuffer(addr.BeginWriting(), kIPv6CStrBufSize);
3647 addr.SetLength(strlen(addr.BeginReading()));
3648
3649 return NS_OK;
3650}
3651
3652NS_IMETHODIMPnsresult
3653HttpBaseChannel::TakeAllSecurityMessages(
3654 nsCOMArray<nsISecurityConsoleMessage>& aMessages) {
3655 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3655); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3655; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3656
3657 aMessages.Clear();
3658 for (const auto& pair : mSecurityConsoleMessages) {
3659 nsresult rv;
3660 nsCOMPtr<nsISecurityConsoleMessage> message =
3661 do_CreateInstance(NS_SECURITY_CONSOLE_MESSAGE_CONTRACTID"@mozilla.org/securityconsole/message;1", &rv);
3662 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3662); return rv; } } while (false)
;
3663
3664 message->SetTag(pair.first);
3665 message->SetCategory(pair.second);
3666 aMessages.AppendElement(message);
3667 }
3668
3669 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()", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3669); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSecurityConsoleMessages.Length() == aMessages.Length()"
")"); do { *((volatile int*)__null) = 3669; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3670 mSecurityConsoleMessages.Clear();
3671
3672 return NS_OK;
3673}
3674
3675/* Please use this method with care. This can cause the message
3676 * queue to grow large and cause the channel to take up a lot
3677 * of memory. Use only static string messages and do not add
3678 * server side data to the queue, as that can be large.
3679 * Add only a limited number of messages to the queue to keep
3680 * the channel size down and do so only in rare erroneous situations.
3681 * More information can be found here:
3682 * https://bugzilla.mozilla.org/show_bug.cgi?id=846918
3683 */
3684nsresult HttpBaseChannel::AddSecurityMessage(
3685 const nsAString& aMessageTag, const nsAString& aMessageCategory) {
3686 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3686); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3686; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3687
3688 nsresult rv;
3689
3690 // nsSecurityConsoleMessage is not thread-safe refcounted.
3691 // Delay the object construction until requested.
3692 // See TakeAllSecurityMessages()
3693 std::pair<nsString, nsString> pair(aMessageTag, aMessageCategory);
3694 mSecurityConsoleMessages.AppendElement(std::move(pair));
3695
3696 nsCOMPtr<nsIConsoleService> console(
3697 do_GetService(NS_CONSOLESERVICE_CONTRACTID"@mozilla.org/consoleservice;1"));
3698 if (!console) {
3699 return NS_ERROR_FAILURE;
3700 }
3701
3702 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
3703
3704 auto innerWindowID = loadInfo->GetInnerWindowID();
3705
3706 nsAutoString errorText;
3707 rv = nsContentUtils::GetLocalizedString(
3708 nsContentUtils::eSECURITY_PROPERTIES,
3709 NS_ConvertUTF16toUTF8(aMessageTag).get(), errorText);
3710 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3710); return rv; } } while (false)
;
3711
3712 nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID"@mozilla.org/scripterror;1"));
3713 error->InitWithSourceURI(errorText, mURI, 0, 0, nsIScriptError::warningFlag,
3714 NS_ConvertUTF16toUTF8(aMessageCategory),
3715 innerWindowID);
3716
3717 console->LogMessage(error);
3718
3719 return NS_OK;
3720}
3721
3722NS_IMETHODIMPnsresult
3723HttpBaseChannel::GetLocalPort(int32_t* port) {
3724 NS_ENSURE_ARG_POINTER(port)do { if ((__builtin_expect(!!(!(port)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "port" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3724); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3725
3726 if (mSelfAddr.raw.family == PR_AF_INET2) {
3727 *port = (int32_t)ntohs(mSelfAddr.inet.port)__bswap_16 (mSelfAddr.inet.port);
3728 } else if (mSelfAddr.raw.family == PR_AF_INET610) {
3729 *port = (int32_t)ntohs(mSelfAddr.inet6.port)__bswap_16 (mSelfAddr.inet6.port);
3730 } else {
3731 return NS_ERROR_NOT_AVAILABLE;
3732 }
3733
3734 return NS_OK;
3735}
3736
3737NS_IMETHODIMPnsresult
3738HttpBaseChannel::GetRemoteAddress(nsACString& addr) {
3739 if (mPeerAddr.raw.family == PR_AF_UNSPEC0) return NS_ERROR_NOT_AVAILABLE;
3740
3741 addr.SetLength(kIPv6CStrBufSize);
3742 mPeerAddr.ToStringBuffer(addr.BeginWriting(), kIPv6CStrBufSize);
3743 addr.SetLength(strlen(addr.BeginReading()));
3744
3745 return NS_OK;
3746}
3747
3748NS_IMETHODIMPnsresult
3749HttpBaseChannel::GetRemotePort(int32_t* port) {
3750 NS_ENSURE_ARG_POINTER(port)do { if ((__builtin_expect(!!(!(port)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "port" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3750); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3751
3752 if (mPeerAddr.raw.family == PR_AF_INET2) {
3753 *port = (int32_t)ntohs(mPeerAddr.inet.port)__bswap_16 (mPeerAddr.inet.port);
3754 } else if (mPeerAddr.raw.family == PR_AF_INET610) {
3755 *port = (int32_t)ntohs(mPeerAddr.inet6.port)__bswap_16 (mPeerAddr.inet6.port);
3756 } else {
3757 return NS_ERROR_NOT_AVAILABLE;
3758 }
3759
3760 return NS_OK;
3761}
3762
3763NS_IMETHODIMPnsresult
3764HttpBaseChannel::HTTPUpgrade(const nsACString& aProtocolName,
3765 nsIHttpUpgradeListener* aListener) {
3766 NS_ENSURE_ARG(!aProtocolName.IsEmpty())do { if ((__builtin_expect(!!(!(!aProtocolName.IsEmpty())), 0
))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!aProtocolName.IsEmpty()"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3766); return NS_ERROR_INVALID_ARG; } } while (false)
;
3767 NS_ENSURE_ARG_POINTER(aListener)do { if ((__builtin_expect(!!(!(aListener)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aListener" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3767); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3768
3769 mUpgradeProtocol = aProtocolName;
3770 mUpgradeProtocolCallback = aListener;
3771 return NS_OK;
3772}
3773
3774NS_IMETHODIMPnsresult
3775HttpBaseChannel::GetOnlyConnect(bool* aOnlyConnect) {
3776 NS_ENSURE_ARG_POINTER(aOnlyConnect)do { if ((__builtin_expect(!!(!(aOnlyConnect)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOnlyConnect" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3776); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3777
3778 *aOnlyConnect = mCaps & NS_HTTP_CONNECT_ONLY(1 << 16);
3779 return NS_OK;
3780}
3781
3782NS_IMETHODIMPnsresult
3783HttpBaseChannel::SetConnectOnly(bool aTlsTunnel) {
3784 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3784); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3784, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3784); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3784); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 3784; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
3785
3786 if (!mUpgradeProtocolCallback) {
3787 return NS_ERROR_FAILURE;
3788 }
3789
3790 mCaps |= NS_HTTP_CONNECT_ONLY(1 << 16);
3791 if (aTlsTunnel) {
3792 mCaps |= NS_HTTP_TLS_TUNNEL(1 << 29);
3793 }
3794 mProxyResolveFlags = nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY |
3795 nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL;
3796 return SetLoadFlags(nsIRequest::INHIBIT_CACHING | nsIChannel::LOAD_ANONYMOUS |
3797 nsIRequest::LOAD_BYPASS_CACHE |
3798 nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
3799}
3800
3801NS_IMETHODIMPnsresult
3802HttpBaseChannel::GetAllowSpdy(bool* aAllowSpdy) {
3803 NS_ENSURE_ARG_POINTER(aAllowSpdy)do { if ((__builtin_expect(!!(!(aAllowSpdy)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowSpdy" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3803); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3804
3805 *aAllowSpdy = LoadAllowSpdy();
3806 return NS_OK;
3807}
3808
3809NS_IMETHODIMPnsresult
3810HttpBaseChannel::SetAllowSpdy(bool aAllowSpdy) {
3811 StoreAllowSpdy(aAllowSpdy);
3812 return NS_OK;
3813}
3814
3815NS_IMETHODIMPnsresult
3816HttpBaseChannel::GetAllowHttp3(bool* aAllowHttp3) {
3817 NS_ENSURE_ARG_POINTER(aAllowHttp3)do { if ((__builtin_expect(!!(!(aAllowHttp3)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowHttp3" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3817); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3818
3819 *aAllowHttp3 = LoadAllowHttp3();
3820 return NS_OK;
3821}
3822
3823NS_IMETHODIMPnsresult
3824HttpBaseChannel::SetAllowHttp3(bool aAllowHttp3) {
3825 StoreAllowHttp3(aAllowHttp3);
3826 return NS_OK;
3827}
3828
3829NS_IMETHODIMPnsresult
3830HttpBaseChannel::GetAllowAltSvc(bool* aAllowAltSvc) {
3831 NS_ENSURE_ARG_POINTER(aAllowAltSvc)do { if ((__builtin_expect(!!(!(aAllowAltSvc)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowAltSvc" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3831); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3832
3833 *aAllowAltSvc = LoadAllowAltSvc();
3834 return NS_OK;
3835}
3836
3837NS_IMETHODIMPnsresult
3838HttpBaseChannel::SetAllowAltSvc(bool aAllowAltSvc) {
3839 StoreAllowAltSvc(aAllowAltSvc);
3840 return NS_OK;
3841}
3842
3843NS_IMETHODIMPnsresult
3844HttpBaseChannel::GetBeConservative(bool* aBeConservative) {
3845 NS_ENSURE_ARG_POINTER(aBeConservative)do { if ((__builtin_expect(!!(!(aBeConservative)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aBeConservative" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3845); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3846
3847 *aBeConservative = LoadBeConservative();
3848 return NS_OK;
3849}
3850
3851NS_IMETHODIMPnsresult
3852HttpBaseChannel::SetBeConservative(bool aBeConservative) {
3853 StoreBeConservative(aBeConservative);
3854 return NS_OK;
3855}
3856
3857bool HttpBaseChannel::BypassProxy() {
3858 return StaticPrefs::network_proxy_allow_bypass() && LoadBypassProxy();
3859}
3860
3861NS_IMETHODIMPnsresult
3862HttpBaseChannel::GetBypassProxy(bool* aBypassProxy) {
3863 NS_ENSURE_ARG_POINTER(aBypassProxy)do { if ((__builtin_expect(!!(!(aBypassProxy)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aBypassProxy" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3863); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3864
3865 *aBypassProxy = BypassProxy();
3866 return NS_OK;
3867}
3868
3869NS_IMETHODIMPnsresult
3870HttpBaseChannel::SetBypassProxy(bool aBypassProxy) {
3871 if (StaticPrefs::network_proxy_allow_bypass()) {
3872 StoreBypassProxy(aBypassProxy);
3873 } else {
3874 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3874)
;
3875 return NS_ERROR_FAILURE;
3876 }
3877 return NS_OK;
3878}
3879
3880NS_IMETHODIMPnsresult
3881HttpBaseChannel::GetIsTRRServiceChannel(bool* aIsTRRServiceChannel) {
3882 NS_ENSURE_ARG_POINTER(aIsTRRServiceChannel)do { if ((__builtin_expect(!!(!(aIsTRRServiceChannel)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aIsTRRServiceChannel"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3882); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3883
3884 *aIsTRRServiceChannel = LoadIsTRRServiceChannel();
3885 return NS_OK;
3886}
3887
3888NS_IMETHODIMPnsresult
3889HttpBaseChannel::SetIsTRRServiceChannel(bool aIsTRRServiceChannel) {
3890 StoreIsTRRServiceChannel(aIsTRRServiceChannel);
3891 return NS_OK;
3892}
3893
3894NS_IMETHODIMPnsresult
3895HttpBaseChannel::GetIsResolvedByTRR(bool* aResolvedByTRR) {
3896 NS_ENSURE_ARG_POINTER(aResolvedByTRR)do { if ((__builtin_expect(!!(!(aResolvedByTRR)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResolvedByTRR" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3896); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3897 *aResolvedByTRR = LoadResolvedByTRR();
3898 return NS_OK;
3899}
3900
3901NS_IMETHODIMPnsresult
3902HttpBaseChannel::GetEffectiveTRRMode(nsIRequest::TRRMode* aEffectiveTRRMode) {
3903 *aEffectiveTRRMode = mEffectiveTRRMode;
3904 return NS_OK;
3905}
3906
3907NS_IMETHODIMPnsresult
3908HttpBaseChannel::GetTrrSkipReason(nsITRRSkipReason::value* aTrrSkipReason) {
3909 *aTrrSkipReason = mTRRSkipReason;
3910 return NS_OK;
3911}
3912
3913NS_IMETHODIMPnsresult
3914HttpBaseChannel::GetIsLoadedBySocketProcess(bool* aResult) {
3915 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3915); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3916 *aResult = LoadLoadedBySocketProcess();
3917 return NS_OK;
3918}
3919
3920NS_IMETHODIMPnsresult
3921HttpBaseChannel::GetTlsFlags(uint32_t* aTlsFlags) {
3922 NS_ENSURE_ARG_POINTER(aTlsFlags)do { if ((__builtin_expect(!!(!(aTlsFlags)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aTlsFlags" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3922); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3923
3924 *aTlsFlags = mTlsFlags;
3925 return NS_OK;
3926}
3927
3928NS_IMETHODIMPnsresult
3929HttpBaseChannel::SetTlsFlags(uint32_t aTlsFlags) {
3930 mTlsFlags = aTlsFlags;
3931 return NS_OK;
3932}
3933
3934NS_IMETHODIMPnsresult
3935HttpBaseChannel::GetApiRedirectToURI(nsIURI** aResult) {
3936 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3936); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3937 *aResult = do_AddRef(mAPIRedirectToURI).take();
3938 return NS_OK;
3939}
3940
3941NS_IMETHODIMPnsresult
3942HttpBaseChannel::GetResponseTimeoutEnabled(bool* aEnable) {
3943 if (NS_WARN_IF(!aEnable)NS_warn_if_impl(!aEnable, "!aEnable", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3943)
) {
3944 return NS_ERROR_NULL_POINTER;
3945 }
3946 *aEnable = LoadResponseTimeoutEnabled();
3947 return NS_OK;
3948}
3949
3950NS_IMETHODIMPnsresult
3951HttpBaseChannel::SetResponseTimeoutEnabled(bool aEnable) {
3952 StoreResponseTimeoutEnabled(aEnable);
3953 return NS_OK;
3954}
3955
3956NS_IMETHODIMPnsresult
3957HttpBaseChannel::GetInitialRwin(uint32_t* aRwin) {
3958 if (NS_WARN_IF(!aRwin)NS_warn_if_impl(!aRwin, "!aRwin", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3958)
) {
3959 return NS_ERROR_NULL_POINTER;
3960 }
3961 *aRwin = mInitialRwin;
3962 return NS_OK;
3963}
3964
3965NS_IMETHODIMPnsresult
3966HttpBaseChannel::SetInitialRwin(uint32_t aRwin) {
3967 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3967); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3967, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3967); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3967); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 3967; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
3968 mInitialRwin = aRwin;
3969 return NS_OK;
3970}
3971
3972NS_IMETHODIMPnsresult
3973HttpBaseChannel::ForcePending(bool aForcePending) {
3974 StoreForcePending(aForcePending);
3975 return NS_OK;
3976}
3977
3978NS_IMETHODIMPnsresult
3979HttpBaseChannel::GetLastModifiedTime(PRTime* lastModifiedTime) {
3980 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
3981 uint32_t lastMod;
3982 nsresult rv = mResponseHead->GetLastModifiedValue(&lastMod);
3983 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3983); return rv; } } while (false)
;
3984 *lastModifiedTime = lastMod;
3985 return NS_OK;
3986}
3987
3988NS_IMETHODIMPnsresult
3989HttpBaseChannel::GetCorsIncludeCredentials(bool* aInclude) {
3990 *aInclude = LoadCorsIncludeCredentials();
3991 return NS_OK;
3992}
3993
3994NS_IMETHODIMPnsresult
3995HttpBaseChannel::SetCorsIncludeCredentials(bool aInclude) {
3996 StoreCorsIncludeCredentials(aInclude);
3997 return NS_OK;
3998}
3999
4000NS_IMETHODIMPnsresult
4001HttpBaseChannel::GetRequestMode(RequestMode* aMode) {
4002 *aMode = mRequestMode;
4003 return NS_OK;
4004}
4005
4006NS_IMETHODIMPnsresult
4007HttpBaseChannel::SetRequestMode(RequestMode aMode) {
4008 mRequestMode = aMode;
4009 return NS_OK;
4010}
4011
4012NS_IMETHODIMPnsresult
4013HttpBaseChannel::GetRedirectMode(uint32_t* aMode) {
4014 *aMode = mRedirectMode;
4015 return NS_OK;
4016}
4017
4018NS_IMETHODIMPnsresult
4019HttpBaseChannel::SetRedirectMode(uint32_t aMode) {
4020 mRedirectMode = aMode;
4021 return NS_OK;
4022}
4023
4024namespace {
4025
4026bool ContainsAllFlags(uint32_t aLoadFlags, uint32_t aMask) {
4027 return (aLoadFlags & aMask) == aMask;
4028}
4029
4030} // anonymous namespace
4031
4032NS_IMETHODIMPnsresult
4033HttpBaseChannel::GetFetchCacheMode(uint32_t* aFetchCacheMode) {
4034 NS_ENSURE_ARG_POINTER(aFetchCacheMode)do { if ((__builtin_expect(!!(!(aFetchCacheMode)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aFetchCacheMode" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4034); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4035
4036 // Otherwise try to guess an appropriate cache mode from the load flags.
4037 if (ContainsAllFlags(mLoadFlags, INHIBIT_CACHING | LOAD_BYPASS_CACHE)) {
4038 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE;
4039 } else if (ContainsAllFlags(mLoadFlags, LOAD_BYPASS_CACHE)) {
4040 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD;
4041 } else if (ContainsAllFlags(mLoadFlags, VALIDATE_ALWAYS) ||
4042 LoadForceValidateCacheContent()) {
4043 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE;
4044 } else if (ContainsAllFlags(
4045 mLoadFlags,
4046 VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE)) {
4047 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED;
4048 } else if (ContainsAllFlags(mLoadFlags, VALIDATE_NEVER)) {
4049 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE;
4050 } else {
4051 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT;
4052 }
4053
4054 return NS_OK;
4055}
4056
4057namespace {
4058
4059void SetCacheFlags(uint32_t& aLoadFlags, uint32_t aFlags) {
4060 // First, clear any possible cache related flags.
4061 uint32_t allPossibleFlags =
4062 nsIRequest::INHIBIT_CACHING | nsIRequest::LOAD_BYPASS_CACHE |
4063 nsIRequest::VALIDATE_ALWAYS | nsIRequest::LOAD_FROM_CACHE |
4064 nsICachingChannel::LOAD_ONLY_FROM_CACHE;
4065 aLoadFlags &= ~allPossibleFlags;
4066
4067 // Then set the new flags.
4068 aLoadFlags |= aFlags;
4069}
4070
4071} // anonymous namespace
4072
4073NS_IMETHODIMPnsresult
4074HttpBaseChannel::SetFetchCacheMode(uint32_t aFetchCacheMode) {
4075 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4075); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4075, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4075); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4075); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 4075; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
4076
4077 // Now, set the load flags that implement each cache mode.
4078 switch (aFetchCacheMode) {
4079 case nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT:
4080 // The "default" mode means to use the http cache normally and
4081 // respect any http cache-control headers. We effectively want
4082 // to clear our cache related load flags.
4083 SetCacheFlags(mLoadFlags, 0);
4084 break;
4085 case nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE:
4086 // no-store means don't consult the cache on the way to the network, and
4087 // don't store the response in the cache even if it's cacheable.
4088 SetCacheFlags(mLoadFlags, INHIBIT_CACHING | LOAD_BYPASS_CACHE);
4089 break;
4090 case nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD:
4091 // reload means don't consult the cache on the way to the network, but
4092 // do store the response in the cache if possible.
4093 SetCacheFlags(mLoadFlags, LOAD_BYPASS_CACHE);
4094 break;
4095 case nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE:
4096 // no-cache means always validate what's in the cache.
4097 SetCacheFlags(mLoadFlags, VALIDATE_ALWAYS);
4098 break;
4099 case nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE:
4100 // force-cache means don't validate unless if the response would vary.
4101 SetCacheFlags(mLoadFlags, VALIDATE_NEVER);
4102 break;
4103 case nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED:
4104 // only-if-cached means only from cache, no network, no validation,
4105 // generate a network error if the document was't in the cache. The
4106 // privacy implications of these flags (making it fast/easy to check if
4107 // the user has things in their cache without any network traffic side
4108 // effects) are addressed in the Request constructor which
4109 // enforces/requires same-origin request mode.
4110 SetCacheFlags(mLoadFlags,
4111 VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE);
4112 break;
4113 }
4114
4115#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED1
4116 uint32_t finalMode = 0;
4117 MOZ_ALWAYS_SUCCEEDS(GetFetchCacheMode(&finalMode))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(GetFetchCacheMode(&finalMode))), 1)))), 1))) { } else { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(GetFetchCacheMode(&finalMode))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4117); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(GetFetchCacheMode(&finalMode))" ")")
; do { *((volatile int*)__null) = 4117; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4118 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4118); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "finalMode == aFetchCacheMode"
")"); do { *((volatile int*)__null) = 4118; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4119#endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED
4120
4121 return NS_OK;
4122}
4123
4124NS_IMETHODIMPnsresult
4125HttpBaseChannel::SetIntegrityMetadata(const nsAString& aIntegrityMetadata) {
4126 mIntegrityMetadata = aIntegrityMetadata;
4127 return NS_OK;
4128}
4129
4130NS_IMETHODIMPnsresult
4131HttpBaseChannel::GetIntegrityMetadata(nsAString& aIntegrityMetadata) {
4132 aIntegrityMetadata = mIntegrityMetadata;
4133 return NS_OK;
4134}
4135
4136//-----------------------------------------------------------------------------
4137// HttpBaseChannel::nsISupportsPriority
4138//-----------------------------------------------------------------------------
4139
4140NS_IMETHODIMPnsresult
4141HttpBaseChannel::GetPriority(int32_t* value) {
4142 *value = mPriority;
4143 return NS_OK;
4144}
4145
4146NS_IMETHODIMPnsresult
4147HttpBaseChannel::AdjustPriority(int32_t delta) {
4148 return SetPriority(mPriority + delta);
4149}
4150
4151//-----------------------------------------------------------------------------
4152// HttpBaseChannel::nsIResumableChannel
4153//-----------------------------------------------------------------------------
4154
4155NS_IMETHODIMPnsresult
4156HttpBaseChannel::GetEntityID(nsACString& aEntityID) {
4157 // Don't return an entity ID for Non-GET requests which require
4158 // additional data
4159 if (!mRequestHead.IsGet()) {
4160 return NS_ERROR_NOT_RESUMABLE;
4161 }
4162
4163 uint64_t size = UINT64_MAX(18446744073709551615UL);
4164 nsAutoCString etag, lastmod;
4165 if (mResponseHead) {
4166 // Don't return an entity if the server sent the following header:
4167 // Accept-Ranges: none
4168 // Not sending the Accept-Ranges header means we can still try
4169 // sending range requests.
4170 nsAutoCString acceptRanges;
4171 Unused << mResponseHead->GetHeader(nsHttp::Accept_Ranges, acceptRanges);
4172 if (!acceptRanges.IsEmpty() &&
4173 !nsHttp::FindToken(acceptRanges.get(), "bytes",
4174 HTTP_HEADER_VALUE_SEPS" \t" ",")) {
4175 return NS_ERROR_NOT_RESUMABLE;
4176 }
4177
4178 size = mResponseHead->TotalEntitySize();
4179 Unused << mResponseHead->GetHeader(nsHttp::Last_Modified, lastmod);
4180 Unused << mResponseHead->GetHeader(nsHttp::ETag, etag);
4181 }
4182 nsCString entityID;
4183 NS_EscapeURL(etag.BeginReading(), etag.Length(),
4184 esc_AlwaysCopy | esc_FileBaseName | esc_Forced, entityID);
4185 entityID.Append('/');
4186 entityID.AppendInt(int64_t(size));
4187 entityID.Append('/');
4188 entityID.Append(lastmod);
4189 // NOTE: Appending lastmod as the last part avoids having to escape it
4190
4191 aEntityID = entityID;
4192
4193 return NS_OK;
4194}
4195
4196//-----------------------------------------------------------------------------
4197// HttpBaseChannel::nsIConsoleReportCollector
4198//-----------------------------------------------------------------------------
4199
4200void HttpBaseChannel::AddConsoleReport(
4201 uint32_t aErrorFlags, const nsACString& aCategory,
4202 nsContentUtils::PropertiesFile aPropertiesFile,
4203 const nsACString& aSourceFileURI, uint32_t aLineNumber,
4204 uint32_t aColumnNumber, const nsACString& aMessageName,
4205 const nsTArray<nsString>& aStringParams) {
4206 mReportCollector->AddConsoleReport(aErrorFlags, aCategory, aPropertiesFile,
4207 aSourceFileURI, aLineNumber, aColumnNumber,
4208 aMessageName, aStringParams);
4209
4210 // If this channel is already part of a loadGroup, we can flush this console
4211 // report immediately.
4212 HttpBaseChannel::MaybeFlushConsoleReports();
4213}
4214
4215void HttpBaseChannel::FlushReportsToConsole(uint64_t aInnerWindowID,
4216 ReportAction aAction) {
4217 mReportCollector->FlushReportsToConsole(aInnerWindowID, aAction);
4218}
4219
4220void HttpBaseChannel::FlushReportsToConsoleForServiceWorkerScope(
4221 const nsACString& aScope, ReportAction aAction) {
4222 mReportCollector->FlushReportsToConsoleForServiceWorkerScope(aScope, aAction);
4223}
4224
4225void HttpBaseChannel::FlushConsoleReports(dom::Document* aDocument,
4226 ReportAction aAction) {
4227 mReportCollector->FlushConsoleReports(aDocument, aAction);
4228}
4229
4230void HttpBaseChannel::FlushConsoleReports(nsILoadGroup* aLoadGroup,
4231 ReportAction aAction) {
4232 mReportCollector->FlushConsoleReports(aLoadGroup, aAction);
4233}
4234
4235void HttpBaseChannel::FlushConsoleReports(
4236 nsIConsoleReportCollector* aCollector) {
4237 mReportCollector->FlushConsoleReports(aCollector);
4238}
4239
4240void HttpBaseChannel::StealConsoleReports(
4241 nsTArray<net::ConsoleReportCollected>& aReports) {
4242 mReportCollector->StealConsoleReports(aReports);
4243}
4244
4245void HttpBaseChannel::ClearConsoleReports() {
4246 mReportCollector->ClearConsoleReports();
4247}
4248
4249bool HttpBaseChannel::IsNavigation() {
4250 return LoadForceMainDocumentChannel() || (mLoadFlags & LOAD_DOCUMENT_URI);
4251}
4252
4253bool HttpBaseChannel::BypassServiceWorker() const {
4254 return mLoadFlags & LOAD_BYPASS_SERVICE_WORKER;
4255}
4256
4257bool HttpBaseChannel::ShouldIntercept(nsIURI* aURI) {
4258 nsCOMPtr<nsINetworkInterceptController> controller;
4259 GetCallback(controller);
4260 bool shouldIntercept = false;
4261
4262 if (!StaticPrefs::dom_serviceWorkers_enabled()) {
4263 return false;
4264 }
4265
4266 // We should never intercept internal redirects. The ServiceWorker code
4267 // can trigger interntal redirects as the result of a FetchEvent. If
4268 // we re-intercept then an infinite loop can occur.
4269 //
4270 // Its also important that we do not set the LOAD_BYPASS_SERVICE_WORKER
4271 // flag because an internal redirect occurs. Its possible that another
4272 // interception should occur after the internal redirect. For example,
4273 // if the ServiceWorker chooses not to call respondWith() the channel
4274 // will be reset with an internal redirect. If the request is a navigation
4275 // and the network then triggers a redirect its possible the new URL
4276 // should be intercepted again.
4277 //
4278 // Note, HSTS upgrade redirects are often treated the same as internal
4279 // redirects. In this case, however, we intentionally allow interception
4280 // of HSTS upgrade redirects. This matches the expected spec behavior and
4281 // does not run the risk of infinite loops as described above.
4282 bool internalRedirect =
4283 mLastRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL;
4284
4285 if (controller && mLoadInfo && !BypassServiceWorker() && !internalRedirect) {
4286 nsresult rv = controller->ShouldPrepareForIntercept(
4287 aURI ? aURI : mURI.get(), this, &shouldIntercept);
4288 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4289 return false;
4290 }
4291 }
4292 return shouldIntercept;
4293}
4294
4295void HttpBaseChannel::AddAsNonTailRequest() {
4296 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4296); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4296; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4297
4298 if (EnsureRequestContext()) {
4299 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)
4300 "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)
4301 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)
;
4302
4303 if (!LoadAddedAsNonTailRequest()) {
4304 mRequestContext->AddNonTailRequest();
4305 StoreAddedAsNonTailRequest(true);
4306 }
4307 }
4308}
4309
4310void HttpBaseChannel::RemoveAsNonTailRequest() {
4311 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4311); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4311; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4312
4313 if (mRequestContext) {
4314 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)
4315 ("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)
4316 "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)
4317 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)
;
4318
4319 if (LoadAddedAsNonTailRequest()) {
4320 mRequestContext->RemoveNonTailRequest();
4321 StoreAddedAsNonTailRequest(false);
4322 }
4323 }
4324}
4325
4326#ifdef DEBUG1
4327void HttpBaseChannel::AssertPrivateBrowsingId() {
4328 nsCOMPtr<nsILoadContext> loadContext;
4329 NS_QueryNotificationCallbacks(this, loadContext);
4330
4331 if (!loadContext) {
4332 return;
4333 }
4334
4335 // We skip testing of favicon loading here since it could be triggered by XUL
4336 // image which uses SystemPrincipal. The SystemPrincpal doesn't have
4337 // mPrivateBrowsingId.
4338 if (mLoadInfo->GetLoadingPrincipal() &&
4339 mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal() &&
4340 mLoadInfo->InternalContentPolicyType() ==
4341 nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
4342 return;
4343 }
4344
4345 OriginAttributes docShellAttrs;
4346 loadContext->GetOriginAttributes(docShellAttrs);
4347 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." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4350; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4348 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." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4350; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4349 "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." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4350; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4350 "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." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4350; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
4351}
4352#endif
4353
4354already_AddRefed<nsILoadInfo> HttpBaseChannel::CloneLoadInfoForRedirect(
4355 nsIURI* aNewURI, uint32_t aRedirectFlags) {
4356 // make a copy of the loadinfo, append to the redirectchain
4357 // this will be set on the newly created channel for the redirect target.
4358 nsCOMPtr<nsILoadInfo> newLoadInfo =
4359 static_cast<mozilla::net::LoadInfo*>(mLoadInfo.get())->Clone();
4360
4361 ExtContentPolicyType contentPolicyType =
4362 mLoadInfo->GetExternalContentPolicyType();
4363 if (contentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
4364 contentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
4365 // Reset PrincipalToInherit to a null principal. We'll credit the the
4366 // redirecting resource's result principal as the new principal's precursor.
4367 // This means that a data: URI will end up loading in a process based on the
4368 // redirected-from URI.
4369 nsCOMPtr<nsIPrincipal> redirectPrincipal;
4370 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
4371 this, getter_AddRefs(redirectPrincipal));
4372 nsCOMPtr<nsIPrincipal> nullPrincipalToInherit =
4373 NullPrincipal::CreateWithInheritedAttributes(redirectPrincipal);
4374 newLoadInfo->SetPrincipalToInherit(nullPrincipalToInherit);
4375 }
4376
4377 bool isTopLevelDoc = newLoadInfo->GetExternalContentPolicyType() ==
4378 ExtContentPolicy::TYPE_DOCUMENT;
4379
4380 if (isTopLevelDoc) {
4381 // re-compute the origin attributes of the loadInfo if it's top-level load.
4382 nsCOMPtr<nsILoadContext> loadContext;
4383 NS_QueryNotificationCallbacks(this, loadContext);
4384 OriginAttributes docShellAttrs;
4385 if (loadContext) {
4386 loadContext->GetOriginAttributes(docShellAttrs);
4387 }
4388
4389 OriginAttributes attrs = newLoadInfo->GetOriginAttributes();
4390
4391 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mUserContextId == attrs.mUserContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mUserContextId == attrs.mUserContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mUserContextId == attrs.mUserContextId" " (" "docshell and necko should have the same userContextId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4393); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4393; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4392 docShellAttrs.mUserContextId == attrs.mUserContextId,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mUserContextId == attrs.mUserContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mUserContextId == attrs.mUserContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mUserContextId == attrs.mUserContextId" " (" "docshell and necko should have the same userContextId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4393); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4393; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4393 "docshell and necko should have the same userContextId attribute.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mUserContextId == attrs.mUserContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mUserContextId == attrs.mUserContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mUserContextId == attrs.mUserContextId" " (" "docshell and necko should have the same userContextId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4393); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4393; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4394 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
" (" "docshell and necko should have the same privateBrowsingId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4396); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4396; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4395 docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
" (" "docshell and necko should have the same privateBrowsingId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4396); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4396; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4396 "docshell and necko should have the same privateBrowsingId attribute.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
" (" "docshell and necko should have the same privateBrowsingId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4396); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4396; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4397 MOZ_ASSERT(docShellAttrs.mGeckoViewSessionContextId ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4400); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4400; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4398 attrs.mGeckoViewSessionContextId,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4400); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4400; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4399 "docshell and necko should have the same "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4400); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4400; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4400 "geckoViewSessionContextId attribute")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4400); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4400; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4401
4402 attrs = docShellAttrs;
4403 attrs.SetFirstPartyDomain(true, aNewURI);
4404 newLoadInfo->SetOriginAttributes(attrs);
4405
4406 // re-compute the upgrade insecure requests bit for document navigations
4407 // since it should only apply to same-origin navigations (redirects).
4408 // we only do this if the CSP of the triggering element (the cspToInherit)
4409 // uses 'upgrade-insecure-requests', otherwise UIR does not apply.
4410 nsCOMPtr<nsIContentSecurityPolicy> csp = newLoadInfo->GetCspToInherit();
4411 if (csp) {
4412 bool upgradeInsecureRequests = false;
4413 csp->GetUpgradeInsecureRequests(&upgradeInsecureRequests);
4414 if (upgradeInsecureRequests) {
4415 nsCOMPtr<nsIPrincipal> resultPrincipal =
4416 BasePrincipal::CreateContentPrincipal(
4417 aNewURI, newLoadInfo->GetOriginAttributes());
4418 bool isConsideredSameOriginforUIR =
4419 nsContentSecurityUtils::IsConsideredSameOriginForUIR(
4420 newLoadInfo->TriggeringPrincipal(), resultPrincipal);
4421 static_cast<mozilla::net::LoadInfo*>(newLoadInfo.get())
4422 ->SetUpgradeInsecureRequests(isConsideredSameOriginforUIR);
4423 }
4424 }
4425 }
4426
4427 // Leave empty, we want a 'clean ground' when creating the new channel.
4428 // This will be ensured to be either set by the protocol handler or set
4429 // to the redirect target URI properly after the channel creation.
4430 newLoadInfo->SetResultPrincipalURI(nullptr);
4431
4432 bool isInternalRedirect =
4433 (aRedirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
4434 nsIChannelEventSink::REDIRECT_STS_UPGRADE));
4435
4436 // Reset our sandboxed null principal ID when cloning loadInfo for an
4437 // externally visible redirect.
4438 if (!isInternalRedirect) {
4439 // If we've redirected from http to something that isn't, clear
4440 // the "external" flag, as loads that now go to other apps should be
4441 // allowed to go ahead and not trip infinite-loop protection
4442 // (see bug 1717314 for context).
4443 if (!aNewURI->SchemeIs("http") && !aNewURI->SchemeIs("https")) {
4444 newLoadInfo->SetLoadTriggeredFromExternal(false);
4445 }
4446 newLoadInfo->ResetSandboxedNullPrincipalID();
4447 }
4448
4449 newLoadInfo->AppendRedirectHistoryEntry(this, isInternalRedirect);
4450
4451 return newLoadInfo.forget();
4452}
4453
4454//-----------------------------------------------------------------------------
4455// nsHttpChannel::nsITraceableChannel
4456//-----------------------------------------------------------------------------
4457
4458NS_IMETHODIMPnsresult
4459HttpBaseChannel::SetNewListener(nsIStreamListener* aListener,
4460 bool aMustApplyContentConversion,
4461 nsIStreamListener** _retval) {
4462 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)
4463 "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)
4464 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)
;
4465
4466 if (!LoadTracingEnabled()) return NS_ERROR_FAILURE;
4467
4468 NS_ENSURE_STATE(mListener)do { if ((__builtin_expect(!!(!(mListener)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mListener" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4468); return NS_ERROR_UNEXPECTED; } } while (false)
;
4469 NS_ENSURE_ARG_POINTER(aListener)do { if ((__builtin_expect(!!(!(aListener)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aListener" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4469); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4470
4471 nsCOMPtr<nsIStreamListener> wrapper = new nsStreamListenerWrapper(mListener);
4472
4473 wrapper.forget(_retval);
4474 mListener = aListener;
4475 if (aMustApplyContentConversion) {
4476 StoreListenerRequiresContentConversion(true);
4477 }
4478 return NS_OK;
4479}
4480
4481//-----------------------------------------------------------------------------
4482// HttpBaseChannel helpers
4483//-----------------------------------------------------------------------------
4484
4485void HttpBaseChannel::ReleaseListeners() {
4486 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4487); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentThread->IsOnCurrentThread()"
") (" "Should only be called on the current thread" ")"); do
{ *((volatile int*)__null) = 4487; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
4487 "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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4487); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentThread->IsOnCurrentThread()"
") (" "Should only be called on the current thread" ")"); do
{ *((volatile int*)__null) = 4487; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
4488
4489 mListener = nullptr;
4490 mCallbacks = nullptr;
4491 mProgressSink = nullptr;
4492 mCompressListener = nullptr;
4493 mORB = nullptr;
4494}
4495
4496void HttpBaseChannel::DoNotifyListener() {
4497 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)
;
4498
4499 // In case nsHttpChannel::OnStartRequest wasn't called (e.g. due to flag
4500 // LOAD_ONLY_IF_MODIFIED) we want to set AfterOnStartRequestBegun to true
4501 // before notifying listener.
4502 if (!LoadAfterOnStartRequestBegun()) {
4503 StoreAfterOnStartRequestBegun(true);
4504 }
4505
4506 if (mListener && !LoadOnStartRequestCalled()) {
4507 nsCOMPtr<nsIStreamListener> listener = mListener;
4508 StoreOnStartRequestCalled(true);
4509 listener->OnStartRequest(this);
4510 }
4511 StoreOnStartRequestCalled(true);
4512
4513 // Make sure IsPending is set to false. At this moment we are done from
4514 // the point of view of our consumer and we have to report our self
4515 // as not-pending.
4516 StoreIsPending(false);
4517
4518 // notify "http-on-before-stop-request" observers
4519 gHttpHandler->OnBeforeStopRequest(this);
4520
4521 if (mListener && !LoadOnStopRequestCalled()) {
4522 nsCOMPtr<nsIStreamListener> listener = mListener;
4523 StoreOnStopRequestCalled(true);
4524 listener->OnStopRequest(this, mStatus);
4525 }
4526 StoreOnStopRequestCalled(true);
4527
4528 // notify "http-on-stop-request" observers
4529 gHttpHandler->OnStopRequest(this);
4530
4531 // This channel has finished its job, potentially release any tail-blocked
4532 // requests with this.
4533 RemoveAsNonTailRequest();
4534
4535 // We have to make sure to drop the references to listeners and callbacks
4536 // no longer needed.
4537 ReleaseListeners();
4538
4539 DoNotifyListenerCleanup();
4540
4541 // If this is a navigation, then we must let the docshell flush the reports
4542 // to the console later. The LoadDocument() is pointing at the detached
4543 // document that started the navigation. We want to show the reports on the
4544 // new document. Otherwise the console is wiped and the user never sees
4545 // the information.
4546 if (!IsNavigation()) {
4547 if (mLoadGroup) {
4548 FlushConsoleReports(mLoadGroup);
4549 } else {
4550 RefPtr<dom::Document> doc;
4551 mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
4552 FlushConsoleReports(doc);
4553 }
4554 }
4555}
4556
4557void HttpBaseChannel::AddCookiesToRequest() {
4558 if (mLoadFlags & LOAD_ANONYMOUS) {
4559 return;
4560 }
4561
4562 bool useCookieService = (XRE_IsParentProcess());
4563 nsAutoCString cookie;
4564 if (useCookieService) {
4565 nsICookieService* cs = gHttpHandler->GetCookieService();
4566 if (cs) {
4567 cs->GetCookieStringFromHttp(mURI, this, cookie);
4568 }
4569
4570 if (cookie.IsEmpty()) {
4571 cookie = mUserSetCookieHeader;
4572 } else if (!mUserSetCookieHeader.IsEmpty()) {
4573 cookie.AppendLiteral("; ");
4574 cookie.Append(mUserSetCookieHeader);
4575 }
4576 } else {
4577 cookie = mUserSetCookieHeader;
4578 }
4579
4580 // If we are in the child process, we want the parent seeing any
4581 // cookie headers that might have been set by SetRequestHeader()
4582 SetRequestHeader(nsHttp::Cookie.val(), cookie, false);
4583}
4584
4585/* static */
4586void HttpBaseChannel::PropagateReferenceIfNeeded(
4587 nsIURI* aURI, nsCOMPtr<nsIURI>& aRedirectURI) {
4588 bool hasRef = false;
4589 nsresult rv = aRedirectURI->GetHasRef(&hasRef);
4590 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !hasRef) {
4591 nsAutoCString ref;
4592 aURI->GetRef(ref);
4593 if (!ref.IsEmpty()) {
4594 // NOTE: SetRef will fail if mRedirectURI is immutable
4595 // (e.g. an about: URI)... Oh well.
4596 Unused << NS_MutateURI(aRedirectURI).SetRef(ref).Finalize(aRedirectURI);
4597 }
4598 }
4599}
4600
4601bool HttpBaseChannel::ShouldRewriteRedirectToGET(
4602 uint32_t httpStatus, nsHttpRequestHead::ParsedMethodType method) {
4603 // for 301 and 302, only rewrite POST
4604 if (httpStatus == 301 || httpStatus == 302) {
4605 return method == nsHttpRequestHead::kMethod_Post;
4606 }
4607
4608 // rewrite for 303 unless it was HEAD
4609 if (httpStatus == 303) return method != nsHttpRequestHead::kMethod_Head;
4610
4611 // otherwise, such as for 307, do not rewrite
4612 return false;
4613}
4614
4615NS_IMETHODIMPnsresult
4616HttpBaseChannel::ShouldStripRequestBodyHeader(const nsACString& aMethod,
4617 bool* aResult) {
4618 *aResult = false;
4619 uint32_t httpStatus = 0;
4620 if (NS_FAILED(GetResponseStatus(&httpStatus))((bool)(__builtin_expect(!!(NS_FAILED_impl(GetResponseStatus(
&httpStatus))), 0)))
) {
4621 return NS_OK;
4622 }
4623
4624 nsAutoCString method(aMethod);
4625 nsHttpRequestHead::ParsedMethodType parsedMethod;
4626 nsHttpRequestHead::ParseMethod(method, parsedMethod);
4627 // Fetch 4.4.11, which is slightly different than the perserved method
4628 // algrorithm: strip request-body-header for GET->GET redirection for 303.
4629 *aResult =
4630 ShouldRewriteRedirectToGET(httpStatus, parsedMethod) &&
4631 !(httpStatus == 303 && parsedMethod == nsHttpRequestHead::kMethod_Get);
4632
4633 return NS_OK;
4634}
4635
4636HttpBaseChannel::ReplacementChannelConfig
4637HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod,
4638 uint32_t aRedirectFlags,
4639 ReplacementReason aReason) {
4640 ReplacementChannelConfig config;
4641 config.redirectFlags = aRedirectFlags;
4642 config.classOfService = mClassOfService;
4643
4644 if (mPrivateBrowsingOverriden) {
4645 config.privateBrowsing = Some(mPrivateBrowsing);
4646 }
4647
4648 if (mReferrerInfo) {
4649 // When cloning for a document channel replacement (parent process
4650 // copying values for a new content process channel), this happens after
4651 // OnStartRequest so we have the headers for the response available.
4652 // We don't want to apply them to the referrer for the channel though,
4653 // since that is the referrer for the current document, and the header
4654 // should only apply to navigations from the current document.
4655 if (aReason == ReplacementReason::DocumentChannel) {
4656 config.referrerInfo = mReferrerInfo;
4657 } else {
4658 dom::ReferrerPolicy referrerPolicy = dom::ReferrerPolicy::_empty;
4659 nsAutoCString tRPHeaderCValue;
4660 Unused << GetResponseHeader("referrer-policy"_ns, tRPHeaderCValue);
4661 NS_ConvertUTF8toUTF16 tRPHeaderValue(tRPHeaderCValue);
4662
4663 if (!tRPHeaderValue.IsEmpty()) {
4664 referrerPolicy =
4665 dom::ReferrerInfo::ReferrerPolicyFromHeaderString(tRPHeaderValue);
4666 }
4667
4668 // In case we are here because an upgrade happened through mixed content
4669 // upgrading, CSP upgrade-insecure-requests, HTTPS-Only or HTTPS-First, we
4670 // have to recalculate the referrer based on the original referrer to
4671 // account for the different scheme. This does NOT apply to HSTS.
4672 // See Bug 1857894 and order of https://fetch.spec.whatwg.org/#main-fetch.
4673 // Otherwise, if we have a new referrer policy, we want to recalculate the
4674 // referrer based on the old computed referrer (Bug 1678545).
4675 bool wasNonHSTSUpgrade =
4676 (aRedirectFlags & nsIChannelEventSink::REDIRECT_STS_UPGRADE) &&
4677 (!mLoadInfo->GetHstsStatus());
4678 if (wasNonHSTSUpgrade) {
4679 nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetOriginalReferrer();
4680 config.referrerInfo =
4681 new dom::ReferrerInfo(referrer, mReferrerInfo->ReferrerPolicy(),
4682 mReferrerInfo->GetSendReferrer());
4683 } else if (referrerPolicy != dom::ReferrerPolicy::_empty) {
4684 nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetComputedReferrer();
4685 config.referrerInfo = new dom::ReferrerInfo(
4686 referrer, referrerPolicy, mReferrerInfo->GetSendReferrer());
4687 } else {
4688 config.referrerInfo = mReferrerInfo;
4689 }
4690 }
4691 }
4692
4693 nsCOMPtr<nsITimedChannel> oldTimedChannel(
4694 do_QueryInterface(static_cast<nsIHttpChannel*>(this)));
4695 if (oldTimedChannel) {
4696 config.timedChannelInfo = Some(dom::TimedChannelInfo());
4697 config.timedChannelInfo->timingEnabled() = LoadTimingEnabled();
4698 config.timedChannelInfo->redirectCount() = mRedirectCount;
4699 config.timedChannelInfo->internalRedirectCount() = mInternalRedirectCount;
4700 config.timedChannelInfo->asyncOpen() = mAsyncOpenTime;
4701 config.timedChannelInfo->channelCreation() = mChannelCreationTimestamp;
4702 config.timedChannelInfo->redirectStart() = mRedirectStartTimeStamp;
4703 config.timedChannelInfo->redirectEnd() = mRedirectEndTimeStamp;
4704 config.timedChannelInfo->initiatorType() = mInitiatorType;
4705 config.timedChannelInfo->allRedirectsSameOrigin() =
4706 LoadAllRedirectsSameOrigin();
4707 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() =
4708 LoadAllRedirectsPassTimingAllowCheck();
4709 // Execute the timing allow check to determine whether
4710 // to report the redirect timing info
4711 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
4712 // TYPE_DOCUMENT loads don't have a loadingPrincipal, so we can't set
4713 // AllRedirectsPassTimingAllowCheck on them.
4714 if (loadInfo->GetExternalContentPolicyType() !=
4715 ExtContentPolicy::TYPE_DOCUMENT) {
4716 nsCOMPtr<nsIPrincipal> principal = loadInfo->GetLoadingPrincipal();
4717 config.timedChannelInfo->timingAllowCheckForPrincipal() =
4718 Some(oldTimedChannel->TimingAllowCheck(principal));
4719 }
4720
4721 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() =
4722 LoadAllRedirectsPassTimingAllowCheck();
4723 config.timedChannelInfo->launchServiceWorkerStart() =
4724 mLaunchServiceWorkerStart;
4725 config.timedChannelInfo->launchServiceWorkerEnd() = mLaunchServiceWorkerEnd;
4726 config.timedChannelInfo->dispatchFetchEventStart() =
4727 mDispatchFetchEventStart;
4728 config.timedChannelInfo->dispatchFetchEventEnd() = mDispatchFetchEventEnd;
4729 config.timedChannelInfo->handleFetchEventStart() = mHandleFetchEventStart;
4730 config.timedChannelInfo->handleFetchEventEnd() = mHandleFetchEventEnd;
4731 config.timedChannelInfo->responseStart() =
4732 mTransactionTimings.responseStart;
4733 config.timedChannelInfo->responseEnd() = mTransactionTimings.responseEnd;
4734 }
4735
4736 if (aPreserveMethod) {
4737 // since preserveMethod is true, we need to ensure that the appropriate
4738 // request method gets set on the channel, regardless of whether or not
4739 // we set the upload stream above. This means SetRequestMethod() will
4740 // be called twice if ExplicitSetUploadStream() gets called above.
4741
4742 nsAutoCString method;
4743 mRequestHead.Method(method);
4744 config.method = Some(method);
4745
4746 if (mUploadStream) {
4747 // rewind upload stream
4748 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
4749 if (seekable) {
4750 seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
4751 }
4752 config.uploadStream = mUploadStream;
4753 }
4754 config.uploadStreamLength = mReqContentLength;
4755 config.uploadStreamHasHeaders = LoadUploadStreamHasHeaders();
4756
4757 nsAutoCString contentType;
4758 nsresult rv = mRequestHead.GetHeader(nsHttp::Content_Type, contentType);
4759 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4760 config.contentType = Some(contentType);
4761 }
4762
4763 nsAutoCString contentLength;
4764 rv = mRequestHead.GetHeader(nsHttp::Content_Length, contentLength);
4765 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4766 config.contentLength = Some(contentLength);
4767 }
4768 }
4769
4770 return config;
4771}
4772
4773/* static */ void HttpBaseChannel::ConfigureReplacementChannel(
4774 nsIChannel* newChannel, const ReplacementChannelConfig& config,
4775 ReplacementReason aReason) {
4776 nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(newChannel));
4777 if (cos) {
4778 cos->SetClassOfService(config.classOfService);
4779 }
4780
4781 // Try to preserve the privacy bit if it has been overridden
4782 if (config.privateBrowsing) {
4783 nsCOMPtr<nsIPrivateBrowsingChannel> newPBChannel =
4784 do_QueryInterface(newChannel);
4785 if (newPBChannel) {
4786 newPBChannel->SetPrivate(*config.privateBrowsing);
4787 }
4788 }
4789
4790 // Transfer the timing data (if we are dealing with an nsITimedChannel).
4791 nsCOMPtr<nsITimedChannel> newTimedChannel(do_QueryInterface(newChannel));
4792 if (config.timedChannelInfo && newTimedChannel) {
4793 newTimedChannel->SetTimingEnabled(config.timedChannelInfo->timingEnabled());
4794
4795 // If we're an internal redirect, or a document channel replacement,
4796 // then we shouldn't record any new timing for this and just copy
4797 // over the existing values.
4798 bool shouldHideTiming = aReason != ReplacementReason::Redirect;
4799 if (shouldHideTiming) {
4800 newTimedChannel->SetRedirectCount(
4801 config.timedChannelInfo->redirectCount());
4802 int32_t newCount = config.timedChannelInfo->internalRedirectCount() + 1;
4803 newTimedChannel->SetInternalRedirectCount(std::max(
4804 newCount, static_cast<int32_t>(
4805 config.timedChannelInfo->internalRedirectCount())));
4806 } else {
4807 int32_t newCount = config.timedChannelInfo->redirectCount() + 1;
4808 newTimedChannel->SetRedirectCount(std::max(
4809 newCount,
4810 static_cast<int32_t>(config.timedChannelInfo->redirectCount())));
4811 newTimedChannel->SetInternalRedirectCount(
4812 config.timedChannelInfo->internalRedirectCount());
4813 }
4814
4815 if (shouldHideTiming) {
4816 if (!config.timedChannelInfo->channelCreation().IsNull()) {
4817 newTimedChannel->SetChannelCreation(
4818 config.timedChannelInfo->channelCreation());
4819 }
4820
4821 if (!config.timedChannelInfo->asyncOpen().IsNull()) {
4822 newTimedChannel->SetAsyncOpen(config.timedChannelInfo->asyncOpen());
4823 }
4824 }
4825
4826 // If the RedirectStart is null, we will use the AsyncOpen value of the
4827 // previous channel (this is the first redirect in the redirects chain).
4828 if (config.timedChannelInfo->redirectStart().IsNull()) {
4829 // Only do this for real redirects. Internal redirects should be hidden.
4830 if (!shouldHideTiming) {
4831 newTimedChannel->SetRedirectStart(config.timedChannelInfo->asyncOpen());
4832 }
4833 } else {
4834 newTimedChannel->SetRedirectStart(
4835 config.timedChannelInfo->redirectStart());
4836 }
4837
4838 // For internal redirects just propagate the last redirect end time
4839 // forward. Otherwise the new redirect end time is the last response
4840 // end time.
4841 TimeStamp newRedirectEnd;
4842 if (shouldHideTiming) {
4843 newRedirectEnd = config.timedChannelInfo->redirectEnd();
4844 } else if (!config.timedChannelInfo->responseEnd().IsNull()) {
4845 newRedirectEnd = config.timedChannelInfo->responseEnd();
4846 } else {
4847 newRedirectEnd = TimeStamp::Now();
4848 }
4849 newTimedChannel->SetRedirectEnd(newRedirectEnd);
4850
4851 newTimedChannel->SetInitiatorType(config.timedChannelInfo->initiatorType());
4852
4853 nsCOMPtr<nsILoadInfo> loadInfo = newChannel->LoadInfo();
4854 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4854); AnnotateMozCrashReason("MOZ_ASSERT" "(" "loadInfo" ")"
); do { *((volatile int*)__null) = 4854; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4855
4856 newTimedChannel->SetAllRedirectsSameOrigin(
4857 config.timedChannelInfo->allRedirectsSameOrigin());
4858
4859 if (config.timedChannelInfo->timingAllowCheckForPrincipal()) {
4860 newTimedChannel->SetAllRedirectsPassTimingAllowCheck(
4861 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() &&
4862 *config.timedChannelInfo->timingAllowCheckForPrincipal());
4863 }
4864
4865 // Propagate service worker measurements across redirects. The
4866 // PeformanceResourceTiming.workerStart API expects to see the
4867 // worker start time after a redirect.
4868 newTimedChannel->SetLaunchServiceWorkerStart(
4869 config.timedChannelInfo->launchServiceWorkerStart());
4870 newTimedChannel->SetLaunchServiceWorkerEnd(
4871 config.timedChannelInfo->launchServiceWorkerEnd());
4872 newTimedChannel->SetDispatchFetchEventStart(
4873 config.timedChannelInfo->dispatchFetchEventStart());
4874 newTimedChannel->SetDispatchFetchEventEnd(
4875 config.timedChannelInfo->dispatchFetchEventEnd());
4876 newTimedChannel->SetHandleFetchEventStart(
4877 config.timedChannelInfo->handleFetchEventStart());
4878 newTimedChannel->SetHandleFetchEventEnd(
4879 config.timedChannelInfo->handleFetchEventEnd());
4880 }
4881
4882 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
4883 if (!httpChannel) {
4884 return; // no other options to set
4885 }
4886
4887 if (config.uploadStream) {
4888 nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(httpChannel);
4889 nsCOMPtr<nsIUploadChannel2> uploadChannel2 = do_QueryInterface(httpChannel);
4890 if (uploadChannel2 || uploadChannel) {
4891 // replicate original call to SetUploadStream...
4892 if (uploadChannel2) {
4893 const nsACString& ctype =
4894 config.contentType ? *config.contentType : VoidCString();
4895 // If header is not present mRequestHead.HasHeaderValue will truncated
4896 // it. But we want to end up with a void string, not an empty string,
4897 // because ExplicitSetUploadStream treats the former as "no header" and
4898 // the latter as "header with empty string value".
4899
4900 const nsACString& method =
4901 config.method ? *config.method : VoidCString();
4902
4903 uploadChannel2->ExplicitSetUploadStream(
4904 config.uploadStream, ctype, config.uploadStreamLength, method,
4905 config.uploadStreamHasHeaders);
4906 } else {
4907 if (config.uploadStreamHasHeaders) {
4908 uploadChannel->SetUploadStream(config.uploadStream, ""_ns,
4909 config.uploadStreamLength);
4910 } else {
4911 nsAutoCString ctype;
4912 if (config.contentType) {
4913 ctype = *config.contentType;
4914 } else {
4915 ctype = "application/octet-stream"_ns;
4916 }
4917 if (config.contentLength && !config.contentLength->IsEmpty()) {
4918 uploadChannel->SetUploadStream(
4919 config.uploadStream, ctype,
4920 nsCRT::atoll(config.contentLength->get()));
4921 }
4922 }
4923 }
4924 }
4925 }
4926
4927 if (config.referrerInfo) {
4928 DebugOnly<nsresult> success{};
4929 success = httpChannel->SetReferrerInfo(config.referrerInfo);
4930 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)))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4930); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)), 1)))"
")"); do { *((volatile int*)__null) = 4930; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4931 }
4932
4933 if (config.method) {
4934 DebugOnly<nsresult> rv = httpChannel->SetRequestMethod(*config.method);
4935 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4935); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4935; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4936 }
4937}
4938
4939HttpBaseChannel::ReplacementChannelConfig::ReplacementChannelConfig(
4940 const dom::ReplacementChannelConfigInit& aInit) {
4941 redirectFlags = aInit.redirectFlags();
4942 classOfService = aInit.classOfService();
4943 privateBrowsing = aInit.privateBrowsing();
4944 method = aInit.method();
4945 referrerInfo = aInit.referrerInfo();
4946 timedChannelInfo = aInit.timedChannelInfo();
4947 uploadStream = aInit.uploadStream();
4948 uploadStreamLength = aInit.uploadStreamLength();
4949 uploadStreamHasHeaders = aInit.uploadStreamHasHeaders();
4950 contentType = aInit.contentType();
4951 contentLength = aInit.contentLength();
4952}
4953
4954dom::ReplacementChannelConfigInit
4955HttpBaseChannel::ReplacementChannelConfig::Serialize() {
4956 dom::ReplacementChannelConfigInit config;
4957 config.redirectFlags() = redirectFlags;
4958 config.classOfService() = classOfService;
4959 config.privateBrowsing() = privateBrowsing;
4960 config.method() = method;
4961 config.referrerInfo() = referrerInfo;
4962 config.timedChannelInfo() = timedChannelInfo;
4963 config.uploadStream() =
4964 uploadStream ? RemoteLazyInputStream::WrapStream(uploadStream) : nullptr;
4965 config.uploadStreamLength() = uploadStreamLength;
4966 config.uploadStreamHasHeaders() = uploadStreamHasHeaders;
4967 config.contentType() = contentType;
4968 config.contentLength() = contentLength;
4969
4970 return config;
4971}
4972
4973nsresult HttpBaseChannel::SetupReplacementChannel(nsIURI* newURI,
4974 nsIChannel* newChannel,
4975 bool preserveMethod,
4976 uint32_t redirectFlags) {
4977 nsresult rv;
4978
4979 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)
4980 ("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)
4981 "[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)
4982 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)
;
4983
4984 // Ensure the channel's loadInfo's result principal URI so that it's
4985 // either non-null or updated to the redirect target URI.
4986 // We must do this because in case the loadInfo's result principal URI
4987 // is null, it would be taken from OriginalURI of the channel. But we
4988 // overwrite it with the whole redirect chain first URI before opening
4989 // the target channel, hence the information would be lost.
4990 // If the protocol handler that created the channel wants to use
4991 // the originalURI of the channel as the principal URI, this fulfills
4992 // that request - newURI is the original URI of the channel.
4993 nsCOMPtr<nsILoadInfo> newLoadInfo = newChannel->LoadInfo();
4994 nsCOMPtr<nsIURI> resultPrincipalURI;
4995 rv = newLoadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
4996 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4996); return rv; } } while (false)
;
4997 if (!resultPrincipalURI) {
4998 rv = newLoadInfo->SetResultPrincipalURI(newURI);
4999 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4999); return rv; } } while (false)
;
5000 }
5001
5002 nsLoadFlags loadFlags = mLoadFlags;
5003 loadFlags |= LOAD_REPLACE;
5004
5005 // if the original channel was using SSL and this channel is not using
5006 // SSL, then no need to inhibit persistent caching. however, if the
5007 // original channel was not using SSL and has INHIBIT_PERSISTENT_CACHING
5008 // set, then allow the flag to apply to the redirected channel as well.
5009 // since we force set INHIBIT_PERSISTENT_CACHING on all HTTPS channels,
5010 // we only need to check if the original channel was using SSL.
5011 if (mURI->SchemeIs("https")) {
5012 loadFlags &= ~INHIBIT_PERSISTENT_CACHING;
5013 }
5014
5015 newChannel->SetLoadFlags(loadFlags);
5016
5017 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
5018
5019 ReplacementReason redirectType =
5020 (redirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL)
5021 ? ReplacementReason::InternalRedirect
5022 : ReplacementReason::Redirect;
5023 ReplacementChannelConfig config = CloneReplacementChannelConfig(
5024 preserveMethod, redirectFlags, redirectType);
5025 ConfigureReplacementChannel(newChannel, config, redirectType);
5026
5027 // Check whether or not this was a cross-domain redirect.
5028 nsCOMPtr<nsITimedChannel> newTimedChannel(do_QueryInterface(newChannel));
5029 bool sameOriginWithOriginalUri = SameOriginWithOriginalUri(newURI);
5030 if (config.timedChannelInfo && newTimedChannel) {
5031 newTimedChannel->SetAllRedirectsSameOrigin(
5032 config.timedChannelInfo->allRedirectsSameOrigin() &&
5033 sameOriginWithOriginalUri);
5034 }
5035
5036 newChannel->SetLoadGroup(mLoadGroup);
5037 newChannel->SetNotificationCallbacks(mCallbacks);
5038 // TODO: create tests for cross-origin redirect in bug 1662896.
5039 if (sameOriginWithOriginalUri) {
5040 newChannel->SetContentDisposition(mContentDispositionHint);
5041 if (mContentDispositionFilename) {
5042 newChannel->SetContentDispositionFilename(*mContentDispositionFilename);
5043 }
5044 }
5045
5046 if (!httpChannel) return NS_OK; // no other options to set
5047
5048 // Preserve the CORS preflight information.
5049 nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(newChannel);
5050 if (httpInternal) {
5051 httpInternal->SetLastRedirectFlags(redirectFlags);
5052
5053 if (LoadRequireCORSPreflight()) {
5054 httpInternal->SetCorsPreflightParameters(mUnsafeHeaders, false, false);
5055 }
5056 }
5057
5058 // convey the LoadAllowSTS() flags
5059 rv = httpChannel->SetAllowSTS(LoadAllowSTS());
5060 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5060); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5060; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5061
5062 // convey the Accept header value
5063 {
5064 nsAutoCString oldAcceptValue;
5065 nsresult hasHeader = mRequestHead.GetHeader(nsHttp::Accept, oldAcceptValue);
5066 if (NS_SUCCEEDED(hasHeader)((bool)(__builtin_expect(!!(!NS_FAILED_impl(hasHeader)), 1)))) {
5067 rv = httpChannel->SetRequestHeader("Accept"_ns, oldAcceptValue, false);
5068 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5068); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5068; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5069 }
5070 }
5071
5072 // convey the User-Agent header value
5073 // since we might be setting custom user agent from DevTools.
5074 if (httpInternal && mRequestMode == RequestMode::No_cors &&
5075 redirectType == ReplacementReason::Redirect) {
5076 nsAutoCString oldUserAgent;
5077 nsresult hasHeader =
5078 mRequestHead.GetHeader(nsHttp::User_Agent, oldUserAgent);
5079 if (NS_SUCCEEDED(hasHeader)((bool)(__builtin_expect(!!(!NS_FAILED_impl(hasHeader)), 1)))) {
5080 rv = httpChannel->SetRequestHeader("User-Agent"_ns, oldUserAgent, false);
5081 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5081); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5081; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5082 }
5083 }
5084
5085 // convery the IsUserAgentHeaderModified value.
5086 if (httpInternal) {
5087 rv = httpInternal->SetIsUserAgentHeaderModified(
5088 LoadIsUserAgentHeaderModified());
5089 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5089); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5089; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5090 }
5091
5092 // share the request context - see bug 1236650
5093 rv = httpChannel->SetRequestContextID(mRequestContextID);
5094 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5094); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5094; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5095
5096 // When on the parent process, the channel can't attempt to get it itself.
5097 // When on the child process, it would be waste to query it again.
5098 rv = httpChannel->SetBrowserId(mBrowserId);
5099 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5099; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5100
5101 // Not setting this flag would break carrying permissions down to the child
5102 // process when the channel is artificially forced to be a main document load.
5103 rv = httpChannel->SetIsMainDocumentChannel(LoadForceMainDocumentChannel());
5104 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5104); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5104; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5105
5106 // Preserve the loading order
5107 nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(newChannel);
5108 if (p) {
5109 p->SetPriority(mPriority);
5110 }
5111
5112 if (httpInternal) {
5113 // Convey third party cookie, conservative, and spdy flags.
5114 rv = httpInternal->SetThirdPartyFlags(LoadThirdPartyFlags());
5115 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5115); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5115; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5116 rv = httpInternal->SetAllowSpdy(LoadAllowSpdy());
5117 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5117); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5117; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5118 rv = httpInternal->SetAllowHttp3(LoadAllowHttp3());
5119 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5119); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5119; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5120 rv = httpInternal->SetAllowAltSvc(LoadAllowAltSvc());
5121 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5121); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5121; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5122 rv = httpInternal->SetBeConservative(LoadBeConservative());
5123 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5123); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5123; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5124 rv = httpInternal->SetIsTRRServiceChannel(LoadIsTRRServiceChannel());
5125 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5125); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5125; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5126 rv = httpInternal->SetTlsFlags(mTlsFlags);
5127 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5127); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5127; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5128
5129 // Ensure the type of realChannel involves all types it may redirect to.
5130 // Such as nsHttpChannel and InterceptedChannel.
5131 // Even thought InterceptedChannel itself doesn't require these information,
5132 // it may still be necessary for the following redirections.
5133 // E.g. nsHttpChannel -> InterceptedChannel -> nsHttpChannel
5134 RefPtr<HttpBaseChannel> realChannel;
5135 CallQueryInterface(newChannel, realChannel.StartAssignment());
5136 if (realChannel) {
5137 realChannel->SetTopWindowURI(mTopWindowURI);
5138
5139 realChannel->StoreTaintedOriginFlag(
5140 ShouldTaintReplacementChannelOrigin(newChannel, redirectFlags));
5141 }
5142
5143 // update the DocumentURI indicator since we are being redirected.
5144 // if this was a top-level document channel, then the new channel
5145 // should have its mDocumentURI point to newURI; otherwise, we
5146 // just need to pass along our mDocumentURI to the new channel.
5147 if (newURI && (mURI == mDocumentURI)) {
5148 rv = httpInternal->SetDocumentURI(newURI);
5149 } else {
5150 rv = httpInternal->SetDocumentURI(mDocumentURI);
5151 }
5152 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5152); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5152; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5153
5154 // if there is a chain of keys for redirect-responses we transfer it to
5155 // the new channel (see bug #561276)
5156 {
5157 auto redirectedCachekeys = mRedirectedCachekeys.Lock();
5158 auto& ref = redirectedCachekeys.ref();
5159 if (ref) {
5160 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)
5161 ("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)
5162 "[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)
5163 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)
;
5164 rv = httpInternal->SetCacheKeysRedirectChain(ref.release());
5165 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5165); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5165; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5166 }
5167 }
5168
5169 // Preserve Request mode.
5170 rv = httpInternal->SetRequestMode(mRequestMode);
5171 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5171); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5171; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5172
5173 // Preserve Redirect mode flag.
5174 rv = httpInternal->SetRedirectMode(mRedirectMode);
5175 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5175); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5175; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5176
5177 // Preserve Integrity metadata.
5178 rv = httpInternal->SetIntegrityMetadata(mIntegrityMetadata);
5179 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5179; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5180
5181 httpInternal->SetAltDataForChild(LoadAltDataForChild());
5182 if (LoadDisableAltDataCache()) {
5183 httpInternal->DisableAltDataCache();
5184 }
5185 }
5186
5187 // transfer any properties
5188 nsCOMPtr<nsIWritablePropertyBag> bag(do_QueryInterface(newChannel));
5189 if (bag) {
5190 for (const auto& entry : mPropertyHash) {
5191 bag->SetProperty(entry.GetKey(), entry.GetWeak());
5192 }
5193 }
5194
5195 // Pass the preferred alt-data type on to the new channel.
5196 nsCOMPtr<nsICacheInfoChannel> cacheInfoChan(do_QueryInterface(newChannel));
5197 if (cacheInfoChan) {
5198 for (auto& data : mPreferredCachedAltDataTypes) {
5199 cacheInfoChan->PreferAlternativeDataType(data.type(), data.contentType(),
5200 data.deliverAltData());
5201 }
5202
5203 if (LoadForceValidateCacheContent()) {
5204 Unused << cacheInfoChan->SetForceValidateCacheContent(true);
5205 }
5206 }
5207
5208 if (redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
5209 nsIChannelEventSink::REDIRECT_STS_UPGRADE)) {
5210 // Copy non-origin related headers to the new channel.
5211 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
5212 new AddHeadersToChannelVisitor(httpChannel);
5213 rv = mRequestHead.VisitHeaders(visitor);
5214 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5214); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5214; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5215 }
5216
5217 // we need to strip Authentication headers for cross-origin requests
5218 // Ref: https://fetch.spec.whatwg.org/#http-redirect-fetch
5219 nsAutoCString authHeader;
5220 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetRequestHeader
("Authorization"_ns, authHeader))), 1)))
5221 httpChannel->GetRequestHeader("Authorization"_ns, authHeader))((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetRequestHeader
("Authorization"_ns, authHeader))), 1)))
&&
5222 NS_ShouldRemoveAuthHeaderOnRedirect(static_cast<nsIChannel*>(this),
5223 newChannel, redirectFlags)) {
5224 rv = httpChannel->SetRequestHeader("Authorization"_ns, ""_ns, false);
5225 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)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5225); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5225; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5226 }
5227
5228 return NS_OK;
5229}
5230
5231// check whether the new channel is of same origin as the current channel
5232bool HttpBaseChannel::IsNewChannelSameOrigin(nsIChannel* aNewChannel) {
5233 bool isSameOrigin = false;
5234 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5235
5236 if (!ssm) {
5237 return false;
5238 }
5239
5240 nsCOMPtr<nsIURI> newURI;
5241 NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
5242
5243 nsresult rv = ssm->CheckSameOriginURI(newURI, mURI, false, false);
5244 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5245 isSameOrigin = true;
5246 }
5247
5248 return isSameOrigin;
5249}
5250
5251bool HttpBaseChannel::ShouldTaintReplacementChannelOrigin(
5252 nsIChannel* aNewChannel, uint32_t aRedirectFlags) {
5253 if (LoadTaintedOriginFlag()) {
5254 return true;
5255 }
5256
5257 if (NS_IsInternalSameURIRedirect(this, aNewChannel, aRedirectFlags) ||
5258 NS_IsHSTSUpgradeRedirect(this, aNewChannel, aRedirectFlags)) {
5259 return false;
5260 }
5261
5262 // If new channel is not of same origin we need to taint unless
5263 // mURI <-> mOriginalURI/LoadingPrincipal are same origin.
5264 if (IsNewChannelSameOrigin(aNewChannel)) {
5265 return false;
5266 }
5267
5268 nsresult rv;
5269
5270 if (mLoadInfo->GetLoadingPrincipal()) {
5271 bool sameOrigin = false;
5272 rv = mLoadInfo->GetLoadingPrincipal()->IsSameOrigin(mURI, &sameOrigin);
5273 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5274 return true;
5275 }
5276 return !sameOrigin;
5277 }
5278 if (!mOriginalURI) {
5279 return true;
5280 }
5281
5282 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5283 if (!ssm) {
5284 return true;
5285 }
5286
5287 rv = ssm->CheckSameOriginURI(mOriginalURI, mURI, false, false);
5288 return NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)));
5289}
5290
5291// Redirect Tracking
5292bool HttpBaseChannel::SameOriginWithOriginalUri(nsIURI* aURI) {
5293 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5294 bool isPrivateWin = mLoadInfo->GetOriginAttributes().IsPrivateBrowsing();
5295 nsresult rv =
5296 ssm->CheckSameOriginURI(aURI, mOriginalURI, false, isPrivateWin);
5297 return (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))));
5298}
5299
5300//-----------------------------------------------------------------------------
5301// HttpBaseChannel::nsIClassifiedChannel
5302
5303NS_IMETHODIMPnsresult
5304HttpBaseChannel::GetMatchedList(nsACString& aList) {
5305 aList = mMatchedList;
5306 return NS_OK;
5307}
5308
5309NS_IMETHODIMPnsresult
5310HttpBaseChannel::GetMatchedProvider(nsACString& aProvider) {
5311 aProvider = mMatchedProvider;
5312 return NS_OK;
5313}
5314
5315NS_IMETHODIMPnsresult
5316HttpBaseChannel::GetMatchedFullHash(nsACString& aFullHash) {
5317 aFullHash = mMatchedFullHash;
5318 return NS_OK;
5319}
5320
5321NS_IMETHODIMPnsresult
5322HttpBaseChannel::SetMatchedInfo(const nsACString& aList,
5323 const nsACString& aProvider,
5324 const nsACString& aFullHash) {
5325 NS_ENSURE_ARG(!aList.IsEmpty())do { if ((__builtin_expect(!!(!(!aList.IsEmpty())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!aList.IsEmpty()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5325); return NS_ERROR_INVALID_ARG; } } while (false)
;
5326
5327 mMatchedList = aList;
5328 mMatchedProvider = aProvider;
5329 mMatchedFullHash = aFullHash;
5330 return NS_OK;
5331}
5332
5333NS_IMETHODIMPnsresult
5334HttpBaseChannel::GetMatchedTrackingLists(nsTArray<nsCString>& aLists) {
5335 aLists = mMatchedTrackingLists.Clone();
5336 return NS_OK;
5337}
5338
5339NS_IMETHODIMPnsresult
5340HttpBaseChannel::GetMatchedTrackingFullHashes(
5341 nsTArray<nsCString>& aFullHashes) {
5342 aFullHashes = mMatchedTrackingFullHashes.Clone();
5343 return NS_OK;
5344}
5345
5346NS_IMETHODIMPnsresult
5347HttpBaseChannel::SetMatchedTrackingInfo(
5348 const nsTArray<nsCString>& aLists, const nsTArray<nsCString>& aFullHashes) {
5349 NS_ENSURE_ARG(!aLists.IsEmpty())do { if ((__builtin_expect(!!(!(!aLists.IsEmpty())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!aLists.IsEmpty()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5349); return NS_ERROR_INVALID_ARG; } } while (false)
;
5350 // aFullHashes can be empty for non hash-matching algorithm, for example,
5351 // host based test entries in preference.
5352
5353 mMatchedTrackingLists = aLists.Clone();
5354 mMatchedTrackingFullHashes = aFullHashes.Clone();
5355 return NS_OK;
5356}
5357//-----------------------------------------------------------------------------
5358// HttpBaseChannel::nsITimedChannel
5359//-----------------------------------------------------------------------------
5360
5361NS_IMETHODIMPnsresult
5362HttpBaseChannel::SetTimingEnabled(bool enabled) {
5363 StoreTimingEnabled(enabled);
5364 return NS_OK;
5365}
5366
5367NS_IMETHODIMPnsresult
5368HttpBaseChannel::GetTimingEnabled(bool* _retval) {
5369 *_retval = LoadTimingEnabled();
5370 return NS_OK;
5371}
5372
5373NS_IMETHODIMPnsresult
5374HttpBaseChannel::GetChannelCreation(TimeStamp* _retval) {
5375 *_retval = mChannelCreationTimestamp;
5376 return NS_OK;
5377}
5378
5379NS_IMETHODIMPnsresult
5380HttpBaseChannel::SetChannelCreation(TimeStamp aValue) {
5381 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5381); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!aValue.IsNull()"
")"); do { *((volatile int*)__null) = 5381; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5382 TimeDuration adjust = aValue - mChannelCreationTimestamp;
5383 mChannelCreationTimestamp = aValue;
5384 mChannelCreationTime += (PRTime)adjust.ToMicroseconds();
5385 return NS_OK;
5386}
5387
5388NS_IMETHODIMPnsresult
5389HttpBaseChannel::GetAsyncOpen(TimeStamp* _retval) {
5390 *_retval = mAsyncOpenTime;
5391 return NS_OK;
5392}
5393
5394NS_IMETHODIMPnsresult
5395HttpBaseChannel::SetAsyncOpen(TimeStamp aValue) {
5396 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5396); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!aValue.IsNull()"
")"); do { *((volatile int*)__null) = 5396; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5397 mAsyncOpenTime = aValue;
5398 StoreAsyncOpenTimeOverriden(true);
5399 return NS_OK;
5400}
5401
5402/**
5403 * @return the number of redirects. There is no check for cross-domain
5404 * redirects. This check must be done by the consumers.
5405 */
5406NS_IMETHODIMPnsresult
5407HttpBaseChannel::GetRedirectCount(uint8_t* aRedirectCount) {
5408 *aRedirectCount = mRedirectCount;
5409 return NS_OK;
5410}
5411
5412NS_IMETHODIMPnsresult
5413HttpBaseChannel::SetRedirectCount(uint8_t aRedirectCount) {
5414 mRedirectCount = aRedirectCount;
5415 return NS_OK;
5416}
5417
5418NS_IMETHODIMPnsresult
5419HttpBaseChannel::GetInternalRedirectCount(uint8_t* aRedirectCount) {
5420 *aRedirectCount = mInternalRedirectCount;
5421 return NS_OK;
5422}
5423
5424NS_IMETHODIMPnsresult
5425HttpBaseChannel::SetInternalRedirectCount(uint8_t aRedirectCount) {
5426 mInternalRedirectCount = aRedirectCount;
5427 return NS_OK;
5428}
5429
5430NS_IMETHODIMPnsresult
5431HttpBaseChannel::GetRedirectStart(TimeStamp* _retval) {
5432 *_retval = mRedirectStartTimeStamp;
5433 return NS_OK;
5434}
5435
5436NS_IMETHODIMPnsresult
5437HttpBaseChannel::SetRedirectStart(TimeStamp aRedirectStart) {
5438 mRedirectStartTimeStamp = aRedirectStart;
5439 return NS_OK;
5440}
5441
5442NS_IMETHODIMPnsresult
5443HttpBaseChannel::GetRedirectEnd(TimeStamp* _retval) {
5444 *_retval = mRedirectEndTimeStamp;
5445 return NS_OK;
5446}
5447
5448NS_IMETHODIMPnsresult
5449HttpBaseChannel::SetRedirectEnd(TimeStamp aRedirectEnd) {
5450 mRedirectEndTimeStamp = aRedirectEnd;
5451 return NS_OK;
5452}
5453
5454NS_IMETHODIMPnsresult
5455HttpBaseChannel::GetAllRedirectsSameOrigin(bool* aAllRedirectsSameOrigin) {
5456 *aAllRedirectsSameOrigin = LoadAllRedirectsSameOrigin();
5457 return NS_OK;
5458}
5459
5460NS_IMETHODIMPnsresult
5461HttpBaseChannel::SetAllRedirectsSameOrigin(bool aAllRedirectsSameOrigin) {
5462 StoreAllRedirectsSameOrigin(aAllRedirectsSameOrigin);
5463 return NS_OK;
5464}
5465
5466NS_IMETHODIMPnsresult
5467HttpBaseChannel::GetAllRedirectsPassTimingAllowCheck(bool* aPassesCheck) {
5468 *aPassesCheck = LoadAllRedirectsPassTimingAllowCheck();
5469 return NS_OK;
5470}
5471
5472NS_IMETHODIMPnsresult
5473HttpBaseChannel::SetAllRedirectsPassTimingAllowCheck(bool aPassesCheck) {
5474 StoreAllRedirectsPassTimingAllowCheck(aPassesCheck);
5475 return NS_OK;
5476}
5477
5478// https://fetch.spec.whatwg.org/#cors-check
5479bool HttpBaseChannel::PerformCORSCheck() {
5480 // Step 1
5481 // Let origin be the result of getting `Access-Control-Allow-Origin`
5482 // from response’s header list.
5483 nsAutoCString origin;
5484 nsresult rv = GetResponseHeader("Access-Control-Allow-Origin"_ns, origin);
5485
5486 // Step 2
5487 // If origin is null, then return failure. (Note: null, not 'null').
5488 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || origin.IsVoid()) {
5489 return false;
5490 }
5491
5492 // Step 3
5493 // If request’s credentials mode is not "include"
5494 // and origin is `*`, then return success.
5495 uint32_t cookiePolicy = mLoadInfo->GetCookiePolicy();
5496 if (cookiePolicy != nsILoadInfo::SEC_COOKIES_INCLUDE &&
5497 origin.EqualsLiteral("*")) {
5498 return true;
5499 }
5500
5501 // Step 4
5502 // If the result of byte-serializing a request origin
5503 // with request is not origin, then return failure.
5504 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5505 nsCOMPtr<nsIPrincipal> resourcePrincipal;
5506 rv = ssm->GetChannelURIPrincipal(this, getter_AddRefs(resourcePrincipal));
5507 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !resourcePrincipal) {
5508 return false;
5509 }
5510 nsAutoCString serializedOrigin;
5511 nsContentSecurityManager::GetSerializedOrigin(
5512 mLoadInfo->TriggeringPrincipal(), resourcePrincipal, serializedOrigin,
5513 mLoadInfo);
5514 if (!serializedOrigin.Equals(origin)) {
5515 return false;
5516 }
5517
5518 // Step 5
5519 // If request’s credentials mode is not "include", then return success.
5520 if (cookiePolicy != nsILoadInfo::SEC_COOKIES_INCLUDE) {
5521 return true;
5522 }
5523
5524 // Step 6
5525 // Let credentials be the result of getting
5526 // `Access-Control-Allow-Credentials` from response’s header list.
5527 nsAutoCString credentials;
5528 rv = GetResponseHeader("Access-Control-Allow-Credentials"_ns, credentials);
5529
5530 // Step 7 and 8
5531 // If credentials is `true`, then return success.
5532 // (else) return failure.
5533 return NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && credentials.EqualsLiteral("true");
5534}
5535
5536NS_IMETHODIMPnsresult
5537HttpBaseChannel::BodyInfoAccessAllowedCheck(nsIPrincipal* aOrigin,
5538 BodyInfoAccess* _retval) {
5539 // Per the Fetch spec, https://fetch.spec.whatwg.org/#response-body-info,
5540 // the bodyInfo for Resource Timing and Navigation Timing info consists of
5541 // encoded size, decoded size, and content type. It is however made opaque
5542 // whenever the response is turned into a network error, which sets its
5543 // bodyInfo to its default values (sizes=0, content-type="").
5544
5545 // Case 1:
5546 // "no-cors" -> Upon success, fetch will return an opaque filtered response.
5547 // An opaque(-redirect) filtered response is a filtered response
5548 // whose ... body info is a new response body info.
5549 auto tainting = mLoadInfo->GetTainting();
5550 if (tainting == mozilla::LoadTainting::Opaque) {
5551 *_retval = BodyInfoAccess::DISALLOWED;
5552 return NS_OK;
5553 }
5554
5555 // Case 2:
5556 // If request’s response tainting is "cors" and a CORS check for request
5557 // and response returns failure, then return a network error.
5558 if (tainting == mozilla::LoadTainting::CORS && !PerformCORSCheck()) {
5559 *_retval = BodyInfoAccess::DISALLOWED;
5560 return NS_OK;
5561 }
5562
5563 // Otherwise:
5564 // The fetch response handover, given a fetch params fetchParams
5565 // and a response response, run these steps:
5566 // processResponseEndOfBody:
5567 // - If fetchParams’s request’s mode is not "navigate" or response’s
5568 // has-cross-origin-redirects is false:
5569 // - Let mimeType be the result of extracting a MIME type from
5570 // response’s header list.
5571 // - If mimeType is not failure, then set bodyInfo’s content type to the
5572 // result of minimizing a supported MIME type given mimeType.
5573 dom::RequestMode requestMode;
5574 MOZ_ALWAYS_SUCCEEDS(GetRequestMode(&requestMode))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(GetRequestMode(&requestMode))), 1)))), 1))) { } else { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(GetRequestMode(&requestMode))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5574); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(GetRequestMode(&requestMode))" ")");
do { *((volatile int*)__null) = 5574; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
5575 if (requestMode != RequestMode::Navigate || LoadAllRedirectsSameOrigin()) {
5576 *_retval = BodyInfoAccess::ALLOW_ALL;
5577 return NS_OK;
5578 }
5579
5580 *_retval = BodyInfoAccess::ALLOW_SIZES;
5581 return NS_OK;
5582}
5583
5584// https://fetch.spec.whatwg.org/#tao-check
5585NS_IMETHODIMPnsresult
5586HttpBaseChannel::TimingAllowCheck(nsIPrincipal* aOrigin, bool* _retval) {
5587 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5588 nsCOMPtr<nsIPrincipal> resourcePrincipal;
5589 nsresult rv =
5590 ssm->GetChannelURIPrincipal(this, getter_AddRefs(resourcePrincipal));
5591 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !resourcePrincipal || !aOrigin) {
5592 *_retval = false;
5593 return NS_OK;
5594 }
5595
5596 bool sameOrigin = false;
5597 rv = resourcePrincipal->Equals(aOrigin, &sameOrigin);
Value stored to 'rv' is never read
5598
5599 nsAutoCString serializedOrigin;
5600 nsContentSecurityManager::GetSerializedOrigin(aOrigin, resourcePrincipal,
5601 serializedOrigin, mLoadInfo);
5602
5603 // All redirects are same origin
5604 if (sameOrigin && (!serializedOrigin.IsEmpty() &&
5605 !serializedOrigin.EqualsLiteral("null"))) {
5606 *_retval = true;
5607 return NS_OK;
5608 }
5609
5610 nsAutoCString headerValue;
5611 rv = GetResponseHeader("Timing-Allow-Origin"_ns, headerValue);
5612 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5613 *_retval = false;
5614 return NS_OK;
5615 }
5616
5617 Tokenizer p(headerValue);
5618 Tokenizer::Token t;
5619
5620 p.Record();
5621 nsAutoCString headerItem;
5622 while (p.Next(t)) {
5623 if (t.Type() == Tokenizer::TOKEN_EOF ||
5624 t.Equals(Tokenizer::Token::Char(','))) {
5625 p.Claim(headerItem);
5626 nsHttp::TrimHTTPWhitespace(headerItem, headerItem);
5627 // If the list item contains a case-sensitive match for the value of the
5628 // origin, or a wildcard, return pass
5629 if (headerItem == serializedOrigin || headerItem == "*") {
5630 *_retval = true;
5631 return NS_OK;
5632 }
5633 // We start recording again for the following items in the list
5634 p.Record();
5635 }
5636 }
5637
5638 *_retval = false;
5639 return NS_OK;
5640}
5641
5642NS_IMETHODIMPnsresult
5643HttpBaseChannel::GetLaunchServiceWorkerStart(TimeStamp* _retval) {
5644 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5644); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5644; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5645 *_retval = mLaunchServiceWorkerStart;
5646 return NS_OK;
5647}
5648
5649NS_IMETHODIMPnsresult
5650HttpBaseChannel::SetLaunchServiceWorkerStart(TimeStamp aTimeStamp) {
5651 mLaunchServiceWorkerStart = aTimeStamp;
5652 return NS_OK;
5653}
5654
5655NS_IMETHODIMPnsresult
5656HttpBaseChannel::GetLaunchServiceWorkerEnd(TimeStamp* _retval) {
5657 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5657); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5657; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5658 *_retval = mLaunchServiceWorkerEnd;
5659 return NS_OK;
5660}
5661
5662NS_IMETHODIMPnsresult
5663HttpBaseChannel::SetLaunchServiceWorkerEnd(TimeStamp aTimeStamp) {
5664 mLaunchServiceWorkerEnd = aTimeStamp;
5665 return NS_OK;
5666}
5667
5668NS_IMETHODIMPnsresult
5669HttpBaseChannel::GetDispatchFetchEventStart(TimeStamp* _retval) {
5670 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5670); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5670; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5671 *_retval = mDispatchFetchEventStart;
5672 return NS_OK;
5673}
5674
5675NS_IMETHODIMPnsresult
5676HttpBaseChannel::SetDispatchFetchEventStart(TimeStamp aTimeStamp) {
5677 mDispatchFetchEventStart = aTimeStamp;
5678 return NS_OK;
5679}
5680
5681NS_IMETHODIMPnsresult
5682HttpBaseChannel::GetDispatchFetchEventEnd(TimeStamp* _retval) {
5683 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5683); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5683; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5684 *_retval = mDispatchFetchEventEnd;
5685 return NS_OK;
5686}
5687
5688NS_IMETHODIMPnsresult
5689HttpBaseChannel::SetDispatchFetchEventEnd(TimeStamp aTimeStamp) {
5690 mDispatchFetchEventEnd = aTimeStamp;
5691 return NS_OK;
5692}
5693
5694NS_IMETHODIMPnsresult
5695HttpBaseChannel::GetHandleFetchEventStart(TimeStamp* _retval) {
5696 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5696); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5696; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5697 *_retval = mHandleFetchEventStart;
5698 return NS_OK;
5699}
5700
5701NS_IMETHODIMPnsresult
5702HttpBaseChannel::SetHandleFetchEventStart(TimeStamp aTimeStamp) {
5703 mHandleFetchEventStart = aTimeStamp;
5704 return NS_OK;
5705}
5706
5707NS_IMETHODIMPnsresult
5708HttpBaseChannel::GetHandleFetchEventEnd(TimeStamp* _retval) {
5709 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5709); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5709; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5710 *_retval = mHandleFetchEventEnd;
5711 return NS_OK;
5712}
5713
5714NS_IMETHODIMPnsresult
5715HttpBaseChannel::SetHandleFetchEventEnd(TimeStamp aTimeStamp) {
5716 mHandleFetchEventEnd = aTimeStamp;
5717 return NS_OK;
5718}
5719
5720NS_IMETHODIMPnsresult
5721HttpBaseChannel::GetDomainLookupStart(TimeStamp* _retval) {
5722 *_retval = mTransactionTimings.domainLookupStart;
5723 return NS_OK;
5724}
5725
5726NS_IMETHODIMPnsresult
5727HttpBaseChannel::GetDomainLookupEnd(TimeStamp* _retval) {
5728 *_retval = mTransactionTimings.domainLookupEnd;
5729 return NS_OK;
5730}
5731
5732NS_IMETHODIMPnsresult
5733HttpBaseChannel::GetConnectStart(TimeStamp* _retval) {
5734 *_retval = mTransactionTimings.connectStart;
5735 return NS_OK;
5736}
5737
5738NS_IMETHODIMPnsresult
5739HttpBaseChannel::GetTcpConnectEnd(TimeStamp* _retval) {
5740 *_retval = mTransactionTimings.tcpConnectEnd;
5741 return NS_OK;
5742}
5743
5744NS_IMETHODIMPnsresult
5745HttpBaseChannel::GetSecureConnectionStart(TimeStamp* _retval) {
5746 *_retval = mTransactionTimings.secureConnectionStart;
5747 return NS_OK;
5748}
5749
5750NS_IMETHODIMPnsresult
5751HttpBaseChannel::GetConnectEnd(TimeStamp* _retval) {
5752 *_retval = mTransactionTimings.connectEnd;
5753 return NS_OK;
5754}
5755
5756NS_IMETHODIMPnsresult
5757HttpBaseChannel::GetRequestStart(TimeStamp* _retval) {
5758 *_retval = mTransactionTimings.requestStart;
5759 return NS_OK;
5760}
5761
5762NS_IMETHODIMPnsresult
5763HttpBaseChannel::GetResponseStart(TimeStamp* _retval) {
5764 *_retval = mTransactionTimings.responseStart;
5765 return NS_OK;
5766}
5767
5768NS_IMETHODIMPnsresult
5769HttpBaseChannel::GetResponseEnd(TimeStamp* _retval) {
5770 *_retval = mTransactionTimings.responseEnd;
5771 return NS_OK;
5772}
5773
5774NS_IMETHODIMPnsresult
5775HttpBaseChannel::GetCacheReadStart(TimeStamp* _retval) {
5776 *_retval = mCacheReadStart;
5777 return NS_OK;
5778}
5779
5780NS_IMETHODIMPnsresult
5781HttpBaseChannel::GetCacheReadEnd(TimeStamp* _retval) {
5782 *_retval = mCacheReadEnd;
5783 return NS_OK;
5784}
5785
5786NS_IMETHODIMPnsresult
5787HttpBaseChannel::GetTransactionPending(TimeStamp* _retval) {
5788 *_retval = mTransactionTimings.transactionPending;
5789 return NS_OK;
5790}
5791
5792NS_IMETHODIMPnsresult
5793HttpBaseChannel::GetInitiatorType(nsAString& aInitiatorType) {
5794 aInitiatorType = mInitiatorType;
5795 return NS_OK;
5796}
5797
5798NS_IMETHODIMPnsresult
5799HttpBaseChannel::SetInitiatorType(const nsAString& aInitiatorType) {
5800 mInitiatorType = aInitiatorType;
5801 return NS_OK;
5802}
5803
5804#define IMPL_TIMING_ATTR(name) \
5805 NS_IMETHODIMPnsresult \
5806 HttpBaseChannel::Get##name##Time(PRTime* _retval) { \
5807 TimeStamp stamp; \
5808 Get##name(&stamp); \
5809 if (stamp.IsNull()) { \
5810 *_retval = 0; \
5811 return NS_OK; \
5812 } \
5813 *_retval = \
5814 mChannelCreationTime + \
5815 (PRTime)((stamp - mChannelCreationTimestamp).ToSeconds() * 1e6); \
5816 return NS_OK; \
5817 }
5818
5819IMPL_TIMING_ATTR(ChannelCreation)
5820IMPL_TIMING_ATTR(AsyncOpen)
5821IMPL_TIMING_ATTR(LaunchServiceWorkerStart)
5822IMPL_TIMING_ATTR(LaunchServiceWorkerEnd)
5823IMPL_TIMING_ATTR(DispatchFetchEventStart)
5824IMPL_TIMING_ATTR(DispatchFetchEventEnd)
5825IMPL_TIMING_ATTR(HandleFetchEventStart)
5826IMPL_TIMING_ATTR(HandleFetchEventEnd)
5827IMPL_TIMING_ATTR(DomainLookupStart)
5828IMPL_TIMING_ATTR(DomainLookupEnd)
5829IMPL_TIMING_ATTR(ConnectStart)
5830IMPL_TIMING_ATTR(TcpConnectEnd)
5831IMPL_TIMING_ATTR(SecureConnectionStart)
5832IMPL_TIMING_ATTR(ConnectEnd)
5833IMPL_TIMING_ATTR(RequestStart)
5834IMPL_TIMING_ATTR(ResponseStart)
5835IMPL_TIMING_ATTR(ResponseEnd)
5836IMPL_TIMING_ATTR(CacheReadStart)
5837IMPL_TIMING_ATTR(CacheReadEnd)
5838IMPL_TIMING_ATTR(RedirectStart)
5839IMPL_TIMING_ATTR(RedirectEnd)
5840IMPL_TIMING_ATTR(TransactionPending)
5841
5842#undef IMPL_TIMING_ATTR
5843
5844void HttpBaseChannel::MaybeReportTimingData() {
5845 // If performance timing is disabled, there is no need for the Performance
5846 // object anymore.
5847 if (!LoadTimingEnabled()) {
5848 return;
5849 }
5850
5851 // There is no point in continuing, since the performance object in the parent
5852 // isn't the same as the one in the child which will be reporting resource
5853 // performance.
5854 if (XRE_IsE10sParentProcess()) {
5855 return;
5856 }
5857
5858 // Devtools can create fetch requests on behalf the content document.
5859 // If we don't exclude these requests, they'd also be reported
5860 // to the content document.
5861 bool isInDevToolsContext;
5862 mLoadInfo->GetIsInDevToolsContext(&isInDevToolsContext);
5863 if (isInDevToolsContext) {
5864 return;
5865 }
5866
5867 mozilla::dom::PerformanceStorage* documentPerformance =
5868 mLoadInfo->GetPerformanceStorage();
5869 if (documentPerformance) {
5870 documentPerformance->AddEntry(this, this);
5871 return;
5872 }
5873
5874 if (!nsGlobalWindowInner::GetInnerWindowWithId(
5875 mLoadInfo->GetInnerWindowID())) {
5876 // The inner window is in a different process.
5877 dom::ContentChild* child = dom::ContentChild::GetSingleton();
5878
5879 if (!child) {
5880 return;
5881 }
5882 nsAutoString initiatorType;
5883 nsAutoString entryName;
5884
5885 UniquePtr<dom::PerformanceTimingData> performanceTimingData(
5886 dom::PerformanceTimingData::Create(this, this, 0, initiatorType,
5887 entryName));
5888 if (!performanceTimingData) {
5889 return;
5890 }
5891
5892 LoadInfoArgs loadInfoArgs;
5893 mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &loadInfoArgs);
5894 child->SendReportFrameTimingData(loadInfoArgs, entryName, initiatorType,
5895 std::move(performanceTimingData));
5896 }
5897}
5898
5899NS_IMETHODIMPnsresult
5900HttpBaseChannel::SetReportResourceTiming(bool enabled) {
5901 StoreReportTiming(enabled);
5902 return NS_OK;
5903}
5904
5905NS_IMETHODIMPnsresult
5906HttpBaseChannel::GetReportResourceTiming(bool* _retval) {
5907 *_retval = LoadReportTiming();
5908 return NS_OK;
5909}
5910
5911nsIURI* HttpBaseChannel::GetReferringPage() {
5912 nsCOMPtr<nsPIDOMWindowInner> pDomWindow = GetInnerDOMWindow();
5913 if (!pDomWindow) {
5914 return nullptr;
5915 }
5916 return pDomWindow->GetDocumentURI();
5917}
5918
5919nsPIDOMWindowInner* HttpBaseChannel::GetInnerDOMWindow() {
5920 nsCOMPtr<nsILoadContext> loadContext;
5921 NS_QueryNotificationCallbacks(this, loadContext);
5922 if (!loadContext) {
5923 return nullptr;
5924 }
5925 nsCOMPtr<mozIDOMWindowProxy> domWindow;
5926 loadContext->GetAssociatedWindow(getter_AddRefs(domWindow));
5927 if (!domWindow) {
5928 return nullptr;
5929 }
5930 auto* pDomWindow = nsPIDOMWindowOuter::From(domWindow);
5931 if (!pDomWindow) {
5932 return nullptr;
5933 }
5934 nsCOMPtr<nsPIDOMWindowInner> innerWindow =
5935 pDomWindow->GetCurrentInnerWindow();
5936 if (!innerWindow) {
5937 return nullptr;
5938 }
5939
5940 return innerWindow;
5941}
5942
5943//-----------------------------------------------------------------------------
5944// HttpBaseChannel::nsIThrottledInputChannel
5945//-----------------------------------------------------------------------------
5946
5947NS_IMETHODIMPnsresult
5948HttpBaseChannel::SetThrottleQueue(nsIInputChannelThrottleQueue* aQueue) {
5949 if (!XRE_IsParentProcess()) {
5950 return NS_ERROR_FAILURE;
5951 }
5952
5953 mThrottleQueue = aQueue;
5954 return NS_OK;
5955}
5956
5957NS_IMETHODIMPnsresult
5958HttpBaseChannel::GetThrottleQueue(nsIInputChannelThrottleQueue** aQueue) {
5959 NS_ENSURE_ARG_POINTER(aQueue)do { if ((__builtin_expect(!!(!(aQueue)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aQueue" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5959); return NS_ERROR_INVALID_POINTER; } } while (false)
;
5960 nsCOMPtr<nsIInputChannelThrottleQueue> queue = mThrottleQueue;
5961 queue.forget(aQueue);
5962 return NS_OK;
5963}
5964
5965//------------------------------------------------------------------------------
5966
5967bool HttpBaseChannel::EnsureRequestContextID() {
5968 if (mRequestContextID) {
5969 // Already have a request context ID, no need to do the rest of this work
5970 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)
5971 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)
;
5972 return true;
5973 }
5974
5975 // Find the loadgroup at the end of the chain in order
5976 // to make sure all channels derived from the load group
5977 // use the same connection scope.
5978 nsCOMPtr<nsILoadGroupChild> childLoadGroup = do_QueryInterface(mLoadGroup);
5979 if (!childLoadGroup) {
5980 return false;
5981 }
5982
5983 nsCOMPtr<nsILoadGroup> rootLoadGroup;
5984 childLoadGroup->GetRootLoadGroup(getter_AddRefs(rootLoadGroup));
5985 if (!rootLoadGroup) {
5986 return false;
5987 }
5988
5989 // Set the load group connection scope on this channel and its transaction
5990 rootLoadGroup->GetRequestContextID(&mRequestContextID);
5991
5992 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)
5993 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)
;
5994
5995 return true;
5996}
5997
5998bool HttpBaseChannel::EnsureRequestContext() {
5999 if (mRequestContext) {
6000 // Already have a request context, no need to do the rest of this work
6001 return true;
6002 }
6003
6004 if (!EnsureRequestContextID()) {
6005 return false;
6006 }
6007
6008 nsIRequestContextService* rcsvc = gHttpHandler->GetRequestContextService();
6009 if (!rcsvc) {
6010 return false;
6011 }
6012
6013 rcsvc->GetRequestContext(mRequestContextID, getter_AddRefs(mRequestContext));
6014 return static_cast<bool>(mRequestContext);
6015}
6016
6017void HttpBaseChannel::EnsureBrowserId() {
6018 if (mBrowserId) {
6019 return;
6020 }
6021
6022 RefPtr<dom::BrowsingContext> bc;
6023 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 { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6023); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
")"); do { *((volatile int*)__null) = 6023; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6024
6025 if (bc) {
6026 mBrowserId = bc->GetBrowserId();
6027 }
6028}
6029
6030void HttpBaseChannel::SetCorsPreflightParameters(
6031 const nsTArray<nsCString>& aUnsafeHeaders,
6032 bool aShouldStripRequestBodyHeader, bool aShouldStripAuthHeader) {
6033 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()", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6033); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequestObserversCalled()"
")"); do { *((volatile int*)__null) = 6033; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6034
6035 StoreRequireCORSPreflight(true);
6036 mUnsafeHeaders = aUnsafeHeaders.Clone();
6037 if (aShouldStripRequestBodyHeader || aShouldStripAuthHeader) {
6038 mUnsafeHeaders.RemoveElementsBy([&](const nsCString& aHeader) {
6039 return (aShouldStripRequestBodyHeader &&
6040 (aHeader.LowerCaseEqualsASCII("content-type") ||
6041 aHeader.LowerCaseEqualsASCII("content-encoding") ||
6042 aHeader.LowerCaseEqualsASCII("content-language") ||
6043 aHeader.LowerCaseEqualsASCII("content-location"))) ||
6044 (aShouldStripAuthHeader &&
6045 aHeader.LowerCaseEqualsASCII("authorization"));
6046 });
6047 }
6048}
6049
6050void HttpBaseChannel::SetAltDataForChild(bool aIsForChild) {
6051 StoreAltDataForChild(aIsForChild);
6052}
6053
6054NS_IMETHODIMPnsresult
6055HttpBaseChannel::GetBlockAuthPrompt(bool* aValue) {
6056 if (!aValue) {
6057 return NS_ERROR_FAILURE;
6058 }
6059
6060 *aValue = LoadBlockAuthPrompt();
6061 return NS_OK;
6062}
6063
6064NS_IMETHODIMPnsresult
6065HttpBaseChannel::SetBlockAuthPrompt(bool aValue) {
6066 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6066); 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("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6066, 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6066); } } 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6066); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 6066; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
6067
6068 StoreBlockAuthPrompt(aValue);
6069 return NS_OK;
6070}
6071
6072NS_IMETHODIMPnsresult
6073HttpBaseChannel::GetConnectionInfoHashKey(nsACString& aConnectionInfoHashKey) {
6074 if (!mConnectionInfo) {
6075 return NS_ERROR_FAILURE;
6076 }
6077 aConnectionInfoHashKey.Assign(mConnectionInfo->HashKey());
6078 return NS_OK;
6079}
6080
6081NS_IMETHODIMPnsresult
6082HttpBaseChannel::GetLastRedirectFlags(uint32_t* aValue) {
6083 NS_ENSURE_ARG(aValue)do { if ((__builtin_expect(!!(!(aValue)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aValue" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6083); return NS_ERROR_INVALID_ARG; } } while (false)
;
6084 *aValue = mLastRedirectFlags;
6085 return NS_OK;
6086}
6087
6088NS_IMETHODIMPnsresult
6089HttpBaseChannel::SetLastRedirectFlags(uint32_t aValue) {
6090 mLastRedirectFlags = aValue;
6091 return NS_OK;
6092}
6093
6094NS_IMETHODIMPnsresult
6095HttpBaseChannel::GetNavigationStartTimeStamp(TimeStamp* aTimeStamp) {
6096 return NS_ERROR_NOT_IMPLEMENTED;
6097}
6098
6099NS_IMETHODIMPnsresult
6100HttpBaseChannel::SetNavigationStartTimeStamp(TimeStamp aTimeStamp) {
6101 return NS_ERROR_NOT_IMPLEMENTED;
6102}
6103
6104nsresult HttpBaseChannel::CheckRedirectLimit(nsIURI* aNewURI,
6105 uint32_t aRedirectFlags) const {
6106 if (aRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
6107 // for internal redirect due to auth retry we do not have any limit
6108 // as we might restrict the number of times a user might retry
6109 // authentication
6110 if (aRedirectFlags & nsIChannelEventSink::REDIRECT_AUTH_RETRY) {
6111 return NS_OK;
6112 }
6113 // Some platform features, like Service Workers, depend on internal
6114 // redirects. We should allow some number of internal redirects above
6115 // and beyond the normal redirect limit so these features continue
6116 // to work.
6117 static const int8_t kMinInternalRedirects = 5;
6118
6119 if (mInternalRedirectCount >= (mRedirectionLimit + kMinInternalRedirects)) {
6120 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)
;
6121 return NS_ERROR_REDIRECT_LOOP;
6122 }
6123 return NS_OK;
6124 }
6125
6126 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { *((volatile int*)__null) = 6128; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6127 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { *((volatile int*)__null) = 6128; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6128 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)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { *((volatile int*)__null) = 6128; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6129
6130 if (mRedirectCount >= mRedirectionLimit) {
6131 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)
;
6132 return NS_ERROR_REDIRECT_LOOP;
6133 }
6134
6135 // in case https-only mode is enabled which upgrades top-level requests to
6136 // https and the page answers with a redirect (meta, 302, win.location, ...)
6137 // then this method can break the cycle which causes the https-only exception
6138 // page to appear. Note that https-first mode breaks upgrade downgrade endless
6139 // loops within ShouldUpgradeHttpsFirstRequest because https-first does not
6140 // display an exception page but needs a soft fallback/downgrade.
6141 if (nsHTTPSOnlyUtils::IsUpgradeDowngradeEndlessLoop(
6142 mURI, aNewURI, mLoadInfo,
6143 {nsHTTPSOnlyUtils::UpgradeDowngradeEndlessLoopOptions::
6144 EnforceForHTTPSOnlyMode})) {
6145 // Mark that we didn't upgrade to https due to loop detection in https-only
6146 // mode to show https-only error page. We know that we are in https-only
6147 // mode, because we passed `EnforceForHTTPSOnlyMode` to
6148 // `IsUpgradeDowngradeEndlessLoop`. In other words we upgrade the request
6149 // with https-only mode, but then immediately cancel the request.
6150 uint32_t httpsOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
6151 if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_UNINITIALIZED) {
6152 httpsOnlyStatus ^= nsILoadInfo::HTTPS_ONLY_UNINITIALIZED;
6153 httpsOnlyStatus |=
6154 nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_NOT_REGISTERED;
6155 mLoadInfo->SetHttpsOnlyStatus(httpsOnlyStatus);
6156 }
6157
6158 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)
;
6159 return NS_ERROR_REDIRECT_LOOP;
6160 }
6161 // in case of http-first mode we want to add an exception to disable the
6162 // upgrade behavior if we have upgrade-downgrade loop to break the loop and
6163 // load the http request next
6164 if (mozilla::StaticPrefs::
6165 dom_security_https_first_add_exception_on_failiure() &&
6166 nsHTTPSOnlyUtils::IsUpgradeDowngradeEndlessLoop(
6167 mURI, aNewURI, mLoadInfo,
6168 {nsHTTPSOnlyUtils::UpgradeDowngradeEndlessLoopOptions::
6169 EnforceForHTTPSFirstMode})) {
6170 nsHTTPSOnlyUtils::AddHTTPSFirstExceptionForSession(mURI, mLoadInfo);
6171 }
6172
6173 return NS_OK;
6174}
6175
6176// NOTE: This function duplicates code from nsBaseChannel. This will go away
6177// once HTTP uses nsBaseChannel (part of bug 312760)
6178/* static */
6179void HttpBaseChannel::CallTypeSniffers(void* aClosure, const uint8_t* aData,
6180 uint32_t aCount) {
6181 nsIChannel* chan = static_cast<nsIChannel*>(aClosure);
6182 const char* snifferType = [chan]() {
6183 if (RefPtr<nsHttpChannel> httpChannel = do_QueryObject(chan)) {
6184 switch (httpChannel->GetSnifferCategoryType()) {
6185 case SnifferCategoryType::NetContent:
6186 return NS_CONTENT_SNIFFER_CATEGORY"net-content-sniffers";
6187 case SnifferCategoryType::OpaqueResponseBlocking:
6188 return NS_ORB_SNIFFER_CATEGORY"orb-content-sniffers";
6189 case SnifferCategoryType::All:
6190 return NS_CONTENT_AND_ORB_SNIFFER_CATEGORY"net-and-orb-content-sniffers";
6191 default:
6192 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!" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6192); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected SnifferCategoryType!"
")"); do { *((volatile int*)__null) = 6192; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6193 }
6194 }
6195
6196 return NS_CONTENT_SNIFFER_CATEGORY"net-content-sniffers";
6197 }();
6198
6199 nsAutoCString newType;
6200 NS_SniffContent(snifferType, chan, aData, aCount, newType);
6201 if (!newType.IsEmpty()) {
6202 chan->SetContentType(newType);
6203 }
6204}
6205
6206template <class T>
6207static void ParseServerTimingHeader(
6208 const UniquePtr<T>& aHeader, nsTArray<nsCOMPtr<nsIServerTiming>>& aOutput) {
6209 if (!aHeader) {
6210 return;
6211 }
6212
6213 nsAutoCString serverTimingHeader;
6214 Unused << aHeader->GetHeader(nsHttp::Server_Timing, serverTimingHeader);
6215 if (serverTimingHeader.IsEmpty()) {
6216 return;
6217 }
6218
6219 ServerTimingParser parser(serverTimingHeader);
6220 parser.Parse();
6221
6222 nsTArray<nsCOMPtr<nsIServerTiming>> array = parser.TakeServerTimingHeaders();
6223 aOutput.AppendElements(array);
6224}
6225
6226NS_IMETHODIMPnsresult
6227HttpBaseChannel::GetServerTiming(nsIArray** aServerTiming) {
6228 nsresult rv;
6229 NS_ENSURE_ARG_POINTER(aServerTiming)do { if ((__builtin_expect(!!(!(aServerTiming)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aServerTiming" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6229); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6230
6231 nsCOMPtr<nsIMutableArray> array = do_CreateInstance(NS_ARRAY_CONTRACTID"@mozilla.org/array;1", &rv);
6232 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6232); return rv; } } while (false)
;
6233
6234 nsTArray<nsCOMPtr<nsIServerTiming>> data;
6235 rv = GetNativeServerTiming(data);
6236 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6236); return rv; } } while (false)
;
6237
6238 for (const auto& entry : data) {
6239 array->AppendElement(entry);
6240 }
6241
6242 array.forget(aServerTiming);
6243 return NS_OK;
6244}
6245
6246NS_IMETHODIMPnsresult
6247HttpBaseChannel::GetNativeServerTiming(
6248 nsTArray<nsCOMPtr<nsIServerTiming>>& aServerTiming) {
6249 aServerTiming.Clear();
6250
6251 if (nsContentUtils::ComputeIsSecureContext(this)) {
6252 ParseServerTimingHeader(mResponseHead, aServerTiming);
6253 ParseServerTimingHeader(mResponseTrailers, aServerTiming);
6254 }
6255
6256 return NS_OK;
6257}
6258
6259NS_IMETHODIMPnsresult
6260HttpBaseChannel::CancelByURLClassifier(nsresult aErrorCode) {
6261 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6262); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6262; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6262 UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6262); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6262; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6263 return Cancel(aErrorCode);
6264}
6265
6266NS_IMETHODIMPnsresult HttpBaseChannel::SetIPv4Disabled() {
6267 mCaps |= NS_HTTP_DISABLE_IPV4(1 << 17);
6268 return NS_OK;
6269}
6270
6271NS_IMETHODIMPnsresult HttpBaseChannel::SetIPv6Disabled() {
6272 mCaps |= NS_HTTP_DISABLE_IPV6(1 << 18);
6273 return NS_OK;
6274}
6275
6276NS_IMETHODIMPnsresult HttpBaseChannel::GetResponseEmbedderPolicy(
6277 bool aIsOriginTrialCoepCredentiallessEnabled,
6278 nsILoadInfo::CrossOriginEmbedderPolicy* aOutPolicy) {
6279 *aOutPolicy = nsILoadInfo::EMBEDDER_POLICY_NULL;
6280 if (!mResponseHead) {
6281 return NS_ERROR_NOT_AVAILABLE;
6282 }
6283
6284 if (!nsContentUtils::ComputeIsSecureContext(this)) {
6285 // Feature is only available for secure contexts.
6286 return NS_OK;
6287 }
6288
6289 nsAutoCString content;
6290 Unused << mResponseHead->GetHeader(nsHttp::Cross_Origin_Embedder_Policy,
6291 content);
6292 *aOutPolicy = NS_GetCrossOriginEmbedderPolicyFromHeader(
6293 content, aIsOriginTrialCoepCredentiallessEnabled);
6294 return NS_OK;
6295}
6296
6297// Obtain a cross-origin opener-policy from a response response and a
6298// cross-origin opener policy initiator.
6299// https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
6300NS_IMETHODIMPnsresult HttpBaseChannel::ComputeCrossOriginOpenerPolicy(
6301 nsILoadInfo::CrossOriginOpenerPolicy aInitiatorPolicy,
6302 nsILoadInfo::CrossOriginOpenerPolicy* aOutPolicy) {
6303 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6303); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOutPolicy"
")"); do { *((volatile int*)__null) = 6303; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6304 *aOutPolicy = nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
6305
6306 if (!mResponseHead) {
6307 return NS_ERROR_NOT_AVAILABLE;
6308 }
6309
6310 // COOP headers are ignored for insecure-context loads.
6311 if (!nsContentUtils::ComputeIsSecureContext(this)) {
6312 return NS_OK;
6313 }
6314
6315 nsAutoCString openerPolicy;
6316 Unused << mResponseHead->GetHeader(nsHttp::Cross_Origin_Opener_Policy,
6317 openerPolicy);
6318
6319 // Cross-Origin-Opener-Policy = %s"same-origin" /
6320 // %s"same-origin-allow-popups" /
6321 // %s"unsafe-none"; case-sensitive
6322
6323 nsCOMPtr<nsISFVService> sfv = GetSFVService();
6324
6325 nsCOMPtr<nsISFVItem> item;
6326 nsresult rv = sfv->ParseItem(openerPolicy, getter_AddRefs(item));
6327 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6328 return rv;
6329 }
6330
6331 nsCOMPtr<nsISFVBareItem> value;
6332 rv = item->GetValue(getter_AddRefs(value));
6333 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6334 return rv;
6335 }
6336
6337 nsCOMPtr<nsISFVToken> token = do_QueryInterface(value);
6338 if (!token) {
6339 return NS_ERROR_UNEXPECTED;
6340 }
6341
6342 rv = token->GetValue(openerPolicy);
6343 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6344 return rv;
6345 }
6346
6347 nsILoadInfo::CrossOriginOpenerPolicy policy =
6348 nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
6349
6350 if (openerPolicy.EqualsLiteral("same-origin")) {
6351 policy = nsILoadInfo::OPENER_POLICY_SAME_ORIGIN;
6352 } else if (openerPolicy.EqualsLiteral("same-origin-allow-popups")) {
6353 policy = nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_ALLOW_POPUPS;
6354 }
6355 if (policy == nsILoadInfo::OPENER_POLICY_SAME_ORIGIN) {
6356 nsILoadInfo::CrossOriginEmbedderPolicy coep =
6357 nsILoadInfo::EMBEDDER_POLICY_NULL;
6358 bool isCoepCredentiallessEnabled;
6359 rv = mLoadInfo->GetIsOriginTrialCoepCredentiallessEnabledForTopLevel(
6360 &isCoepCredentiallessEnabled);
6361 if (!isCoepCredentiallessEnabled) {
6362 nsAutoCString originTrialToken;
6363 Unused << mResponseHead->GetHeader(nsHttp::OriginTrial, originTrialToken);
6364 if (!originTrialToken.IsEmpty()) {
6365 nsCOMPtr<nsIPrincipal> resultPrincipal;
6366 rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
6367 this, getter_AddRefs(resultPrincipal));
6368 if (!NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6368)
) {
6369 OriginTrials trials;
6370 trials.UpdateFromToken(NS_ConvertASCIItoUTF16(originTrialToken),
6371 resultPrincipal);
6372 if (trials.IsEnabled(OriginTrial::CoepCredentialless)) {
6373 isCoepCredentiallessEnabled = true;
6374 }
6375 }
6376 }
6377 }
6378
6379 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, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6379); return rv; } } while (false)
;
6380 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetResponseEmbedderPolicy
(isCoepCredentiallessEnabled, &coep))), 1)))
6381 GetResponseEmbedderPolicy(isCoepCredentiallessEnabled, &coep))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetResponseEmbedderPolicy
(isCoepCredentiallessEnabled, &coep))), 1)))
&&
6382 (coep == nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP ||
6383 coep == nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS)) {
6384 policy =
6385 nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP;
6386 }
6387 }
6388
6389 *aOutPolicy = policy;
6390 return NS_OK;
6391}
6392
6393NS_IMETHODIMPnsresult
6394HttpBaseChannel::GetCrossOriginOpenerPolicy(
6395 nsILoadInfo::CrossOriginOpenerPolicy* aPolicy) {
6396 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", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6396); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPolicy" ")"
); do { *((volatile int*)__null) = 6396; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6397 if (!aPolicy) {
6398 return NS_ERROR_INVALID_ARG;
6399 }
6400 // If this method is called before OnStartRequest (ie. before we call
6401 // ComputeCrossOriginOpenerPolicy) or if we were unable to compute the
6402 // policy we'll throw an error.
6403 if (!LoadOnStartRequestCalled()) {
6404 return NS_ERROR_NOT_AVAILABLE;
6405 }
6406 *aPolicy = mComputedCrossOriginOpenerPolicy;
6407 return NS_OK;
6408}
6409
6410NS_IMETHODIMPnsresult
6411HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch(bool* aIsMismatch) {
6412 // This should only be called in parent process.
6413 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6413); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 6413; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6414 *aIsMismatch = LoadHasCrossOriginOpenerPolicyMismatch();
6415 return NS_OK;
6416}
6417
6418void HttpBaseChannel::MaybeFlushConsoleReports() {
6419 // Flush if we have a known window ID.
6420 if (mLoadInfo->GetInnerWindowID() > 0) {
6421 FlushReportsToConsole(mLoadInfo->GetInnerWindowID());
6422 return;
6423 }
6424
6425 // If this channel is part of a loadGroup, we can flush the console reports
6426 // immediately.
6427 nsCOMPtr<nsILoadGroup> loadGroup;
6428 nsresult rv = GetLoadGroup(getter_AddRefs(loadGroup));
6429 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && loadGroup) {
6430 FlushConsoleReports(loadGroup);
6431 }
6432}
6433
6434void HttpBaseChannel::DoDiagnosticAssertWhenOnStopNotCalledOnDestroy() {}
6435
6436bool HttpBaseChannel::Http3Allowed() const {
6437 bool isDirectOrNoProxy =
6438 mProxyInfo ? static_cast<nsProxyInfo*>(mProxyInfo.get())->IsDirect()
6439 : true;
6440 return !mUpgradeProtocolCallback && isDirectOrNoProxy &&
6441 !(mCaps & NS_HTTP_BE_CONSERVATIVE(1 << 11)) && !LoadBeConservative() &&
6442 LoadAllowHttp3();
6443}
6444
6445void HttpBaseChannel::SetDummyChannelForCachedResource() {
6446 mDummyChannelForCachedResource = true;
6447 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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mResponseHead"
") (" "SetDummyChannelForCachedResource should only be called once"
")"); do { *((volatile int*)__null) = 6448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6448 "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"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mResponseHead"
") (" "SetDummyChannelForCachedResource should only be called once"
")"); do { *((volatile int*)__null) = 6448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6449 mResponseHead = MakeUnique<nsHttpResponseHead>();
6450}
6451
6452void HttpBaseChannel::SetEarlyHints(
6453 nsTArray<EarlyHintConnectArgs>&& aEarlyHints) {
6454 mEarlyHints = std::move(aEarlyHints);
6455}
6456
6457nsTArray<EarlyHintConnectArgs>&& HttpBaseChannel::TakeEarlyHints() {
6458 return std::move(mEarlyHints);
6459}
6460
6461NS_IMETHODIMPnsresult
6462HttpBaseChannel::SetEarlyHintPreloaderId(uint64_t aEarlyHintPreloaderId) {
6463 mEarlyHintPreloaderId = aEarlyHintPreloaderId;
6464 return NS_OK;
6465}
6466
6467NS_IMETHODIMPnsresult
6468HttpBaseChannel::GetEarlyHintPreloaderId(uint64_t* aEarlyHintPreloaderId) {
6469 NS_ENSURE_ARG_POINTER(aEarlyHintPreloaderId)do { if ((__builtin_expect(!!(!(aEarlyHintPreloaderId)), 0)))
{ NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aEarlyHintPreloaderId"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6469); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6470 *aEarlyHintPreloaderId = mEarlyHintPreloaderId;
6471 return NS_OK;
6472}
6473
6474NS_IMETHODIMPnsresult
6475HttpBaseChannel::SetClassicScriptHintCharset(
6476 const nsAString& aClassicScriptHintCharset) {
6477 mClassicScriptHintCharset = aClassicScriptHintCharset;
6478 return NS_OK;
6479}
6480
6481NS_IMETHODIMPnsresult HttpBaseChannel::GetClassicScriptHintCharset(
6482 nsAString& aClassicScriptHintCharset) {
6483 aClassicScriptHintCharset = mClassicScriptHintCharset;
6484 return NS_OK;
6485}
6486
6487NS_IMETHODIMPnsresult HttpBaseChannel::SetDocumentCharacterSet(
6488 const nsAString& aDocumentCharacterSet) {
6489 mDocumentCharacterSet = aDocumentCharacterSet;
6490 return NS_OK;
6491}
6492
6493NS_IMETHODIMPnsresult HttpBaseChannel::GetDocumentCharacterSet(
6494 nsAString& aDocumentCharacterSet) {
6495 aDocumentCharacterSet = mDocumentCharacterSet;
6496 return NS_OK;
6497}
6498
6499void HttpBaseChannel::SetConnectionInfo(nsHttpConnectionInfo* aCI) {
6500 mConnectionInfo = aCI ? aCI->Clone() : nullptr;
6501}
6502
6503NS_IMETHODIMPnsresult
6504HttpBaseChannel::GetIsProxyUsed(bool* aIsProxyUsed) {
6505 if (mProxyInfo) {
6506 if (!static_cast<nsProxyInfo*>(mProxyInfo.get())->IsDirect()) {
6507 StoreIsProxyUsed(true);
6508 }
6509 }
6510 *aIsProxyUsed = LoadIsProxyUsed();
6511 return NS_OK;
6512}
6513
6514static void CollectORBBlockTelemetry(
6515 const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
6516 ExtContentPolicy aPolicy) {
6517 Telemetry::LABELS_ORB_BLOCK_REASON label{
6518 static_cast<uint32_t>(aTelemetryReason)};
6519 Telemetry::AccumulateCategorical(label);
6520
6521 switch (aPolicy) {
6522 case ExtContentPolicy::TYPE_INVALID:
6523 Telemetry::AccumulateCategorical(
6524 Telemetry::LABELS_ORB_BLOCK_INITIATOR::INVALID);
6525 break;
6526 case ExtContentPolicy::TYPE_OTHER:
6527 Telemetry::AccumulateCategorical(
6528 Telemetry::LABELS_ORB_BLOCK_INITIATOR::OTHER);
6529 break;
6530 case ExtContentPolicy::TYPE_FETCH:
6531 Telemetry::AccumulateCategorical(
6532 Telemetry::LABELS_ORB_BLOCK_INITIATOR::BLOCKED_FETCH);
6533 break;
6534 case ExtContentPolicy::TYPE_SCRIPT:
6535 Telemetry::AccumulateCategorical(
6536 Telemetry::LABELS_ORB_BLOCK_INITIATOR::SCRIPT);
6537 break;
6538 case ExtContentPolicy::TYPE_IMAGE:
6539 Telemetry::AccumulateCategorical(
6540 Telemetry::LABELS_ORB_BLOCK_INITIATOR::IMAGE);
6541 break;
6542 case ExtContentPolicy::TYPE_STYLESHEET:
6543 Telemetry::AccumulateCategorical(
6544 Telemetry::LABELS_ORB_BLOCK_INITIATOR::STYLESHEET);
6545 break;
6546 case ExtContentPolicy::TYPE_XMLHTTPREQUEST:
6547 Telemetry::AccumulateCategorical(
6548 Telemetry::LABELS_ORB_BLOCK_INITIATOR::XMLHTTPREQUEST);
6549 break;
6550 case ExtContentPolicy::TYPE_DTD:
6551 Telemetry::AccumulateCategorical(
6552 Telemetry::LABELS_ORB_BLOCK_INITIATOR::DTD);
6553 break;
6554 case ExtContentPolicy::TYPE_FONT:
6555 Telemetry::AccumulateCategorical(
6556 Telemetry::LABELS_ORB_BLOCK_INITIATOR::FONT);
6557 break;
6558 case ExtContentPolicy::TYPE_MEDIA:
6559 Telemetry::AccumulateCategorical(
6560 Telemetry::LABELS_ORB_BLOCK_INITIATOR::MEDIA);
6561 break;
6562 case ExtContentPolicy::TYPE_CSP_REPORT:
6563 Telemetry::AccumulateCategorical(
6564 Telemetry::LABELS_ORB_BLOCK_INITIATOR::CSP_REPORT);
6565 break;
6566 case ExtContentPolicy::TYPE_XSLT:
6567 Telemetry::AccumulateCategorical(
6568 Telemetry::LABELS_ORB_BLOCK_INITIATOR::XSLT);
6569 break;
6570 case ExtContentPolicy::TYPE_IMAGESET:
6571 Telemetry::AccumulateCategorical(
6572 Telemetry::LABELS_ORB_BLOCK_INITIATOR::IMAGESET);
6573 break;
6574 case ExtContentPolicy::TYPE_WEB_MANIFEST:
6575 Telemetry::AccumulateCategorical(
6576 Telemetry::LABELS_ORB_BLOCK_INITIATOR::WEB_MANIFEST);
6577 break;
6578 case ExtContentPolicy::TYPE_SPECULATIVE:
6579 Telemetry::AccumulateCategorical(
6580 Telemetry::LABELS_ORB_BLOCK_INITIATOR::SPECULATIVE);
6581 break;
6582 case ExtContentPolicy::TYPE_UA_FONT:
6583 Telemetry::AccumulateCategorical(
6584 Telemetry::LABELS_ORB_BLOCK_INITIATOR::UA_FONT);
6585 break;
6586 case ExtContentPolicy::TYPE_PROXIED_WEBRTC_MEDIA:
6587 Telemetry::AccumulateCategorical(
6588 Telemetry::LABELS_ORB_BLOCK_INITIATOR::PROXIED_WEBRTC_MEDIA);
6589 break;
6590 case ExtContentPolicy::TYPE_PING:
6591 Telemetry::AccumulateCategorical(
6592 Telemetry::LABELS_ORB_BLOCK_INITIATOR::PING);
6593 break;
6594 case ExtContentPolicy::TYPE_BEACON:
6595 Telemetry::AccumulateCategorical(
6596 Telemetry::LABELS_ORB_BLOCK_INITIATOR::BEACON);
6597 break;
6598 case ExtContentPolicy::TYPE_WEB_TRANSPORT:
6599 Telemetry::AccumulateCategorical(
6600 Telemetry::LABELS_ORB_BLOCK_INITIATOR::WEB_TRANSPORT);
6601 break;
6602 case ExtContentPolicy::TYPE_WEB_IDENTITY:
6603 // Don't bother extending the telemetry for this.
6604 Telemetry::AccumulateCategorical(
6605 Telemetry::LABELS_ORB_BLOCK_INITIATOR::OTHER);
6606 break;
6607 case ExtContentPolicy::TYPE_DOCUMENT:
6608 case ExtContentPolicy::TYPE_SUBDOCUMENT:
6609 case ExtContentPolicy::TYPE_OBJECT:
6610 case ExtContentPolicy::TYPE_OBJECT_SUBREQUEST:
6611 case ExtContentPolicy::TYPE_WEBSOCKET:
6612 case ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD:
6613 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6613); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Shouldn't block this type" ")");
do { *((volatile int*)__null) = 6613; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6614 // DOCUMENT, SUBDOCUMENT, OBJECT, OBJECT_SUBREQUEST,
6615 // WEBSOCKET and SAVEAS_DOWNLOAD are excluded from ORB
6616 Telemetry::AccumulateCategorical(
6617 Telemetry::LABELS_ORB_BLOCK_INITIATOR::EXCLUDED);
6618 break;
6619 // Do not add default: so that compilers can catch the missing case.
6620 }
6621}
6622
6623void HttpBaseChannel::LogORBError(
6624 const nsAString& aReason,
6625 const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
6626 auto policy = mLoadInfo->GetExternalContentPolicyType();
6627 CollectORBBlockTelemetry(aTelemetryReason, policy);
6628
6629 // Blocking `ExtContentPolicy::TYPE_BEACON` isn't web observable, so keep
6630 // quiet in the console about blocking it.
6631 if (policy == ExtContentPolicy::TYPE_BEACON) {
6632 return;
6633 }
6634
6635 RefPtr<dom::Document> doc;
6636 mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
6637
6638 nsAutoCString uri;
6639 nsresult rv = nsContentUtils::AnonymizeURI(mURI, uri);
6640 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6640)
) {
6641 return;
6642 }
6643
6644 uint64_t contentWindowId;
6645 GetTopLevelContentWindowId(&contentWindowId);
6646 if (contentWindowId) {
6647 nsContentUtils::ReportToConsoleByWindowID(
6648 u"A resource is blocked by OpaqueResponseBlocking, please check browser console for details."_ns,
6649 nsIScriptError::warningFlag, "ORB"_ns, contentWindowId,
6650 SourceLocation(mURI.get()));
6651 }
6652
6653 AutoTArray<nsString, 2> params;
6654 params.AppendElement(NS_ConvertUTF8toUTF16(uri));
6655 params.AppendElement(aReason);
6656 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "ORB"_ns, doc,
6657 nsContentUtils::eNECKO_PROPERTIES,
6658 "ResourceBlockedORB", params);
6659}
6660
6661NS_IMETHODIMPnsresult HttpBaseChannel::SetEarlyHintLinkType(
6662 uint32_t aEarlyHintLinkType) {
6663 mEarlyHintLinkType = aEarlyHintLinkType;
6664 return NS_OK;
6665}
6666
6667NS_IMETHODIMPnsresult HttpBaseChannel::GetEarlyHintLinkType(
6668 uint32_t* aEarlyHintLinkType) {
6669 *aEarlyHintLinkType = mEarlyHintLinkType;
6670 return NS_OK;
6671}
6672
6673NS_IMETHODIMPnsresult
6674HttpBaseChannel::SetHasContentDecompressed(bool aValue) {
6675 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)
6676 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)
;
6677 mHasContentDecompressed = aValue;
6678 return NS_OK;
6679}
6680NS_IMETHODIMPnsresult
6681HttpBaseChannel::GetHasContentDecompressed(bool* value) {
6682 *value = mHasContentDecompressed;
6683 return NS_OK;
6684}
6685
6686NS_IMETHODIMPnsresult
6687HttpBaseChannel::SetRenderBlocking(bool aRenderBlocking) {
6688 mRenderBlocking = aRenderBlocking;
6689 return NS_OK;
6690}
6691
6692NS_IMETHODIMPnsresult
6693HttpBaseChannel::GetRenderBlocking(bool* aRenderBlocking) {
6694 *aRenderBlocking = mRenderBlocking;
6695 return NS_OK;
6696}
6697
6698NS_IMETHODIMPnsresult HttpBaseChannel::GetLastTransportStatus(
6699 nsresult* aLastTransportStatus) {
6700 return NS_ERROR_NOT_IMPLEMENTED;
6701}
6702
6703} // namespace net
6704} // namespace mozilla