Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp
Warning:line 5590, 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-18/lib/clang/18 -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-18/lib/clang/18/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 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -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-07-27-022226-2793976-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 mDummyChannelForImageCache(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() || mDummyChannelForImageCache) {
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 (!mDummyChannelForImageCache) {
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
2501void HttpBaseChannel::NotifySetCookie(const nsACString& aCookie) {
2502 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2503 if (obs) {
2504 obs->NotifyObservers(static_cast<nsIChannel*>(this),
2505 "http-on-response-set-cookie",
2506 NS_ConvertASCIItoUTF16(aCookie).get());
2507 }
2508}
2509
2510bool HttpBaseChannel::IsBrowsingContextDiscarded() const {
2511 // If there is no loadGroup attached to the current channel, we check the
2512 // global private browsing state for the private channel instead. For
2513 // non-private channel, we will always return false here.
2514 //
2515 // Note that we can only access the global private browsing state in the
2516 // parent process. So, we will fallback to just return false in the content
2517 // process.
2518 if (!mLoadGroup) {
2519 if (!XRE_IsParentProcess()) {
2520 return false;
2521 }
2522
2523 return mLoadInfo->GetOriginAttributes().IsPrivateBrowsing() &&
2524 !dom::CanonicalBrowsingContext::IsPrivateBrowsingActive();
2525 }
2526
2527 return mLoadGroup->GetIsBrowsingContextDiscarded();
2528}
2529
2530// https://mikewest.github.io/corpp/#process-navigation-response
2531nsresult HttpBaseChannel::ProcessCrossOriginEmbedderPolicyHeader() {
2532 nsresult rv;
2533 if (!StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2534 return NS_OK;
2535 }
2536
2537 // Only consider Cross-Origin-Embedder-Policy for document loads.
2538 if (mLoadInfo->GetExternalContentPolicyType() !=
2539 ExtContentPolicy::TYPE_DOCUMENT &&
2540 mLoadInfo->GetExternalContentPolicyType() !=
2541 ExtContentPolicy::TYPE_SUBDOCUMENT) {
2542 return NS_OK;
2543 }
2544
2545 nsILoadInfo::CrossOriginEmbedderPolicy resultPolicy =
2546 nsILoadInfo::EMBEDDER_POLICY_NULL;
2547 bool isCoepCredentiallessEnabled;
2548 rv = mLoadInfo->GetIsOriginTrialCoepCredentiallessEnabledForTopLevel(
2549 &isCoepCredentiallessEnabled);
2550 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"
, 2550); return rv; } } while (false)
;
2551 rv = GetResponseEmbedderPolicy(isCoepCredentiallessEnabled, &resultPolicy);
2552 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2553 return NS_OK;
2554 }
2555
2556 // https://html.spec.whatwg.org/multipage/origin.html#coep
2557 if (mLoadInfo->GetExternalContentPolicyType() ==
2558 ExtContentPolicy::TYPE_SUBDOCUMENT &&
2559 !nsHttpChannel::IsRedirectStatus(mResponseHead->Status()) &&
2560 mLoadInfo->GetLoadingEmbedderPolicy() !=
2561 nsILoadInfo::EMBEDDER_POLICY_NULL &&
2562 resultPolicy != nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP &&
2563 resultPolicy != nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
2564 return NS_ERROR_DOM_COEP_FAILED;
2565 }
2566
2567 return NS_OK;
2568}
2569
2570// https://mikewest.github.io/corpp/#corp-check
2571nsresult HttpBaseChannel::ProcessCrossOriginResourcePolicyHeader() {
2572 // Fetch 4.5.9
2573 dom::RequestMode requestMode;
2574 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"
, 2574); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(GetRequestMode(&requestMode))" ")");
do { *((volatile int*)__null) = 2574; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2575 // XXX this seems wrong per spec? What about navigate
2576 if (requestMode != RequestMode::No_cors) {
2577 return NS_OK;
2578 }
2579
2580 // We only apply this for resources.
2581 auto extContentPolicyType = mLoadInfo->GetExternalContentPolicyType();
2582 if (extContentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
2583 extContentPolicyType == ExtContentPolicy::TYPE_WEBSOCKET ||
2584 extContentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
2585 return NS_OK;
2586 }
2587
2588 if (extContentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
2589 // COEP pref off, skip CORP checking for subdocument.
2590 if (!StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2591 return NS_OK;
2592 }
2593 // COEP 3.2.1.2 when request targets a nested browsing context then embedder
2594 // policy value is "unsafe-none", then return allowed.
2595 if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2596 nsILoadInfo::EMBEDDER_POLICY_NULL) {
2597 return NS_OK;
2598 }
2599 }
2600
2601 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"
, 2602); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetLoadingPrincipal()"
") (" "Resources should always have a LoadingPrincipal" ")")
; do { *((volatile int*)__null) = 2602; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2602 "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"
, 2602); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetLoadingPrincipal()"
") (" "Resources should always have a LoadingPrincipal" ")")
; do { *((volatile int*)__null) = 2602; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2603 if (!mResponseHead) {
2604 return NS_OK;
2605 }
2606
2607 if (mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()) {
2608 return NS_OK;
2609 }
2610
2611 nsAutoCString content;
2612 Unused << mResponseHead->GetHeader(nsHttp::Cross_Origin_Resource_Policy,
2613 content);
2614
2615 if (StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2616 if (content.IsEmpty()) {
2617 if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2618 nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
2619 bool requestIncludesCredentials = false;
2620 nsresult rv = GetCorsIncludeCredentials(&requestIncludesCredentials);
2621 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2622 return NS_OK;
2623 }
2624 // COEP: Set policy to `same-origin` if: response’s
2625 // request-includes-credentials is true, or forNavigation is true.
2626 if (requestIncludesCredentials ||
2627 extContentPolicyType == ExtContentPolicyType::TYPE_SUBDOCUMENT) {
2628 content = "same-origin"_ns;
2629 }
2630 } else if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2631 nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP) {
2632 // COEP 3.2.1.6 If policy is null, and embedder policy is
2633 // "require-corp", set policy to "same-origin". Note that we treat
2634 // invalid value as "cross-origin", which spec indicates. We might want
2635 // to make that stricter.
2636 content = "same-origin"_ns;
2637 }
2638 }
2639 }
2640
2641 if (content.IsEmpty()) {
2642 return NS_OK;
2643 }
2644
2645 nsCOMPtr<nsIPrincipal> channelOrigin;
2646 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
2647 this, getter_AddRefs(channelOrigin));
2648
2649 // Cross-Origin-Resource-Policy = %s"same-origin" / %s"same-site" /
2650 // %s"cross-origin"
2651 if (content.EqualsLiteral("same-origin")) {
2652 if (!channelOrigin->Equals(mLoadInfo->GetLoadingPrincipal())) {
2653 return NS_ERROR_DOM_CORP_FAILED;
2654 }
2655 return NS_OK;
2656 }
2657 if (content.EqualsLiteral("same-site")) {
2658 nsAutoCString documentBaseDomain;
2659 nsAutoCString resourceBaseDomain;
2660 mLoadInfo->GetLoadingPrincipal()->GetBaseDomain(documentBaseDomain);
2661 channelOrigin->GetBaseDomain(resourceBaseDomain);
2662 if (documentBaseDomain != resourceBaseDomain) {
2663 return NS_ERROR_DOM_CORP_FAILED;
2664 }
2665
2666 nsCOMPtr<nsIURI> resourceURI = channelOrigin->GetURI();
2667 if (!mLoadInfo->GetLoadingPrincipal()->SchemeIs("https") &&
2668 resourceURI->SchemeIs("https")) {
2669 return NS_ERROR_DOM_CORP_FAILED;
2670 }
2671
2672 return NS_OK;
2673 }
2674
2675 return NS_OK;
2676}
2677
2678// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
2679// This method runs steps 1-4 of the algorithm to compare
2680// cross-origin-opener policies
2681static bool CompareCrossOriginOpenerPolicies(
2682 nsILoadInfo::CrossOriginOpenerPolicy documentPolicy,
2683 nsIPrincipal* documentOrigin,
2684 nsILoadInfo::CrossOriginOpenerPolicy resultPolicy,
2685 nsIPrincipal* resultOrigin) {
2686 if (documentPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE &&
2687 resultPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2688 return true;
2689 }
2690
2691 if (documentPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE ||
2692 resultPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2693 return false;
2694 }
2695
2696 if (documentPolicy == resultPolicy && documentOrigin->Equals(resultOrigin)) {
2697 return true;
2698 }
2699
2700 return false;
2701}
2702
2703// This runs steps 1-5 of the algorithm when navigating a top level document.
2704// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
2705nsresult HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch() {
2706 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"
, 2706); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 2706; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2707
2708 StoreHasCrossOriginOpenerPolicyMismatch(false);
2709 if (!StaticPrefs::browser_tabs_remote_useCrossOriginOpenerPolicy()) {
2710 return NS_OK;
2711 }
2712
2713 // Only consider Cross-Origin-Opener-Policy for toplevel document loads.
2714 if (mLoadInfo->GetExternalContentPolicyType() !=
2715 ExtContentPolicy::TYPE_DOCUMENT) {
2716 return NS_OK;
2717 }
2718
2719 // Maybe the channel failed and we have no response head?
2720 if (!mResponseHead) {
2721 // Not having a response head is not a hard failure at the point where
2722 // this method is called.
2723 return NS_OK;
2724 }
2725
2726 RefPtr<mozilla::dom::BrowsingContext> ctx;
2727 mLoadInfo->GetBrowsingContext(getter_AddRefs(ctx));
2728
2729 // In xpcshell-tests we don't always have a browsingContext
2730 if (!ctx) {
2731 return NS_OK;
2732 }
2733
2734 nsCOMPtr<nsIPrincipal> resultOrigin;
2735 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
2736 this, getter_AddRefs(resultOrigin));
2737
2738 // Get the policy of the active document, and the policy for the result.
2739 nsILoadInfo::CrossOriginOpenerPolicy documentPolicy = ctx->GetOpenerPolicy();
2740 nsILoadInfo::CrossOriginOpenerPolicy resultPolicy =
2741 nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
2742 Unused << ComputeCrossOriginOpenerPolicy(documentPolicy, &resultPolicy);
2743 mComputedCrossOriginOpenerPolicy = resultPolicy;
2744
2745 // Add a permission to mark this site as high-value into the permission DB.
2746 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2747 mozilla::dom::AddHighValuePermission(
2748 resultOrigin, mozilla::dom::kHighValueCOOPPermission);
2749 }
2750
2751 // If bc's popup sandboxing flag set is not empty and potentialCOOP is
2752 // non-null, then navigate bc to a network error and abort these steps.
2753 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE &&
2754 mLoadInfo->GetSandboxFlags()) {
2755 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)
2756 "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)
2757 "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)
;
2758 return NS_ERROR_DOM_COOP_FAILED;
2759 }
2760
2761 // In xpcshell-tests we don't always have a current window global
2762 RefPtr<mozilla::dom::WindowGlobalParent> currentWindowGlobal =
2763 ctx->Canonical()->GetCurrentWindowGlobal();
2764 if (!currentWindowGlobal) {
2765 return NS_OK;
2766 }
2767
2768 // We use the top window principal as the documentOrigin
2769 nsCOMPtr<nsIPrincipal> documentOrigin =
2770 currentWindowGlobal->DocumentPrincipal();
2771
2772 bool compareResult = CompareCrossOriginOpenerPolicies(
2773 documentPolicy, documentOrigin, resultPolicy, resultOrigin);
2774
2775 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
2776 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)
2777 ("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)
2778 "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)
2779 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)
;
2780 nsAutoCString docOrigin("(null)");
2781 nsCOMPtr<nsIURI> uri = documentOrigin->GetURI();
2782 if (uri) {
2783 uri->GetSpec(docOrigin);
2784 }
2785 nsAutoCString resOrigin("(null)");
2786 uri = resultOrigin->GetURI();
2787 if (uri) {
2788 uri->GetSpec(resOrigin);
2789 }
2790 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)
;
2791 }
2792
2793 if (compareResult) {
2794 return NS_OK;
2795 }
2796
2797 // If one of the following is false:
2798 // - document's policy is same-origin-allow-popups
2799 // - resultPolicy is null
2800 // - doc is the initial about:blank document
2801 // then we have a mismatch.
2802
2803 if (documentPolicy != nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_ALLOW_POPUPS) {
2804 StoreHasCrossOriginOpenerPolicyMismatch(true);
2805 return NS_OK;
2806 }
2807
2808 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2809 StoreHasCrossOriginOpenerPolicyMismatch(true);
2810 return NS_OK;
2811 }
2812
2813 if (!currentWindowGlobal->IsInitialDocument()) {
2814 StoreHasCrossOriginOpenerPolicyMismatch(true);
2815 return NS_OK;
2816 }
2817
2818 return NS_OK;
2819}
2820
2821nsresult HttpBaseChannel::ProcessCrossOriginSecurityHeaders() {
2822 StoreProcessCrossOriginSecurityHeadersCalled(true);
2823 nsresult rv = ProcessCrossOriginEmbedderPolicyHeader();
2824 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2825 return rv;
2826 }
2827 rv = ProcessCrossOriginResourcePolicyHeader();
2828 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2829 return rv;
2830 }
2831 return ComputeCrossOriginOpenerPolicyMismatch();
2832}
2833
2834enum class Report { Error, Warning };
2835
2836// Helper Function to report messages to the console when the loaded
2837// script had a wrong MIME type.
2838void ReportMimeTypeMismatch(HttpBaseChannel* aChannel, const char* aMessageName,
2839 nsIURI* aURI, const nsACString& aContentType,
2840 Report report) {
2841 NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
2842 NS_ConvertUTF8toUTF16 contentType(aContentType);
2843
2844 aChannel->LogMimeTypeMismatch(nsCString(aMessageName),
2845 report == Report::Warning, spec, contentType);
2846}
2847
2848// Check and potentially enforce X-Content-Type-Options: nosniff
2849nsresult ProcessXCTO(HttpBaseChannel* aChannel, nsIURI* aURI,
2850 nsHttpResponseHead* aResponseHead,
2851 nsILoadInfo* aLoadInfo) {
2852 if (!aURI || !aResponseHead || !aLoadInfo) {
2853 // if there is no uri, no response head or no loadInfo, then there is
2854 // nothing to do
2855 return NS_OK;
2856 }
2857
2858 // 1) Query the XCTO header and check if 'nosniff' is the first value.
2859 nsAutoCString contentTypeOptionsHeader;
2860 if (!aResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader)) {
2861 // if failed to get XCTO header, then there is nothing to do.
2862 return NS_OK;
2863 }
2864
2865 // let's compare the header (ignoring case)
2866 // e.g. "NoSniFF" -> "nosniff"
2867 // if it's not 'nosniff' then there is nothing to do here
2868 if (!contentTypeOptionsHeader.EqualsIgnoreCase("nosniff")) {
2869 // since we are getting here, the XCTO header was sent;
2870 // a non matching value most likely means a mistake happenend;
2871 // e.g. sending 'nosnif' instead of 'nosniff', let's log a warning.
2872 AutoTArray<nsString, 1> params;
2873 CopyUTF8toUTF16(contentTypeOptionsHeader, *params.AppendElement());
2874 RefPtr<dom::Document> doc;
2875 aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
2876 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "XCTO"_ns, doc,
2877 nsContentUtils::eSECURITY_PROPERTIES,
2878 "XCTOHeaderValueMissing", params);
2879 return NS_OK;
2880 }
2881
2882 // 2) Query the content type from the channel
2883 nsAutoCString contentType;
2884 aResponseHead->ContentType(contentType);
2885
2886 // 3) Compare the expected MIME type with the actual type
2887 if (aLoadInfo->GetExternalContentPolicyType() ==
2888 ExtContentPolicy::TYPE_STYLESHEET) {
2889 if (contentType.EqualsLiteral(TEXT_CSS"text/css")) {
2890 return NS_OK;
2891 }
2892 ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
2893 Report::Error);
2894 return NS_ERROR_CORRUPTED_CONTENT;
2895 }
2896
2897 if (aLoadInfo->GetExternalContentPolicyType() ==
2898 ExtContentPolicy::TYPE_SCRIPT) {
2899 if (nsContentUtils::IsJavascriptMIMEType(
2900 NS_ConvertUTF8toUTF16(contentType))) {
2901 return NS_OK;
2902 }
2903 ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
2904 Report::Error);
2905 return NS_ERROR_CORRUPTED_CONTENT;
2906 }
2907
2908 auto policyType = aLoadInfo->GetExternalContentPolicyType();
2909 if (policyType == ExtContentPolicy::TYPE_DOCUMENT ||
2910 policyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
2911 // If the header XCTO nosniff is set for any browsing context, then
2912 // we set the skipContentSniffing flag on the Loadinfo. Within
2913 // GetMIMETypeFromContent we then bail early and do not do any sniffing.
2914 aLoadInfo->SetSkipContentSniffing(true);
2915 return NS_OK;
2916 }
2917
2918 return NS_OK;
2919}
2920
2921// Ensure that a load of type script has correct MIME type
2922nsresult EnsureMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
2923 nsHttpResponseHead* aResponseHead,
2924 nsILoadInfo* aLoadInfo) {
2925 if (!aURI || !aResponseHead || !aLoadInfo) {
2926 // if there is no uri, no response head or no loadInfo, then there is
2927 // nothing to do
2928 return NS_OK;
2929 }
2930
2931 if (aLoadInfo->GetExternalContentPolicyType() !=
2932 ExtContentPolicy::TYPE_SCRIPT) {
2933 // if this is not a script load, then there is nothing to do
2934 return NS_OK;
2935 }
2936
2937 nsAutoCString contentType;
2938 aResponseHead->ContentType(contentType);
2939 NS_ConvertUTF8toUTF16 typeString(contentType);
2940
2941 if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
2942 // script load has type script
2943 AccumulateCategorical(
2944 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
2945 return NS_OK;
2946 }
2947
2948 switch (aLoadInfo->InternalContentPolicyType()) {
2949 case nsIContentPolicy::TYPE_SCRIPT:
2950 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
2951 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
2952 case nsIContentPolicy::TYPE_INTERNAL_MODULE:
2953 case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
2954 case nsIContentPolicy::TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT:
2955 case nsIContentPolicy::TYPE_INTERNAL_FRAME_MESSAGEMANAGER_SCRIPT:
2956 AccumulateCategorical(
2957 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::script_load);
2958 break;
2959 case nsIContentPolicy::TYPE_INTERNAL_WORKER:
2960 case nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE:
2961 case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
2962 AccumulateCategorical(
2963 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worker_load);
2964 break;
2965 case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
2966 AccumulateCategorical(
2967 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::serviceworker_load);
2968 break;
2969 case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
2970 AccumulateCategorical(
2971 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::importScript_load);
2972 break;
2973 case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
2974 case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
2975 AccumulateCategorical(
2976 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worklet_load);
2977 break;
2978 default:
2979 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"
, 2979); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "unexpected script type" ")"); do
{ *((volatile int*)__null) = 2979; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
2980 break;
2981 }
2982
2983 if (aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(aURI)) {
2984 // same origin
2985 AccumulateCategorical(
2986 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::same_origin);
2987 } else {
2988 bool cors = false;
2989 nsAutoCString corsOrigin;
2990 nsresult rv = aResponseHead->GetHeader(
2991 nsHttp::ResolveAtom("Access-Control-Allow-Origin"_ns), corsOrigin);
2992 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2993 if (corsOrigin.Equals("*")) {
2994 cors = true;
2995 } else {
2996 nsCOMPtr<nsIURI> corsOriginURI;
2997 rv = NS_NewURI(getter_AddRefs(corsOriginURI), corsOrigin);
2998 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2999 if (aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(corsOriginURI)) {
3000 cors = true;
3001 }
3002 }
3003 }
3004 }
3005 if (cors) {
3006 // cors origin
3007 AccumulateCategorical(
3008 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::CORS_origin);
3009 } else {
3010 // cross origin
3011 AccumulateCategorical(
3012 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::cross_origin);
3013 }
3014 }
3015
3016 bool block = false;
3017 if (StringBeginsWith(contentType, "image/"_ns)) {
3018 // script load has type image
3019 AccumulateCategorical(
3020 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::image);
3021 block = true;
3022 } else if (StringBeginsWith(contentType, "audio/"_ns)) {
3023 // script load has type audio
3024 AccumulateCategorical(
3025 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::audio);
3026 block = true;
3027 } else if (StringBeginsWith(contentType, "video/"_ns)) {
3028 // script load has type video
3029 AccumulateCategorical(
3030 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::video);
3031 block = true;
3032 } else if (StringBeginsWith(contentType, "text/csv"_ns)) {
3033 // script load has type text/csv
3034 AccumulateCategorical(
3035 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_csv);
3036 block = true;
3037 }
3038
3039 if (block) {
3040 ReportMimeTypeMismatch(aChannel, "BlockScriptWithWrongMimeType2", aURI,
3041 contentType, Report::Error);
3042 return NS_ERROR_CORRUPTED_CONTENT;
3043 }
3044
3045 if (StringBeginsWith(contentType, "text/plain"_ns)) {
3046 // script load has type text/plain
3047 AccumulateCategorical(
3048 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
3049 } else if (StringBeginsWith(contentType, "text/xml"_ns)) {
3050 // script load has type text/xml
3051 AccumulateCategorical(
3052 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_xml);
3053 } else if (StringBeginsWith(contentType, "application/octet-stream"_ns)) {
3054 // script load has type application/octet-stream
3055 AccumulateCategorical(
3056 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_octet_stream);
3057 } else if (StringBeginsWith(contentType, "application/xml"_ns)) {
3058 // script load has type application/xml
3059 AccumulateCategorical(
3060 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_xml);
3061 } else if (StringBeginsWith(contentType, "application/json"_ns)) {
3062 // script load has type application/json
3063 AccumulateCategorical(
3064 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_json);
3065 } else if (StringBeginsWith(contentType, "text/json"_ns)) {
3066 // script load has type text/json
3067 AccumulateCategorical(
3068 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_json);
3069 } else if (StringBeginsWith(contentType, "text/html"_ns)) {
3070 // script load has type text/html
3071 AccumulateCategorical(
3072 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_html);
3073 } else if (contentType.IsEmpty()) {
3074 // script load has no type
3075 AccumulateCategorical(
3076 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::empty);
3077 } else {
3078 // script load has unknown type
3079 AccumulateCategorical(
3080 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::unknown);
3081 }
3082
3083 // We restrict importScripts() in worker code to JavaScript MIME types.
3084 nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
3085 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS ||
3086 internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE) {
3087 ReportMimeTypeMismatch(aChannel, "BlockImportScriptsWithWrongMimeType",
3088 aURI, contentType, Report::Error);
3089 return NS_ERROR_CORRUPTED_CONTENT;
3090 }
3091
3092 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
3093 internalType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
3094 // Do not block the load if the feature is not enabled.
3095 if (!StaticPrefs::security_block_Worker_with_wrong_mime()) {
3096 return NS_OK;
3097 }
3098
3099 ReportMimeTypeMismatch(aChannel, "BlockWorkerWithWrongMimeType", aURI,
3100 contentType, Report::Error);
3101 return NS_ERROR_CORRUPTED_CONTENT;
3102 }
3103
3104 // ES6 modules require a strict MIME type check.
3105 if (internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
3106 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD) {
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 if (!nsContentUtils::IsJavascriptMIMEType(typeString)) {
3143 ReportMimeTypeMismatch(aChannel, "WarnScriptWithWrongMimeType", aURI,
3144 contentType, Report::Warning);
3145 }
3146}
3147
3148nsresult HttpBaseChannel::ValidateMIMEType() {
3149 nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
3150 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3151 return rv;
3152 }
3153
3154 rv = ProcessXCTO(this, mURI, mResponseHead.get(), mLoadInfo);
3155 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3156 return rv;
3157 }
3158
3159 WarnWrongMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
3160 return NS_OK;
3161}
3162
3163bool HttpBaseChannel::ShouldFilterOpaqueResponse(
3164 OpaqueResponseFilterFetch aFilterType) const {
3165 MOZ_DIAGNOSTIC_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"
, 3165); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "ShouldBlockOpaqueResponse()"
")"); do { *((volatile int*)__null) = 3165; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3166
3167 if (!mLoadInfo || ConfiguredFilterFetchResponseBehaviour() != aFilterType) {
3168 return false;
3169 }
3170
3171 // We should filter a response in the parent if it is opaque and is the result
3172 // of a fetch() function from the Fetch specification.
3173 return mLoadInfo->InternalContentPolicyType() == nsIContentPolicy::TYPE_FETCH;
3174}
3175
3176bool HttpBaseChannel::ShouldBlockOpaqueResponse() const {
3177 if (!mURI || !mResponseHead || !mLoadInfo) {
3178 // if there is no uri, no response head or no loadInfo, then there is
3179 // nothing to do
3180 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)
;
3181 return false;
3182 }
3183
3184 nsCOMPtr<nsIPrincipal> principal = mLoadInfo->GetLoadingPrincipal();
3185 if (!principal || principal->IsSystemPrincipal()) {
3186 // If it's a top-level load or a system principal, then there is nothing to
3187 // do.
3188 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)
;
3189 return false;
3190 }
3191
3192 // Check if the response is a opaque response, which means requestMode should
3193 // be RequestMode::No_cors and responseType should be ResponseType::Opaque.
3194 nsContentPolicyType contentPolicy = mLoadInfo->InternalContentPolicyType();
3195
3196 // Skip the RequestMode would be RequestMode::Navigate
3197 if (contentPolicy == nsIContentPolicy::TYPE_DOCUMENT ||
3198 contentPolicy == nsIContentPolicy::TYPE_SUBDOCUMENT ||
3199 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_FRAME ||
3200 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_IFRAME ||
3201 // Skip the RequestMode would be RequestMode::Same_origin
3202 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
3203 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
3204 return false;
3205 }
3206
3207 uint32_t securityMode = mLoadInfo->GetSecurityMode();
3208 // Skip when RequestMode would not be RequestMode::no_cors
3209 if (securityMode !=
3210 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT &&
3211 securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL) {
3212 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)
;
3213 return false;
3214 }
3215
3216 // Only continue when ResponseType would be ResponseType::Opaque
3217 if (mLoadInfo->GetTainting() != mozilla::LoadTainting::Opaque) {
3218 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)
;
3219 return false;
3220 }
3221
3222 auto extContentPolicyType = mLoadInfo->GetExternalContentPolicyType();
3223 if (extContentPolicyType == ExtContentPolicy::TYPE_OBJECT ||
3224 extContentPolicyType == ExtContentPolicy::TYPE_OBJECT_SUBREQUEST ||
3225 extContentPolicyType == ExtContentPolicy::TYPE_WEBSOCKET ||
3226 extContentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
3227 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)
;
3228 return false;
3229 }
3230
3231 // Ignore the request from object or embed elements
3232 if (mLoadInfo->GetIsFromObjectOrEmbed()) {
3233 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)
;
3234 return false;
3235 }
3236
3237 // Exclude no_cors System XHR
3238 if (extContentPolicyType == ExtContentPolicy::TYPE_XMLHTTPREQUEST) {
3239 if (securityMode ==
3240 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT) {
3241 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)
;
3242 return false;
3243 }
3244 }
3245
3246 uint32_t httpsOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
3247 if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_BYPASS_ORB) {
3248 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)
;
3249 return false;
3250 }
3251
3252 bool isInDevToolsContext;
3253 mLoadInfo->GetIsInDevToolsContext(&isInDevToolsContext);
3254 if (isInDevToolsContext) {
3255 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)
;
3256 return false;
3257 }
3258
3259 return true;
3260}
3261
3262OpaqueResponse HttpBaseChannel::BlockOrFilterOpaqueResponse(
3263 OpaqueResponseBlocker* aORB, const nsAString& aReason,
3264 const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
3265 const char* aFormat, ...) {
3266 NimbusFeatures::RecordExposureEvent("opaqueResponseBlocking"_ns, true);
3267
3268 const bool shouldFilter =
3269 ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::BlockedByORB);
3270
3271 if (MOZ_UNLIKELY(MOZ_LOG_TEST(GetORBLog(), LogLevel::Debug))(__builtin_expect(!!((__builtin_expect(!!(mozilla::detail::log_test
(GetORBLog(), LogLevel::Debug)), 0))), 0))
) {
3272 va_list ap;
3273 va_start(ap, aFormat)__builtin_va_start(ap, aFormat);
3274 nsVprintfCString logString(aFormat, ap);
3275 va_end(ap)__builtin_va_end(ap);
3276
3277 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)
;
3278 }
3279
3280 if (shouldFilter) {
3281 Telemetry::AccumulateCategorical(
3282 Telemetry::LABELS_ORB_BLOCK_INITIATOR::FILTERED_FETCH);
3283 // The existence of `mORB` depends on `BlockOrFilterOpaqueResponse` being
3284 // called before or after sniffing has completed.
3285 // Another requirement is that `OpaqueResponseFilter` must come after
3286 // `OpaqueResponseBlocker`, which is why in the case of having an
3287 // `OpaqueResponseBlocker` we let it handle creating an
3288 // `OpaqueResponseFilter`.
3289 if (aORB) {
3290 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"
, 3290); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mORB || aORB == mORB"
")"); do { *((volatile int*)__null) = 3290; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3291 aORB->FilterResponse();
3292 } else {
3293 mListener = new OpaqueResponseFilter(mListener);
3294 }
3295 return OpaqueResponse::Allow;
3296 }
3297
3298 LogORBError(aReason, aTelemetryReason);
3299 return OpaqueResponse::Block;
3300}
3301
3302// The specification for ORB is currently being written:
3303// https://whatpr.org/fetch/1442.html#orb-algorithm
3304// The `opaque-response-safelist check` is implemented in:
3305// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
3306// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3307// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
3308// * `OpaqueResponseBlocker::ValidateJavaScript`
3309OpaqueResponse
3310HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff() {
3311 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"
, 3311); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 3311; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3312
3313 // https://whatpr.org/fetch/1442.html#http-fetch, step 6.4
3314 if (!ShouldBlockOpaqueResponse()) {
3315 return OpaqueResponse::Allow;
3316 }
3317
3318 // Regardless of if ORB is enabled or not, we check if we should filter the
3319 // response in the parent. This way data won't reach a content process that
3320 // will create a filtered `Response` object. This is enabled when
3321 // 'browser.opaqueResponseBlocking.filterFetchResponse' is
3322 // `OpaqueResponseFilterFetch::All`.
3323 // See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
3324 if (ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::All)) {
3325 mListener = new OpaqueResponseFilter(mListener);
3326
3327 // If we're filtering a response in the parent, there will be no data to
3328 // determine if it should be blocked or not so the only option we have is to
3329 // allow it.
3330 return OpaqueResponse::Allow;
3331 }
3332
3333 if (!mCachedOpaqueResponseBlockingPref) {
3334 return OpaqueResponse::Allow;
3335 }
3336
3337 // If ORB is enabled, we check if we should filter the response in the parent.
3338 // This way data won't reach a content process that will create a filtered
3339 // `Response` object. We allow ORB to determine if the response should be
3340 // blocked or filtered, but regardless no data should reach the content
3341 // process. This is enabled when
3342 // 'browser.opaqueResponseBlocking.filterFetchResponse' is
3343 // `OpaqueResponseFilterFetch::AllowedByORB`.
3344 // See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
3345 if (ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::AllowedByORB)) {
3346 mListener = new OpaqueResponseFilter(mListener);
3347 }
3348
3349 Telemetry::ScalarAdd(
3350 Telemetry::ScalarID::
3351 OPAQUE_RESPONSE_BLOCKING_CROSS_ORIGIN_OPAQUE_RESPONSE_COUNT,
3352 1);
3353
3354 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)
;
3355
3356 // https://whatpr.org/fetch/1442.html#orb-algorithm
3357 // Step 1
3358 nsAutoCString contentType;
3359 mResponseHead->ContentType(contentType);
3360
3361 // Step 2
3362 nsAutoCString contentTypeOptionsHeader;
3363 bool nosniff =
3364 mResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader) &&
3365 contentTypeOptionsHeader.EqualsIgnoreCase("nosniff");
3366
3367 // Step 3
3368 switch (GetOpaqueResponseBlockedReason(contentType, mResponseHead->Status(),
3369 nosniff)) {
3370 case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED:
3371 // Step 3.1
3372 return OpaqueResponse::Allow;
3373 case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED_SPEC_BREAKING:
3374 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)
;
3375 return OpaqueResponse::Allow;
3376 case OpaqueResponseBlockedReason::BLOCKED_BLOCKLISTED_NEVER_SNIFFED:
3377 return BlockOrFilterOpaqueResponse(
3378 mORB, u"mimeType is an opaque-blocklisted-never-sniffed MIME type"_ns,
3379 OpaqueResponseBlockedTelemetryReason::MIME_NEVER_SNIFFED,
3380 "BLOCKED_BLOCKLISTED_NEVER_SNIFFED");
3381 case OpaqueResponseBlockedReason::BLOCKED_206_AND_BLOCKLISTED:
3382 // Step 3.3
3383 return BlockOrFilterOpaqueResponse(
3384 mORB,
3385 u"response's status is 206 and mimeType is an opaque-blocklisted MIME type"_ns,
3386 OpaqueResponseBlockedTelemetryReason::RESP_206_BLCLISTED,
3387 "BLOCKED_206_AND_BLOCKEDLISTED");
3388 case OpaqueResponseBlockedReason::
3389 BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN:
3390 // Step 3.4
3391 return BlockOrFilterOpaqueResponse(
3392 mORB,
3393 u"nosniff is true and mimeType is an opaque-blocklisted MIME type or its essence is 'text/plain'"_ns,
3394 OpaqueResponseBlockedTelemetryReason::NOSNIFF_BLC_OR_TEXTP,
3395 "BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN");
3396 default:
3397 break;
3398 }
3399
3400 // Step 4
3401 // If it's a media subsequent request, we assume that it will only be made
3402 // after a successful initial request.
3403 bool isMediaRequest;
3404 mLoadInfo->GetIsMediaRequest(&isMediaRequest);
3405 if (isMediaRequest) {
3406 bool isMediaInitialRequest;
3407 mLoadInfo->GetIsMediaInitialRequest(&isMediaInitialRequest);
3408 if (!isMediaInitialRequest) {
3409 return OpaqueResponse::Allow;
3410 }
3411 }
3412
3413 // Step 5
3414 if (mResponseHead->Status() == 206 &&
3415 !IsFirstPartialResponse(*mResponseHead)) {
3416 return BlockOrFilterOpaqueResponse(
3417 mORB, u"response status is 206 and not first partial response"_ns,
3418 OpaqueResponseBlockedTelemetryReason::RESP_206_BLCLISTED,
3419 "Is not a valid partial response given 0");
3420 }
3421
3422 // Setup for steps 6, 7, 8 and 10.
3423 // Steps 6 and 7 are handled by the sniffer framework.
3424 // Steps 8 and 10 by are handled by
3425 // `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3426 if (mLoadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS) {
3427 mSnifferCategoryType = SnifferCategoryType::All;
3428 } else {
3429 mSnifferCategoryType = SnifferCategoryType::OpaqueResponseBlocking;
3430 }
3431
3432 mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
3433 nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
3434
3435 // Install an input stream listener that performs ORB checks that depend on
3436 // inspecting the incoming data. It is crucial that `OnStartRequest` is called
3437 // on this listener either after sniffing is completed or that we skip
3438 // sniffing, otherwise `OpaqueResponseBlocker` will allow responses that it
3439 // shouldn't.
3440 mORB = new OpaqueResponseBlocker(mListener, this, contentType, nosniff);
3441 mListener = mORB;
3442
3443 nsAutoCString contentEncoding;
3444 nsresult rv =
3445 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
3446
3447 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !contentEncoding.IsEmpty()) {
3448 return OpaqueResponse::SniffCompressed;
3449 }
3450 mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
3451 nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
3452 return OpaqueResponse::Sniff;
3453}
3454
3455// The specification for ORB is currently being written:
3456// https://whatpr.org/fetch/1442.html#orb-algorithm
3457// The `opaque-response-safelist check` is implemented in:
3458// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
3459// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3460// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
3461// * `OpaqueResponseBlocker::ValidateJavaScript`
3462OpaqueResponse HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff(
3463 const nsACString& aContentType, bool aNoSniff) {
3464 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)
;
3465
3466 // https://whatpr.org/fetch/1442.html#orb-algorithm
3467 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"
, 3467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 3467; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3468 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"
, 3468); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedOpaqueResponseBlockingPref"
")"); do { *((volatile int*)__null) = 3468; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3469
3470 // Step 9
3471 bool isMediaRequest;
3472 mLoadInfo->GetIsMediaRequest(&isMediaRequest);
3473 if (isMediaRequest) {
3474 return BlockOrFilterOpaqueResponse(
3475 mORB, u"after sniff: media request"_ns,
3476 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_MEDIA,
3477 "media request");
3478 }
3479
3480 // Step 11
3481 if (aNoSniff) {
3482 return BlockOrFilterOpaqueResponse(
3483 mORB, u"after sniff: nosniff is true"_ns,
3484 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_NOSNIFF, "nosniff");
3485 }
3486
3487 // Step 12
3488 if (mResponseHead &&
3489 (mResponseHead->Status() < 200 || mResponseHead->Status() > 299)) {
3490 return BlockOrFilterOpaqueResponse(
3491 mORB, u"after sniff: status code is not in allowed range"_ns,
3492 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_STA_CODE,
3493 "status code (%d) is not allowed", mResponseHead->Status());
3494 }
3495
3496 // Step 13
3497 if (!mResponseHead || aContentType.IsEmpty()) {
3498 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)
;
3499 return OpaqueResponse::Allow;
3500 }
3501
3502 // Step 14
3503 if (StringBeginsWith(aContentType, "image/"_ns) ||
3504 StringBeginsWith(aContentType, "video/"_ns) ||
3505 StringBeginsWith(aContentType, "audio/"_ns)) {
3506 return BlockOrFilterOpaqueResponse(
3507 mORB,
3508 u"after sniff: content-type declares image/video/audio, but sniffing fails"_ns,
3509 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_CT_FAIL,
3510 "ContentType is image/video/audio");
3511 }
3512
3513 return OpaqueResponse::Sniff;
3514}
3515
3516bool HttpBaseChannel::NeedOpaqueResponseAllowedCheckAfterSniff() const {
3517 return mORB ? mORB->IsSniffing() : false;
3518}
3519
3520void HttpBaseChannel::BlockOpaqueResponseAfterSniff(
3521 const nsAString& aReason,
3522 const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
3523 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"
, 3523); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { *((volatile int*)__null) = 3523; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3524 LogORBError(aReason, aTelemetryReason);
3525 mORB->BlockResponse(this, NS_ERROR_FAILURE);
3526}
3527
3528void HttpBaseChannel::AllowOpaqueResponseAfterSniff() {
3529 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"
, 3529); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { *((volatile int*)__null) = 3529; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3530 mORB->AllowResponse();
3531}
3532
3533void HttpBaseChannel::SetChannelBlockedByOpaqueResponse() {
3534 mChannelBlockedByOpaqueResponse = true;
3535
3536 RefPtr<dom::BrowsingContext> browsingContext =
3537 dom::BrowsingContext::GetCurrentTopByBrowserId(mBrowserId);
3538 if (!browsingContext) {
3539 return;
3540 }
3541
3542 dom::WindowContext* windowContext = browsingContext->GetTopWindowContext();
3543 if (windowContext) {
3544 windowContext->Canonical()->SetShouldReportHasBlockedOpaqueResponse(
3545 mLoadInfo->InternalContentPolicyType());
3546 }
3547}
3548
3549NS_IMETHODIMPnsresult
3550HttpBaseChannel::SetCookie(const nsACString& aCookieHeader) {
3551 if (mLoadFlags & LOAD_ANONYMOUS) return NS_OK;
3552
3553 if (IsBrowsingContextDiscarded()) {
3554 return NS_OK;
3555 }
3556
3557 // empty header isn't an error
3558 if (aCookieHeader.IsEmpty()) {
3559 return NS_OK;
3560 }
3561
3562 nsICookieService* cs = gHttpHandler->GetCookieService();
3563 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"
, 3563); return NS_ERROR_FAILURE; } } while (false)
;
3564
3565 nsresult rv = cs->SetCookieStringFromHttp(mURI, aCookieHeader, this);
3566 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3567 NotifySetCookie(aCookieHeader);
3568 }
3569 return rv;
3570}
3571
3572NS_IMETHODIMPnsresult
3573HttpBaseChannel::GetThirdPartyFlags(uint32_t* aFlags) {
3574 *aFlags = LoadThirdPartyFlags();
3575 return NS_OK;
3576}
3577
3578NS_IMETHODIMPnsresult
3579HttpBaseChannel::SetThirdPartyFlags(uint32_t aFlags) {
3580 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"
, 3580); 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"
, 3580, 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"
, 3580); } } 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"
, 3580); 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"
, 3580); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
3581
3582 StoreThirdPartyFlags(aFlags);
3583 return NS_OK;
3584}
3585
3586NS_IMETHODIMPnsresult
3587HttpBaseChannel::GetForceAllowThirdPartyCookie(bool* aForce) {
3588 *aForce = !!(LoadThirdPartyFlags() &
3589 nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3590 return NS_OK;
3591}
3592
3593NS_IMETHODIMPnsresult
3594HttpBaseChannel::SetForceAllowThirdPartyCookie(bool aForce) {
3595 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"
, 3595); 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"
, 3595, 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"
, 3595); } } 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"
, 3595); 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"
, 3595); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
3596
3597 if (aForce) {
3598 StoreThirdPartyFlags(LoadThirdPartyFlags() |
3599 nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3600 } else {
3601 StoreThirdPartyFlags(LoadThirdPartyFlags() &
3602 ~nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3603 }
3604
3605 return NS_OK;
3606}
3607
3608NS_IMETHODIMPnsresult
3609HttpBaseChannel::GetCanceled(bool* aCanceled) {
3610 *aCanceled = mCanceled;
3611 return NS_OK;
3612}
3613
3614NS_IMETHODIMPnsresult
3615HttpBaseChannel::GetChannelIsForDownload(bool* aChannelIsForDownload) {
3616 *aChannelIsForDownload = LoadChannelIsForDownload();
3617 return NS_OK;
3618}
3619
3620NS_IMETHODIMPnsresult
3621HttpBaseChannel::SetChannelIsForDownload(bool aChannelIsForDownload) {
3622 StoreChannelIsForDownload(aChannelIsForDownload);
3623 return NS_OK;
3624}
3625
3626NS_IMETHODIMPnsresult
3627HttpBaseChannel::SetCacheKeysRedirectChain(nsTArray<nsCString>* cacheKeys) {
3628 auto RedirectedCachekeys = mRedirectedCachekeys.Lock();
3629 auto& ref = RedirectedCachekeys.ref();
3630 ref = WrapUnique(cacheKeys);
3631 return NS_OK;
3632}
3633
3634NS_IMETHODIMPnsresult
3635HttpBaseChannel::GetLocalAddress(nsACString& addr) {
3636 if (mSelfAddr.raw.family == PR_AF_UNSPEC0) return NS_ERROR_NOT_AVAILABLE;
3637
3638 addr.SetLength(kIPv6CStrBufSize);
3639 mSelfAddr.ToStringBuffer(addr.BeginWriting(), kIPv6CStrBufSize);
3640 addr.SetLength(strlen(addr.BeginReading()));
3641
3642 return NS_OK;
3643}
3644
3645NS_IMETHODIMPnsresult
3646HttpBaseChannel::TakeAllSecurityMessages(
3647 nsCOMArray<nsISecurityConsoleMessage>& aMessages) {
3648 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"
, 3648); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3648; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3649
3650 aMessages.Clear();
3651 for (const auto& pair : mSecurityConsoleMessages) {
3652 nsresult rv;
3653 nsCOMPtr<nsISecurityConsoleMessage> message =
3654 do_CreateInstance(NS_SECURITY_CONSOLE_MESSAGE_CONTRACTID"@mozilla.org/securityconsole/message;1", &rv);
3655 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"
, 3655); return rv; } } while (false)
;
3656
3657 message->SetTag(pair.first);
3658 message->SetCategory(pair.second);
3659 aMessages.AppendElement(message);
3660 }
3661
3662 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"
, 3662); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSecurityConsoleMessages.Length() == aMessages.Length()"
")"); do { *((volatile int*)__null) = 3662; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3663 mSecurityConsoleMessages.Clear();
3664
3665 return NS_OK;
3666}
3667
3668/* Please use this method with care. This can cause the message
3669 * queue to grow large and cause the channel to take up a lot
3670 * of memory. Use only static string messages and do not add
3671 * server side data to the queue, as that can be large.
3672 * Add only a limited number of messages to the queue to keep
3673 * the channel size down and do so only in rare erroneous situations.
3674 * More information can be found here:
3675 * https://bugzilla.mozilla.org/show_bug.cgi?id=846918
3676 */
3677nsresult HttpBaseChannel::AddSecurityMessage(
3678 const nsAString& aMessageTag, const nsAString& aMessageCategory) {
3679 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"
, 3679); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3679; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3680
3681 nsresult rv;
3682
3683 // nsSecurityConsoleMessage is not thread-safe refcounted.
3684 // Delay the object construction until requested.
3685 // See TakeAllSecurityMessages()
3686 std::pair<nsString, nsString> pair(aMessageTag, aMessageCategory);
3687 mSecurityConsoleMessages.AppendElement(std::move(pair));
3688
3689 nsCOMPtr<nsIConsoleService> console(
3690 do_GetService(NS_CONSOLESERVICE_CONTRACTID"@mozilla.org/consoleservice;1"));
3691 if (!console) {
3692 return NS_ERROR_FAILURE;
3693 }
3694
3695 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
3696
3697 auto innerWindowID = loadInfo->GetInnerWindowID();
3698
3699 nsAutoString errorText;
3700 rv = nsContentUtils::GetLocalizedString(
3701 nsContentUtils::eSECURITY_PROPERTIES,
3702 NS_ConvertUTF16toUTF8(aMessageTag).get(), errorText);
3703 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"
, 3703); return rv; } } while (false)
;
3704
3705 nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID"@mozilla.org/scripterror;1"));
3706 error->InitWithSourceURI(
3707 errorText, mURI, u""_ns, 0, 0, nsIScriptError::warningFlag,
3708 NS_ConvertUTF16toUTF8(aMessageCategory), innerWindowID);
3709
3710 console->LogMessage(error);
3711
3712 return NS_OK;
3713}
3714
3715NS_IMETHODIMPnsresult
3716HttpBaseChannel::GetLocalPort(int32_t* port) {
3717 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"
, 3717); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3718
3719 if (mSelfAddr.raw.family == PR_AF_INET2) {
3720 *port = (int32_t)ntohs(mSelfAddr.inet.port)__bswap_16 (mSelfAddr.inet.port);
3721 } else if (mSelfAddr.raw.family == PR_AF_INET610) {
3722 *port = (int32_t)ntohs(mSelfAddr.inet6.port)__bswap_16 (mSelfAddr.inet6.port);
3723 } else {
3724 return NS_ERROR_NOT_AVAILABLE;
3725 }
3726
3727 return NS_OK;
3728}
3729
3730NS_IMETHODIMPnsresult
3731HttpBaseChannel::GetRemoteAddress(nsACString& addr) {
3732 if (mPeerAddr.raw.family == PR_AF_UNSPEC0) return NS_ERROR_NOT_AVAILABLE;
3733
3734 addr.SetLength(kIPv6CStrBufSize);
3735 mPeerAddr.ToStringBuffer(addr.BeginWriting(), kIPv6CStrBufSize);
3736 addr.SetLength(strlen(addr.BeginReading()));
3737
3738 return NS_OK;
3739}
3740
3741NS_IMETHODIMPnsresult
3742HttpBaseChannel::GetRemotePort(int32_t* port) {
3743 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"
, 3743); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3744
3745 if (mPeerAddr.raw.family == PR_AF_INET2) {
3746 *port = (int32_t)ntohs(mPeerAddr.inet.port)__bswap_16 (mPeerAddr.inet.port);
3747 } else if (mPeerAddr.raw.family == PR_AF_INET610) {
3748 *port = (int32_t)ntohs(mPeerAddr.inet6.port)__bswap_16 (mPeerAddr.inet6.port);
3749 } else {
3750 return NS_ERROR_NOT_AVAILABLE;
3751 }
3752
3753 return NS_OK;
3754}
3755
3756NS_IMETHODIMPnsresult
3757HttpBaseChannel::HTTPUpgrade(const nsACString& aProtocolName,
3758 nsIHttpUpgradeListener* aListener) {
3759 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"
, 3759); return NS_ERROR_INVALID_ARG; } } while (false)
;
3760 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"
, 3760); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3761
3762 mUpgradeProtocol = aProtocolName;
3763 mUpgradeProtocolCallback = aListener;
3764 return NS_OK;
3765}
3766
3767NS_IMETHODIMPnsresult
3768HttpBaseChannel::GetOnlyConnect(bool* aOnlyConnect) {
3769 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"
, 3769); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3770
3771 *aOnlyConnect = mCaps & NS_HTTP_CONNECT_ONLY(1 << 16);
3772 return NS_OK;
3773}
3774
3775NS_IMETHODIMPnsresult
3776HttpBaseChannel::SetConnectOnly(bool aTlsTunnel) {
3777 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"
, 3777); 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"
, 3777, 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"
, 3777); } } 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"
, 3777); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 3777; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
3778
3779 if (!mUpgradeProtocolCallback) {
3780 return NS_ERROR_FAILURE;
3781 }
3782
3783 mCaps |= NS_HTTP_CONNECT_ONLY(1 << 16);
3784 if (aTlsTunnel) {
3785 mCaps |= NS_HTTP_TLS_TUNNEL(1 << 29);
3786 }
3787 mProxyResolveFlags = nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY |
3788 nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL;
3789 return SetLoadFlags(nsIRequest::INHIBIT_CACHING | nsIChannel::LOAD_ANONYMOUS |
3790 nsIRequest::LOAD_BYPASS_CACHE |
3791 nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
3792}
3793
3794NS_IMETHODIMPnsresult
3795HttpBaseChannel::GetAllowSpdy(bool* aAllowSpdy) {
3796 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"
, 3796); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3797
3798 *aAllowSpdy = LoadAllowSpdy();
3799 return NS_OK;
3800}
3801
3802NS_IMETHODIMPnsresult
3803HttpBaseChannel::SetAllowSpdy(bool aAllowSpdy) {
3804 StoreAllowSpdy(aAllowSpdy);
3805 return NS_OK;
3806}
3807
3808NS_IMETHODIMPnsresult
3809HttpBaseChannel::GetAllowHttp3(bool* aAllowHttp3) {
3810 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"
, 3810); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3811
3812 *aAllowHttp3 = LoadAllowHttp3();
3813 return NS_OK;
3814}
3815
3816NS_IMETHODIMPnsresult
3817HttpBaseChannel::SetAllowHttp3(bool aAllowHttp3) {
3818 StoreAllowHttp3(aAllowHttp3);
3819 return NS_OK;
3820}
3821
3822NS_IMETHODIMPnsresult
3823HttpBaseChannel::GetAllowAltSvc(bool* aAllowAltSvc) {
3824 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"
, 3824); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3825
3826 *aAllowAltSvc = LoadAllowAltSvc();
3827 return NS_OK;
3828}
3829
3830NS_IMETHODIMPnsresult
3831HttpBaseChannel::SetAllowAltSvc(bool aAllowAltSvc) {
3832 StoreAllowAltSvc(aAllowAltSvc);
3833 return NS_OK;
3834}
3835
3836NS_IMETHODIMPnsresult
3837HttpBaseChannel::GetBeConservative(bool* aBeConservative) {
3838 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"
, 3838); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3839
3840 *aBeConservative = LoadBeConservative();
3841 return NS_OK;
3842}
3843
3844NS_IMETHODIMPnsresult
3845HttpBaseChannel::SetBeConservative(bool aBeConservative) {
3846 StoreBeConservative(aBeConservative);
3847 return NS_OK;
3848}
3849
3850bool HttpBaseChannel::BypassProxy() {
3851 return StaticPrefs::network_proxy_allow_bypass() && LoadBypassProxy();
3852}
3853
3854NS_IMETHODIMPnsresult
3855HttpBaseChannel::GetBypassProxy(bool* aBypassProxy) {
3856 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"
, 3856); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3857
3858 *aBypassProxy = BypassProxy();
3859 return NS_OK;
3860}
3861
3862NS_IMETHODIMPnsresult
3863HttpBaseChannel::SetBypassProxy(bool aBypassProxy) {
3864 if (StaticPrefs::network_proxy_allow_bypass()) {
3865 StoreBypassProxy(aBypassProxy);
3866 } else {
3867 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"
, 3867)
;
3868 return NS_ERROR_FAILURE;
3869 }
3870 return NS_OK;
3871}
3872
3873NS_IMETHODIMPnsresult
3874HttpBaseChannel::GetIsTRRServiceChannel(bool* aIsTRRServiceChannel) {
3875 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"
, 3875); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3876
3877 *aIsTRRServiceChannel = LoadIsTRRServiceChannel();
3878 return NS_OK;
3879}
3880
3881NS_IMETHODIMPnsresult
3882HttpBaseChannel::SetIsTRRServiceChannel(bool aIsTRRServiceChannel) {
3883 StoreIsTRRServiceChannel(aIsTRRServiceChannel);
3884 return NS_OK;
3885}
3886
3887NS_IMETHODIMPnsresult
3888HttpBaseChannel::GetIsResolvedByTRR(bool* aResolvedByTRR) {
3889 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"
, 3889); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3890 *aResolvedByTRR = LoadResolvedByTRR();
3891 return NS_OK;
3892}
3893
3894NS_IMETHODIMPnsresult
3895HttpBaseChannel::GetEffectiveTRRMode(nsIRequest::TRRMode* aEffectiveTRRMode) {
3896 *aEffectiveTRRMode = mEffectiveTRRMode;
3897 return NS_OK;
3898}
3899
3900NS_IMETHODIMPnsresult
3901HttpBaseChannel::GetTrrSkipReason(nsITRRSkipReason::value* aTrrSkipReason) {
3902 *aTrrSkipReason = mTRRSkipReason;
3903 return NS_OK;
3904}
3905
3906NS_IMETHODIMPnsresult
3907HttpBaseChannel::GetIsLoadedBySocketProcess(bool* aResult) {
3908 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"
, 3908); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3909 *aResult = LoadLoadedBySocketProcess();
3910 return NS_OK;
3911}
3912
3913NS_IMETHODIMPnsresult
3914HttpBaseChannel::GetTlsFlags(uint32_t* aTlsFlags) {
3915 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"
, 3915); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3916
3917 *aTlsFlags = mTlsFlags;
3918 return NS_OK;
3919}
3920
3921NS_IMETHODIMPnsresult
3922HttpBaseChannel::SetTlsFlags(uint32_t aTlsFlags) {
3923 mTlsFlags = aTlsFlags;
3924 return NS_OK;
3925}
3926
3927NS_IMETHODIMPnsresult
3928HttpBaseChannel::GetApiRedirectToURI(nsIURI** aResult) {
3929 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"
, 3929); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3930 *aResult = do_AddRef(mAPIRedirectToURI).take();
3931 return NS_OK;
3932}
3933
3934NS_IMETHODIMPnsresult
3935HttpBaseChannel::GetResponseTimeoutEnabled(bool* aEnable) {
3936 if (NS_WARN_IF(!aEnable)NS_warn_if_impl(!aEnable, "!aEnable", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3936)
) {
3937 return NS_ERROR_NULL_POINTER;
3938 }
3939 *aEnable = LoadResponseTimeoutEnabled();
3940 return NS_OK;
3941}
3942
3943NS_IMETHODIMPnsresult
3944HttpBaseChannel::SetResponseTimeoutEnabled(bool aEnable) {
3945 StoreResponseTimeoutEnabled(aEnable);
3946 return NS_OK;
3947}
3948
3949NS_IMETHODIMPnsresult
3950HttpBaseChannel::GetInitialRwin(uint32_t* aRwin) {
3951 if (NS_WARN_IF(!aRwin)NS_warn_if_impl(!aRwin, "!aRwin", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3951)
) {
3952 return NS_ERROR_NULL_POINTER;
3953 }
3954 *aRwin = mInitialRwin;
3955 return NS_OK;
3956}
3957
3958NS_IMETHODIMPnsresult
3959HttpBaseChannel::SetInitialRwin(uint32_t aRwin) {
3960 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"
, 3960); 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"
, 3960, 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"
, 3960); } } 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"
, 3960); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 3960; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
3961 mInitialRwin = aRwin;
3962 return NS_OK;
3963}
3964
3965NS_IMETHODIMPnsresult
3966HttpBaseChannel::ForcePending(bool aForcePending) {
3967 StoreForcePending(aForcePending);
3968 return NS_OK;
3969}
3970
3971NS_IMETHODIMPnsresult
3972HttpBaseChannel::GetLastModifiedTime(PRTime* lastModifiedTime) {
3973 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
3974 uint32_t lastMod;
3975 nsresult rv = mResponseHead->GetLastModifiedValue(&lastMod);
3976 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"
, 3976); return rv; } } while (false)
;
3977 *lastModifiedTime = lastMod;
3978 return NS_OK;
3979}
3980
3981NS_IMETHODIMPnsresult
3982HttpBaseChannel::GetCorsIncludeCredentials(bool* aInclude) {
3983 *aInclude = LoadCorsIncludeCredentials();
3984 return NS_OK;
3985}
3986
3987NS_IMETHODIMPnsresult
3988HttpBaseChannel::SetCorsIncludeCredentials(bool aInclude) {
3989 StoreCorsIncludeCredentials(aInclude);
3990 return NS_OK;
3991}
3992
3993NS_IMETHODIMPnsresult
3994HttpBaseChannel::GetRequestMode(RequestMode* aMode) {
3995 *aMode = mRequestMode;
3996 return NS_OK;
3997}
3998
3999NS_IMETHODIMPnsresult
4000HttpBaseChannel::SetRequestMode(RequestMode aMode) {
4001 mRequestMode = aMode;
4002 return NS_OK;
4003}
4004
4005NS_IMETHODIMPnsresult
4006HttpBaseChannel::GetRedirectMode(uint32_t* aMode) {
4007 *aMode = mRedirectMode;
4008 return NS_OK;
4009}
4010
4011NS_IMETHODIMPnsresult
4012HttpBaseChannel::SetRedirectMode(uint32_t aMode) {
4013 mRedirectMode = aMode;
4014 return NS_OK;
4015}
4016
4017namespace {
4018
4019bool ContainsAllFlags(uint32_t aLoadFlags, uint32_t aMask) {
4020 return (aLoadFlags & aMask) == aMask;
4021}
4022
4023} // anonymous namespace
4024
4025NS_IMETHODIMPnsresult
4026HttpBaseChannel::GetFetchCacheMode(uint32_t* aFetchCacheMode) {
4027 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"
, 4027); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4028
4029 // Otherwise try to guess an appropriate cache mode from the load flags.
4030 if (ContainsAllFlags(mLoadFlags, INHIBIT_CACHING | LOAD_BYPASS_CACHE)) {
4031 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE;
4032 } else if (ContainsAllFlags(mLoadFlags, LOAD_BYPASS_CACHE)) {
4033 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD;
4034 } else if (ContainsAllFlags(mLoadFlags, VALIDATE_ALWAYS) ||
4035 LoadForceValidateCacheContent()) {
4036 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE;
4037 } else if (ContainsAllFlags(
4038 mLoadFlags,
4039 VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE)) {
4040 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED;
4041 } else if (ContainsAllFlags(mLoadFlags, VALIDATE_NEVER)) {
4042 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE;
4043 } else {
4044 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT;
4045 }
4046
4047 return NS_OK;
4048}
4049
4050namespace {
4051
4052void SetCacheFlags(uint32_t& aLoadFlags, uint32_t aFlags) {
4053 // First, clear any possible cache related flags.
4054 uint32_t allPossibleFlags =
4055 nsIRequest::INHIBIT_CACHING | nsIRequest::LOAD_BYPASS_CACHE |
4056 nsIRequest::VALIDATE_ALWAYS | nsIRequest::LOAD_FROM_CACHE |
4057 nsICachingChannel::LOAD_ONLY_FROM_CACHE;
4058 aLoadFlags &= ~allPossibleFlags;
4059
4060 // Then set the new flags.
4061 aLoadFlags |= aFlags;
4062}
4063
4064} // anonymous namespace
4065
4066NS_IMETHODIMPnsresult
4067HttpBaseChannel::SetFetchCacheMode(uint32_t aFetchCacheMode) {
4068 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"
, 4068); 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"
, 4068, 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"
, 4068); } } 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"
, 4068); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 4068; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
4069
4070 // Now, set the load flags that implement each cache mode.
4071 switch (aFetchCacheMode) {
4072 case nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT:
4073 // The "default" mode means to use the http cache normally and
4074 // respect any http cache-control headers. We effectively want
4075 // to clear our cache related load flags.
4076 SetCacheFlags(mLoadFlags, 0);
4077 break;
4078 case nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE:
4079 // no-store means don't consult the cache on the way to the network, and
4080 // don't store the response in the cache even if it's cacheable.
4081 SetCacheFlags(mLoadFlags, INHIBIT_CACHING | LOAD_BYPASS_CACHE);
4082 break;
4083 case nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD:
4084 // reload means don't consult the cache on the way to the network, but
4085 // do store the response in the cache if possible.
4086 SetCacheFlags(mLoadFlags, LOAD_BYPASS_CACHE);
4087 break;
4088 case nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE:
4089 // no-cache means always validate what's in the cache.
4090 SetCacheFlags(mLoadFlags, VALIDATE_ALWAYS);
4091 break;
4092 case nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE:
4093 // force-cache means don't validate unless if the response would vary.
4094 SetCacheFlags(mLoadFlags, VALIDATE_NEVER);
4095 break;
4096 case nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED:
4097 // only-if-cached means only from cache, no network, no validation,
4098 // generate a network error if the document was't in the cache. The
4099 // privacy implications of these flags (making it fast/easy to check if
4100 // the user has things in their cache without any network traffic side
4101 // effects) are addressed in the Request constructor which
4102 // enforces/requires same-origin request mode.
4103 SetCacheFlags(mLoadFlags,
4104 VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE);
4105 break;
4106 }
4107
4108#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED1
4109 uint32_t finalMode = 0;
4110 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"
, 4110); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(GetFetchCacheMode(&finalMode))" ")")
; do { *((volatile int*)__null) = 4110; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4111 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"
, 4111); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "finalMode == aFetchCacheMode"
")"); do { *((volatile int*)__null) = 4111; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4112#endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED
4113
4114 return NS_OK;
4115}
4116
4117NS_IMETHODIMPnsresult
4118HttpBaseChannel::SetIntegrityMetadata(const nsAString& aIntegrityMetadata) {
4119 mIntegrityMetadata = aIntegrityMetadata;
4120 return NS_OK;
4121}
4122
4123NS_IMETHODIMPnsresult
4124HttpBaseChannel::GetIntegrityMetadata(nsAString& aIntegrityMetadata) {
4125 aIntegrityMetadata = mIntegrityMetadata;
4126 return NS_OK;
4127}
4128
4129//-----------------------------------------------------------------------------
4130// HttpBaseChannel::nsISupportsPriority
4131//-----------------------------------------------------------------------------
4132
4133NS_IMETHODIMPnsresult
4134HttpBaseChannel::GetPriority(int32_t* value) {
4135 *value = mPriority;
4136 return NS_OK;
4137}
4138
4139NS_IMETHODIMPnsresult
4140HttpBaseChannel::AdjustPriority(int32_t delta) {
4141 return SetPriority(mPriority + delta);
4142}
4143
4144//-----------------------------------------------------------------------------
4145// HttpBaseChannel::nsIResumableChannel
4146//-----------------------------------------------------------------------------
4147
4148NS_IMETHODIMPnsresult
4149HttpBaseChannel::GetEntityID(nsACString& aEntityID) {
4150 // Don't return an entity ID for Non-GET requests which require
4151 // additional data
4152 if (!mRequestHead.IsGet()) {
4153 return NS_ERROR_NOT_RESUMABLE;
4154 }
4155
4156 uint64_t size = UINT64_MAX(18446744073709551615UL);
4157 nsAutoCString etag, lastmod;
4158 if (mResponseHead) {
4159 // Don't return an entity if the server sent the following header:
4160 // Accept-Ranges: none
4161 // Not sending the Accept-Ranges header means we can still try
4162 // sending range requests.
4163 nsAutoCString acceptRanges;
4164 Unused << mResponseHead->GetHeader(nsHttp::Accept_Ranges, acceptRanges);
4165 if (!acceptRanges.IsEmpty() &&
4166 !nsHttp::FindToken(acceptRanges.get(), "bytes",
4167 HTTP_HEADER_VALUE_SEPS" \t" ",")) {
4168 return NS_ERROR_NOT_RESUMABLE;
4169 }
4170
4171 size = mResponseHead->TotalEntitySize();
4172 Unused << mResponseHead->GetHeader(nsHttp::Last_Modified, lastmod);
4173 Unused << mResponseHead->GetHeader(nsHttp::ETag, etag);
4174 }
4175 nsCString entityID;
4176 NS_EscapeURL(etag.BeginReading(), etag.Length(),
4177 esc_AlwaysCopy | esc_FileBaseName | esc_Forced, entityID);
4178 entityID.Append('/');
4179 entityID.AppendInt(int64_t(size));
4180 entityID.Append('/');
4181 entityID.Append(lastmod);
4182 // NOTE: Appending lastmod as the last part avoids having to escape it
4183
4184 aEntityID = entityID;
4185
4186 return NS_OK;
4187}
4188
4189//-----------------------------------------------------------------------------
4190// HttpBaseChannel::nsIConsoleReportCollector
4191//-----------------------------------------------------------------------------
4192
4193void HttpBaseChannel::AddConsoleReport(
4194 uint32_t aErrorFlags, const nsACString& aCategory,
4195 nsContentUtils::PropertiesFile aPropertiesFile,
4196 const nsACString& aSourceFileURI, uint32_t aLineNumber,
4197 uint32_t aColumnNumber, const nsACString& aMessageName,
4198 const nsTArray<nsString>& aStringParams) {
4199 mReportCollector->AddConsoleReport(aErrorFlags, aCategory, aPropertiesFile,
4200 aSourceFileURI, aLineNumber, aColumnNumber,
4201 aMessageName, aStringParams);
4202
4203 // If this channel is already part of a loadGroup, we can flush this console
4204 // report immediately.
4205 HttpBaseChannel::MaybeFlushConsoleReports();
4206}
4207
4208void HttpBaseChannel::FlushReportsToConsole(uint64_t aInnerWindowID,
4209 ReportAction aAction) {
4210 mReportCollector->FlushReportsToConsole(aInnerWindowID, aAction);
4211}
4212
4213void HttpBaseChannel::FlushReportsToConsoleForServiceWorkerScope(
4214 const nsACString& aScope, ReportAction aAction) {
4215 mReportCollector->FlushReportsToConsoleForServiceWorkerScope(aScope, aAction);
4216}
4217
4218void HttpBaseChannel::FlushConsoleReports(dom::Document* aDocument,
4219 ReportAction aAction) {
4220 mReportCollector->FlushConsoleReports(aDocument, aAction);
4221}
4222
4223void HttpBaseChannel::FlushConsoleReports(nsILoadGroup* aLoadGroup,
4224 ReportAction aAction) {
4225 mReportCollector->FlushConsoleReports(aLoadGroup, aAction);
4226}
4227
4228void HttpBaseChannel::FlushConsoleReports(
4229 nsIConsoleReportCollector* aCollector) {
4230 mReportCollector->FlushConsoleReports(aCollector);
4231}
4232
4233void HttpBaseChannel::StealConsoleReports(
4234 nsTArray<net::ConsoleReportCollected>& aReports) {
4235 mReportCollector->StealConsoleReports(aReports);
4236}
4237
4238void HttpBaseChannel::ClearConsoleReports() {
4239 mReportCollector->ClearConsoleReports();
4240}
4241
4242bool HttpBaseChannel::IsNavigation() {
4243 return LoadForceMainDocumentChannel() || (mLoadFlags & LOAD_DOCUMENT_URI);
4244}
4245
4246bool HttpBaseChannel::BypassServiceWorker() const {
4247 return mLoadFlags & LOAD_BYPASS_SERVICE_WORKER;
4248}
4249
4250bool HttpBaseChannel::ShouldIntercept(nsIURI* aURI) {
4251 nsCOMPtr<nsINetworkInterceptController> controller;
4252 GetCallback(controller);
4253 bool shouldIntercept = false;
4254
4255 if (!StaticPrefs::dom_serviceWorkers_enabled()) {
4256 return false;
4257 }
4258
4259 // We should never intercept internal redirects. The ServiceWorker code
4260 // can trigger interntal redirects as the result of a FetchEvent. If
4261 // we re-intercept then an infinite loop can occur.
4262 //
4263 // Its also important that we do not set the LOAD_BYPASS_SERVICE_WORKER
4264 // flag because an internal redirect occurs. Its possible that another
4265 // interception should occur after the internal redirect. For example,
4266 // if the ServiceWorker chooses not to call respondWith() the channel
4267 // will be reset with an internal redirect. If the request is a navigation
4268 // and the network then triggers a redirect its possible the new URL
4269 // should be intercepted again.
4270 //
4271 // Note, HSTS upgrade redirects are often treated the same as internal
4272 // redirects. In this case, however, we intentionally allow interception
4273 // of HSTS upgrade redirects. This matches the expected spec behavior and
4274 // does not run the risk of infinite loops as described above.
4275 bool internalRedirect =
4276 mLastRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL;
4277
4278 if (controller && mLoadInfo && !BypassServiceWorker() && !internalRedirect) {
4279 nsresult rv = controller->ShouldPrepareForIntercept(
4280 aURI ? aURI : mURI.get(), this, &shouldIntercept);
4281 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4282 return false;
4283 }
4284 }
4285 return shouldIntercept;
4286}
4287
4288void HttpBaseChannel::AddAsNonTailRequest() {
4289 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"
, 4289); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4289; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4290
4291 if (EnsureRequestContext()) {
4292 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)
4293 "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)
4294 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)
;
4295
4296 if (!LoadAddedAsNonTailRequest()) {
4297 mRequestContext->AddNonTailRequest();
4298 StoreAddedAsNonTailRequest(true);
4299 }
4300 }
4301}
4302
4303void HttpBaseChannel::RemoveAsNonTailRequest() {
4304 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"
, 4304); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4304; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4305
4306 if (mRequestContext) {
4307 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)
4308 ("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)
4309 "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)
4310 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)
;
4311
4312 if (LoadAddedAsNonTailRequest()) {
4313 mRequestContext->RemoveNonTailRequest();
4314 StoreAddedAsNonTailRequest(false);
4315 }
4316 }
4317}
4318
4319#ifdef DEBUG1
4320void HttpBaseChannel::AssertPrivateBrowsingId() {
4321 nsCOMPtr<nsILoadContext> loadContext;
4322 NS_QueryNotificationCallbacks(this, loadContext);
4323
4324 if (!loadContext) {
4325 return;
4326 }
4327
4328 // We skip testing of favicon loading here since it could be triggered by XUL
4329 // image which uses SystemPrincipal. The SystemPrincpal doesn't have
4330 // mPrivateBrowsingId.
4331 if (mLoadInfo->GetLoadingPrincipal() &&
4332 mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal() &&
4333 mLoadInfo->InternalContentPolicyType() ==
4334 nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
4335 return;
4336 }
4337
4338 OriginAttributes docShellAttrs;
4339 loadContext->GetOriginAttributes(docShellAttrs);
4340 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"
, 4343); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4343; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4341 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"
, 4343); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4343; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4342 "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"
, 4343); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4343; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4343 "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"
, 4343); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4343; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
4344}
4345#endif
4346
4347already_AddRefed<nsILoadInfo> HttpBaseChannel::CloneLoadInfoForRedirect(
4348 nsIURI* aNewURI, uint32_t aRedirectFlags) {
4349 // make a copy of the loadinfo, append to the redirectchain
4350 // this will be set on the newly created channel for the redirect target.
4351 nsCOMPtr<nsILoadInfo> newLoadInfo =
4352 static_cast<mozilla::net::LoadInfo*>(mLoadInfo.get())->Clone();
4353
4354 ExtContentPolicyType contentPolicyType =
4355 mLoadInfo->GetExternalContentPolicyType();
4356 if (contentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
4357 contentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
4358 // Reset PrincipalToInherit to a null principal. We'll credit the the
4359 // redirecting resource's result principal as the new principal's precursor.
4360 // This means that a data: URI will end up loading in a process based on the
4361 // redirected-from URI.
4362 nsCOMPtr<nsIPrincipal> redirectPrincipal;
4363 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
4364 this, getter_AddRefs(redirectPrincipal));
4365 nsCOMPtr<nsIPrincipal> nullPrincipalToInherit =
4366 NullPrincipal::CreateWithInheritedAttributes(redirectPrincipal);
4367 newLoadInfo->SetPrincipalToInherit(nullPrincipalToInherit);
4368 }
4369
4370 bool isTopLevelDoc = newLoadInfo->GetExternalContentPolicyType() ==
4371 ExtContentPolicy::TYPE_DOCUMENT;
4372
4373 if (isTopLevelDoc) {
4374 // re-compute the origin attributes of the loadInfo if it's top-level load.
4375 nsCOMPtr<nsILoadContext> loadContext;
4376 NS_QueryNotificationCallbacks(this, loadContext);
4377 OriginAttributes docShellAttrs;
4378 if (loadContext) {
4379 loadContext->GetOriginAttributes(docShellAttrs);
4380 }
4381
4382 OriginAttributes attrs = newLoadInfo->GetOriginAttributes();
4383
4384 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"
, 4386); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4386; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4385 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"
, 4386); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4386; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4386 "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"
, 4386); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4386; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4387 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"
, 4389); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4389; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4388 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"
, 4389); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4389; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4389 "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"
, 4389); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4389; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4390 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"
, 4393); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4393; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4391 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"
, 4393); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4393; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4392 "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"
, 4393); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4393; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4393 "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"
, 4393); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4393; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4394
4395 attrs = docShellAttrs;
4396 attrs.SetFirstPartyDomain(true, aNewURI);
4397 newLoadInfo->SetOriginAttributes(attrs);
4398
4399 // re-compute the upgrade insecure requests bit for document navigations
4400 // since it should only apply to same-origin navigations (redirects).
4401 // we only do this if the CSP of the triggering element (the cspToInherit)
4402 // uses 'upgrade-insecure-requests', otherwise UIR does not apply.
4403 nsCOMPtr<nsIContentSecurityPolicy> csp = newLoadInfo->GetCspToInherit();
4404 if (csp) {
4405 bool upgradeInsecureRequests = false;
4406 csp->GetUpgradeInsecureRequests(&upgradeInsecureRequests);
4407 if (upgradeInsecureRequests) {
4408 nsCOMPtr<nsIPrincipal> resultPrincipal =
4409 BasePrincipal::CreateContentPrincipal(
4410 aNewURI, newLoadInfo->GetOriginAttributes());
4411 bool isConsideredSameOriginforUIR =
4412 nsContentSecurityUtils::IsConsideredSameOriginForUIR(
4413 newLoadInfo->TriggeringPrincipal(), resultPrincipal);
4414 static_cast<mozilla::net::LoadInfo*>(newLoadInfo.get())
4415 ->SetUpgradeInsecureRequests(isConsideredSameOriginforUIR);
4416 }
4417 }
4418 }
4419
4420 // Leave empty, we want a 'clean ground' when creating the new channel.
4421 // This will be ensured to be either set by the protocol handler or set
4422 // to the redirect target URI properly after the channel creation.
4423 newLoadInfo->SetResultPrincipalURI(nullptr);
4424
4425 bool isInternalRedirect =
4426 (aRedirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
4427 nsIChannelEventSink::REDIRECT_STS_UPGRADE));
4428
4429 // Reset our sandboxed null principal ID when cloning loadInfo for an
4430 // externally visible redirect.
4431 if (!isInternalRedirect) {
4432 // If we've redirected from http to something that isn't, clear
4433 // the "external" flag, as loads that now go to other apps should be
4434 // allowed to go ahead and not trip infinite-loop protection
4435 // (see bug 1717314 for context).
4436 if (!aNewURI->SchemeIs("http") && !aNewURI->SchemeIs("https")) {
4437 newLoadInfo->SetLoadTriggeredFromExternal(false);
4438 }
4439 newLoadInfo->ResetSandboxedNullPrincipalID();
4440 }
4441
4442 newLoadInfo->AppendRedirectHistoryEntry(this, isInternalRedirect);
4443
4444 return newLoadInfo.forget();
4445}
4446
4447//-----------------------------------------------------------------------------
4448// nsHttpChannel::nsITraceableChannel
4449//-----------------------------------------------------------------------------
4450
4451NS_IMETHODIMPnsresult
4452HttpBaseChannel::SetNewListener(nsIStreamListener* aListener,
4453 bool aMustApplyContentConversion,
4454 nsIStreamListener** _retval) {
4455 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)
4456 "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)
4457 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)
;
4458
4459 if (!LoadTracingEnabled()) return NS_ERROR_FAILURE;
4460
4461 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"
, 4461); return NS_ERROR_UNEXPECTED; } } while (false)
;
4462 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"
, 4462); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4463
4464 nsCOMPtr<nsIStreamListener> wrapper = new nsStreamListenerWrapper(mListener);
4465
4466 wrapper.forget(_retval);
4467 mListener = aListener;
4468 if (aMustApplyContentConversion) {
4469 StoreListenerRequiresContentConversion(true);
4470 }
4471 return NS_OK;
4472}
4473
4474//-----------------------------------------------------------------------------
4475// HttpBaseChannel helpers
4476//-----------------------------------------------------------------------------
4477
4478void HttpBaseChannel::ReleaseListeners() {
4479 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"
, 4480); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentThread->IsOnCurrentThread()"
") (" "Should only be called on the current thread" ")"); do
{ *((volatile int*)__null) = 4480; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
4480 "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"
, 4480); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentThread->IsOnCurrentThread()"
") (" "Should only be called on the current thread" ")"); do
{ *((volatile int*)__null) = 4480; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
4481
4482 mListener = nullptr;
4483 mCallbacks = nullptr;
4484 mProgressSink = nullptr;
4485 mCompressListener = nullptr;
4486 mORB = nullptr;
4487}
4488
4489void HttpBaseChannel::DoNotifyListener() {
4490 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)
;
4491
4492 // In case nsHttpChannel::OnStartRequest wasn't called (e.g. due to flag
4493 // LOAD_ONLY_IF_MODIFIED) we want to set AfterOnStartRequestBegun to true
4494 // before notifying listener.
4495 if (!LoadAfterOnStartRequestBegun()) {
4496 StoreAfterOnStartRequestBegun(true);
4497 }
4498
4499 if (mListener && !LoadOnStartRequestCalled()) {
4500 nsCOMPtr<nsIStreamListener> listener = mListener;
4501 StoreOnStartRequestCalled(true);
4502 listener->OnStartRequest(this);
4503 }
4504 StoreOnStartRequestCalled(true);
4505
4506 // Make sure IsPending is set to false. At this moment we are done from
4507 // the point of view of our consumer and we have to report our self
4508 // as not-pending.
4509 StoreIsPending(false);
4510
4511 // notify "http-on-before-stop-request" observers
4512 gHttpHandler->OnBeforeStopRequest(this);
4513
4514 if (mListener && !LoadOnStopRequestCalled()) {
4515 nsCOMPtr<nsIStreamListener> listener = mListener;
4516 StoreOnStopRequestCalled(true);
4517 listener->OnStopRequest(this, mStatus);
4518 }
4519 StoreOnStopRequestCalled(true);
4520
4521 // notify "http-on-stop-request" observers
4522 gHttpHandler->OnStopRequest(this);
4523
4524 // This channel has finished its job, potentially release any tail-blocked
4525 // requests with this.
4526 RemoveAsNonTailRequest();
4527
4528 // We have to make sure to drop the references to listeners and callbacks
4529 // no longer needed.
4530 ReleaseListeners();
4531
4532 DoNotifyListenerCleanup();
4533
4534 // If this is a navigation, then we must let the docshell flush the reports
4535 // to the console later. The LoadDocument() is pointing at the detached
4536 // document that started the navigation. We want to show the reports on the
4537 // new document. Otherwise the console is wiped and the user never sees
4538 // the information.
4539 if (!IsNavigation()) {
4540 if (mLoadGroup) {
4541 FlushConsoleReports(mLoadGroup);
4542 } else {
4543 RefPtr<dom::Document> doc;
4544 mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
4545 FlushConsoleReports(doc);
4546 }
4547 }
4548}
4549
4550void HttpBaseChannel::AddCookiesToRequest() {
4551 if (mLoadFlags & LOAD_ANONYMOUS) {
4552 return;
4553 }
4554
4555 bool useCookieService = (XRE_IsParentProcess());
4556 nsAutoCString cookie;
4557 if (useCookieService) {
4558 nsICookieService* cs = gHttpHandler->GetCookieService();
4559 if (cs) {
4560 cs->GetCookieStringFromHttp(mURI, this, cookie);
4561 }
4562
4563 if (cookie.IsEmpty()) {
4564 cookie = mUserSetCookieHeader;
4565 } else if (!mUserSetCookieHeader.IsEmpty()) {
4566 cookie.AppendLiteral("; ");
4567 cookie.Append(mUserSetCookieHeader);
4568 }
4569 } else {
4570 cookie = mUserSetCookieHeader;
4571 }
4572
4573 // If we are in the child process, we want the parent seeing any
4574 // cookie headers that might have been set by SetRequestHeader()
4575 SetRequestHeader(nsHttp::Cookie.val(), cookie, false);
4576}
4577
4578/* static */
4579void HttpBaseChannel::PropagateReferenceIfNeeded(
4580 nsIURI* aURI, nsCOMPtr<nsIURI>& aRedirectURI) {
4581 bool hasRef = false;
4582 nsresult rv = aRedirectURI->GetHasRef(&hasRef);
4583 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !hasRef) {
4584 nsAutoCString ref;
4585 aURI->GetRef(ref);
4586 if (!ref.IsEmpty()) {
4587 // NOTE: SetRef will fail if mRedirectURI is immutable
4588 // (e.g. an about: URI)... Oh well.
4589 Unused << NS_MutateURI(aRedirectURI).SetRef(ref).Finalize(aRedirectURI);
4590 }
4591 }
4592}
4593
4594bool HttpBaseChannel::ShouldRewriteRedirectToGET(
4595 uint32_t httpStatus, nsHttpRequestHead::ParsedMethodType method) {
4596 // for 301 and 302, only rewrite POST
4597 if (httpStatus == 301 || httpStatus == 302) {
4598 return method == nsHttpRequestHead::kMethod_Post;
4599 }
4600
4601 // rewrite for 303 unless it was HEAD
4602 if (httpStatus == 303) return method != nsHttpRequestHead::kMethod_Head;
4603
4604 // otherwise, such as for 307, do not rewrite
4605 return false;
4606}
4607
4608NS_IMETHODIMPnsresult
4609HttpBaseChannel::ShouldStripRequestBodyHeader(const nsACString& aMethod,
4610 bool* aResult) {
4611 *aResult = false;
4612 uint32_t httpStatus = 0;
4613 if (NS_FAILED(GetResponseStatus(&httpStatus))((bool)(__builtin_expect(!!(NS_FAILED_impl(GetResponseStatus(
&httpStatus))), 0)))
) {
4614 return NS_OK;
4615 }
4616
4617 nsAutoCString method(aMethod);
4618 nsHttpRequestHead::ParsedMethodType parsedMethod;
4619 nsHttpRequestHead::ParseMethod(method, parsedMethod);
4620 // Fetch 4.4.11, which is slightly different than the perserved method
4621 // algrorithm: strip request-body-header for GET->GET redirection for 303.
4622 *aResult =
4623 ShouldRewriteRedirectToGET(httpStatus, parsedMethod) &&
4624 !(httpStatus == 303 && parsedMethod == nsHttpRequestHead::kMethod_Get);
4625
4626 return NS_OK;
4627}
4628
4629HttpBaseChannel::ReplacementChannelConfig
4630HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod,
4631 uint32_t aRedirectFlags,
4632 ReplacementReason aReason) {
4633 ReplacementChannelConfig config;
4634 config.redirectFlags = aRedirectFlags;
4635 config.classOfService = mClassOfService;
4636
4637 if (mPrivateBrowsingOverriden) {
4638 config.privateBrowsing = Some(mPrivateBrowsing);
4639 }
4640
4641 if (mReferrerInfo) {
4642 // When cloning for a document channel replacement (parent process
4643 // copying values for a new content process channel), this happens after
4644 // OnStartRequest so we have the headers for the response available.
4645 // We don't want to apply them to the referrer for the channel though,
4646 // since that is the referrer for the current document, and the header
4647 // should only apply to navigations from the current document.
4648 if (aReason == ReplacementReason::DocumentChannel) {
4649 config.referrerInfo = mReferrerInfo;
4650 } else {
4651 dom::ReferrerPolicy referrerPolicy = dom::ReferrerPolicy::_empty;
4652 nsAutoCString tRPHeaderCValue;
4653 Unused << GetResponseHeader("referrer-policy"_ns, tRPHeaderCValue);
4654 NS_ConvertUTF8toUTF16 tRPHeaderValue(tRPHeaderCValue);
4655
4656 if (!tRPHeaderValue.IsEmpty()) {
4657 referrerPolicy =
4658 dom::ReferrerInfo::ReferrerPolicyFromHeaderString(tRPHeaderValue);
4659 }
4660
4661 // In case we are here because an upgrade happened through mixed content
4662 // upgrading, CSP upgrade-insecure-requests, HTTPS-Only or HTTPS-First, we
4663 // have to recalculate the referrer based on the original referrer to
4664 // account for the different scheme. This does NOT apply to HSTS.
4665 // See Bug 1857894 and order of https://fetch.spec.whatwg.org/#main-fetch.
4666 // Otherwise, if we have a new referrer policy, we want to recalculate the
4667 // referrer based on the old computed referrer (Bug 1678545).
4668 bool wasNonHSTSUpgrade =
4669 (aRedirectFlags & nsIChannelEventSink::REDIRECT_STS_UPGRADE) &&
4670 (!mLoadInfo->GetHstsStatus());
4671 if (wasNonHSTSUpgrade) {
4672 nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetOriginalReferrer();
4673 config.referrerInfo =
4674 new dom::ReferrerInfo(referrer, mReferrerInfo->ReferrerPolicy(),
4675 mReferrerInfo->GetSendReferrer());
4676 } else if (referrerPolicy != dom::ReferrerPolicy::_empty) {
4677 nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetComputedReferrer();
4678 config.referrerInfo = new dom::ReferrerInfo(
4679 referrer, referrerPolicy, mReferrerInfo->GetSendReferrer());
4680 } else {
4681 config.referrerInfo = mReferrerInfo;
4682 }
4683 }
4684 }
4685
4686 nsCOMPtr<nsITimedChannel> oldTimedChannel(
4687 do_QueryInterface(static_cast<nsIHttpChannel*>(this)));
4688 if (oldTimedChannel) {
4689 config.timedChannelInfo = Some(dom::TimedChannelInfo());
4690 config.timedChannelInfo->timingEnabled() = LoadTimingEnabled();
4691 config.timedChannelInfo->redirectCount() = mRedirectCount;
4692 config.timedChannelInfo->internalRedirectCount() = mInternalRedirectCount;
4693 config.timedChannelInfo->asyncOpen() = mAsyncOpenTime;
4694 config.timedChannelInfo->channelCreation() = mChannelCreationTimestamp;
4695 config.timedChannelInfo->redirectStart() = mRedirectStartTimeStamp;
4696 config.timedChannelInfo->redirectEnd() = mRedirectEndTimeStamp;
4697 config.timedChannelInfo->initiatorType() = mInitiatorType;
4698 config.timedChannelInfo->allRedirectsSameOrigin() =
4699 LoadAllRedirectsSameOrigin();
4700 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() =
4701 LoadAllRedirectsPassTimingAllowCheck();
4702 // Execute the timing allow check to determine whether
4703 // to report the redirect timing info
4704 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
4705 // TYPE_DOCUMENT loads don't have a loadingPrincipal, so we can't set
4706 // AllRedirectsPassTimingAllowCheck on them.
4707 if (loadInfo->GetExternalContentPolicyType() !=
4708 ExtContentPolicy::TYPE_DOCUMENT) {
4709 nsCOMPtr<nsIPrincipal> principal = loadInfo->GetLoadingPrincipal();
4710 config.timedChannelInfo->timingAllowCheckForPrincipal() =
4711 Some(oldTimedChannel->TimingAllowCheck(principal));
4712 }
4713
4714 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() =
4715 LoadAllRedirectsPassTimingAllowCheck();
4716 config.timedChannelInfo->launchServiceWorkerStart() =
4717 mLaunchServiceWorkerStart;
4718 config.timedChannelInfo->launchServiceWorkerEnd() = mLaunchServiceWorkerEnd;
4719 config.timedChannelInfo->dispatchFetchEventStart() =
4720 mDispatchFetchEventStart;
4721 config.timedChannelInfo->dispatchFetchEventEnd() = mDispatchFetchEventEnd;
4722 config.timedChannelInfo->handleFetchEventStart() = mHandleFetchEventStart;
4723 config.timedChannelInfo->handleFetchEventEnd() = mHandleFetchEventEnd;
4724 config.timedChannelInfo->responseStart() =
4725 mTransactionTimings.responseStart;
4726 config.timedChannelInfo->responseEnd() = mTransactionTimings.responseEnd;
4727 }
4728
4729 if (aPreserveMethod) {
4730 // since preserveMethod is true, we need to ensure that the appropriate
4731 // request method gets set on the channel, regardless of whether or not
4732 // we set the upload stream above. This means SetRequestMethod() will
4733 // be called twice if ExplicitSetUploadStream() gets called above.
4734
4735 nsAutoCString method;
4736 mRequestHead.Method(method);
4737 config.method = Some(method);
4738
4739 if (mUploadStream) {
4740 // rewind upload stream
4741 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
4742 if (seekable) {
4743 seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
4744 }
4745 config.uploadStream = mUploadStream;
4746 }
4747 config.uploadStreamLength = mReqContentLength;
4748 config.uploadStreamHasHeaders = LoadUploadStreamHasHeaders();
4749
4750 nsAutoCString contentType;
4751 nsresult rv = mRequestHead.GetHeader(nsHttp::Content_Type, contentType);
4752 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4753 config.contentType = Some(contentType);
4754 }
4755
4756 nsAutoCString contentLength;
4757 rv = mRequestHead.GetHeader(nsHttp::Content_Length, contentLength);
4758 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4759 config.contentLength = Some(contentLength);
4760 }
4761 }
4762
4763 return config;
4764}
4765
4766/* static */ void HttpBaseChannel::ConfigureReplacementChannel(
4767 nsIChannel* newChannel, const ReplacementChannelConfig& config,
4768 ReplacementReason aReason) {
4769 nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(newChannel));
4770 if (cos) {
4771 cos->SetClassOfService(config.classOfService);
4772 }
4773
4774 // Try to preserve the privacy bit if it has been overridden
4775 if (config.privateBrowsing) {
4776 nsCOMPtr<nsIPrivateBrowsingChannel> newPBChannel =
4777 do_QueryInterface(newChannel);
4778 if (newPBChannel) {
4779 newPBChannel->SetPrivate(*config.privateBrowsing);
4780 }
4781 }
4782
4783 // Transfer the timing data (if we are dealing with an nsITimedChannel).
4784 nsCOMPtr<nsITimedChannel> newTimedChannel(do_QueryInterface(newChannel));
4785 if (config.timedChannelInfo && newTimedChannel) {
4786 newTimedChannel->SetTimingEnabled(config.timedChannelInfo->timingEnabled());
4787
4788 // If we're an internal redirect, or a document channel replacement,
4789 // then we shouldn't record any new timing for this and just copy
4790 // over the existing values.
4791 bool shouldHideTiming = aReason != ReplacementReason::Redirect;
4792 if (shouldHideTiming) {
4793 newTimedChannel->SetRedirectCount(
4794 config.timedChannelInfo->redirectCount());
4795 int32_t newCount = config.timedChannelInfo->internalRedirectCount() + 1;
4796 newTimedChannel->SetInternalRedirectCount(std::max(
4797 newCount, static_cast<int32_t>(
4798 config.timedChannelInfo->internalRedirectCount())));
4799 } else {
4800 int32_t newCount = config.timedChannelInfo->redirectCount() + 1;
4801 newTimedChannel->SetRedirectCount(std::max(
4802 newCount,
4803 static_cast<int32_t>(config.timedChannelInfo->redirectCount())));
4804 newTimedChannel->SetInternalRedirectCount(
4805 config.timedChannelInfo->internalRedirectCount());
4806 }
4807
4808 if (shouldHideTiming) {
4809 if (!config.timedChannelInfo->channelCreation().IsNull()) {
4810 newTimedChannel->SetChannelCreation(
4811 config.timedChannelInfo->channelCreation());
4812 }
4813
4814 if (!config.timedChannelInfo->asyncOpen().IsNull()) {
4815 newTimedChannel->SetAsyncOpen(config.timedChannelInfo->asyncOpen());
4816 }
4817 }
4818
4819 // If the RedirectStart is null, we will use the AsyncOpen value of the
4820 // previous channel (this is the first redirect in the redirects chain).
4821 if (config.timedChannelInfo->redirectStart().IsNull()) {
4822 // Only do this for real redirects. Internal redirects should be hidden.
4823 if (!shouldHideTiming) {
4824 newTimedChannel->SetRedirectStart(config.timedChannelInfo->asyncOpen());
4825 }
4826 } else {
4827 newTimedChannel->SetRedirectStart(
4828 config.timedChannelInfo->redirectStart());
4829 }
4830
4831 // For internal redirects just propagate the last redirect end time
4832 // forward. Otherwise the new redirect end time is the last response
4833 // end time.
4834 TimeStamp newRedirectEnd;
4835 if (shouldHideTiming) {
4836 newRedirectEnd = config.timedChannelInfo->redirectEnd();
4837 } else if (!config.timedChannelInfo->responseEnd().IsNull()) {
4838 newRedirectEnd = config.timedChannelInfo->responseEnd();
4839 } else {
4840 newRedirectEnd = TimeStamp::Now();
4841 }
4842 newTimedChannel->SetRedirectEnd(newRedirectEnd);
4843
4844 newTimedChannel->SetInitiatorType(config.timedChannelInfo->initiatorType());
4845
4846 nsCOMPtr<nsILoadInfo> loadInfo = newChannel->LoadInfo();
4847 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"
, 4847); AnnotateMozCrashReason("MOZ_ASSERT" "(" "loadInfo" ")"
); do { *((volatile int*)__null) = 4847; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4848
4849 newTimedChannel->SetAllRedirectsSameOrigin(
4850 config.timedChannelInfo->allRedirectsSameOrigin());
4851
4852 if (config.timedChannelInfo->timingAllowCheckForPrincipal()) {
4853 newTimedChannel->SetAllRedirectsPassTimingAllowCheck(
4854 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() &&
4855 *config.timedChannelInfo->timingAllowCheckForPrincipal());
4856 }
4857
4858 // Propagate service worker measurements across redirects. The
4859 // PeformanceResourceTiming.workerStart API expects to see the
4860 // worker start time after a redirect.
4861 newTimedChannel->SetLaunchServiceWorkerStart(
4862 config.timedChannelInfo->launchServiceWorkerStart());
4863 newTimedChannel->SetLaunchServiceWorkerEnd(
4864 config.timedChannelInfo->launchServiceWorkerEnd());
4865 newTimedChannel->SetDispatchFetchEventStart(
4866 config.timedChannelInfo->dispatchFetchEventStart());
4867 newTimedChannel->SetDispatchFetchEventEnd(
4868 config.timedChannelInfo->dispatchFetchEventEnd());
4869 newTimedChannel->SetHandleFetchEventStart(
4870 config.timedChannelInfo->handleFetchEventStart());
4871 newTimedChannel->SetHandleFetchEventEnd(
4872 config.timedChannelInfo->handleFetchEventEnd());
4873 }
4874
4875 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
4876 if (!httpChannel) {
4877 return; // no other options to set
4878 }
4879
4880 if (config.uploadStream) {
4881 nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(httpChannel);
4882 nsCOMPtr<nsIUploadChannel2> uploadChannel2 = do_QueryInterface(httpChannel);
4883 if (uploadChannel2 || uploadChannel) {
4884 // replicate original call to SetUploadStream...
4885 if (uploadChannel2) {
4886 const nsACString& ctype =
4887 config.contentType ? *config.contentType : VoidCString();
4888 // If header is not present mRequestHead.HasHeaderValue will truncated
4889 // it. But we want to end up with a void string, not an empty string,
4890 // because ExplicitSetUploadStream treats the former as "no header" and
4891 // the latter as "header with empty string value".
4892
4893 const nsACString& method =
4894 config.method ? *config.method : VoidCString();
4895
4896 uploadChannel2->ExplicitSetUploadStream(
4897 config.uploadStream, ctype, config.uploadStreamLength, method,
4898 config.uploadStreamHasHeaders);
4899 } else {
4900 if (config.uploadStreamHasHeaders) {
4901 uploadChannel->SetUploadStream(config.uploadStream, ""_ns,
4902 config.uploadStreamLength);
4903 } else {
4904 nsAutoCString ctype;
4905 if (config.contentType) {
4906 ctype = *config.contentType;
4907 } else {
4908 ctype = "application/octet-stream"_ns;
4909 }
4910 if (config.contentLength && !config.contentLength->IsEmpty()) {
4911 uploadChannel->SetUploadStream(
4912 config.uploadStream, ctype,
4913 nsCRT::atoll(config.contentLength->get()));
4914 }
4915 }
4916 }
4917 }
4918 }
4919
4920 if (config.referrerInfo) {
4921 DebugOnly<nsresult> success{};
4922 success = httpChannel->SetReferrerInfo(config.referrerInfo);
4923 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"
, 4923); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)), 1)))"
")"); do { *((volatile int*)__null) = 4923; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4924 }
4925
4926 if (config.method) {
4927 DebugOnly<nsresult> rv = httpChannel->SetRequestMethod(*config.method);
4928 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"
, 4928); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4928; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4929 }
4930}
4931
4932HttpBaseChannel::ReplacementChannelConfig::ReplacementChannelConfig(
4933 const dom::ReplacementChannelConfigInit& aInit) {
4934 redirectFlags = aInit.redirectFlags();
4935 classOfService = aInit.classOfService();
4936 privateBrowsing = aInit.privateBrowsing();
4937 method = aInit.method();
4938 referrerInfo = aInit.referrerInfo();
4939 timedChannelInfo = aInit.timedChannelInfo();
4940 uploadStream = aInit.uploadStream();
4941 uploadStreamLength = aInit.uploadStreamLength();
4942 uploadStreamHasHeaders = aInit.uploadStreamHasHeaders();
4943 contentType = aInit.contentType();
4944 contentLength = aInit.contentLength();
4945}
4946
4947dom::ReplacementChannelConfigInit
4948HttpBaseChannel::ReplacementChannelConfig::Serialize() {
4949 dom::ReplacementChannelConfigInit config;
4950 config.redirectFlags() = redirectFlags;
4951 config.classOfService() = classOfService;
4952 config.privateBrowsing() = privateBrowsing;
4953 config.method() = method;
4954 config.referrerInfo() = referrerInfo;
4955 config.timedChannelInfo() = timedChannelInfo;
4956 config.uploadStream() =
4957 uploadStream ? RemoteLazyInputStream::WrapStream(uploadStream) : nullptr;
4958 config.uploadStreamLength() = uploadStreamLength;
4959 config.uploadStreamHasHeaders() = uploadStreamHasHeaders;
4960 config.contentType() = contentType;
4961 config.contentLength() = contentLength;
4962
4963 return config;
4964}
4965
4966nsresult HttpBaseChannel::SetupReplacementChannel(nsIURI* newURI,
4967 nsIChannel* newChannel,
4968 bool preserveMethod,
4969 uint32_t redirectFlags) {
4970 nsresult rv;
4971
4972 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)
4973 ("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)
4974 "[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)
4975 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)
;
4976
4977 // Ensure the channel's loadInfo's result principal URI so that it's
4978 // either non-null or updated to the redirect target URI.
4979 // We must do this because in case the loadInfo's result principal URI
4980 // is null, it would be taken from OriginalURI of the channel. But we
4981 // overwrite it with the whole redirect chain first URI before opening
4982 // the target channel, hence the information would be lost.
4983 // If the protocol handler that created the channel wants to use
4984 // the originalURI of the channel as the principal URI, this fulfills
4985 // that request - newURI is the original URI of the channel.
4986 nsCOMPtr<nsILoadInfo> newLoadInfo = newChannel->LoadInfo();
4987 nsCOMPtr<nsIURI> resultPrincipalURI;
4988 rv = newLoadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
4989 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"
, 4989); return rv; } } while (false)
;
4990 if (!resultPrincipalURI) {
4991 rv = newLoadInfo->SetResultPrincipalURI(newURI);
4992 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"
, 4992); return rv; } } while (false)
;
4993 }
4994
4995 nsLoadFlags loadFlags = mLoadFlags;
4996 loadFlags |= LOAD_REPLACE;
4997
4998 // if the original channel was using SSL and this channel is not using
4999 // SSL, then no need to inhibit persistent caching. however, if the
5000 // original channel was not using SSL and has INHIBIT_PERSISTENT_CACHING
5001 // set, then allow the flag to apply to the redirected channel as well.
5002 // since we force set INHIBIT_PERSISTENT_CACHING on all HTTPS channels,
5003 // we only need to check if the original channel was using SSL.
5004 if (mURI->SchemeIs("https")) {
5005 loadFlags &= ~INHIBIT_PERSISTENT_CACHING;
5006 }
5007
5008 newChannel->SetLoadFlags(loadFlags);
5009
5010 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
5011
5012 ReplacementReason redirectType =
5013 (redirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL)
5014 ? ReplacementReason::InternalRedirect
5015 : ReplacementReason::Redirect;
5016 ReplacementChannelConfig config = CloneReplacementChannelConfig(
5017 preserveMethod, redirectFlags, redirectType);
5018 ConfigureReplacementChannel(newChannel, config, redirectType);
5019
5020 // Check whether or not this was a cross-domain redirect.
5021 nsCOMPtr<nsITimedChannel> newTimedChannel(do_QueryInterface(newChannel));
5022 bool sameOriginWithOriginalUri = SameOriginWithOriginalUri(newURI);
5023 if (config.timedChannelInfo && newTimedChannel) {
5024 newTimedChannel->SetAllRedirectsSameOrigin(
5025 config.timedChannelInfo->allRedirectsSameOrigin() &&
5026 sameOriginWithOriginalUri);
5027 }
5028
5029 newChannel->SetLoadGroup(mLoadGroup);
5030 newChannel->SetNotificationCallbacks(mCallbacks);
5031 // TODO: create tests for cross-origin redirect in bug 1662896.
5032 if (sameOriginWithOriginalUri) {
5033 newChannel->SetContentDisposition(mContentDispositionHint);
5034 if (mContentDispositionFilename) {
5035 newChannel->SetContentDispositionFilename(*mContentDispositionFilename);
5036 }
5037 }
5038
5039 if (!httpChannel) return NS_OK; // no other options to set
5040
5041 // Preserve the CORS preflight information.
5042 nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(newChannel);
5043 if (httpInternal) {
5044 httpInternal->SetLastRedirectFlags(redirectFlags);
5045
5046 if (LoadRequireCORSPreflight()) {
5047 httpInternal->SetCorsPreflightParameters(mUnsafeHeaders, false, false);
5048 }
5049 }
5050
5051 // convey the LoadAllowSTS() flags
5052 rv = httpChannel->SetAllowSTS(LoadAllowSTS());
5053 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"
, 5053); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5053; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5054
5055 // convey the Accept header value
5056 {
5057 nsAutoCString oldAcceptValue;
5058 nsresult hasHeader = mRequestHead.GetHeader(nsHttp::Accept, oldAcceptValue);
5059 if (NS_SUCCEEDED(hasHeader)((bool)(__builtin_expect(!!(!NS_FAILED_impl(hasHeader)), 1)))) {
5060 rv = httpChannel->SetRequestHeader("Accept"_ns, oldAcceptValue, false);
5061 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"
, 5061); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5061; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5062 }
5063 }
5064
5065 // convey the User-Agent header value
5066 // since we might be setting custom user agent from DevTools.
5067 if (httpInternal && mRequestMode == RequestMode::No_cors &&
5068 redirectType == ReplacementReason::Redirect) {
5069 nsAutoCString oldUserAgent;
5070 nsresult hasHeader =
5071 mRequestHead.GetHeader(nsHttp::User_Agent, oldUserAgent);
5072 if (NS_SUCCEEDED(hasHeader)((bool)(__builtin_expect(!!(!NS_FAILED_impl(hasHeader)), 1)))) {
5073 rv = httpChannel->SetRequestHeader("User-Agent"_ns, oldUserAgent, false);
5074 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"
, 5074); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5074; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5075 }
5076 }
5077
5078 // convery the IsUserAgentHeaderModified value.
5079 if (httpInternal) {
5080 rv = httpInternal->SetIsUserAgentHeaderModified(
5081 LoadIsUserAgentHeaderModified());
5082 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"
, 5082); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5082; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5083 }
5084
5085 // share the request context - see bug 1236650
5086 rv = httpChannel->SetRequestContextID(mRequestContextID);
5087 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"
, 5087); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5087; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5088
5089 // When on the parent process, the channel can't attempt to get it itself.
5090 // When on the child process, it would be waste to query it again.
5091 rv = httpChannel->SetBrowserId(mBrowserId);
5092 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"
, 5092); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5092; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5093
5094 // Not setting this flag would break carrying permissions down to the child
5095 // process when the channel is artificially forced to be a main document load.
5096 rv = httpChannel->SetIsMainDocumentChannel(LoadForceMainDocumentChannel());
5097 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"
, 5097); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5097; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5098
5099 // Preserve the loading order
5100 nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(newChannel);
5101 if (p) {
5102 p->SetPriority(mPriority);
5103 }
5104
5105 if (httpInternal) {
5106 // Convey third party cookie, conservative, and spdy flags.
5107 rv = httpInternal->SetThirdPartyFlags(LoadThirdPartyFlags());
5108 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"
, 5108); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5108; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5109 rv = httpInternal->SetAllowSpdy(LoadAllowSpdy());
5110 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"
, 5110); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5110; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5111 rv = httpInternal->SetAllowHttp3(LoadAllowHttp3());
5112 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"
, 5112); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5112; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5113 rv = httpInternal->SetAllowAltSvc(LoadAllowAltSvc());
5114 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"
, 5114); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5114; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5115 rv = httpInternal->SetBeConservative(LoadBeConservative());
5116 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"
, 5116); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5116; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5117 rv = httpInternal->SetIsTRRServiceChannel(LoadIsTRRServiceChannel());
5118 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"
, 5118); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5118; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5119 rv = httpInternal->SetTlsFlags(mTlsFlags);
5120 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"
, 5120); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5120; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5121
5122 // Ensure the type of realChannel involves all types it may redirect to.
5123 // Such as nsHttpChannel and InterceptedChannel.
5124 // Even thought InterceptedChannel itself doesn't require these information,
5125 // it may still be necessary for the following redirections.
5126 // E.g. nsHttpChannel -> InterceptedChannel -> nsHttpChannel
5127 RefPtr<HttpBaseChannel> realChannel;
5128 CallQueryInterface(newChannel, realChannel.StartAssignment());
5129 if (realChannel) {
5130 realChannel->SetTopWindowURI(mTopWindowURI);
5131
5132 realChannel->StoreTaintedOriginFlag(
5133 ShouldTaintReplacementChannelOrigin(newChannel, redirectFlags));
5134 }
5135
5136 // update the DocumentURI indicator since we are being redirected.
5137 // if this was a top-level document channel, then the new channel
5138 // should have its mDocumentURI point to newURI; otherwise, we
5139 // just need to pass along our mDocumentURI to the new channel.
5140 if (newURI && (mURI == mDocumentURI)) {
5141 rv = httpInternal->SetDocumentURI(newURI);
5142 } else {
5143 rv = httpInternal->SetDocumentURI(mDocumentURI);
5144 }
5145 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"
, 5145); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5145; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5146
5147 // if there is a chain of keys for redirect-responses we transfer it to
5148 // the new channel (see bug #561276)
5149 {
5150 auto redirectedCachekeys = mRedirectedCachekeys.Lock();
5151 auto& ref = redirectedCachekeys.ref();
5152 if (ref) {
5153 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)
5154 ("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)
5155 "[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)
5156 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)
;
5157 rv = httpInternal->SetCacheKeysRedirectChain(ref.release());
5158 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"
, 5158); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5158; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5159 }
5160 }
5161
5162 // Preserve Request mode.
5163 rv = httpInternal->SetRequestMode(mRequestMode);
5164 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"
, 5164); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5164; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5165
5166 // Preserve Redirect mode flag.
5167 rv = httpInternal->SetRedirectMode(mRedirectMode);
5168 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"
, 5168); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5168; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5169
5170 // Preserve Integrity metadata.
5171 rv = httpInternal->SetIntegrityMetadata(mIntegrityMetadata);
5172 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"
, 5172); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5172; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5173
5174 httpInternal->SetAltDataForChild(LoadAltDataForChild());
5175 if (LoadDisableAltDataCache()) {
5176 httpInternal->DisableAltDataCache();
5177 }
5178 }
5179
5180 // transfer any properties
5181 nsCOMPtr<nsIWritablePropertyBag> bag(do_QueryInterface(newChannel));
5182 if (bag) {
5183 for (const auto& entry : mPropertyHash) {
5184 bag->SetProperty(entry.GetKey(), entry.GetWeak());
5185 }
5186 }
5187
5188 // Pass the preferred alt-data type on to the new channel.
5189 nsCOMPtr<nsICacheInfoChannel> cacheInfoChan(do_QueryInterface(newChannel));
5190 if (cacheInfoChan) {
5191 for (auto& data : mPreferredCachedAltDataTypes) {
5192 cacheInfoChan->PreferAlternativeDataType(data.type(), data.contentType(),
5193 data.deliverAltData());
5194 }
5195
5196 if (LoadForceValidateCacheContent()) {
5197 Unused << cacheInfoChan->SetForceValidateCacheContent(true);
5198 }
5199 }
5200
5201 if (redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
5202 nsIChannelEventSink::REDIRECT_STS_UPGRADE)) {
5203 // Copy non-origin related headers to the new channel.
5204 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
5205 new AddHeadersToChannelVisitor(httpChannel);
5206 rv = mRequestHead.VisitHeaders(visitor);
5207 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"
, 5207); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5207; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5208 }
5209
5210 // we need to strip Authentication headers for cross-origin requests
5211 // Ref: https://fetch.spec.whatwg.org/#http-redirect-fetch
5212 nsAutoCString authHeader;
5213 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetRequestHeader
("Authorization"_ns, authHeader))), 1)))
5214 httpChannel->GetRequestHeader("Authorization"_ns, authHeader))((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetRequestHeader
("Authorization"_ns, authHeader))), 1)))
&&
5215 NS_ShouldRemoveAuthHeaderOnRedirect(static_cast<nsIChannel*>(this),
5216 newChannel, redirectFlags)) {
5217 rv = httpChannel->SetRequestHeader("Authorization"_ns, ""_ns, false);
5218 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"
, 5218); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5218; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5219 }
5220
5221 return NS_OK;
5222}
5223
5224// check whether the new channel is of same origin as the current channel
5225bool HttpBaseChannel::IsNewChannelSameOrigin(nsIChannel* aNewChannel) {
5226 bool isSameOrigin = false;
5227 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5228
5229 if (!ssm) {
5230 return false;
5231 }
5232
5233 nsCOMPtr<nsIURI> newURI;
5234 NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
5235
5236 nsresult rv = ssm->CheckSameOriginURI(newURI, mURI, false, false);
5237 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5238 isSameOrigin = true;
5239 }
5240
5241 return isSameOrigin;
5242}
5243
5244bool HttpBaseChannel::ShouldTaintReplacementChannelOrigin(
5245 nsIChannel* aNewChannel, uint32_t aRedirectFlags) {
5246 if (LoadTaintedOriginFlag()) {
5247 return true;
5248 }
5249
5250 if (NS_IsInternalSameURIRedirect(this, aNewChannel, aRedirectFlags) ||
5251 NS_IsHSTSUpgradeRedirect(this, aNewChannel, aRedirectFlags)) {
5252 return false;
5253 }
5254
5255 // If new channel is not of same origin we need to taint unless
5256 // mURI <-> mOriginalURI/LoadingPrincipal are same origin.
5257 if (IsNewChannelSameOrigin(aNewChannel)) {
5258 return false;
5259 }
5260
5261 nsresult rv;
5262
5263 if (mLoadInfo->GetLoadingPrincipal()) {
5264 bool sameOrigin = false;
5265 rv = mLoadInfo->GetLoadingPrincipal()->IsSameOrigin(mURI, &sameOrigin);
5266 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5267 return true;
5268 }
5269 return !sameOrigin;
5270 }
5271 if (!mOriginalURI) {
5272 return true;
5273 }
5274
5275 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5276 if (!ssm) {
5277 return true;
5278 }
5279
5280 rv = ssm->CheckSameOriginURI(mOriginalURI, mURI, false, false);
5281 return NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)));
5282}
5283
5284// Redirect Tracking
5285bool HttpBaseChannel::SameOriginWithOriginalUri(nsIURI* aURI) {
5286 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5287 bool isPrivateWin = mLoadInfo->GetOriginAttributes().IsPrivateBrowsing();
5288 nsresult rv =
5289 ssm->CheckSameOriginURI(aURI, mOriginalURI, false, isPrivateWin);
5290 return (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))));
5291}
5292
5293//-----------------------------------------------------------------------------
5294// HttpBaseChannel::nsIClassifiedChannel
5295
5296NS_IMETHODIMPnsresult
5297HttpBaseChannel::GetMatchedList(nsACString& aList) {
5298 aList = mMatchedList;
5299 return NS_OK;
5300}
5301
5302NS_IMETHODIMPnsresult
5303HttpBaseChannel::GetMatchedProvider(nsACString& aProvider) {
5304 aProvider = mMatchedProvider;
5305 return NS_OK;
5306}
5307
5308NS_IMETHODIMPnsresult
5309HttpBaseChannel::GetMatchedFullHash(nsACString& aFullHash) {
5310 aFullHash = mMatchedFullHash;
5311 return NS_OK;
5312}
5313
5314NS_IMETHODIMPnsresult
5315HttpBaseChannel::SetMatchedInfo(const nsACString& aList,
5316 const nsACString& aProvider,
5317 const nsACString& aFullHash) {
5318 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"
, 5318); return NS_ERROR_INVALID_ARG; } } while (false)
;
5319
5320 mMatchedList = aList;
5321 mMatchedProvider = aProvider;
5322 mMatchedFullHash = aFullHash;
5323 return NS_OK;
5324}
5325
5326NS_IMETHODIMPnsresult
5327HttpBaseChannel::GetMatchedTrackingLists(nsTArray<nsCString>& aLists) {
5328 aLists = mMatchedTrackingLists.Clone();
5329 return NS_OK;
5330}
5331
5332NS_IMETHODIMPnsresult
5333HttpBaseChannel::GetMatchedTrackingFullHashes(
5334 nsTArray<nsCString>& aFullHashes) {
5335 aFullHashes = mMatchedTrackingFullHashes.Clone();
5336 return NS_OK;
5337}
5338
5339NS_IMETHODIMPnsresult
5340HttpBaseChannel::SetMatchedTrackingInfo(
5341 const nsTArray<nsCString>& aLists, const nsTArray<nsCString>& aFullHashes) {
5342 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"
, 5342); return NS_ERROR_INVALID_ARG; } } while (false)
;
5343 // aFullHashes can be empty for non hash-matching algorithm, for example,
5344 // host based test entries in preference.
5345
5346 mMatchedTrackingLists = aLists.Clone();
5347 mMatchedTrackingFullHashes = aFullHashes.Clone();
5348 return NS_OK;
5349}
5350//-----------------------------------------------------------------------------
5351// HttpBaseChannel::nsITimedChannel
5352//-----------------------------------------------------------------------------
5353
5354NS_IMETHODIMPnsresult
5355HttpBaseChannel::SetTimingEnabled(bool enabled) {
5356 StoreTimingEnabled(enabled);
5357 return NS_OK;
5358}
5359
5360NS_IMETHODIMPnsresult
5361HttpBaseChannel::GetTimingEnabled(bool* _retval) {
5362 *_retval = LoadTimingEnabled();
5363 return NS_OK;
5364}
5365
5366NS_IMETHODIMPnsresult
5367HttpBaseChannel::GetChannelCreation(TimeStamp* _retval) {
5368 *_retval = mChannelCreationTimestamp;
5369 return NS_OK;
5370}
5371
5372NS_IMETHODIMPnsresult
5373HttpBaseChannel::SetChannelCreation(TimeStamp aValue) {
5374 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"
, 5374); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!aValue.IsNull()"
")"); do { *((volatile int*)__null) = 5374; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5375 TimeDuration adjust = aValue - mChannelCreationTimestamp;
5376 mChannelCreationTimestamp = aValue;
5377 mChannelCreationTime += (PRTime)adjust.ToMicroseconds();
5378 return NS_OK;
5379}
5380
5381NS_IMETHODIMPnsresult
5382HttpBaseChannel::GetAsyncOpen(TimeStamp* _retval) {
5383 *_retval = mAsyncOpenTime;
5384 return NS_OK;
5385}
5386
5387NS_IMETHODIMPnsresult
5388HttpBaseChannel::SetAsyncOpen(TimeStamp aValue) {
5389 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"
, 5389); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!aValue.IsNull()"
")"); do { *((volatile int*)__null) = 5389; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5390 mAsyncOpenTime = aValue;
5391 StoreAsyncOpenTimeOverriden(true);
5392 return NS_OK;
5393}
5394
5395/**
5396 * @return the number of redirects. There is no check for cross-domain
5397 * redirects. This check must be done by the consumers.
5398 */
5399NS_IMETHODIMPnsresult
5400HttpBaseChannel::GetRedirectCount(uint8_t* aRedirectCount) {
5401 *aRedirectCount = mRedirectCount;
5402 return NS_OK;
5403}
5404
5405NS_IMETHODIMPnsresult
5406HttpBaseChannel::SetRedirectCount(uint8_t aRedirectCount) {
5407 mRedirectCount = aRedirectCount;
5408 return NS_OK;
5409}
5410
5411NS_IMETHODIMPnsresult
5412HttpBaseChannel::GetInternalRedirectCount(uint8_t* aRedirectCount) {
5413 *aRedirectCount = mInternalRedirectCount;
5414 return NS_OK;
5415}
5416
5417NS_IMETHODIMPnsresult
5418HttpBaseChannel::SetInternalRedirectCount(uint8_t aRedirectCount) {
5419 mInternalRedirectCount = aRedirectCount;
5420 return NS_OK;
5421}
5422
5423NS_IMETHODIMPnsresult
5424HttpBaseChannel::GetRedirectStart(TimeStamp* _retval) {
5425 *_retval = mRedirectStartTimeStamp;
5426 return NS_OK;
5427}
5428
5429NS_IMETHODIMPnsresult
5430HttpBaseChannel::SetRedirectStart(TimeStamp aRedirectStart) {
5431 mRedirectStartTimeStamp = aRedirectStart;
5432 return NS_OK;
5433}
5434
5435NS_IMETHODIMPnsresult
5436HttpBaseChannel::GetRedirectEnd(TimeStamp* _retval) {
5437 *_retval = mRedirectEndTimeStamp;
5438 return NS_OK;
5439}
5440
5441NS_IMETHODIMPnsresult
5442HttpBaseChannel::SetRedirectEnd(TimeStamp aRedirectEnd) {
5443 mRedirectEndTimeStamp = aRedirectEnd;
5444 return NS_OK;
5445}
5446
5447NS_IMETHODIMPnsresult
5448HttpBaseChannel::GetAllRedirectsSameOrigin(bool* aAllRedirectsSameOrigin) {
5449 *aAllRedirectsSameOrigin = LoadAllRedirectsSameOrigin();
5450 return NS_OK;
5451}
5452
5453NS_IMETHODIMPnsresult
5454HttpBaseChannel::SetAllRedirectsSameOrigin(bool aAllRedirectsSameOrigin) {
5455 StoreAllRedirectsSameOrigin(aAllRedirectsSameOrigin);
5456 return NS_OK;
5457}
5458
5459NS_IMETHODIMPnsresult
5460HttpBaseChannel::GetAllRedirectsPassTimingAllowCheck(bool* aPassesCheck) {
5461 *aPassesCheck = LoadAllRedirectsPassTimingAllowCheck();
5462 return NS_OK;
5463}
5464
5465NS_IMETHODIMPnsresult
5466HttpBaseChannel::SetAllRedirectsPassTimingAllowCheck(bool aPassesCheck) {
5467 StoreAllRedirectsPassTimingAllowCheck(aPassesCheck);
5468 return NS_OK;
5469}
5470
5471// https://fetch.spec.whatwg.org/#cors-check
5472bool HttpBaseChannel::PerformCORSCheck() {
5473 // Step 1
5474 // Let origin be the result of getting `Access-Control-Allow-Origin`
5475 // from response’s header list.
5476 nsAutoCString origin;
5477 nsresult rv = GetResponseHeader("Access-Control-Allow-Origin"_ns, origin);
5478
5479 // Step 2
5480 // If origin is null, then return failure. (Note: null, not 'null').
5481 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || origin.IsVoid()) {
5482 return false;
5483 }
5484
5485 // Step 3
5486 // If request’s credentials mode is not "include"
5487 // and origin is `*`, then return success.
5488 uint32_t cookiePolicy = mLoadInfo->GetCookiePolicy();
5489 if (cookiePolicy != nsILoadInfo::SEC_COOKIES_INCLUDE &&
5490 origin.EqualsLiteral("*")) {
5491 return true;
5492 }
5493
5494 // Step 4
5495 // If the result of byte-serializing a request origin
5496 // with request is not origin, then return failure.
5497 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5498 nsCOMPtr<nsIPrincipal> resourcePrincipal;
5499 rv = ssm->GetChannelURIPrincipal(this, getter_AddRefs(resourcePrincipal));
5500 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !resourcePrincipal) {
5501 return false;
5502 }
5503 nsAutoCString serializedOrigin;
5504 nsContentSecurityManager::GetSerializedOrigin(
5505 mLoadInfo->TriggeringPrincipal(), resourcePrincipal, serializedOrigin,
5506 mLoadInfo);
5507 if (!serializedOrigin.Equals(origin)) {
5508 return false;
5509 }
5510
5511 // Step 5
5512 // If request’s credentials mode is not "include", then return success.
5513 if (cookiePolicy != nsILoadInfo::SEC_COOKIES_INCLUDE) {
5514 return true;
5515 }
5516
5517 // Step 6
5518 // Let credentials be the result of getting
5519 // `Access-Control-Allow-Credentials` from response’s header list.
5520 nsAutoCString credentials;
5521 rv = GetResponseHeader("Access-Control-Allow-Credentials"_ns, credentials);
5522
5523 // Step 7 and 8
5524 // If credentials is `true`, then return success.
5525 // (else) return failure.
5526 return NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && credentials.EqualsLiteral("true");
5527}
5528
5529NS_IMETHODIMPnsresult
5530HttpBaseChannel::BodyInfoAccessAllowedCheck(nsIPrincipal* aOrigin,
5531 BodyInfoAccess* _retval) {
5532 // Per the Fetch spec, https://fetch.spec.whatwg.org/#response-body-info,
5533 // the bodyInfo for Resource Timing and Navigation Timing info consists of
5534 // encoded size, decoded size, and content type. It is however made opaque
5535 // whenever the response is turned into a network error, which sets its
5536 // bodyInfo to its default values (sizes=0, content-type="").
5537
5538 // Case 1:
5539 // "no-cors" -> Upon success, fetch will return an opaque filtered response.
5540 // An opaque(-redirect) filtered response is a filtered response
5541 // whose ... body info is a new response body info.
5542 auto tainting = mLoadInfo->GetTainting();
5543 if (tainting == mozilla::LoadTainting::Opaque) {
5544 *_retval = BodyInfoAccess::DISALLOWED;
5545 return NS_OK;
5546 }
5547
5548 // Case 2:
5549 // If request’s response tainting is "cors" and a CORS check for request
5550 // and response returns failure, then return a network error.
5551 if (tainting == mozilla::LoadTainting::CORS && !PerformCORSCheck()) {
5552 *_retval = BodyInfoAccess::DISALLOWED;
5553 return NS_OK;
5554 }
5555
5556 // Otherwise:
5557 // The fetch response handover, given a fetch params fetchParams
5558 // and a response response, run these steps:
5559 // processResponseEndOfBody:
5560 // - If fetchParams’s request’s mode is not "navigate" or response’s
5561 // has-cross-origin-redirects is false:
5562 // - Let mimeType be the result of extracting a MIME type from
5563 // response’s header list.
5564 // - If mimeType is not failure, then set bodyInfo’s content type to the
5565 // result of minimizing a supported MIME type given mimeType.
5566 dom::RequestMode requestMode;
5567 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"
, 5567); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(GetRequestMode(&requestMode))" ")");
do { *((volatile int*)__null) = 5567; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
5568 if (requestMode != RequestMode::Navigate || LoadAllRedirectsSameOrigin()) {
5569 *_retval = BodyInfoAccess::ALLOW_ALL;
5570 return NS_OK;
5571 }
5572
5573 *_retval = BodyInfoAccess::ALLOW_SIZES;
5574 return NS_OK;
5575}
5576
5577// https://fetch.spec.whatwg.org/#tao-check
5578NS_IMETHODIMPnsresult
5579HttpBaseChannel::TimingAllowCheck(nsIPrincipal* aOrigin, bool* _retval) {
5580 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5581 nsCOMPtr<nsIPrincipal> resourcePrincipal;
5582 nsresult rv =
5583 ssm->GetChannelURIPrincipal(this, getter_AddRefs(resourcePrincipal));
5584 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !resourcePrincipal || !aOrigin) {
5585 *_retval = false;
5586 return NS_OK;
5587 }
5588
5589 bool sameOrigin = false;
5590 rv = resourcePrincipal->Equals(aOrigin, &sameOrigin);
Value stored to 'rv' is never read
5591
5592 nsAutoCString serializedOrigin;
5593 nsContentSecurityManager::GetSerializedOrigin(aOrigin, resourcePrincipal,
5594 serializedOrigin, mLoadInfo);
5595
5596 // All redirects are same origin
5597 if (sameOrigin && (!serializedOrigin.IsEmpty() &&
5598 !serializedOrigin.EqualsLiteral("null"))) {
5599 *_retval = true;
5600 return NS_OK;
5601 }
5602
5603 nsAutoCString headerValue;
5604 rv = GetResponseHeader("Timing-Allow-Origin"_ns, headerValue);
5605 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5606 *_retval = false;
5607 return NS_OK;
5608 }
5609
5610 Tokenizer p(headerValue);
5611 Tokenizer::Token t;
5612
5613 p.Record();
5614 nsAutoCString headerItem;
5615 while (p.Next(t)) {
5616 if (t.Type() == Tokenizer::TOKEN_EOF ||
5617 t.Equals(Tokenizer::Token::Char(','))) {
5618 p.Claim(headerItem);
5619 nsHttp::TrimHTTPWhitespace(headerItem, headerItem);
5620 // If the list item contains a case-sensitive match for the value of the
5621 // origin, or a wildcard, return pass
5622 if (headerItem == serializedOrigin || headerItem == "*") {
5623 *_retval = true;
5624 return NS_OK;
5625 }
5626 // We start recording again for the following items in the list
5627 p.Record();
5628 }
5629 }
5630
5631 *_retval = false;
5632 return NS_OK;
5633}
5634
5635NS_IMETHODIMPnsresult
5636HttpBaseChannel::GetLaunchServiceWorkerStart(TimeStamp* _retval) {
5637 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"
, 5637); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5637; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5638 *_retval = mLaunchServiceWorkerStart;
5639 return NS_OK;
5640}
5641
5642NS_IMETHODIMPnsresult
5643HttpBaseChannel::SetLaunchServiceWorkerStart(TimeStamp aTimeStamp) {
5644 mLaunchServiceWorkerStart = aTimeStamp;
5645 return NS_OK;
5646}
5647
5648NS_IMETHODIMPnsresult
5649HttpBaseChannel::GetLaunchServiceWorkerEnd(TimeStamp* _retval) {
5650 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"
, 5650); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5650; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5651 *_retval = mLaunchServiceWorkerEnd;
5652 return NS_OK;
5653}
5654
5655NS_IMETHODIMPnsresult
5656HttpBaseChannel::SetLaunchServiceWorkerEnd(TimeStamp aTimeStamp) {
5657 mLaunchServiceWorkerEnd = aTimeStamp;
5658 return NS_OK;
5659}
5660
5661NS_IMETHODIMPnsresult
5662HttpBaseChannel::GetDispatchFetchEventStart(TimeStamp* _retval) {
5663 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"
, 5663); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5663; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5664 *_retval = mDispatchFetchEventStart;
5665 return NS_OK;
5666}
5667
5668NS_IMETHODIMPnsresult
5669HttpBaseChannel::SetDispatchFetchEventStart(TimeStamp aTimeStamp) {
5670 mDispatchFetchEventStart = aTimeStamp;
5671 return NS_OK;
5672}
5673
5674NS_IMETHODIMPnsresult
5675HttpBaseChannel::GetDispatchFetchEventEnd(TimeStamp* _retval) {
5676 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"
, 5676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5676; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5677 *_retval = mDispatchFetchEventEnd;
5678 return NS_OK;
5679}
5680
5681NS_IMETHODIMPnsresult
5682HttpBaseChannel::SetDispatchFetchEventEnd(TimeStamp aTimeStamp) {
5683 mDispatchFetchEventEnd = aTimeStamp;
5684 return NS_OK;
5685}
5686
5687NS_IMETHODIMPnsresult
5688HttpBaseChannel::GetHandleFetchEventStart(TimeStamp* _retval) {
5689 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"
, 5689); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5689; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5690 *_retval = mHandleFetchEventStart;
5691 return NS_OK;
5692}
5693
5694NS_IMETHODIMPnsresult
5695HttpBaseChannel::SetHandleFetchEventStart(TimeStamp aTimeStamp) {
5696 mHandleFetchEventStart = aTimeStamp;
5697 return NS_OK;
5698}
5699
5700NS_IMETHODIMPnsresult
5701HttpBaseChannel::GetHandleFetchEventEnd(TimeStamp* _retval) {
5702 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"
, 5702); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5702; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5703 *_retval = mHandleFetchEventEnd;
5704 return NS_OK;
5705}
5706
5707NS_IMETHODIMPnsresult
5708HttpBaseChannel::SetHandleFetchEventEnd(TimeStamp aTimeStamp) {
5709 mHandleFetchEventEnd = aTimeStamp;
5710 return NS_OK;
5711}
5712
5713NS_IMETHODIMPnsresult
5714HttpBaseChannel::GetDomainLookupStart(TimeStamp* _retval) {
5715 *_retval = mTransactionTimings.domainLookupStart;
5716 return NS_OK;
5717}
5718
5719NS_IMETHODIMPnsresult
5720HttpBaseChannel::GetDomainLookupEnd(TimeStamp* _retval) {
5721 *_retval = mTransactionTimings.domainLookupEnd;
5722 return NS_OK;
5723}
5724
5725NS_IMETHODIMPnsresult
5726HttpBaseChannel::GetConnectStart(TimeStamp* _retval) {
5727 *_retval = mTransactionTimings.connectStart;
5728 return NS_OK;
5729}
5730
5731NS_IMETHODIMPnsresult
5732HttpBaseChannel::GetTcpConnectEnd(TimeStamp* _retval) {
5733 *_retval = mTransactionTimings.tcpConnectEnd;
5734 return NS_OK;
5735}
5736
5737NS_IMETHODIMPnsresult
5738HttpBaseChannel::GetSecureConnectionStart(TimeStamp* _retval) {
5739 *_retval = mTransactionTimings.secureConnectionStart;
5740 return NS_OK;
5741}
5742
5743NS_IMETHODIMPnsresult
5744HttpBaseChannel::GetConnectEnd(TimeStamp* _retval) {
5745 *_retval = mTransactionTimings.connectEnd;
5746 return NS_OK;
5747}
5748
5749NS_IMETHODIMPnsresult
5750HttpBaseChannel::GetRequestStart(TimeStamp* _retval) {
5751 *_retval = mTransactionTimings.requestStart;
5752 return NS_OK;
5753}
5754
5755NS_IMETHODIMPnsresult
5756HttpBaseChannel::GetResponseStart(TimeStamp* _retval) {
5757 *_retval = mTransactionTimings.responseStart;
5758 return NS_OK;
5759}
5760
5761NS_IMETHODIMPnsresult
5762HttpBaseChannel::GetResponseEnd(TimeStamp* _retval) {
5763 *_retval = mTransactionTimings.responseEnd;
5764 return NS_OK;
5765}
5766
5767NS_IMETHODIMPnsresult
5768HttpBaseChannel::GetCacheReadStart(TimeStamp* _retval) {
5769 *_retval = mCacheReadStart;
5770 return NS_OK;
5771}
5772
5773NS_IMETHODIMPnsresult
5774HttpBaseChannel::GetCacheReadEnd(TimeStamp* _retval) {
5775 *_retval = mCacheReadEnd;
5776 return NS_OK;
5777}
5778
5779NS_IMETHODIMPnsresult
5780HttpBaseChannel::GetTransactionPending(TimeStamp* _retval) {
5781 *_retval = mTransactionTimings.transactionPending;
5782 return NS_OK;
5783}
5784
5785NS_IMETHODIMPnsresult
5786HttpBaseChannel::GetInitiatorType(nsAString& aInitiatorType) {
5787 aInitiatorType = mInitiatorType;
5788 return NS_OK;
5789}
5790
5791NS_IMETHODIMPnsresult
5792HttpBaseChannel::SetInitiatorType(const nsAString& aInitiatorType) {
5793 mInitiatorType = aInitiatorType;
5794 return NS_OK;
5795}
5796
5797#define IMPL_TIMING_ATTR(name) \
5798 NS_IMETHODIMPnsresult \
5799 HttpBaseChannel::Get##name##Time(PRTime* _retval) { \
5800 TimeStamp stamp; \
5801 Get##name(&stamp); \
5802 if (stamp.IsNull()) { \
5803 *_retval = 0; \
5804 return NS_OK; \
5805 } \
5806 *_retval = \
5807 mChannelCreationTime + \
5808 (PRTime)((stamp - mChannelCreationTimestamp).ToSeconds() * 1e6); \
5809 return NS_OK; \
5810 }
5811
5812IMPL_TIMING_ATTR(ChannelCreation)
5813IMPL_TIMING_ATTR(AsyncOpen)
5814IMPL_TIMING_ATTR(LaunchServiceWorkerStart)
5815IMPL_TIMING_ATTR(LaunchServiceWorkerEnd)
5816IMPL_TIMING_ATTR(DispatchFetchEventStart)
5817IMPL_TIMING_ATTR(DispatchFetchEventEnd)
5818IMPL_TIMING_ATTR(HandleFetchEventStart)
5819IMPL_TIMING_ATTR(HandleFetchEventEnd)
5820IMPL_TIMING_ATTR(DomainLookupStart)
5821IMPL_TIMING_ATTR(DomainLookupEnd)
5822IMPL_TIMING_ATTR(ConnectStart)
5823IMPL_TIMING_ATTR(TcpConnectEnd)
5824IMPL_TIMING_ATTR(SecureConnectionStart)
5825IMPL_TIMING_ATTR(ConnectEnd)
5826IMPL_TIMING_ATTR(RequestStart)
5827IMPL_TIMING_ATTR(ResponseStart)
5828IMPL_TIMING_ATTR(ResponseEnd)
5829IMPL_TIMING_ATTR(CacheReadStart)
5830IMPL_TIMING_ATTR(CacheReadEnd)
5831IMPL_TIMING_ATTR(RedirectStart)
5832IMPL_TIMING_ATTR(RedirectEnd)
5833IMPL_TIMING_ATTR(TransactionPending)
5834
5835#undef IMPL_TIMING_ATTR
5836
5837void HttpBaseChannel::MaybeReportTimingData() {
5838 // If performance timing is disabled, there is no need for the Performance
5839 // object anymore.
5840 if (!LoadTimingEnabled()) {
5841 return;
5842 }
5843
5844 // There is no point in continuing, since the performance object in the parent
5845 // isn't the same as the one in the child which will be reporting resource
5846 // performance.
5847 if (XRE_IsE10sParentProcess()) {
5848 return;
5849 }
5850
5851 // Devtools can create fetch requests on behalf the content document.
5852 // If we don't exclude these requests, they'd also be reported
5853 // to the content document.
5854 bool isInDevToolsContext;
5855 mLoadInfo->GetIsInDevToolsContext(&isInDevToolsContext);
5856 if (isInDevToolsContext) {
5857 return;
5858 }
5859
5860 mozilla::dom::PerformanceStorage* documentPerformance =
5861 mLoadInfo->GetPerformanceStorage();
5862 if (documentPerformance) {
5863 documentPerformance->AddEntry(this, this);
5864 return;
5865 }
5866
5867 if (!nsGlobalWindowInner::GetInnerWindowWithId(
5868 mLoadInfo->GetInnerWindowID())) {
5869 // The inner window is in a different process.
5870 dom::ContentChild* child = dom::ContentChild::GetSingleton();
5871
5872 if (!child) {
5873 return;
5874 }
5875 nsAutoString initiatorType;
5876 nsAutoString entryName;
5877
5878 UniquePtr<dom::PerformanceTimingData> performanceTimingData(
5879 dom::PerformanceTimingData::Create(this, this, 0, initiatorType,
5880 entryName));
5881 if (!performanceTimingData) {
5882 return;
5883 }
5884
5885 LoadInfoArgs loadInfoArgs;
5886 mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &loadInfoArgs);
5887 child->SendReportFrameTimingData(loadInfoArgs, entryName, initiatorType,
5888 std::move(performanceTimingData));
5889 }
5890}
5891
5892NS_IMETHODIMPnsresult
5893HttpBaseChannel::SetReportResourceTiming(bool enabled) {
5894 StoreReportTiming(enabled);
5895 return NS_OK;
5896}
5897
5898NS_IMETHODIMPnsresult
5899HttpBaseChannel::GetReportResourceTiming(bool* _retval) {
5900 *_retval = LoadReportTiming();
5901 return NS_OK;
5902}
5903
5904nsIURI* HttpBaseChannel::GetReferringPage() {
5905 nsCOMPtr<nsPIDOMWindowInner> pDomWindow = GetInnerDOMWindow();
5906 if (!pDomWindow) {
5907 return nullptr;
5908 }
5909 return pDomWindow->GetDocumentURI();
5910}
5911
5912nsPIDOMWindowInner* HttpBaseChannel::GetInnerDOMWindow() {
5913 nsCOMPtr<nsILoadContext> loadContext;
5914 NS_QueryNotificationCallbacks(this, loadContext);
5915 if (!loadContext) {
5916 return nullptr;
5917 }
5918 nsCOMPtr<mozIDOMWindowProxy> domWindow;
5919 loadContext->GetAssociatedWindow(getter_AddRefs(domWindow));
5920 if (!domWindow) {
5921 return nullptr;
5922 }
5923 auto* pDomWindow = nsPIDOMWindowOuter::From(domWindow);
5924 if (!pDomWindow) {
5925 return nullptr;
5926 }
5927 nsCOMPtr<nsPIDOMWindowInner> innerWindow =
5928 pDomWindow->GetCurrentInnerWindow();
5929 if (!innerWindow) {
5930 return nullptr;
5931 }
5932
5933 return innerWindow;
5934}
5935
5936//-----------------------------------------------------------------------------
5937// HttpBaseChannel::nsIThrottledInputChannel
5938//-----------------------------------------------------------------------------
5939
5940NS_IMETHODIMPnsresult
5941HttpBaseChannel::SetThrottleQueue(nsIInputChannelThrottleQueue* aQueue) {
5942 if (!XRE_IsParentProcess()) {
5943 return NS_ERROR_FAILURE;
5944 }
5945
5946 mThrottleQueue = aQueue;
5947 return NS_OK;
5948}
5949
5950NS_IMETHODIMPnsresult
5951HttpBaseChannel::GetThrottleQueue(nsIInputChannelThrottleQueue** aQueue) {
5952 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"
, 5952); return NS_ERROR_INVALID_POINTER; } } while (false)
;
5953 nsCOMPtr<nsIInputChannelThrottleQueue> queue = mThrottleQueue;
5954 queue.forget(aQueue);
5955 return NS_OK;
5956}
5957
5958//------------------------------------------------------------------------------
5959
5960bool HttpBaseChannel::EnsureRequestContextID() {
5961 if (mRequestContextID) {
5962 // Already have a request context ID, no need to do the rest of this work
5963 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)
5964 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)
;
5965 return true;
5966 }
5967
5968 // Find the loadgroup at the end of the chain in order
5969 // to make sure all channels derived from the load group
5970 // use the same connection scope.
5971 nsCOMPtr<nsILoadGroupChild> childLoadGroup = do_QueryInterface(mLoadGroup);
5972 if (!childLoadGroup) {
5973 return false;
5974 }
5975
5976 nsCOMPtr<nsILoadGroup> rootLoadGroup;
5977 childLoadGroup->GetRootLoadGroup(getter_AddRefs(rootLoadGroup));
5978 if (!rootLoadGroup) {
5979 return false;
5980 }
5981
5982 // Set the load group connection scope on this channel and its transaction
5983 rootLoadGroup->GetRequestContextID(&mRequestContextID);
5984
5985 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)
5986 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)
;
5987
5988 return true;
5989}
5990
5991bool HttpBaseChannel::EnsureRequestContext() {
5992 if (mRequestContext) {
5993 // Already have a request context, no need to do the rest of this work
5994 return true;
5995 }
5996
5997 if (!EnsureRequestContextID()) {
5998 return false;
5999 }
6000
6001 nsIRequestContextService* rcsvc = gHttpHandler->GetRequestContextService();
6002 if (!rcsvc) {
6003 return false;
6004 }
6005
6006 rcsvc->GetRequestContext(mRequestContextID, getter_AddRefs(mRequestContext));
6007 return static_cast<bool>(mRequestContext);
6008}
6009
6010void HttpBaseChannel::EnsureBrowserId() {
6011 if (mBrowserId) {
6012 return;
6013 }
6014
6015 RefPtr<dom::BrowsingContext> bc;
6016 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"
, 6016); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
")"); do { *((volatile int*)__null) = 6016; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6017
6018 if (bc) {
6019 mBrowserId = bc->GetBrowserId();
6020 }
6021}
6022
6023void HttpBaseChannel::SetCorsPreflightParameters(
6024 const nsTArray<nsCString>& aUnsafeHeaders,
6025 bool aShouldStripRequestBodyHeader, bool aShouldStripAuthHeader) {
6026 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"
, 6026); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequestObserversCalled()"
")"); do { *((volatile int*)__null) = 6026; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6027
6028 StoreRequireCORSPreflight(true);
6029 mUnsafeHeaders = aUnsafeHeaders.Clone();
6030 if (aShouldStripRequestBodyHeader || aShouldStripAuthHeader) {
6031 mUnsafeHeaders.RemoveElementsBy([&](const nsCString& aHeader) {
6032 return (aShouldStripRequestBodyHeader &&
6033 (aHeader.LowerCaseEqualsASCII("content-type") ||
6034 aHeader.LowerCaseEqualsASCII("content-encoding") ||
6035 aHeader.LowerCaseEqualsASCII("content-language") ||
6036 aHeader.LowerCaseEqualsASCII("content-location"))) ||
6037 (aShouldStripAuthHeader &&
6038 aHeader.LowerCaseEqualsASCII("authorization"));
6039 });
6040 }
6041}
6042
6043void HttpBaseChannel::SetAltDataForChild(bool aIsForChild) {
6044 StoreAltDataForChild(aIsForChild);
6045}
6046
6047NS_IMETHODIMPnsresult
6048HttpBaseChannel::GetBlockAuthPrompt(bool* aValue) {
6049 if (!aValue) {
6050 return NS_ERROR_FAILURE;
6051 }
6052
6053 *aValue = LoadBlockAuthPrompt();
6054 return NS_OK;
6055}
6056
6057NS_IMETHODIMPnsresult
6058HttpBaseChannel::SetBlockAuthPrompt(bool aValue) {
6059 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"
, 6059); 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"
, 6059, 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"
, 6059); } } 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"
, 6059); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 6059; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
6060
6061 StoreBlockAuthPrompt(aValue);
6062 return NS_OK;
6063}
6064
6065NS_IMETHODIMPnsresult
6066HttpBaseChannel::GetConnectionInfoHashKey(nsACString& aConnectionInfoHashKey) {
6067 if (!mConnectionInfo) {
6068 return NS_ERROR_FAILURE;
6069 }
6070 aConnectionInfoHashKey.Assign(mConnectionInfo->HashKey());
6071 return NS_OK;
6072}
6073
6074NS_IMETHODIMPnsresult
6075HttpBaseChannel::GetLastRedirectFlags(uint32_t* aValue) {
6076 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"
, 6076); return NS_ERROR_INVALID_ARG; } } while (false)
;
6077 *aValue = mLastRedirectFlags;
6078 return NS_OK;
6079}
6080
6081NS_IMETHODIMPnsresult
6082HttpBaseChannel::SetLastRedirectFlags(uint32_t aValue) {
6083 mLastRedirectFlags = aValue;
6084 return NS_OK;
6085}
6086
6087NS_IMETHODIMPnsresult
6088HttpBaseChannel::GetNavigationStartTimeStamp(TimeStamp* aTimeStamp) {
6089 return NS_ERROR_NOT_IMPLEMENTED;
6090}
6091
6092NS_IMETHODIMPnsresult
6093HttpBaseChannel::SetNavigationStartTimeStamp(TimeStamp aTimeStamp) {
6094 return NS_ERROR_NOT_IMPLEMENTED;
6095}
6096
6097nsresult HttpBaseChannel::CheckRedirectLimit(nsIURI* aNewURI,
6098 uint32_t aRedirectFlags) const {
6099 if (aRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
6100 // for internal redirect due to auth retry we do not have any limit
6101 // as we might restrict the number of times a user might retry
6102 // authentication
6103 if (aRedirectFlags & nsIChannelEventSink::REDIRECT_AUTH_RETRY) {
6104 return NS_OK;
6105 }
6106 // Some platform features, like Service Workers, depend on internal
6107 // redirects. We should allow some number of internal redirects above
6108 // and beyond the normal redirect limit so these features continue
6109 // to work.
6110 static const int8_t kMinInternalRedirects = 5;
6111
6112 if (mInternalRedirectCount >= (mRedirectionLimit + kMinInternalRedirects)) {
6113 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)
;
6114 return NS_ERROR_REDIRECT_LOOP;
6115 }
6116 return NS_OK;
6117 }
6118
6119 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"
, 6121); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { *((volatile int*)__null) = 6121; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6120 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"
, 6121); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { *((volatile int*)__null) = 6121; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6121 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"
, 6121); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { *((volatile int*)__null) = 6121; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6122
6123 if (mRedirectCount >= mRedirectionLimit) {
6124 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)
;
6125 return NS_ERROR_REDIRECT_LOOP;
6126 }
6127
6128 // in case https-only mode is enabled which upgrades top-level requests to
6129 // https and the page answers with a redirect (meta, 302, win.location, ...)
6130 // then this method can break the cycle which causes the https-only exception
6131 // page to appear. Note that https-first mode breaks upgrade downgrade endless
6132 // loops within ShouldUpgradeHttpsFirstRequest because https-first does not
6133 // display an exception page but needs a soft fallback/downgrade.
6134 if (nsHTTPSOnlyUtils::IsUpgradeDowngradeEndlessLoop(
6135 mURI, aNewURI, mLoadInfo,
6136 {nsHTTPSOnlyUtils::UpgradeDowngradeEndlessLoopOptions::
6137 EnforceForHTTPSOnlyMode})) {
6138 // Mark that we didn't upgrade to https due to loop detection in https-only
6139 // mode to show https-only error page. We know that we are in https-only
6140 // mode, because we passed `EnforceForHTTPSOnlyMode` to
6141 // `IsUpgradeDowngradeEndlessLoop`. In other words we upgrade the request
6142 // with https-only mode, but then immediately cancel the request.
6143 uint32_t httpsOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
6144 if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_UNINITIALIZED) {
6145 httpsOnlyStatus ^= nsILoadInfo::HTTPS_ONLY_UNINITIALIZED;
6146 httpsOnlyStatus |=
6147 nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_NOT_REGISTERED;
6148 mLoadInfo->SetHttpsOnlyStatus(httpsOnlyStatus);
6149 }
6150
6151 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)
;
6152 return NS_ERROR_REDIRECT_LOOP;
6153 }
6154 // in case of http-first mode we want to add an exception to disable the
6155 // upgrade behavior if we have upgrade-downgrade loop to break the loop and
6156 // load the http request next
6157 if (mozilla::StaticPrefs::
6158 dom_security_https_first_add_exception_on_failiure() &&
6159 nsHTTPSOnlyUtils::IsUpgradeDowngradeEndlessLoop(
6160 mURI, aNewURI, mLoadInfo,
6161 {nsHTTPSOnlyUtils::UpgradeDowngradeEndlessLoopOptions::
6162 EnforceForHTTPSFirstMode})) {
6163 nsHTTPSOnlyUtils::AddHTTPSFirstExceptionForSession(mURI, mLoadInfo);
6164 }
6165
6166 return NS_OK;
6167}
6168
6169// NOTE: This function duplicates code from nsBaseChannel. This will go away
6170// once HTTP uses nsBaseChannel (part of bug 312760)
6171/* static */
6172void HttpBaseChannel::CallTypeSniffers(void* aClosure, const uint8_t* aData,
6173 uint32_t aCount) {
6174 nsIChannel* chan = static_cast<nsIChannel*>(aClosure);
6175 const char* snifferType = [chan]() {
6176 if (RefPtr<nsHttpChannel> httpChannel = do_QueryObject(chan)) {
6177 switch (httpChannel->GetSnifferCategoryType()) {
6178 case SnifferCategoryType::NetContent:
6179 return NS_CONTENT_SNIFFER_CATEGORY"net-content-sniffers";
6180 case SnifferCategoryType::OpaqueResponseBlocking:
6181 return NS_ORB_SNIFFER_CATEGORY"orb-content-sniffers";
6182 case SnifferCategoryType::All:
6183 return NS_CONTENT_AND_ORB_SNIFFER_CATEGORY"net-and-orb-content-sniffers";
6184 default:
6185 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"
, 6185); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected SnifferCategoryType!"
")"); do { *((volatile int*)__null) = 6185; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6186 }
6187 }
6188
6189 return NS_CONTENT_SNIFFER_CATEGORY"net-content-sniffers";
6190 }();
6191
6192 nsAutoCString newType;
6193 NS_SniffContent(snifferType, chan, aData, aCount, newType);
6194 if (!newType.IsEmpty()) {
6195 chan->SetContentType(newType);
6196 }
6197}
6198
6199template <class T>
6200static void ParseServerTimingHeader(
6201 const UniquePtr<T>& aHeader, nsTArray<nsCOMPtr<nsIServerTiming>>& aOutput) {
6202 if (!aHeader) {
6203 return;
6204 }
6205
6206 nsAutoCString serverTimingHeader;
6207 Unused << aHeader->GetHeader(nsHttp::Server_Timing, serverTimingHeader);
6208 if (serverTimingHeader.IsEmpty()) {
6209 return;
6210 }
6211
6212 ServerTimingParser parser(serverTimingHeader);
6213 parser.Parse();
6214
6215 nsTArray<nsCOMPtr<nsIServerTiming>> array = parser.TakeServerTimingHeaders();
6216 aOutput.AppendElements(array);
6217}
6218
6219NS_IMETHODIMPnsresult
6220HttpBaseChannel::GetServerTiming(nsIArray** aServerTiming) {
6221 nsresult rv;
6222 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"
, 6222); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6223
6224 nsCOMPtr<nsIMutableArray> array = do_CreateInstance(NS_ARRAY_CONTRACTID"@mozilla.org/array;1", &rv);
6225 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"
, 6225); return rv; } } while (false)
;
6226
6227 nsTArray<nsCOMPtr<nsIServerTiming>> data;
6228 rv = GetNativeServerTiming(data);
6229 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"
, 6229); return rv; } } while (false)
;
6230
6231 for (const auto& entry : data) {
6232 array->AppendElement(entry);
6233 }
6234
6235 array.forget(aServerTiming);
6236 return NS_OK;
6237}
6238
6239NS_IMETHODIMPnsresult
6240HttpBaseChannel::GetNativeServerTiming(
6241 nsTArray<nsCOMPtr<nsIServerTiming>>& aServerTiming) {
6242 aServerTiming.Clear();
6243
6244 if (nsContentUtils::ComputeIsSecureContext(this)) {
6245 ParseServerTimingHeader(mResponseHead, aServerTiming);
6246 ParseServerTimingHeader(mResponseTrailers, aServerTiming);
6247 }
6248
6249 return NS_OK;
6250}
6251
6252NS_IMETHODIMPnsresult
6253HttpBaseChannel::CancelByURLClassifier(nsresult aErrorCode) {
6254 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"
, 6255); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6255; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6255 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"
, 6255); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6255; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6256 return Cancel(aErrorCode);
6257}
6258
6259NS_IMETHODIMPnsresult HttpBaseChannel::SetIPv4Disabled() {
6260 mCaps |= NS_HTTP_DISABLE_IPV4(1 << 17);
6261 return NS_OK;
6262}
6263
6264NS_IMETHODIMPnsresult HttpBaseChannel::SetIPv6Disabled() {
6265 mCaps |= NS_HTTP_DISABLE_IPV6(1 << 18);
6266 return NS_OK;
6267}
6268
6269NS_IMETHODIMPnsresult HttpBaseChannel::GetResponseEmbedderPolicy(
6270 bool aIsOriginTrialCoepCredentiallessEnabled,
6271 nsILoadInfo::CrossOriginEmbedderPolicy* aOutPolicy) {
6272 *aOutPolicy = nsILoadInfo::EMBEDDER_POLICY_NULL;
6273 if (!mResponseHead) {
6274 return NS_ERROR_NOT_AVAILABLE;
6275 }
6276
6277 if (!nsContentUtils::ComputeIsSecureContext(this)) {
6278 // Feature is only available for secure contexts.
6279 return NS_OK;
6280 }
6281
6282 nsAutoCString content;
6283 Unused << mResponseHead->GetHeader(nsHttp::Cross_Origin_Embedder_Policy,
6284 content);
6285 *aOutPolicy = NS_GetCrossOriginEmbedderPolicyFromHeader(
6286 content, aIsOriginTrialCoepCredentiallessEnabled);
6287 return NS_OK;
6288}
6289
6290// Obtain a cross-origin opener-policy from a response response and a
6291// cross-origin opener policy initiator.
6292// https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
6293NS_IMETHODIMPnsresult HttpBaseChannel::ComputeCrossOriginOpenerPolicy(
6294 nsILoadInfo::CrossOriginOpenerPolicy aInitiatorPolicy,
6295 nsILoadInfo::CrossOriginOpenerPolicy* aOutPolicy) {
6296 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"
, 6296); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOutPolicy"
")"); do { *((volatile int*)__null) = 6296; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6297 *aOutPolicy = nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
6298
6299 if (!mResponseHead) {
6300 return NS_ERROR_NOT_AVAILABLE;
6301 }
6302
6303 // COOP headers are ignored for insecure-context loads.
6304 if (!nsContentUtils::ComputeIsSecureContext(this)) {
6305 return NS_OK;
6306 }
6307
6308 nsAutoCString openerPolicy;
6309 Unused << mResponseHead->GetHeader(nsHttp::Cross_Origin_Opener_Policy,
6310 openerPolicy);
6311
6312 // Cross-Origin-Opener-Policy = %s"same-origin" /
6313 // %s"same-origin-allow-popups" /
6314 // %s"unsafe-none"; case-sensitive
6315
6316 nsCOMPtr<nsISFVService> sfv = GetSFVService();
6317
6318 nsCOMPtr<nsISFVItem> item;
6319 nsresult rv = sfv->ParseItem(openerPolicy, getter_AddRefs(item));
6320 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6321 return rv;
6322 }
6323
6324 nsCOMPtr<nsISFVBareItem> value;
6325 rv = item->GetValue(getter_AddRefs(value));
6326 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6327 return rv;
6328 }
6329
6330 nsCOMPtr<nsISFVToken> token = do_QueryInterface(value);
6331 if (!token) {
6332 return NS_ERROR_UNEXPECTED;
6333 }
6334
6335 rv = token->GetValue(openerPolicy);
6336 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6337 return rv;
6338 }
6339
6340 nsILoadInfo::CrossOriginOpenerPolicy policy =
6341 nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
6342
6343 if (openerPolicy.EqualsLiteral("same-origin")) {
6344 policy = nsILoadInfo::OPENER_POLICY_SAME_ORIGIN;
6345 } else if (openerPolicy.EqualsLiteral("same-origin-allow-popups")) {
6346 policy = nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_ALLOW_POPUPS;
6347 }
6348 if (policy == nsILoadInfo::OPENER_POLICY_SAME_ORIGIN) {
6349 nsILoadInfo::CrossOriginEmbedderPolicy coep =
6350 nsILoadInfo::EMBEDDER_POLICY_NULL;
6351 bool isCoepCredentiallessEnabled;
6352 rv = mLoadInfo->GetIsOriginTrialCoepCredentiallessEnabledForTopLevel(
6353 &isCoepCredentiallessEnabled);
6354 if (!isCoepCredentiallessEnabled) {
6355 nsAutoCString originTrialToken;
6356 Unused << mResponseHead->GetHeader(nsHttp::OriginTrial, originTrialToken);
6357 if (!originTrialToken.IsEmpty()) {
6358 nsCOMPtr<nsIPrincipal> resultPrincipal;
6359 rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
6360 this, getter_AddRefs(resultPrincipal));
6361 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"
, 6361)
) {
6362 OriginTrials trials;
6363 trials.UpdateFromToken(NS_ConvertASCIItoUTF16(originTrialToken),
6364 resultPrincipal);
6365 if (trials.IsEnabled(OriginTrial::CoepCredentialless)) {
6366 isCoepCredentiallessEnabled = true;
6367 }
6368 }
6369 }
6370 }
6371
6372 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"
, 6372); return rv; } } while (false)
;
6373 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetResponseEmbedderPolicy
(isCoepCredentiallessEnabled, &coep))), 1)))
6374 GetResponseEmbedderPolicy(isCoepCredentiallessEnabled, &coep))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetResponseEmbedderPolicy
(isCoepCredentiallessEnabled, &coep))), 1)))
&&
6375 (coep == nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP ||
6376 coep == nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS)) {
6377 policy =
6378 nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP;
6379 }
6380 }
6381
6382 *aOutPolicy = policy;
6383 return NS_OK;
6384}
6385
6386NS_IMETHODIMPnsresult
6387HttpBaseChannel::GetCrossOriginOpenerPolicy(
6388 nsILoadInfo::CrossOriginOpenerPolicy* aPolicy) {
6389 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"
, 6389); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPolicy" ")"
); do { *((volatile int*)__null) = 6389; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6390 if (!aPolicy) {
6391 return NS_ERROR_INVALID_ARG;
6392 }
6393 // If this method is called before OnStartRequest (ie. before we call
6394 // ComputeCrossOriginOpenerPolicy) or if we were unable to compute the
6395 // policy we'll throw an error.
6396 if (!LoadOnStartRequestCalled()) {
6397 return NS_ERROR_NOT_AVAILABLE;
6398 }
6399 *aPolicy = mComputedCrossOriginOpenerPolicy;
6400 return NS_OK;
6401}
6402
6403NS_IMETHODIMPnsresult
6404HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch(bool* aIsMismatch) {
6405 // This should only be called in parent process.
6406 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"
, 6406); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 6406; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6407 *aIsMismatch = LoadHasCrossOriginOpenerPolicyMismatch();
6408 return NS_OK;
6409}
6410
6411void HttpBaseChannel::MaybeFlushConsoleReports() {
6412 // Flush if we have a known window ID.
6413 if (mLoadInfo->GetInnerWindowID() > 0) {
6414 FlushReportsToConsole(mLoadInfo->GetInnerWindowID());
6415 return;
6416 }
6417
6418 // If this channel is part of a loadGroup, we can flush the console reports
6419 // immediately.
6420 nsCOMPtr<nsILoadGroup> loadGroup;
6421 nsresult rv = GetLoadGroup(getter_AddRefs(loadGroup));
6422 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && loadGroup) {
6423 FlushConsoleReports(loadGroup);
6424 }
6425}
6426
6427void HttpBaseChannel::DoDiagnosticAssertWhenOnStopNotCalledOnDestroy() {}
6428
6429bool HttpBaseChannel::Http3Allowed() const {
6430 bool isDirectOrNoProxy =
6431 mProxyInfo ? static_cast<nsProxyInfo*>(mProxyInfo.get())->IsDirect()
6432 : true;
6433 return !mUpgradeProtocolCallback && isDirectOrNoProxy &&
6434 !(mCaps & NS_HTTP_BE_CONSERVATIVE(1 << 11)) && !LoadBeConservative() &&
6435 LoadAllowHttp3();
6436}
6437
6438void HttpBaseChannel::SetDummyChannelForImageCache() {
6439 mDummyChannelForImageCache = true;
6440 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"
" (" "SetDummyChannelForImageCache should only be called once"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6441); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mResponseHead"
") (" "SetDummyChannelForImageCache should only be called once"
")"); do { *((volatile int*)__null) = 6441; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6441 "SetDummyChannelForImageCache 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"
" (" "SetDummyChannelForImageCache should only be called once"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6441); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mResponseHead"
") (" "SetDummyChannelForImageCache should only be called once"
")"); do { *((volatile int*)__null) = 6441; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6442 mResponseHead = MakeUnique<nsHttpResponseHead>();
6443}
6444
6445void HttpBaseChannel::SetEarlyHints(
6446 nsTArray<EarlyHintConnectArgs>&& aEarlyHints) {
6447 mEarlyHints = std::move(aEarlyHints);
6448}
6449
6450nsTArray<EarlyHintConnectArgs>&& HttpBaseChannel::TakeEarlyHints() {
6451 return std::move(mEarlyHints);
6452}
6453
6454NS_IMETHODIMPnsresult
6455HttpBaseChannel::SetEarlyHintPreloaderId(uint64_t aEarlyHintPreloaderId) {
6456 mEarlyHintPreloaderId = aEarlyHintPreloaderId;
6457 return NS_OK;
6458}
6459
6460NS_IMETHODIMPnsresult
6461HttpBaseChannel::GetEarlyHintPreloaderId(uint64_t* aEarlyHintPreloaderId) {
6462 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"
, 6462); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6463 *aEarlyHintPreloaderId = mEarlyHintPreloaderId;
6464 return NS_OK;
6465}
6466
6467NS_IMETHODIMPnsresult
6468HttpBaseChannel::SetClassicScriptHintCharset(
6469 const nsAString& aClassicScriptHintCharset) {
6470 mClassicScriptHintCharset = aClassicScriptHintCharset;
6471 return NS_OK;
6472}
6473
6474NS_IMETHODIMPnsresult HttpBaseChannel::GetClassicScriptHintCharset(
6475 nsAString& aClassicScriptHintCharset) {
6476 aClassicScriptHintCharset = mClassicScriptHintCharset;
6477 return NS_OK;
6478}
6479
6480NS_IMETHODIMPnsresult HttpBaseChannel::SetDocumentCharacterSet(
6481 const nsAString& aDocumentCharacterSet) {
6482 mDocumentCharacterSet = aDocumentCharacterSet;
6483 return NS_OK;
6484}
6485
6486NS_IMETHODIMPnsresult HttpBaseChannel::GetDocumentCharacterSet(
6487 nsAString& aDocumentCharacterSet) {
6488 aDocumentCharacterSet = mDocumentCharacterSet;
6489 return NS_OK;
6490}
6491
6492void HttpBaseChannel::SetConnectionInfo(nsHttpConnectionInfo* aCI) {
6493 mConnectionInfo = aCI ? aCI->Clone() : nullptr;
6494}
6495
6496NS_IMETHODIMPnsresult
6497HttpBaseChannel::GetIsProxyUsed(bool* aIsProxyUsed) {
6498 if (mProxyInfo) {
6499 if (!static_cast<nsProxyInfo*>(mProxyInfo.get())->IsDirect()) {
6500 StoreIsProxyUsed(true);
6501 }
6502 }
6503 *aIsProxyUsed = LoadIsProxyUsed();
6504 return NS_OK;
6505}
6506
6507static void CollectORBBlockTelemetry(
6508 const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
6509 ExtContentPolicy aPolicy) {
6510 Telemetry::LABELS_ORB_BLOCK_REASON label{
6511 static_cast<uint32_t>(aTelemetryReason)};
6512 Telemetry::AccumulateCategorical(label);
6513
6514 switch (aPolicy) {
6515 case ExtContentPolicy::TYPE_INVALID:
6516 Telemetry::AccumulateCategorical(
6517 Telemetry::LABELS_ORB_BLOCK_INITIATOR::INVALID);
6518 break;
6519 case ExtContentPolicy::TYPE_OTHER:
6520 Telemetry::AccumulateCategorical(
6521 Telemetry::LABELS_ORB_BLOCK_INITIATOR::OTHER);
6522 break;
6523 case ExtContentPolicy::TYPE_FETCH:
6524 Telemetry::AccumulateCategorical(
6525 Telemetry::LABELS_ORB_BLOCK_INITIATOR::BLOCKED_FETCH);
6526 break;
6527 case ExtContentPolicy::TYPE_SCRIPT:
6528 Telemetry::AccumulateCategorical(
6529 Telemetry::LABELS_ORB_BLOCK_INITIATOR::SCRIPT);
6530 break;
6531 case ExtContentPolicy::TYPE_IMAGE:
6532 Telemetry::AccumulateCategorical(
6533 Telemetry::LABELS_ORB_BLOCK_INITIATOR::IMAGE);
6534 break;
6535 case ExtContentPolicy::TYPE_STYLESHEET:
6536 Telemetry::AccumulateCategorical(
6537 Telemetry::LABELS_ORB_BLOCK_INITIATOR::STYLESHEET);
6538 break;
6539 case ExtContentPolicy::TYPE_XMLHTTPREQUEST:
6540 Telemetry::AccumulateCategorical(
6541 Telemetry::LABELS_ORB_BLOCK_INITIATOR::XMLHTTPREQUEST);
6542 break;
6543 case ExtContentPolicy::TYPE_DTD:
6544 Telemetry::AccumulateCategorical(
6545 Telemetry::LABELS_ORB_BLOCK_INITIATOR::DTD);
6546 break;
6547 case ExtContentPolicy::TYPE_FONT:
6548 Telemetry::AccumulateCategorical(
6549 Telemetry::LABELS_ORB_BLOCK_INITIATOR::FONT);
6550 break;
6551 case ExtContentPolicy::TYPE_MEDIA:
6552 Telemetry::AccumulateCategorical(
6553 Telemetry::LABELS_ORB_BLOCK_INITIATOR::MEDIA);
6554 break;
6555 case ExtContentPolicy::TYPE_CSP_REPORT:
6556 Telemetry::AccumulateCategorical(
6557 Telemetry::LABELS_ORB_BLOCK_INITIATOR::CSP_REPORT);
6558 break;
6559 case ExtContentPolicy::TYPE_XSLT:
6560 Telemetry::AccumulateCategorical(
6561 Telemetry::LABELS_ORB_BLOCK_INITIATOR::XSLT);
6562 break;
6563 case ExtContentPolicy::TYPE_IMAGESET:
6564 Telemetry::AccumulateCategorical(
6565 Telemetry::LABELS_ORB_BLOCK_INITIATOR::IMAGESET);
6566 break;
6567 case ExtContentPolicy::TYPE_WEB_MANIFEST:
6568 Telemetry::AccumulateCategorical(
6569 Telemetry::LABELS_ORB_BLOCK_INITIATOR::WEB_MANIFEST);
6570 break;
6571 case ExtContentPolicy::TYPE_SPECULATIVE:
6572 Telemetry::AccumulateCategorical(
6573 Telemetry::LABELS_ORB_BLOCK_INITIATOR::SPECULATIVE);
6574 break;
6575 case ExtContentPolicy::TYPE_UA_FONT:
6576 Telemetry::AccumulateCategorical(
6577 Telemetry::LABELS_ORB_BLOCK_INITIATOR::UA_FONT);
6578 break;
6579 case ExtContentPolicy::TYPE_PROXIED_WEBRTC_MEDIA:
6580 Telemetry::AccumulateCategorical(
6581 Telemetry::LABELS_ORB_BLOCK_INITIATOR::PROXIED_WEBRTC_MEDIA);
6582 break;
6583 case ExtContentPolicy::TYPE_PING:
6584 Telemetry::AccumulateCategorical(
6585 Telemetry::LABELS_ORB_BLOCK_INITIATOR::PING);
6586 break;
6587 case ExtContentPolicy::TYPE_BEACON:
6588 Telemetry::AccumulateCategorical(
6589 Telemetry::LABELS_ORB_BLOCK_INITIATOR::BEACON);
6590 break;
6591 case ExtContentPolicy::TYPE_WEB_TRANSPORT:
6592 Telemetry::AccumulateCategorical(
6593 Telemetry::LABELS_ORB_BLOCK_INITIATOR::WEB_TRANSPORT);
6594 break;
6595 case ExtContentPolicy::TYPE_WEB_IDENTITY:
6596 // Don't bother extending the telemetry for this.
6597 Telemetry::AccumulateCategorical(
6598 Telemetry::LABELS_ORB_BLOCK_INITIATOR::OTHER);
6599 break;
6600 case ExtContentPolicy::TYPE_DOCUMENT:
6601 case ExtContentPolicy::TYPE_SUBDOCUMENT:
6602 case ExtContentPolicy::TYPE_OBJECT:
6603 case ExtContentPolicy::TYPE_OBJECT_SUBREQUEST:
6604 case ExtContentPolicy::TYPE_WEBSOCKET:
6605 case ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD:
6606 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"
, 6606); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Shouldn't block this type" ")");
do { *((volatile int*)__null) = 6606; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6607 // DOCUMENT, SUBDOCUMENT, OBJECT, OBJECT_SUBREQUEST,
6608 // WEBSOCKET and SAVEAS_DOWNLOAD are excluded from ORB
6609 Telemetry::AccumulateCategorical(
6610 Telemetry::LABELS_ORB_BLOCK_INITIATOR::EXCLUDED);
6611 break;
6612 // Do not add default: so that compilers can catch the missing case.
6613 }
6614}
6615
6616void HttpBaseChannel::LogORBError(
6617 const nsAString& aReason,
6618 const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
6619 auto policy = mLoadInfo->GetExternalContentPolicyType();
6620 CollectORBBlockTelemetry(aTelemetryReason, policy);
6621
6622 // Blocking `ExtContentPolicy::TYPE_BEACON` isn't web observable, so keep
6623 // quiet in the console about blocking it.
6624 if (policy == ExtContentPolicy::TYPE_BEACON) {
6625 return;
6626 }
6627
6628 RefPtr<dom::Document> doc;
6629 mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
6630
6631 nsAutoCString uri;
6632 nsresult rv = nsContentUtils::AnonymizeURI(mURI, uri);
6633 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"
, 6633)
) {
6634 return;
6635 }
6636
6637 uint64_t contentWindowId;
6638 GetTopLevelContentWindowId(&contentWindowId);
6639 if (contentWindowId) {
6640 nsContentUtils::ReportToConsoleByWindowID(
6641 u"A resource is blocked by OpaqueResponseBlocking, please check browser console for details."_ns,
6642 nsIScriptError::warningFlag, "ORB"_ns, contentWindowId, mURI);
6643 }
6644
6645 AutoTArray<nsString, 2> params;
6646 params.AppendElement(NS_ConvertUTF8toUTF16(uri));
6647 params.AppendElement(aReason);
6648 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "ORB"_ns, doc,
6649 nsContentUtils::eNECKO_PROPERTIES,
6650 "ResourceBlockedORB", params);
6651}
6652
6653NS_IMETHODIMPnsresult HttpBaseChannel::SetEarlyHintLinkType(
6654 uint32_t aEarlyHintLinkType) {
6655 mEarlyHintLinkType = aEarlyHintLinkType;
6656 return NS_OK;
6657}
6658
6659NS_IMETHODIMPnsresult HttpBaseChannel::GetEarlyHintLinkType(
6660 uint32_t* aEarlyHintLinkType) {
6661 *aEarlyHintLinkType = mEarlyHintLinkType;
6662 return NS_OK;
6663}
6664
6665NS_IMETHODIMPnsresult
6666HttpBaseChannel::SetHasContentDecompressed(bool aValue) {
6667 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)
6668 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)
;
6669 mHasContentDecompressed = aValue;
6670 return NS_OK;
6671}
6672NS_IMETHODIMPnsresult
6673HttpBaseChannel::GetHasContentDecompressed(bool* value) {
6674 *value = mHasContentDecompressed;
6675 return NS_OK;
6676}
6677
6678NS_IMETHODIMPnsresult
6679HttpBaseChannel::SetRenderBlocking(bool aRenderBlocking) {
6680 mRenderBlocking = aRenderBlocking;
6681 return NS_OK;
6682}
6683
6684NS_IMETHODIMPnsresult
6685HttpBaseChannel::GetRenderBlocking(bool* aRenderBlocking) {
6686 *aRenderBlocking = mRenderBlocking;
6687 return NS_OK;
6688}
6689
6690} // namespace net
6691} // namespace mozilla