Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp
Warning:line 5467, 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_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -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/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/x86_64-linux-gnu/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../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-05-16-034744-15991-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 = SetRequestHeader("User-Agent"_ns, utf8CustomUserAgent, false);
553 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
554
555 return NS_OK;
556}
557
558//-----------------------------------------------------------------------------
559// HttpBaseChannel::nsIChannel
560//-----------------------------------------------------------------------------
561
562NS_IMETHODIMPnsresult
563HttpBaseChannel::GetOriginalURI(nsIURI** aOriginalURI) {
564 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"
, 564); return NS_ERROR_INVALID_POINTER; } } while (false)
;
565 *aOriginalURI = do_AddRef(mOriginalURI).take();
566 return NS_OK;
567}
568
569NS_IMETHODIMPnsresult
570HttpBaseChannel::SetOriginalURI(nsIURI* aOriginalURI) {
571 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"
, 571); 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"
, 571, 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"
, 571); } } 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"
, 571); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 571; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
572
573 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"
, 573); return NS_ERROR_INVALID_POINTER; } } while (false)
;
574 mOriginalURI = aOriginalURI;
575 return NS_OK;
576}
577
578NS_IMETHODIMPnsresult
579HttpBaseChannel::GetURI(nsIURI** aURI) {
580 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"
, 580); return NS_ERROR_INVALID_POINTER; } } while (false)
;
581 *aURI = do_AddRef(mURI).take();
582 return NS_OK;
583}
584
585NS_IMETHODIMPnsresult
586HttpBaseChannel::GetOwner(nsISupports** aOwner) {
587 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"
, 587); return NS_ERROR_INVALID_POINTER; } } while (false)
;
588 *aOwner = do_AddRef(mOwner).take();
589 return NS_OK;
590}
591
592NS_IMETHODIMPnsresult
593HttpBaseChannel::SetOwner(nsISupports* aOwner) {
594 mOwner = aOwner;
595 return NS_OK;
596}
597
598NS_IMETHODIMPnsresult
599HttpBaseChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
600 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"
, 600); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aLoadInfo"
") (" "loadinfo can't be null" ")"); do { *((volatile int*)__null
) = 600; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
601 mLoadInfo = aLoadInfo;
602 return NS_OK;
603}
604
605NS_IMETHODIMPnsresult
606HttpBaseChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) {
607 *aLoadInfo = do_AddRef(mLoadInfo).take();
608 return NS_OK;
609}
610
611NS_IMETHODIMPnsresult
612HttpBaseChannel::GetIsDocument(bool* aIsDocument) {
613 return NS_GetIsDocumentChannel(this, aIsDocument);
614}
615
616NS_IMETHODIMPnsresult
617HttpBaseChannel::GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks) {
618 *aCallbacks = do_AddRef(mCallbacks).take();
619 return NS_OK;
620}
621
622NS_IMETHODIMPnsresult
623HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) {
624 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"
, 624); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should only be called on the main thread." ")"); do {
*((volatile int*)__null) = 624; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
625
626 if (!CanSetCallbacks(aCallbacks)) {
627 return NS_ERROR_FAILURE;
628 }
629
630 mCallbacks = aCallbacks;
631 mProgressSink = nullptr;
632
633 UpdatePrivateBrowsing();
634 return NS_OK;
635}
636
637NS_IMETHODIMPnsresult
638HttpBaseChannel::GetContentType(nsACString& aContentType) {
639 if (!mResponseHead) {
640 aContentType.Truncate();
641 return NS_ERROR_NOT_AVAILABLE;
642 }
643
644 mResponseHead->ContentType(aContentType);
645 if (!aContentType.IsEmpty()) {
646 return NS_OK;
647 }
648
649 aContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE"application/x-unknown-content-type");
650 return NS_OK;
651}
652
653NS_IMETHODIMPnsresult
654HttpBaseChannel::SetContentType(const nsACString& aContentType) {
655 if (mListener || LoadWasOpened() || mDummyChannelForImageCache) {
656 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
657
658 nsAutoCString contentTypeBuf, charsetBuf;
659 bool hadCharset;
660 net_ParseContentType(aContentType, contentTypeBuf, charsetBuf, &hadCharset);
661
662 mResponseHead->SetContentType(contentTypeBuf);
663
664 // take care not to stomp on an existing charset
665 if (hadCharset) mResponseHead->SetContentCharset(charsetBuf);
666
667 } else {
668 // We are being given a content-type hint.
669 bool dummy;
670 net_ParseContentType(aContentType, mContentTypeHint, mContentCharsetHint,
671 &dummy);
672 }
673
674 return NS_OK;
675}
676
677NS_IMETHODIMPnsresult
678HttpBaseChannel::GetContentCharset(nsACString& aContentCharset) {
679 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
680
681 mResponseHead->ContentCharset(aContentCharset);
682 return NS_OK;
683}
684
685NS_IMETHODIMPnsresult
686HttpBaseChannel::SetContentCharset(const nsACString& aContentCharset) {
687 if (mListener) {
688 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
689
690 mResponseHead->SetContentCharset(aContentCharset);
691 } else {
692 // Charset hint
693 mContentCharsetHint = aContentCharset;
694 }
695 return NS_OK;
696}
697
698NS_IMETHODIMPnsresult
699HttpBaseChannel::GetContentDisposition(uint32_t* aContentDisposition) {
700 // See bug 1658877. If mContentDispositionHint is already
701 // DISPOSITION_ATTACHMENT, it means this channel is created from a
702 // download attribute. In this case, we should prefer the value from the
703 // download attribute rather than the value in content disposition header.
704 // DISPOSITION_FORCE_INLINE is used to explicitly set inline, used by
705 // the pdf reader when loading a attachment pdf without having to
706 // download it.
707 if (mContentDispositionHint == nsIChannel::DISPOSITION_ATTACHMENT ||
708 mContentDispositionHint == nsIChannel::DISPOSITION_FORCE_INLINE) {
709 *aContentDisposition = mContentDispositionHint;
710 return NS_OK;
711 }
712
713 nsresult rv;
714 nsCString header;
715
716 rv = GetContentDispositionHeader(header);
717 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
718 if (mContentDispositionHint == UINT32_MAX(4294967295U)) return rv;
719
720 *aContentDisposition = mContentDispositionHint;
721 return NS_OK;
722 }
723
724 *aContentDisposition = NS_GetContentDispositionFromHeader(header, this);
725 return NS_OK;
726}
727
728NS_IMETHODIMPnsresult
729HttpBaseChannel::SetContentDisposition(uint32_t aContentDisposition) {
730 mContentDispositionHint = aContentDisposition;
731 return NS_OK;
732}
733
734NS_IMETHODIMPnsresult
735HttpBaseChannel::GetContentDispositionFilename(
736 nsAString& aContentDispositionFilename) {
737 aContentDispositionFilename.Truncate();
738 nsresult rv;
739 nsCString header;
740
741 rv = GetContentDispositionHeader(header);
742 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
743 rv = NS_GetFilenameFromDisposition(aContentDispositionFilename, header);
744 }
745
746 // If we failed to get the filename from header, we should use
747 // mContentDispositionFilename, since mContentDispositionFilename is set from
748 // the download attribute.
749 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
750 if (!mContentDispositionFilename) {
751 return rv;
752 }
753
754 aContentDispositionFilename = *mContentDispositionFilename;
755 return NS_OK;
756 }
757
758 return rv;
759}
760
761NS_IMETHODIMPnsresult
762HttpBaseChannel::SetContentDispositionFilename(
763 const nsAString& aContentDispositionFilename) {
764 mContentDispositionFilename =
765 MakeUnique<nsString>(aContentDispositionFilename);
766
767 // For safety reasons ensure the filename doesn't contain null characters and
768 // replace them with underscores. We may later pass the extension to system
769 // MIME APIs that expect null terminated strings.
770 mContentDispositionFilename->ReplaceChar(char16_t(0), '_');
771
772 return NS_OK;
773}
774
775NS_IMETHODIMPnsresult
776HttpBaseChannel::GetContentDispositionHeader(
777 nsACString& aContentDispositionHeader) {
778 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
779
780 nsresult rv = mResponseHead->GetHeader(nsHttp::Content_Disposition,
781 aContentDispositionHeader);
782 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || aContentDispositionHeader.IsEmpty()) {
783 return NS_ERROR_NOT_AVAILABLE;
784 }
785
786 return NS_OK;
787}
788
789NS_IMETHODIMPnsresult
790HttpBaseChannel::GetContentLength(int64_t* aContentLength) {
791 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"
, 791); return NS_ERROR_INVALID_POINTER; } } while (false)
;
792
793 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
794
795 if (LoadDeliveringAltData()) {
796 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"
, 796); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mAvailableCachedAltDataType.IsEmpty()"
")"); do { *((volatile int*)__null) = 796; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
797 *aContentLength = mAltDataLength;
798 return NS_OK;
799 }
800
801 *aContentLength = mResponseHead->ContentLength();
802 return NS_OK;
803}
804
805NS_IMETHODIMPnsresult
806HttpBaseChannel::SetContentLength(int64_t value) {
807 if (!mDummyChannelForImageCache) {
808 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"
, 808); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "HttpBaseChannel::SetContentLength"
")"); do { *((volatile int*)__null) = 808; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
809 return NS_ERROR_NOT_IMPLEMENTED;
810 }
811 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"
, 811); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mResponseHead"
")"); do { *((volatile int*)__null) = 811; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
812 mResponseHead->SetContentLength(value);
813 return NS_OK;
814}
815
816NS_IMETHODIMPnsresult
817HttpBaseChannel::Open(nsIInputStream** aStream) {
818 if (!gHttpHandler->Active()) {
819 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)
;
820 return NS_ERROR_NOT_AVAILABLE;
821 }
822
823 nsCOMPtr<nsIStreamListener> listener;
824 nsresult rv =
825 nsContentSecurityManager::doContentSecurityCheck(this, listener);
826 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"
, 826); return rv; } } while (false)
;
827
828 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"
, 828); return NS_ERROR_IN_PROGRESS; } } while (false)
;
829
830 if (!gHttpHandler->Active()) {
831 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)
;
832 return NS_ERROR_NOT_AVAILABLE;
833 }
834
835 return NS_ImplementChannelOpen(this, aStream);
836}
837
838//-----------------------------------------------------------------------------
839// HttpBaseChannel::nsIUploadChannel
840//-----------------------------------------------------------------------------
841
842NS_IMETHODIMPnsresult
843HttpBaseChannel::GetUploadStream(nsIInputStream** stream) {
844 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"
, 844); return NS_ERROR_INVALID_POINTER; } } while (false)
;
845 *stream = do_AddRef(mUploadStream).take();
846 return NS_OK;
847}
848
849NS_IMETHODIMPnsresult
850HttpBaseChannel::SetUploadStream(nsIInputStream* stream,
851 const nsACString& contentTypeArg,
852 int64_t contentLength) {
853 // NOTE: for backwards compatibility and for compatibility with old style
854 // plugins, |stream| may include headers, specifically Content-Type and
855 // Content-Length headers. in this case, |contentType| and |contentLength|
856 // would be unspecified. this is traditionally the case of a POST request,
857 // and so we select POST as the request method if contentType and
858 // contentLength are unspecified.
859
860 if (stream) {
861 nsAutoCString method;
862 bool hasHeaders = false;
863
864 // This method and ExplicitSetUploadStream mean different things by "empty
865 // content type string". This method means "no header", but
866 // ExplicitSetUploadStream means "header with empty value". So we have to
867 // massage the contentType argument into the form ExplicitSetUploadStream
868 // expects.
869 nsCOMPtr<nsIMIMEInputStream> mimeStream;
870 nsCString contentType(contentTypeArg);
871 if (contentType.IsEmpty()) {
872 contentType.SetIsVoid(true);
873 method = "POST"_ns;
874
875 // MIME streams are a special case, and include headers which need to be
876 // copied to the channel.
877 mimeStream = do_QueryInterface(stream);
878 if (mimeStream) {
879 // Copy non-origin related headers to the channel.
880 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
881 new AddHeadersToChannelVisitor(this);
882 mimeStream->VisitHeaders(visitor);
883
884 return ExplicitSetUploadStream(stream, contentType, contentLength,
885 method, hasHeaders);
886 }
887
888 hasHeaders = true;
889 } else {
890 method = "PUT"_ns;
891
892 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"
, 894); 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) = 894; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
893 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"
, 894); 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) = 894; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
894 "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"
, 894); 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) = 894; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
895 }
896 return ExplicitSetUploadStream(stream, contentType, contentLength, method,
897 hasHeaders);
898 }
899
900 // if stream is null, ExplicitSetUploadStream returns error.
901 // So we need special case for GET method.
902 StoreUploadStreamHasHeaders(false);
903 mRequestHead.SetMethod("GET"_ns); // revert to GET request
904 mUploadStream = nullptr;
905 return NS_OK;
906}
907
908namespace {
909
910class MIMEHeaderCopyVisitor final : public nsIHttpHeaderVisitor {
911 public:
912 explicit MIMEHeaderCopyVisitor(nsIMIMEInputStream* aDest) : mDest(aDest) {}
913
914 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:
915 NS_IMETHODvirtual nsresult VisitHeader(const nsACString& aName,
916 const nsACString& aValue) override {
917 return mDest->AddHeader(PromiseFlatCStringTPromiseFlatString<char>(aName).get(),
918 PromiseFlatCStringTPromiseFlatString<char>(aValue).get());
919 }
920
921 private:
922 ~MIMEHeaderCopyVisitor() = default;
923
924 nsCOMPtr<nsIMIMEInputStream> mDest;
925};
926
927NS_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"
, 927); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
927; __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"
, 927); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MIMEHeaderCopyVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 927; __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"
, 927); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 927
; __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"
, 927); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MIMEHeaderCopyVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 927; __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"
, 927); 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; }
928
929static void NormalizeCopyComplete(void* aClosure, nsresult aStatus) {
930#ifdef DEBUG1
931 // Called on the STS thread by NS_AsyncCopy
932 nsCOMPtr<nsIEventTarget> sts =
933 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/stream-transport-service;1");
934 bool result = false;
935 sts->IsOnCurrentThread(&result);
936 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"
, 936); AnnotateMozCrashReason("MOZ_ASSERT" "(" "result" ") ("
"Should only be called on the STS thread." ")"); do { *((volatile
int*)__null) = 936; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
937#endif
938
939 RefPtr<GenericPromise::Private> ready =
940 already_AddRefed(static_cast<GenericPromise::Private*>(aClosure));
941 if (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)))) {
942 ready->Resolve(true, __func__);
943 } else {
944 ready->Reject(aStatus, __func__);
945 }
946}
947
948// Normalize the upload stream for a HTTP channel, so that is one of the
949// expected and compatible types. Components like WebExtensions and DevTools
950// expect that upload streams in the parent process are cloneable, seekable, and
951// synchronous to read, which this function helps guarantee somewhat efficiently
952// and without loss of information.
953//
954// If the replacement stream outparameter is not initialized to `nullptr`, the
955// returned stream should be used instead of `aUploadStream` as the upload
956// stream for the HTTP channel, and the previous stream should not be touched
957// again.
958//
959// If aReadyPromise is non-nullptr after the function is called, it is a promise
960// which should be awaited before continuing to `AsyncOpen` the HTTP channel,
961// as the replacement stream will not be ready until it is resolved.
962static nsresult NormalizeUploadStream(nsIInputStream* aUploadStream,
963 nsIInputStream** aReplacementStream,
964 GenericPromise** aReadyPromise) {
965 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"
, 965); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 965; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
966
967 *aReplacementStream = nullptr;
968 *aReadyPromise = nullptr;
969
970 // Unwrap RemoteLazyInputStream and normalize the contents as we're in the
971 // parent process.
972 if (nsCOMPtr<mozIRemoteLazyInputStream> lazyStream =
973 do_QueryInterface(aUploadStream)) {
974 nsCOMPtr<nsIInputStream> internal;
975 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(lazyStream->TakeInternalStream
(getter_AddRefs(internal)))), 1)))
976 lazyStream->TakeInternalStream(getter_AddRefs(internal)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(lazyStream->TakeInternalStream
(getter_AddRefs(internal)))), 1)))
) {
977 nsCOMPtr<nsIInputStream> replacement;
978 nsresult rv = NormalizeUploadStream(internal, getter_AddRefs(replacement),
979 aReadyPromise);
980 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"
, 980); return rv; } } while (false)
;
981
982 if (replacement) {
983 replacement.forget(aReplacementStream);
984 } else {
985 internal.forget(aReplacementStream);
986 }
987 return NS_OK;
988 }
989 }
990
991 // Preserve MIME information on the stream when normalizing.
992 if (nsCOMPtr<nsIMIMEInputStream> mime = do_QueryInterface(aUploadStream)) {
993 nsCOMPtr<nsIInputStream> data;
994 nsresult rv = mime->GetData(getter_AddRefs(data));
995 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"
, 995); return rv; } } while (false)
;
996
997 nsCOMPtr<nsIInputStream> replacement;
998 rv =
999 NormalizeUploadStream(data, getter_AddRefs(replacement), aReadyPromise);
1000 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"
, 1000); return rv; } } while (false)
;
1001
1002 if (replacement) {
1003 nsCOMPtr<nsIMIMEInputStream> replacementMime(
1004 do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv));
1005 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"
, 1005); return rv; } } while (false)
;
1006
1007 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
1008 new MIMEHeaderCopyVisitor(replacementMime);
1009 rv = mime->VisitHeaders(visitor);
1010 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"
, 1010); return rv; } } while (false)
;
1011
1012 rv = replacementMime->SetData(replacement);
1013 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"
, 1013); return rv; } } while (false)
;
1014
1015 replacementMime.forget(aReplacementStream);
1016 }
1017 return NS_OK;
1018 }
1019
1020 // Preserve "real" buffered input streams which wrap data (i.e. are backed by
1021 // nsBufferedInputStream), but normalize the wrapped stream.
1022 if (nsCOMPtr<nsIBufferedInputStream> buffered =
1023 do_QueryInterface(aUploadStream)) {
1024 nsCOMPtr<nsIInputStream> data;
1025 if (NS_SUCCEEDED(buffered->GetData(getter_AddRefs(data)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(buffered->GetData
(getter_AddRefs(data)))), 1)))
) {
1026 nsCOMPtr<nsIInputStream> replacement;
1027 nsresult rv = NormalizeUploadStream(data, getter_AddRefs(replacement),
1028 aReadyPromise);
1029 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"
, 1029); return rv; } } while (false)
;
1030 if (replacement) {
1031 // This buffer size should be kept in sync with HTMLFormSubmission.
1032 rv = NS_NewBufferedInputStream(aReplacementStream, replacement.forget(),
1033 8192);
1034 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"
, 1034); return rv; } } while (false)
;
1035 }
1036 return NS_OK;
1037 }
1038 }
1039
1040 // Preserve multiplex input streams, normalizing each individual inner stream
1041 // to avoid unnecessary copying.
1042 if (nsCOMPtr<nsIMultiplexInputStream> multiplex =
1043 do_QueryInterface(aUploadStream)) {
1044 uint32_t count = multiplex->GetCount();
1045 nsTArray<nsCOMPtr<nsIInputStream>> streams(count);
1046 nsTArray<RefPtr<GenericPromise>> promises(count);
1047 bool replace = false;
1048 for (uint32_t i = 0; i < count; ++i) {
1049 nsCOMPtr<nsIInputStream> inner;
1050 nsresult rv = multiplex->GetStream(i, getter_AddRefs(inner));
1051 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"
, 1051); return rv; } } while (false)
;
1052
1053 RefPtr<GenericPromise> promise;
1054 nsCOMPtr<nsIInputStream> replacement;
1055 rv = NormalizeUploadStream(inner, getter_AddRefs(replacement),
1056 getter_AddRefs(promise));
1057 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1057); return rv; } } while (false)
;
1058 if (promise) {
1059 promises.AppendElement(promise);
1060 }
1061 if (replacement) {
1062 streams.AppendElement(replacement);
1063 replace = true;
1064 } else {
1065 streams.AppendElement(inner);
1066 }
1067 }
1068
1069 // If any of the inner streams needed to be replaced, replace the entire
1070 // nsIMultiplexInputStream.
1071 if (replace) {
1072 nsresult rv;
1073 nsCOMPtr<nsIMultiplexInputStream> replacement =
1074 do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1", &rv);
1075 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"
, 1075); return rv; } } while (false)
;
1076 for (auto& stream : streams) {
1077 rv = replacement->AppendStream(stream);
1078 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"
, 1078); return rv; } } while (false)
;
1079 }
1080
1081 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"
, 1081); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(CallQueryInterface(replacement, aReplacementStream))"
")"); do { *((volatile int*)__null) = 1081; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1082 }
1083
1084 // Wait for all inner promises to settle before resolving the final promise.
1085 if (!promises.IsEmpty()) {
1086 RefPtr<GenericPromise> ready =
1087 GenericPromise::AllSettled(GetCurrentSerialEventTarget(), promises)
1088 ->Then(GetCurrentSerialEventTarget(), __func__,
1089 [](GenericPromise::AllSettledPromiseType::
1090 ResolveOrRejectValue&& aResults)
1091 -> RefPtr<GenericPromise> {
1092 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"
, 1093); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aResults.IsResolve()"
") (" "AllSettled never rejects" ")"); do { *((volatile int*
)__null) = 1093; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1093 "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"
, 1093); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aResults.IsResolve()"
") (" "AllSettled never rejects" ")"); do { *((volatile int*
)__null) = 1093; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1094 for (auto& result : aResults.ResolveValue()) {
1095 if (result.IsReject()) {
1096 return GenericPromise::CreateAndReject(
1097 result.RejectValue(), __func__);
1098 }
1099 }
1100 return GenericPromise::CreateAndResolve(true, __func__);
1101 });
1102 ready.forget(aReadyPromise);
1103 }
1104 return NS_OK;
1105 }
1106
1107 // If the stream is cloneable, seekable and non-async, we can allow it. Async
1108 // input streams can cause issues, as various consumers of input streams
1109 // expect the payload to be synchronous and `Available()` to be the length of
1110 // the stream, which is not true for asynchronous streams.
1111 nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(aUploadStream);
1112 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(aUploadStream);
1113 if (NS_InputStreamIsCloneable(aUploadStream) && seekable && !async) {
1114 return NS_OK;
1115 }
1116
1117 // Asynchronously copy our non-normalized stream into a StorageStream so that
1118 // it is seekable, cloneable, and synchronous once the copy completes.
1119
1120 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"
, 1120)
;
1121
1122 nsCOMPtr<nsIStorageStream> storageStream;
1123 nsresult rv =
1124 NS_NewStorageStream(4096, UINT32_MAX(4294967295U), getter_AddRefs(storageStream));
1125 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"
, 1125); return rv; } } while (false)
;
1126
1127 nsCOMPtr<nsIOutputStream> sink;
1128 rv = storageStream->GetOutputStream(0, getter_AddRefs(sink));
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<nsIInputStream> replacementStream;
1132 rv = storageStream->NewInputStream(0, getter_AddRefs(replacementStream));
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 // Ensure the source stream is buffered before starting the copy so we can use
1136 // ReadSegments, as nsStorageStream doesn't implement WriteSegments.
1137 nsCOMPtr<nsIInputStream> source = aUploadStream;
1138 if (!NS_InputStreamIsBuffered(aUploadStream)) {
1139 nsCOMPtr<nsIInputStream> bufferedSource;
1140 rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedSource),
1141 source.forget(), 4096);
1142 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"
, 1142); return rv; } } while (false)
;
1143 source = bufferedSource.forget();
1144 }
1145
1146 // Perform an AsyncCopy into the input stream on the STS.
1147 nsCOMPtr<nsIEventTarget> target =
1148 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/stream-transport-service;1");
1149 RefPtr<GenericPromise::Private> ready = new GenericPromise::Private(__func__);
1150 rv = NS_AsyncCopy(source, sink, target, NS_ASYNCCOPY_VIA_READSEGMENTS, 4096,
1151 NormalizeCopyComplete, do_AddRef(ready).take());
1152 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"
, 1152)
) {
1153 ready.get()->Release();
1154 return rv;
1155 }
1156
1157 replacementStream.forget(aReplacementStream);
1158 ready.forget(aReadyPromise);
1159 return NS_OK;
1160}
1161
1162} // anonymous namespace
1163
1164NS_IMETHODIMPnsresult
1165HttpBaseChannel::CloneUploadStream(int64_t* aContentLength,
1166 nsIInputStream** aClonedStream) {
1167 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"
, 1167); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1168 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"
, 1168); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1169 *aClonedStream = nullptr;
1170
1171 if (!XRE_IsParentProcess()) {
1172 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"
, 1172)
;
1173 return NS_ERROR_NOT_AVAILABLE;
1174 }
1175
1176 if (!mUploadStream) {
1177 return NS_OK;
1178 }
1179
1180 nsCOMPtr<nsIInputStream> clonedStream;
1181 nsresult rv =
1182 NS_CloneInputStream(mUploadStream, getter_AddRefs(clonedStream));
1183 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"
, 1183); return rv; } } while (false)
;
1184
1185 clonedStream.forget(aClonedStream);
1186
1187 *aContentLength = mReqContentLength;
1188 return NS_OK;
1189}
1190
1191//-----------------------------------------------------------------------------
1192// HttpBaseChannel::nsIUploadChannel2
1193//-----------------------------------------------------------------------------
1194
1195NS_IMETHODIMPnsresult
1196HttpBaseChannel::ExplicitSetUploadStream(nsIInputStream* aStream,
1197 const nsACString& aContentType,
1198 int64_t aContentLength,
1199 const nsACString& aMethod,
1200 bool aStreamHasHeaders) {
1201 // Ensure stream is set and method is valid
1202 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"
, 1202); return NS_ERROR_FAILURE; } } while (false)
;
1203
1204 {
1205 DebugOnly<nsCOMPtr<nsIMIMEInputStream>> mimeStream;
1206 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"
, 1209); 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) = 1209; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
1207 !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"
, 1209); 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) = 1209; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
1208 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"
, 1209); 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) = 1209; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
1209 "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"
, 1209); 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) = 1209; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
1210 }
1211
1212 nsresult rv = SetRequestMethod(aMethod);
1213 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"
, 1213); return rv; } } while (false)
;
1214
1215 if (!aStreamHasHeaders && !aContentType.IsVoid()) {
1216 if (aContentType.IsEmpty()) {
1217 SetEmptyRequestHeader("Content-Type"_ns);
1218 } else {
1219 SetRequestHeader("Content-Type"_ns, aContentType, false);
1220 }
1221 }
1222
1223 StoreUploadStreamHasHeaders(aStreamHasHeaders);
1224
1225 return InternalSetUploadStream(aStream, aContentLength, !aStreamHasHeaders);
1226}
1227
1228nsresult HttpBaseChannel::InternalSetUploadStream(
1229 nsIInputStream* aUploadStream, int64_t aContentLength,
1230 bool aSetContentLengthHeader) {
1231 // If we're not on the main thread, such as for TRR, the content length must
1232 // be provided, as we can't normalize our upload stream.
1233 if (!NS_IsMainThread()) {
1234 if (aContentLength < 0) {
1235 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"
, 1236); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload content length must be explicit off-main-thread"
")"); do { *((volatile int*)__null) = 1236; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1236 "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"
, 1236); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload content length must be explicit off-main-thread"
")"); do { *((volatile int*)__null) = 1236; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1237 return NS_ERROR_INVALID_ARG;
1238 }
1239
1240 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(aUploadStream);
1241 if (!NS_InputStreamIsCloneable(aUploadStream) || !seekable) {
1242 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"
, 1243); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload stream must be cloneable & seekable off-main-thread"
")"); do { *((volatile int*)__null) = 1243; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1243 "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"
, 1243); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload stream must be cloneable & seekable off-main-thread"
")"); do { *((volatile int*)__null) = 1243; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1244 return NS_ERROR_INVALID_ARG;
1245 }
1246
1247 mUploadStream = aUploadStream;
1248 ExplicitSetUploadStreamLength(aContentLength, aSetContentLengthHeader);
1249 return NS_OK;
1250 }
1251
1252 // Normalize the upload stream we're provided to ensure that it is cloneable,
1253 // seekable, and synchronous when in the parent process.
1254 //
1255 // This might be an async operation, in which case ready will be returned and
1256 // resolved when the operation is complete.
1257 nsCOMPtr<nsIInputStream> replacement;
1258 RefPtr<GenericPromise> ready;
1259 if (XRE_IsParentProcess()) {
1260 nsresult rv = NormalizeUploadStream(
1261 aUploadStream, getter_AddRefs(replacement), getter_AddRefs(ready));
1262 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"
, 1262); return rv; } } while (false)
;
1263 }
1264
1265 mUploadStream = replacement ? replacement.get() : aUploadStream;
1266
1267 // Once the upload stream is ready, fetch its length before proceeding with
1268 // AsyncOpen.
1269 auto onReady = [self = RefPtr{this}, aContentLength, aSetContentLengthHeader,
1270 stream = mUploadStream]() {
1271 auto setLengthAndResume = [self, aSetContentLengthHeader](int64_t aLength) {
1272 self->StorePendingUploadStreamNormalization(false);
1273 self->ExplicitSetUploadStreamLength(aLength >= 0 ? aLength : 0,
1274 aSetContentLengthHeader);
1275 self->MaybeResumeAsyncOpen();
1276 };
1277
1278 if (aContentLength >= 0) {
1279 setLengthAndResume(aContentLength);
1280 return;
1281 }
1282
1283 int64_t length;
1284 if (InputStreamLengthHelper::GetSyncLength(stream, &length)) {
1285 setLengthAndResume(length);
1286 return;
1287 }
1288
1289 InputStreamLengthHelper::GetAsyncLength(stream, setLengthAndResume);
1290 };
1291 StorePendingUploadStreamNormalization(true);
1292
1293 // Resolve onReady synchronously unless a promise is returned.
1294 if (ready) {
1295 ready->Then(GetCurrentSerialEventTarget(), __func__,
1296 [onReady = std::move(onReady)](
1297 GenericPromise::ResolveOrRejectValue&&) { onReady(); });
1298 } else {
1299 onReady();
1300 }
1301 return NS_OK;
1302}
1303
1304void HttpBaseChannel::ExplicitSetUploadStreamLength(
1305 uint64_t aContentLength, bool aSetContentLengthHeader) {
1306 // We already have the content length. We don't need to determinate it.
1307 mReqContentLength = aContentLength;
1308
1309 if (!aSetContentLengthHeader) {
1310 return;
1311 }
1312
1313 nsAutoCString header;
1314 header.AssignLiteral("Content-Length");
1315
1316 // Maybe the content-length header has been already set.
1317 nsAutoCString value;
1318 nsresult rv = GetRequestHeader(header, value);
1319 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !value.IsEmpty()) {
1320 return;
1321 }
1322
1323 nsAutoCString contentLengthStr;
1324 contentLengthStr.AppendInt(aContentLength);
1325 SetRequestHeader(header, contentLengthStr, false);
1326}
1327
1328NS_IMETHODIMPnsresult
1329HttpBaseChannel::GetUploadStreamHasHeaders(bool* hasHeaders) {
1330 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"
, 1330); return NS_ERROR_INVALID_ARG; } } while (false)
;
1331
1332 *hasHeaders = LoadUploadStreamHasHeaders();
1333 return NS_OK;
1334}
1335
1336bool HttpBaseChannel::MaybeWaitForUploadStreamNormalization(
1337 nsIStreamListener* aListener, nsISupports* aContext) {
1338 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"
, 1338); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1338; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1339 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"
, 1340); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadAsyncOpenWaitingForStreamNormalization()"
") (" "AsyncOpen() called twice?" ")"); do { *((volatile int
*)__null) = 1340; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1340 "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"
, 1340); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadAsyncOpenWaitingForStreamNormalization()"
") (" "AsyncOpen() called twice?" ")"); do { *((volatile int
*)__null) = 1340; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1341
1342 if (!LoadPendingUploadStreamNormalization()) {
1343 return false;
1344 }
1345
1346 mListener = aListener;
1347 StoreAsyncOpenWaitingForStreamNormalization(true);
1348 return true;
1349}
1350
1351void HttpBaseChannel::MaybeResumeAsyncOpen() {
1352 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"
, 1352); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1352; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1353 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"
, 1353); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadPendingUploadStreamNormalization()"
")"); do { *((volatile int*)__null) = 1353; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1354
1355 if (!LoadAsyncOpenWaitingForStreamNormalization()) {
1356 return;
1357 }
1358
1359 nsCOMPtr<nsIStreamListener> listener;
1360 listener.swap(mListener);
1361
1362 StoreAsyncOpenWaitingForStreamNormalization(false);
1363
1364 nsresult rv = AsyncOpen(listener);
1365 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"
, 1365)
) {
1366 DoAsyncAbort(rv);
1367 }
1368}
1369
1370//-----------------------------------------------------------------------------
1371// HttpBaseChannel::nsIEncodedChannel
1372//-----------------------------------------------------------------------------
1373
1374NS_IMETHODIMPnsresult
1375HttpBaseChannel::GetApplyConversion(bool* value) {
1376 *value = LoadApplyConversion();
1377 return NS_OK;
1378}
1379
1380NS_IMETHODIMPnsresult
1381HttpBaseChannel::SetApplyConversion(bool value) {
1382 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)
1383 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)
;
1384 StoreApplyConversion(value);
1385 return NS_OK;
1386}
1387
1388nsresult HttpBaseChannel::DoApplyContentConversions(
1389 nsIStreamListener* aNextListener, nsIStreamListener** aNewNextListener) {
1390 return DoApplyContentConversions(aNextListener, aNewNextListener, nullptr);
1391}
1392
1393// create a listener chain that looks like this
1394// http-channel -> decompressor (n times) -> InterceptFailedOnSTop ->
1395// channel-creator-listener
1396//
1397// we need to do this because not every decompressor has fully streamed output
1398// so may need a call to OnStopRequest to identify its completion state.. and if
1399// it creates an error there the channel status code needs to be updated before
1400// calling the terminal listener. Having the decompress do it via cancel() means
1401// channels cannot effectively be used in two contexts (specifically this one
1402// and a peek context for sniffing)
1403//
1404class InterceptFailedOnStop : public nsIThreadRetargetableStreamListener {
1405 virtual ~InterceptFailedOnStop() = default;
1406 nsCOMPtr<nsIStreamListener> mNext;
1407 HttpBaseChannel* mChannel;
1408
1409 public:
1410 InterceptFailedOnStop(nsIStreamListener* arg, HttpBaseChannel* chan)
1411 : mNext(arg), mChannel(chan) {}
1412 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:
1413 NS_DECL_NSITHREADRETARGETABLESTREAMLISTENERvirtual nsresult CheckListenerChain(void) override; virtual nsresult
OnDataFinished(nsresult aStatusCode) override;
1414
1415 NS_IMETHODvirtual nsresult OnStartRequest(nsIRequest* aRequest) override {
1416 return mNext->OnStartRequest(aRequest);
1417 }
1418
1419 NS_IMETHODvirtual nsresult OnStopRequest(nsIRequest* aRequest,
1420 nsresult aStatusCode) override {
1421 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)))
) {
1422 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)
1423 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)
;
1424 mChannel->mStatus = aStatusCode;
1425 }
1426 return mNext->OnStopRequest(aRequest, aStatusCode);
1427 }
1428
1429 NS_IMETHODvirtual nsresult OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
1430 uint64_t aOffset, uint32_t aCount) override {
1431 return mNext->OnDataAvailable(aRequest, aInputStream, aOffset, aCount);
1432 }
1433};
1434
1435NS_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"
, 1435); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1435; __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"
, 1435); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"InterceptFailedOnStop\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1435; __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; }
1436NS_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"
, 1436); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1436
; __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"
, 1436); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"InterceptFailedOnStop\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1436; __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; }
1437
1438NS_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"
, 1438); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
1439 NS_INTERFACE_MAP_ENTRY(nsIStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIStreamListener>)) foundInterface
= static_cast<nsIStreamListener*>(this); else
1440 NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequestObserver>)) foundInterface
= static_cast<nsIRequestObserver*>(this); else
1441 NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThreadRetargetableStreamListener>
)) foundInterface = static_cast<nsIThreadRetargetableStreamListener
*>(this); else
1442 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
1443NS_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"
, 1443); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
")"); do { *((volatile int*)__null) = 1443; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
1444
1445NS_IMETHODIMPnsresult
1446InterceptFailedOnStop::CheckListenerChain() {
1447 nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
1448 do_QueryInterface(mNext);
1449 if (!listener) {
1450 return NS_ERROR_NO_INTERFACE;
1451 }
1452
1453 return listener->CheckListenerChain();
1454}
1455
1456NS_IMETHODIMPnsresult
1457InterceptFailedOnStop::OnDataFinished(nsresult aStatus) {
1458 nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
1459 do_QueryInterface(mNext);
1460 if (listener) {
1461 return listener->OnDataFinished(aStatus);
1462 }
1463
1464 return NS_OK;
1465}
1466
1467NS_IMETHODIMPnsresult
1468HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
1469 nsIStreamListener** aNewNextListener,
1470 nsISupports* aCtxt) {
1471 *aNewNextListener = nullptr;
1472 if (!mResponseHead || !aNextListener) {
1473 return NS_OK;
1474 }
1475
1476 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)
;
1477
1478 if (!LoadApplyConversion()) {
1479 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)
;
1480 return NS_OK;
1481 }
1482
1483 if (LoadHasAppliedConversion()) {
1484 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)
;
1485 return NS_OK;
1486 }
1487
1488 if (LoadDeliveringAltData()) {
1489 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"
, 1489); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mAvailableCachedAltDataType.IsEmpty()"
")"); do { *((volatile int*)__null) = 1489; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1490 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)
;
1491 return NS_OK;
1492 }
1493
1494 nsAutoCString contentEncoding;
1495 nsresult rv =
1496 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
1497 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || contentEncoding.IsEmpty()) return NS_OK;
1498
1499 nsCOMPtr<nsIStreamListener> nextListener =
1500 new InterceptFailedOnStop(aNextListener, this);
1501
1502 // The encodings are listed in the order they were applied
1503 // (see rfc 2616 section 14.11), so they need to removed in reverse
1504 // order. This is accomplished because the converter chain ends up
1505 // being a stack with the last converter created being the first one
1506 // to accept the raw network data.
1507
1508 char* cePtr = contentEncoding.BeginWriting();
1509 uint32_t count = 0;
1510 while (char* val = nsCRT::strtok(cePtr, HTTP_LWS" \t" ",", &cePtr)) {
1511 if (++count > 16) {
1512 // That's ridiculous. We only understand 2 different ones :)
1513 // but for compatibility with old code, we will just carry on without
1514 // removing the encodings
1515 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)
;
1516 break;
1517 }
1518
1519 if (gHttpHandler->IsAcceptableEncoding(val,
1520 isSecureOrTrustworthyURL(mURI))) {
1521 RefPtr<nsHTTPCompressConv> converter = new nsHTTPCompressConv();
1522 nsAutoCString from(val);
1523 ToLowerCase(from);
1524 rv = converter->AsyncConvertData(from.get(), "uncompressed", nextListener,
1525 aCtxt);
1526 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1527 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)
;
1528 return rv;
1529 }
1530
1531 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)
;
1532 if (Telemetry::CanRecordPrereleaseData()) {
1533 int mode = 0;
1534 if (from.EqualsLiteral("gzip") || from.EqualsLiteral("x-gzip")) {
1535 mode = 1;
1536 } else if (from.EqualsLiteral("deflate") ||
1537 from.EqualsLiteral("x-deflate")) {
1538 mode = 2;
1539 } else if (from.EqualsLiteral("br")) {
1540 mode = 3;
1541 } else if (from.EqualsLiteral("zstd")) {
1542 mode = 4;
1543 }
1544 Telemetry::Accumulate(Telemetry::HTTP_CONTENT_ENCODING, mode);
1545 }
1546 nextListener = converter;
1547 } else {
1548 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)
;
1549 }
1550 }
1551 *aNewNextListener = do_AddRef(nextListener).take();
1552 return NS_OK;
1553}
1554
1555NS_IMETHODIMPnsresult
1556HttpBaseChannel::GetContentEncodings(nsIUTF8StringEnumerator** aEncodings) {
1557 if (!mResponseHead) {
1558 *aEncodings = nullptr;
1559 return NS_OK;
1560 }
1561
1562 nsAutoCString encoding;
1563 Unused << mResponseHead->GetHeader(nsHttp::Content_Encoding, encoding);
1564 if (encoding.IsEmpty()) {
1565 *aEncodings = nullptr;
1566 return NS_OK;
1567 }
1568 RefPtr<nsContentEncodings> enumerator =
1569 new nsContentEncodings(this, encoding.get());
1570 enumerator.forget(aEncodings);
1571 return NS_OK;
1572}
1573
1574//-----------------------------------------------------------------------------
1575// HttpBaseChannel::nsContentEncodings <public>
1576//-----------------------------------------------------------------------------
1577
1578HttpBaseChannel::nsContentEncodings::nsContentEncodings(
1579 nsIHttpChannel* aChannel, const char* aEncodingHeader)
1580 : mEncodingHeader(aEncodingHeader), mChannel(aChannel), mReady(false) {
1581 mCurEnd = aEncodingHeader + strlen(aEncodingHeader);
1582 mCurStart = mCurEnd;
1583}
1584
1585//-----------------------------------------------------------------------------
1586// HttpBaseChannel::nsContentEncodings::nsISimpleEnumerator
1587//-----------------------------------------------------------------------------
1588
1589NS_IMETHODIMPnsresult
1590HttpBaseChannel::nsContentEncodings::HasMore(bool* aMoreEncodings) {
1591 if (mReady) {
1592 *aMoreEncodings = true;
1593 return NS_OK;
1594 }
1595
1596 nsresult rv = PrepareForNext();
1597 *aMoreEncodings = NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)));
1598 return NS_OK;
1599}
1600
1601NS_IMETHODIMPnsresult
1602HttpBaseChannel::nsContentEncodings::GetNext(nsACString& aNextEncoding) {
1603 aNextEncoding.Truncate();
1604 if (!mReady) {
1605 nsresult rv = PrepareForNext();
1606 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1607 return NS_ERROR_FAILURE;
1608 }
1609 }
1610
1611 const nsACString& encoding = Substring(mCurStart, mCurEnd);
1612
1613 nsACString::const_iterator start, end;
1614 encoding.BeginReading(start);
1615 encoding.EndReading(end);
1616
1617 bool haveType = false;
1618 if (CaseInsensitiveFindInReadable("gzip"_ns, start, end)) {
1619 aNextEncoding.AssignLiteral(APPLICATION_GZIP"application/x-gzip");
1620 haveType = true;
1621 }
1622
1623 if (!haveType) {
1624 encoding.BeginReading(start);
1625 if (CaseInsensitiveFindInReadable("compress"_ns, start, end)) {
1626 aNextEncoding.AssignLiteral(APPLICATION_COMPRESS"application/x-compress");
1627 haveType = true;
1628 }
1629 }
1630
1631 if (!haveType) {
1632 encoding.BeginReading(start);
1633 if (CaseInsensitiveFindInReadable("deflate"_ns, start, end)) {
1634 aNextEncoding.AssignLiteral(APPLICATION_ZIP"application/zip");
1635 haveType = true;
1636 }
1637 }
1638
1639 if (!haveType) {
1640 encoding.BeginReading(start);
1641 if (CaseInsensitiveFindInReadable("br"_ns, start, end)) {
1642 aNextEncoding.AssignLiteral(APPLICATION_BROTLI"application/brotli");
1643 haveType = true;
1644 }
1645 }
1646
1647 if (!haveType) {
1648 encoding.BeginReading(start);
1649 if (CaseInsensitiveFindInReadable("zstd"_ns, start, end)) {
1650 aNextEncoding.AssignLiteral(APPLICATION_ZSTD"application/zstd");
1651 haveType = true;
1652 }
1653 }
1654
1655 // Prepare to fetch the next encoding
1656 mCurEnd = mCurStart;
1657 mReady = false;
1658
1659 if (haveType) return NS_OK;
1660
1661 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"
, 1661)
;
1662 return NS_ERROR_FAILURE;
1663}
1664
1665//-----------------------------------------------------------------------------
1666// HttpBaseChannel::nsContentEncodings::nsISupports
1667//-----------------------------------------------------------------------------
1668
1669NS_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"
, 1670); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1670; __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"
, 1670); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1670; __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"
, 1670); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1670
; __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"
, 1670); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1670; __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"
, 1670); 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; }
1670 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"
, 1670); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1670; __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"
, 1670); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1670; __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"
, 1670); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1670
; __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"
, 1670); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1670; __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"
, 1670); 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; }
1671
1672//-----------------------------------------------------------------------------
1673// HttpBaseChannel::nsContentEncodings <private>
1674//-----------------------------------------------------------------------------
1675
1676nsresult HttpBaseChannel::nsContentEncodings::PrepareForNext(void) {
1677 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"
, 1677); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurStart == mCurEnd"
") (" "Indeterminate state" ")"); do { *((volatile int*)__null
) = 1677; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
1678
1679 // At this point both mCurStart and mCurEnd point to somewhere
1680 // past the end of the next thing we want to return
1681
1682 while (mCurEnd != mEncodingHeader) {
1683 --mCurEnd;
1684 if (*mCurEnd != ',' && !nsCRT::IsAsciiSpace(*mCurEnd)) break;
1685 }
1686 if (mCurEnd == mEncodingHeader) {
1687 return NS_ERROR_NOT_AVAILABLE; // no more encodings
1688 }
1689 ++mCurEnd;
1690
1691 // At this point mCurEnd points to the first char _after_ the
1692 // header we want. Furthermore, mCurEnd - 1 != mEncodingHeader
1693
1694 mCurStart = mCurEnd - 1;
1695 while (mCurStart != mEncodingHeader && *mCurStart != ',' &&
1696 !nsCRT::IsAsciiSpace(*mCurStart)) {
1697 --mCurStart;
1698 }
1699 if (*mCurStart == ',' || nsCRT::IsAsciiSpace(*mCurStart)) {
1700 ++mCurStart; // we stopped because of a weird char, so move up one
1701 }
1702
1703 // At this point mCurStart and mCurEnd bracket the encoding string
1704 // we want. Check that it's not "identity"
1705 if (Substring(mCurStart, mCurEnd)
1706 .Equals("identity", nsCaseInsensitiveCStringComparator)) {
1707 mCurEnd = mCurStart;
1708 return PrepareForNext();
1709 }
1710
1711 mReady = true;
1712 return NS_OK;
1713}
1714
1715//-----------------------------------------------------------------------------
1716// HttpBaseChannel::nsIHttpChannel
1717//-----------------------------------------------------------------------------
1718
1719NS_IMETHODIMPnsresult
1720HttpBaseChannel::GetChannelId(uint64_t* aChannelId) {
1721 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"
, 1721); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1722 *aChannelId = mChannelId;
1723 return NS_OK;
1724}
1725
1726NS_IMETHODIMPnsresult
1727HttpBaseChannel::SetChannelId(uint64_t aChannelId) {
1728 mChannelId = aChannelId;
1729 return NS_OK;
1730}
1731
1732NS_IMETHODIMPnsresult HttpBaseChannel::GetTopLevelContentWindowId(uint64_t* aWindowId) {
1733 if (!mContentWindowId) {
1734 nsCOMPtr<nsILoadContext> loadContext;
1735 GetCallback(loadContext);
1736 if (loadContext) {
1737 nsCOMPtr<mozIDOMWindowProxy> topWindow;
1738 loadContext->GetTopWindow(getter_AddRefs(topWindow));
1739 if (topWindow) {
1740 if (nsPIDOMWindowInner* inner =
1741 nsPIDOMWindowOuter::From(topWindow)->GetCurrentInnerWindow()) {
1742 mContentWindowId = inner->WindowID();
1743 }
1744 }
1745 }
1746 }
1747 *aWindowId = mContentWindowId;
1748 return NS_OK;
1749}
1750
1751NS_IMETHODIMPnsresult HttpBaseChannel::SetBrowserId(uint64_t aId) {
1752 mBrowserId = aId;
1753 return NS_OK;
1754}
1755
1756NS_IMETHODIMPnsresult HttpBaseChannel::GetBrowserId(uint64_t* aId) {
1757 EnsureBrowserId();
1758 *aId = mBrowserId;
1759 return NS_OK;
1760}
1761
1762NS_IMETHODIMPnsresult HttpBaseChannel::SetTopLevelContentWindowId(uint64_t aWindowId) {
1763 mContentWindowId = aWindowId;
1764 return NS_OK;
1765}
1766
1767NS_IMETHODIMPnsresult
1768HttpBaseChannel::IsThirdPartyTrackingResource(bool* aIsTrackingResource) {
1769 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"
, 1770); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags)"
")"); do { *((volatile int*)__null) = 1770; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1770 !(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"
, 1770); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags)"
")"); do { *((volatile int*)__null) = 1770; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1771 *aIsTrackingResource = UrlClassifierCommon::IsTrackingClassificationFlag(
1772 mThirdPartyClassificationFlags,
1773 mLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0);
1774 return NS_OK;
1775}
1776
1777NS_IMETHODIMPnsresult
1778HttpBaseChannel::IsThirdPartySocialTrackingResource(
1779 bool* aIsThirdPartySocialTrackingResource) {
1780 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"
, 1781); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { *((volatile int*)__null) = 1781; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1781 !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"
, 1781); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { *((volatile int*)__null) = 1781; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1782 *aIsThirdPartySocialTrackingResource =
1783 UrlClassifierCommon::IsSocialTrackingClassificationFlag(
1784 mThirdPartyClassificationFlags);
1785 return NS_OK;
1786}
1787
1788NS_IMETHODIMPnsresult
1789HttpBaseChannel::GetClassificationFlags(uint32_t* aFlags) {
1790 if (mThirdPartyClassificationFlags) {
1791 *aFlags = mThirdPartyClassificationFlags;
1792 } else {
1793 *aFlags = mFirstPartyClassificationFlags;
1794 }
1795 return NS_OK;
1796}
1797
1798NS_IMETHODIMPnsresult
1799HttpBaseChannel::GetFirstPartyClassificationFlags(uint32_t* aFlags) {
1800 *aFlags = mFirstPartyClassificationFlags;
1801 return NS_OK;
1802}
1803
1804NS_IMETHODIMPnsresult
1805HttpBaseChannel::GetThirdPartyClassificationFlags(uint32_t* aFlags) {
1806 *aFlags = mThirdPartyClassificationFlags;
1807 return NS_OK;
1808}
1809
1810NS_IMETHODIMPnsresult
1811HttpBaseChannel::GetTransferSize(uint64_t* aTransferSize) {
1812 MutexAutoLock lock(mOnDataFinishedMutex);
1813 *aTransferSize = mTransferSize;
1814 return NS_OK;
1815}
1816
1817NS_IMETHODIMPnsresult
1818HttpBaseChannel::GetRequestSize(uint64_t* aRequestSize) {
1819 *aRequestSize = mRequestSize;
1820 return NS_OK;
1821}
1822
1823NS_IMETHODIMPnsresult
1824HttpBaseChannel::GetDecodedBodySize(uint64_t* aDecodedBodySize) {
1825 *aDecodedBodySize = mDecodedBodySize;
1826 return NS_OK;
1827}
1828
1829NS_IMETHODIMPnsresult
1830HttpBaseChannel::GetEncodedBodySize(uint64_t* aEncodedBodySize) {
1831 MutexAutoLock lock(mOnDataFinishedMutex);
1832 *aEncodedBodySize = mEncodedBodySize;
1833 return NS_OK;
1834}
1835
1836NS_IMETHODIMPnsresult
1837HttpBaseChannel::GetSupportsHTTP3(bool* aSupportsHTTP3) {
1838 *aSupportsHTTP3 = mSupportsHTTP3;
1839 return NS_OK;
1840}
1841
1842NS_IMETHODIMPnsresult
1843HttpBaseChannel::GetHasHTTPSRR(bool* aHasHTTPSRR) {
1844 *aHasHTTPSRR = LoadHasHTTPSRR();
1845 return NS_OK;
1846}
1847
1848NS_IMETHODIMPnsresult
1849HttpBaseChannel::GetRequestMethod(nsACString& aMethod) {
1850 mRequestHead.Method(aMethod);
1851 return NS_OK;
1852}
1853
1854NS_IMETHODIMPnsresult
1855HttpBaseChannel::SetRequestMethod(const nsACString& aMethod) {
1856 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"
, 1856); 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"
, 1856, 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"
, 1856); } } 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"
, 1856); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 1856; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
1857
1858 const nsCString& flatMethod = PromiseFlatCStringTPromiseFlatString<char>(aMethod);
1859
1860 // Method names are restricted to valid HTTP tokens.
1861 if (!nsHttp::IsValidToken(flatMethod)) return NS_ERROR_INVALID_ARG;
1862
1863 mRequestHead.SetMethod(flatMethod);
1864 return NS_OK;
1865}
1866
1867NS_IMETHODIMPnsresult
1868HttpBaseChannel::GetReferrerInfo(nsIReferrerInfo** aReferrerInfo) {
1869 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"
, 1869); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1870 *aReferrerInfo = do_AddRef(mReferrerInfo).take();
1871 return NS_OK;
1872}
1873
1874nsresult HttpBaseChannel::SetReferrerInfoInternal(
1875 nsIReferrerInfo* aReferrerInfo, bool aClone, bool aCompute,
1876 bool aRespectBeforeConnect) {
1877 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)
1878 ("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)
1879 "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)
1880 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)
;
1881 if (aRespectBeforeConnect) {
1882 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"
, 1882); 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"
, 1882, 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"
, 1882); } } 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"
, 1882); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 1882; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
1883 }
1884
1885 mReferrerInfo = aReferrerInfo;
1886
1887 // clear existing referrer, if any
1888 nsresult rv = ClearReferrerHeader();
1889 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"
, 1889)
) {
1890 return rv;
1891 }
1892
1893 if (!mReferrerInfo) {
1894 return NS_OK;
1895 }
1896
1897 if (aClone) {
1898 mReferrerInfo = static_cast<dom::ReferrerInfo*>(aReferrerInfo)->Clone();
1899 }
1900
1901 dom::ReferrerInfo* referrerInfo =
1902 static_cast<dom::ReferrerInfo*>(mReferrerInfo.get());
1903
1904 // Don't set referrerInfo if it has not been initialized.
1905 if (!referrerInfo->IsInitialized()) {
1906 mReferrerInfo = nullptr;
1907 return NS_ERROR_NOT_INITIALIZED;
1908 }
1909
1910 if (aClone) {
1911 // Record the telemetry once we set the referrer info to the channel
1912 // successfully.
1913 referrerInfo->RecordTelemetry(this);
1914 }
1915
1916 if (aCompute) {
1917 rv = referrerInfo->ComputeReferrer(this);
1918 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"
, 1918)
) {
1919 return rv;
1920 }
1921 }
1922
1923 nsCOMPtr<nsIURI> computedReferrer = mReferrerInfo->GetComputedReferrer();
1924 if (!computedReferrer) {
1925 return NS_OK;
1926 }
1927
1928 nsAutoCString spec;
1929 rv = computedReferrer->GetSpec(spec);
1930 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"
, 1930)
) {
1931 return rv;
1932 }
1933
1934 return SetReferrerHeader(spec, aRespectBeforeConnect);
1935}
1936
1937NS_IMETHODIMPnsresult
1938HttpBaseChannel::SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
1939 return SetReferrerInfoInternal(aReferrerInfo, true, true, true);
1940}
1941
1942NS_IMETHODIMPnsresult
1943HttpBaseChannel::SetReferrerInfoWithoutClone(nsIReferrerInfo* aReferrerInfo) {
1944 return SetReferrerInfoInternal(aReferrerInfo, false, true, true);
1945}
1946
1947// Return the channel's proxy URI, or if it doesn't exist, the
1948// channel's main URI.
1949NS_IMETHODIMPnsresult
1950HttpBaseChannel::GetProxyURI(nsIURI** aOut) {
1951 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"
, 1951); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1952 nsCOMPtr<nsIURI> result(mProxyURI);
1953 result.forget(aOut);
1954 return NS_OK;
1955}
1956
1957NS_IMETHODIMPnsresult
1958HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
1959 nsACString& aValue) {
1960 aValue.Truncate();
1961
1962 // XXX might be better to search the header list directly instead of
1963 // hitting the http atom hash table.
1964 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
1965 if (!atom) return NS_ERROR_NOT_AVAILABLE;
1966
1967 return mRequestHead.GetHeader(atom, aValue);
1968}
1969
1970NS_IMETHODIMPnsresult
1971HttpBaseChannel::SetRequestHeader(const nsACString& aHeader,
1972 const nsACString& aValue, bool aMerge) {
1973 const nsCString& flatHeader = PromiseFlatCStringTPromiseFlatString<char>(aHeader);
1974 const nsCString& flatValue = PromiseFlatCStringTPromiseFlatString<char>(aValue);
1975
1976 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)
1977 ("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)
1978 "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)
1979 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)
;
1980
1981 // Verify header names are valid HTTP tokens and header values are reasonably
1982 // close to whats allowed in RFC 2616.
1983 if (!nsHttp::IsValidToken(flatHeader) ||
1984 !nsHttp::IsReasonableHeaderValue(flatValue)) {
1985 return NS_ERROR_INVALID_ARG;
1986 }
1987
1988 // Mark that the User-Agent header has been modified.
1989 if (nsHttp::ResolveAtom(aHeader) == nsHttp::User_Agent) {
1990 StoreIsUserAgentHeaderModified(true);
1991 }
1992
1993 return mRequestHead.SetHeader(aHeader, flatValue, aMerge);
1994}
1995
1996NS_IMETHODIMPnsresult
1997HttpBaseChannel::SetNewReferrerInfo(const nsACString& aUrl,
1998 nsIReferrerInfo::ReferrerPolicyIDL aPolicy,
1999 bool aSendReferrer) {
2000 nsresult rv;
2001 // Create URI from string
2002 nsCOMPtr<nsIURI> aURI;
2003 rv = NS_NewURI(getter_AddRefs(aURI), aUrl);
2004 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"
, 2004); return rv; } } while (false)
;
2005 // Create new ReferrerInfo and initialize it.
2006 nsCOMPtr<nsIReferrerInfo> referrerInfo = new mozilla::dom::ReferrerInfo();
2007 rv = referrerInfo->Init(aPolicy, aSendReferrer, aURI);
2008 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"
, 2008); return rv; } } while (false)
;
2009 // Set ReferrerInfo
2010 return SetReferrerInfo(referrerInfo);
2011}
2012
2013NS_IMETHODIMPnsresult
2014HttpBaseChannel::SetEmptyRequestHeader(const nsACString& aHeader) {
2015 const nsCString& flatHeader = PromiseFlatCStringTPromiseFlatString<char>(aHeader);
2016
2017 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)
2018 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)
;
2019
2020 // Verify header names are valid HTTP tokens and header values are reasonably
2021 // close to whats allowed in RFC 2616.
2022 if (!nsHttp::IsValidToken(flatHeader)) {
2023 return NS_ERROR_INVALID_ARG;
2024 }
2025
2026 // Mark that the User-Agent header has been modified.
2027 if (nsHttp::ResolveAtom(aHeader) == nsHttp::User_Agent) {
2028 StoreIsUserAgentHeaderModified(true);
2029 }
2030
2031 return mRequestHead.SetEmptyHeader(aHeader);
2032}
2033
2034NS_IMETHODIMPnsresult
2035HttpBaseChannel::VisitRequestHeaders(nsIHttpHeaderVisitor* visitor) {
2036 return mRequestHead.VisitHeaders(visitor);
2037}
2038
2039NS_IMETHODIMPnsresult
2040HttpBaseChannel::VisitNonDefaultRequestHeaders(nsIHttpHeaderVisitor* visitor) {
2041 return mRequestHead.VisitHeaders(visitor,
2042 nsHttpHeaderArray::eFilterSkipDefault);
2043}
2044
2045NS_IMETHODIMPnsresult
2046HttpBaseChannel::GetResponseHeader(const nsACString& header,
2047 nsACString& value) {
2048 value.Truncate();
2049
2050 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2051
2052 nsHttpAtom atom = nsHttp::ResolveAtom(header);
2053 if (!atom) return NS_ERROR_NOT_AVAILABLE;
2054
2055 return mResponseHead->GetHeader(atom, value);
2056}
2057
2058NS_IMETHODIMPnsresult
2059HttpBaseChannel::SetResponseHeader(const nsACString& header,
2060 const nsACString& value, bool merge) {
2061 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)
2062 ("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)
2063 "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)
2064 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)
2065 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)
;
2066
2067 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2068
2069 nsHttpAtom atom = nsHttp::ResolveAtom(header);
2070 if (!atom) return NS_ERROR_NOT_AVAILABLE;
2071
2072 // these response headers must not be changed
2073 if (atom == nsHttp::Content_Type || atom == nsHttp::Content_Length ||
2074 atom == nsHttp::Content_Encoding || atom == nsHttp::Trailer ||
2075 atom == nsHttp::Transfer_Encoding) {
2076 return NS_ERROR_ILLEGAL_VALUE;
2077 }
2078
2079 StoreResponseHeadersModified(true);
2080
2081 return mResponseHead->SetHeader(header, value, merge);
2082}
2083
2084NS_IMETHODIMPnsresult
2085HttpBaseChannel::VisitResponseHeaders(nsIHttpHeaderVisitor* visitor) {
2086 if (!mResponseHead) {
2087 return NS_ERROR_NOT_AVAILABLE;
2088 }
2089 return mResponseHead->VisitHeaders(visitor,
2090 nsHttpHeaderArray::eFilterResponse);
2091}
2092
2093NS_IMETHODIMPnsresult
2094HttpBaseChannel::GetOriginalResponseHeader(const nsACString& aHeader,
2095 nsIHttpHeaderVisitor* aVisitor) {
2096 if (!mResponseHead) {
2097 return NS_ERROR_NOT_AVAILABLE;
2098 }
2099
2100 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
2101 if (!atom) {
2102 return NS_ERROR_NOT_AVAILABLE;
2103 }
2104
2105 return mResponseHead->GetOriginalHeader(atom, aVisitor);
2106}
2107
2108NS_IMETHODIMPnsresult
2109HttpBaseChannel::VisitOriginalResponseHeaders(nsIHttpHeaderVisitor* aVisitor) {
2110 if (!mResponseHead) {
2111 return NS_ERROR_NOT_AVAILABLE;
2112 }
2113
2114 return mResponseHead->VisitHeaders(
2115 aVisitor, nsHttpHeaderArray::eFilterResponseOriginal);
2116}
2117
2118NS_IMETHODIMPnsresult
2119HttpBaseChannel::GetAllowSTS(bool* value) {
2120 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"
, 2120); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2121 *value = LoadAllowSTS();
2122 return NS_OK;
2123}
2124
2125NS_IMETHODIMPnsresult
2126HttpBaseChannel::SetAllowSTS(bool value) {
2127 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"
, 2127); 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"
, 2127, 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"
, 2127); } } 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"
, 2127); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2127; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2128 StoreAllowSTS(value);
2129 return NS_OK;
2130}
2131
2132NS_IMETHODIMPnsresult
2133HttpBaseChannel::GetIsOCSP(bool* value) {
2134 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"
, 2134); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2135 *value = LoadIsOCSP();
2136 return NS_OK;
2137}
2138
2139NS_IMETHODIMPnsresult
2140HttpBaseChannel::SetIsOCSP(bool value) {
2141 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"
, 2141); 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"
, 2141, 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"
, 2141); } } 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"
, 2141); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2141; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2142 StoreIsOCSP(value);
2143 return NS_OK;
2144}
2145
2146NS_IMETHODIMPnsresult
2147HttpBaseChannel::GetIsUserAgentHeaderModified(bool* value) {
2148 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"
, 2148); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2149 *value = LoadIsUserAgentHeaderModified();
2150 return NS_OK;
2151}
2152
2153NS_IMETHODIMPnsresult
2154HttpBaseChannel::SetIsUserAgentHeaderModified(bool value) {
2155 StoreIsUserAgentHeaderModified(value);
2156 return NS_OK;
2157}
2158
2159NS_IMETHODIMPnsresult
2160HttpBaseChannel::GetRedirectionLimit(uint32_t* value) {
2161 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"
, 2161); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2162 *value = mRedirectionLimit;
2163 return NS_OK;
2164}
2165
2166NS_IMETHODIMPnsresult
2167HttpBaseChannel::SetRedirectionLimit(uint32_t value) {
2168 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"
, 2168); 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"
, 2168, 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"
, 2168); } } 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"
, 2168); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2168; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2169
2170 mRedirectionLimit = std::min<uint32_t>(value, 0xff);
2171 return NS_OK;
2172}
2173
2174nsresult HttpBaseChannel::OverrideSecurityInfo(
2175 nsITransportSecurityInfo* aSecurityInfo) {
2176 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"
, 2178); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { *((volatile int*)__null) = 2178;
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
2177 "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"
, 2178); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { *((volatile int*)__null) = 2178;
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
2178 "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"
, 2178); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { *((volatile int*)__null) = 2178;
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
2179 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"
, 2181); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { *((volatile int*)__null) = 2181; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2180 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"
, 2181); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { *((volatile int*)__null) = 2181; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2181 "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"
, 2181); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { *((volatile int*)__null) = 2181; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2182 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"
, 2184); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { *((volatile int*)__null) = 2184; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2183 "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"
, 2184); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { *((volatile int*)__null) = 2184; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2184 "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"
, 2184); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { *((volatile int*)__null) = 2184; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
2185 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"
, 2186); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadResponseCouldBeSynthesized()"
") (" "This can only be called on channels that can be intercepted"
")"); do { *((volatile int*)__null) = 2186; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2186 "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"
, 2186); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadResponseCouldBeSynthesized()"
") (" "This can only be called on channels that can be intercepted"
")"); do { *((volatile int*)__null) = 2186; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2187 if (mSecurityInfo) {
2188 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)
2189 ("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)
2190 "[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)
2191 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)
;
2192 return NS_ERROR_UNEXPECTED;
2193 }
2194 if (!LoadResponseCouldBeSynthesized()) {
2195 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)
2196 ("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)
2197 "[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)
2198 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)
;
2199 return NS_ERROR_UNEXPECTED;
2200 }
2201
2202 mSecurityInfo = aSecurityInfo;
2203 return NS_OK;
2204}
2205
2206NS_IMETHODIMPnsresult
2207HttpBaseChannel::IsNoStoreResponse(bool* value) {
2208 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2209 *value = mResponseHead->NoStore();
2210 return NS_OK;
2211}
2212
2213NS_IMETHODIMPnsresult
2214HttpBaseChannel::IsNoCacheResponse(bool* value) {
2215 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2216 *value = mResponseHead->NoCache();
2217 if (!*value) *value = mResponseHead->ExpiresInPast();
2218 return NS_OK;
2219}
2220
2221NS_IMETHODIMPnsresult
2222HttpBaseChannel::IsPrivateResponse(bool* value) {
2223 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2224 *value = mResponseHead->Private();
2225 return NS_OK;
2226}
2227
2228NS_IMETHODIMPnsresult
2229HttpBaseChannel::GetResponseStatus(uint32_t* aValue) {
2230 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2231 *aValue = mResponseHead->Status();
2232 return NS_OK;
2233}
2234
2235NS_IMETHODIMPnsresult
2236HttpBaseChannel::GetResponseStatusText(nsACString& aValue) {
2237 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2238 nsAutoCString version;
2239 // https://fetch.spec.whatwg.org :
2240 // Responses over an HTTP/2 connection will always have the empty byte
2241 // sequence as status message as HTTP/2 does not support them.
2242 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"
, 2242)
||
2243 !version.EqualsLiteral("h2")) {
2244 mResponseHead->StatusText(aValue);
2245 }
2246 return NS_OK;
2247}
2248
2249NS_IMETHODIMPnsresult
2250HttpBaseChannel::GetRequestSucceeded(bool* aValue) {
2251 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2252 uint32_t status = mResponseHead->Status();
2253 *aValue = (status / 100 == 2);
2254 return NS_OK;
2255}
2256
2257NS_IMETHODIMPnsresult
2258HttpBaseChannel::RedirectTo(nsIURI* targetURI) {
2259 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"
, 2259); return NS_ERROR_INVALID_ARG; } } while (false)
;
2260
2261 nsAutoCString spec;
2262 targetURI->GetAsciiSpec(spec);
2263 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)
;
2264 LogCallingScriptLocation(this);
2265
2266 // We cannot redirect after OnStartRequest of the listener
2267 // has been called, since to redirect we have to switch channels
2268 // and the dance with OnStartRequest et al has to start over.
2269 // This would break the nsIStreamListener contract.
2270 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"
, 2270); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2271
2272 mAPIRedirectToURI = targetURI;
2273 // Only Web Extensions are allowed to redirect a channel to a data:
2274 // URI. To avoid any bypasses after the channel was flagged by
2275 // the WebRequst API, we are dropping the flag here.
2276 mLoadInfo->SetAllowInsecureRedirectToDataURI(false);
2277
2278 // We may want to rewrite origin allowance, hence we need an
2279 // artificial response head.
2280 if (!mResponseHead) {
2281 mResponseHead.reset(new nsHttpResponseHead());
2282 }
2283 return NS_OK;
2284}
2285
2286NS_IMETHODIMPnsresult
2287HttpBaseChannel::UpgradeToSecure() {
2288 // Upgrades are handled internally between http-on-modify-request and
2289 // http-on-before-connect, which means upgrades are only possible during
2290 // on-modify, or WebRequest.onBeforeRequest in Web Extensions. Once we are
2291 // past the code path where upgrades are handled, attempting an upgrade
2292 // will throw an error.
2293 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"
, 2293); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2294
2295 StoreUpgradeToSecure(true);
2296 return NS_OK;
2297}
2298
2299NS_IMETHODIMPnsresult
2300HttpBaseChannel::GetRequestObserversCalled(bool* aCalled) {
2301 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"
, 2301); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2302 *aCalled = LoadRequestObserversCalled();
2303 return NS_OK;
2304}
2305
2306NS_IMETHODIMPnsresult
2307HttpBaseChannel::SetRequestObserversCalled(bool aCalled) {
2308 StoreRequestObserversCalled(aCalled);
2309 return NS_OK;
2310}
2311
2312NS_IMETHODIMPnsresult
2313HttpBaseChannel::GetRequestContextID(uint64_t* aRCID) {
2314 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"
, 2314); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2315 *aRCID = mRequestContextID;
2316 return NS_OK;
2317}
2318
2319NS_IMETHODIMPnsresult
2320HttpBaseChannel::SetRequestContextID(uint64_t aRCID) {
2321 mRequestContextID = aRCID;
2322 return NS_OK;
2323}
2324
2325NS_IMETHODIMPnsresult
2326HttpBaseChannel::GetIsMainDocumentChannel(bool* aValue) {
2327 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"
, 2327); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2328 *aValue = IsNavigation();
2329 return NS_OK;
2330}
2331
2332NS_IMETHODIMPnsresult
2333HttpBaseChannel::SetIsMainDocumentChannel(bool aValue) {
2334 StoreForceMainDocumentChannel(aValue);
2335 return NS_OK;
2336}
2337
2338NS_IMETHODIMPnsresult
2339HttpBaseChannel::GetProtocolVersion(nsACString& aProtocolVersion) {
2340 // Try to use ALPN if available and if it is not for a proxy, i.e if an
2341 // https proxy was not used or if https proxy was used but the connection to
2342 // the origin server is also https. In the case, an https proxy was used and
2343 // the connection to the origin server was http, mSecurityInfo will be from
2344 // the proxy.
2345 if (!mConnectionInfo || !mConnectionInfo->UsingHttpsProxy() ||
2346 mConnectionInfo->EndToEndSSL()) {
2347 nsAutoCString protocol;
2348 if (mSecurityInfo &&
2349 NS_SUCCEEDED(mSecurityInfo->GetNegotiatedNPN(protocol))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mSecurityInfo->
GetNegotiatedNPN(protocol))), 1)))
&&
2350 !protocol.IsEmpty()) {
2351 // The negotiated protocol was not empty so we can use it.
2352 aProtocolVersion = protocol;
2353 return NS_OK;
2354 }
2355 }
2356
2357 if (mResponseHead) {
2358 HttpVersion version = mResponseHead->Version();
2359 aProtocolVersion.Assign(nsHttp::GetProtocolVersion(version));
2360 return NS_OK;
2361 }
2362
2363 return NS_ERROR_NOT_AVAILABLE;
2364}
2365
2366//-----------------------------------------------------------------------------
2367// HttpBaseChannel::nsIHttpChannelInternal
2368//-----------------------------------------------------------------------------
2369
2370NS_IMETHODIMPnsresult
2371HttpBaseChannel::SetTopWindowURIIfUnknown(nsIURI* aTopWindowURI) {
2372 if (!aTopWindowURI) {
2373 return NS_ERROR_INVALID_ARG;
2374 }
2375
2376 if (mTopWindowURI) {
2377 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)
2378 ("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)
2379 "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)
2380 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)
;
2381 return NS_ERROR_FAILURE;
2382 }
2383
2384 nsCOMPtr<nsIURI> topWindowURI;
2385 Unused << GetTopWindowURI(getter_AddRefs(topWindowURI));
2386
2387 // Don't modify |mTopWindowURI| if we can get one from GetTopWindowURI().
2388 if (topWindowURI) {
2389 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)
2390 ("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)
2391 "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)
2392 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)
;
2393 return NS_ERROR_FAILURE;
2394 }
2395
2396 mTopWindowURI = aTopWindowURI;
2397 return NS_OK;
2398}
2399
2400NS_IMETHODIMPnsresult
2401HttpBaseChannel::GetTopWindowURI(nsIURI** aTopWindowURI) {
2402 nsCOMPtr<nsIURI> uriBeingLoaded =
2403 AntiTrackingUtils::MaybeGetDocumentURIBeingLoaded(this);
2404 return GetTopWindowURI(uriBeingLoaded, aTopWindowURI);
2405}
2406
2407nsresult HttpBaseChannel::GetTopWindowURI(nsIURI* aURIBeingLoaded,
2408 nsIURI** aTopWindowURI) {
2409 nsresult rv = NS_OK;
2410 nsCOMPtr<mozIThirdPartyUtil> util;
2411 // Only compute the top window URI once. In e10s, this must be computed in the
2412 // child. The parent gets the top window URI through HttpChannelOpenArgs.
2413 if (!mTopWindowURI) {
2414 util = components::ThirdPartyUtil::Service();
2415 if (!util) {
2416 return NS_ERROR_NOT_AVAILABLE;
2417 }
2418 nsCOMPtr<mozIDOMWindowProxy> win;
2419 rv = util->GetTopWindowForChannel(this, aURIBeingLoaded,
2420 getter_AddRefs(win));
2421 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2422 rv = util->GetURIFromWindow(win, getter_AddRefs(mTopWindowURI));
2423#if DEBUG1
2424 if (mTopWindowURI) {
2425 nsCString spec;
2426 if (NS_SUCCEEDED(mTopWindowURI->GetSpec(spec))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mTopWindowURI->
GetSpec(spec))), 1)))
) {
2427 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)
2428 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)
;
2429 }
2430 }
2431#endif
2432 }
2433 }
2434 *aTopWindowURI = do_AddRef(mTopWindowURI).take();
2435 return rv;
2436}
2437
2438NS_IMETHODIMPnsresult
2439HttpBaseChannel::GetDocumentURI(nsIURI** aDocumentURI) {
2440 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"
, 2440); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2441 *aDocumentURI = do_AddRef(mDocumentURI).take();
2442 return NS_OK;
2443}
2444
2445NS_IMETHODIMPnsresult
2446HttpBaseChannel::SetDocumentURI(nsIURI* aDocumentURI) {
2447 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"
, 2447); 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"
, 2447, 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"
, 2447); } } 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"
, 2447); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2447; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2448 mDocumentURI = aDocumentURI;
2449 return NS_OK;
2450}
2451
2452NS_IMETHODIMPnsresult
2453HttpBaseChannel::GetRequestVersion(uint32_t* major, uint32_t* minor) {
2454 HttpVersion version = mRequestHead.Version();
2455
2456 if (major) {
2457 *major = static_cast<uint32_t>(version) / 10;
2458 }
2459 if (minor) {
2460 *minor = static_cast<uint32_t>(version) % 10;
2461 }
2462
2463 return NS_OK;
2464}
2465
2466NS_IMETHODIMPnsresult
2467HttpBaseChannel::GetResponseVersion(uint32_t* major, uint32_t* minor) {
2468 if (!mResponseHead) {
2469 *major = *minor = 0; // we should at least be kind about it
2470 return NS_ERROR_NOT_AVAILABLE;
2471 }
2472
2473 HttpVersion version = mResponseHead->Version();
2474
2475 if (major) {
2476 *major = static_cast<uint32_t>(version) / 10;
2477 }
2478 if (minor) {
2479 *minor = static_cast<uint32_t>(version) % 10;
2480 }
2481
2482 return NS_OK;
2483}
2484
2485void HttpBaseChannel::NotifySetCookie(const nsACString& aCookie) {
2486 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
2487 if (obs) {
2488 obs->NotifyObservers(static_cast<nsIChannel*>(this),
2489 "http-on-response-set-cookie",
2490 NS_ConvertASCIItoUTF16(aCookie).get());
2491 }
2492}
2493
2494bool HttpBaseChannel::IsBrowsingContextDiscarded() const {
2495 // If there is no loadGroup attached to the current channel, we check the
2496 // global private browsing state for the private channel instead. For
2497 // non-private channel, we will always return false here.
2498 //
2499 // Note that we can only access the global private browsing state in the
2500 // parent process. So, we will fallback to just return false in the content
2501 // process.
2502 if (!mLoadGroup) {
2503 if (!XRE_IsParentProcess()) {
2504 return false;
2505 }
2506
2507 return mLoadInfo->GetOriginAttributes().mPrivateBrowsingId != 0 &&
2508 !dom::CanonicalBrowsingContext::IsPrivateBrowsingActive();
2509 }
2510
2511 return mLoadGroup->GetIsBrowsingContextDiscarded();
2512}
2513
2514// https://mikewest.github.io/corpp/#process-navigation-response
2515nsresult HttpBaseChannel::ProcessCrossOriginEmbedderPolicyHeader() {
2516 nsresult rv;
2517 if (!StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2518 return NS_OK;
2519 }
2520
2521 // Only consider Cross-Origin-Embedder-Policy for document loads.
2522 if (mLoadInfo->GetExternalContentPolicyType() !=
2523 ExtContentPolicy::TYPE_DOCUMENT &&
2524 mLoadInfo->GetExternalContentPolicyType() !=
2525 ExtContentPolicy::TYPE_SUBDOCUMENT) {
2526 return NS_OK;
2527 }
2528
2529 nsILoadInfo::CrossOriginEmbedderPolicy resultPolicy =
2530 nsILoadInfo::EMBEDDER_POLICY_NULL;
2531 bool isCoepCredentiallessEnabled;
2532 rv = mLoadInfo->GetIsOriginTrialCoepCredentiallessEnabledForTopLevel(
2533 &isCoepCredentiallessEnabled);
2534 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"
, 2534); return rv; } } while (false)
;
2535 rv = GetResponseEmbedderPolicy(isCoepCredentiallessEnabled, &resultPolicy);
2536 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2537 return NS_OK;
2538 }
2539
2540 // https://html.spec.whatwg.org/multipage/origin.html#coep
2541 if (mLoadInfo->GetExternalContentPolicyType() ==
2542 ExtContentPolicy::TYPE_SUBDOCUMENT &&
2543 !nsHttpChannel::IsRedirectStatus(mResponseHead->Status()) &&
2544 mLoadInfo->GetLoadingEmbedderPolicy() !=
2545 nsILoadInfo::EMBEDDER_POLICY_NULL &&
2546 resultPolicy != nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP &&
2547 resultPolicy != nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
2548 return NS_ERROR_DOM_COEP_FAILED;
2549 }
2550
2551 return NS_OK;
2552}
2553
2554// https://mikewest.github.io/corpp/#corp-check
2555nsresult HttpBaseChannel::ProcessCrossOriginResourcePolicyHeader() {
2556 // Fetch 4.5.9
2557 dom::RequestMode requestMode;
2558 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"
, 2558); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(GetRequestMode(&requestMode))" ")");
do { *((volatile int*)__null) = 2558; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2559 // XXX this seems wrong per spec? What about navigate
2560 if (requestMode != RequestMode::No_cors) {
2561 return NS_OK;
2562 }
2563
2564 // We only apply this for resources.
2565 auto extContentPolicyType = mLoadInfo->GetExternalContentPolicyType();
2566 if (extContentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
2567 extContentPolicyType == ExtContentPolicy::TYPE_WEBSOCKET ||
2568 extContentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
2569 return NS_OK;
2570 }
2571
2572 if (extContentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
2573 // COEP pref off, skip CORP checking for subdocument.
2574 if (!StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2575 return NS_OK;
2576 }
2577 // COEP 3.2.1.2 when request targets a nested browsing context then embedder
2578 // policy value is "unsafe-none", then return allowed.
2579 if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2580 nsILoadInfo::EMBEDDER_POLICY_NULL) {
2581 return NS_OK;
2582 }
2583 }
2584
2585 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"
, 2586); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetLoadingPrincipal()"
") (" "Resources should always have a LoadingPrincipal" ")")
; do { *((volatile int*)__null) = 2586; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2586 "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"
, 2586); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetLoadingPrincipal()"
") (" "Resources should always have a LoadingPrincipal" ")")
; do { *((volatile int*)__null) = 2586; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2587 if (!mResponseHead) {
2588 return NS_OK;
2589 }
2590
2591 if (mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()) {
2592 return NS_OK;
2593 }
2594
2595 nsAutoCString content;
2596 Unused << mResponseHead->GetHeader(nsHttp::Cross_Origin_Resource_Policy,
2597 content);
2598
2599 if (StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2600 if (content.IsEmpty()) {
2601 if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2602 nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
2603 bool requestIncludesCredentials = false;
2604 nsresult rv = GetCorsIncludeCredentials(&requestIncludesCredentials);
2605 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2606 return NS_OK;
2607 }
2608 // COEP: Set policy to `same-origin` if: response’s
2609 // request-includes-credentials is true, or forNavigation is true.
2610 if (requestIncludesCredentials ||
2611 extContentPolicyType == ExtContentPolicyType::TYPE_SUBDOCUMENT) {
2612 content = "same-origin"_ns;
2613 }
2614 } else if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2615 nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP) {
2616 // COEP 3.2.1.6 If policy is null, and embedder policy is
2617 // "require-corp", set policy to "same-origin". Note that we treat
2618 // invalid value as "cross-origin", which spec indicates. We might want
2619 // to make that stricter.
2620 content = "same-origin"_ns;
2621 }
2622 }
2623 }
2624
2625 if (content.IsEmpty()) {
2626 return NS_OK;
2627 }
2628
2629 nsCOMPtr<nsIPrincipal> channelOrigin;
2630 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
2631 this, getter_AddRefs(channelOrigin));
2632
2633 // Cross-Origin-Resource-Policy = %s"same-origin" / %s"same-site" /
2634 // %s"cross-origin"
2635 if (content.EqualsLiteral("same-origin")) {
2636 if (!channelOrigin->Equals(mLoadInfo->GetLoadingPrincipal())) {
2637 return NS_ERROR_DOM_CORP_FAILED;
2638 }
2639 return NS_OK;
2640 }
2641 if (content.EqualsLiteral("same-site")) {
2642 nsAutoCString documentBaseDomain;
2643 nsAutoCString resourceBaseDomain;
2644 mLoadInfo->GetLoadingPrincipal()->GetBaseDomain(documentBaseDomain);
2645 channelOrigin->GetBaseDomain(resourceBaseDomain);
2646 if (documentBaseDomain != resourceBaseDomain) {
2647 return NS_ERROR_DOM_CORP_FAILED;
2648 }
2649
2650 nsCOMPtr<nsIURI> resourceURI = channelOrigin->GetURI();
2651 if (!mLoadInfo->GetLoadingPrincipal()->SchemeIs("https") &&
2652 resourceURI->SchemeIs("https")) {
2653 return NS_ERROR_DOM_CORP_FAILED;
2654 }
2655
2656 return NS_OK;
2657 }
2658
2659 return NS_OK;
2660}
2661
2662// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
2663// This method runs steps 1-4 of the algorithm to compare
2664// cross-origin-opener policies
2665static bool CompareCrossOriginOpenerPolicies(
2666 nsILoadInfo::CrossOriginOpenerPolicy documentPolicy,
2667 nsIPrincipal* documentOrigin,
2668 nsILoadInfo::CrossOriginOpenerPolicy resultPolicy,
2669 nsIPrincipal* resultOrigin) {
2670 if (documentPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE &&
2671 resultPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2672 return true;
2673 }
2674
2675 if (documentPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE ||
2676 resultPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2677 return false;
2678 }
2679
2680 if (documentPolicy == resultPolicy && documentOrigin->Equals(resultOrigin)) {
2681 return true;
2682 }
2683
2684 return false;
2685}
2686
2687// This runs steps 1-5 of the algorithm when navigating a top level document.
2688// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
2689nsresult HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch() {
2690 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"
, 2690); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 2690; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2691
2692 StoreHasCrossOriginOpenerPolicyMismatch(false);
2693 if (!StaticPrefs::browser_tabs_remote_useCrossOriginOpenerPolicy()) {
2694 return NS_OK;
2695 }
2696
2697 // Only consider Cross-Origin-Opener-Policy for toplevel document loads.
2698 if (mLoadInfo->GetExternalContentPolicyType() !=
2699 ExtContentPolicy::TYPE_DOCUMENT) {
2700 return NS_OK;
2701 }
2702
2703 // Maybe the channel failed and we have no response head?
2704 if (!mResponseHead) {
2705 // Not having a response head is not a hard failure at the point where
2706 // this method is called.
2707 return NS_OK;
2708 }
2709
2710 RefPtr<mozilla::dom::BrowsingContext> ctx;
2711 mLoadInfo->GetBrowsingContext(getter_AddRefs(ctx));
2712
2713 // In xpcshell-tests we don't always have a browsingContext
2714 if (!ctx) {
2715 return NS_OK;
2716 }
2717
2718 nsCOMPtr<nsIPrincipal> resultOrigin;
2719 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
2720 this, getter_AddRefs(resultOrigin));
2721
2722 // Get the policy of the active document, and the policy for the result.
2723 nsILoadInfo::CrossOriginOpenerPolicy documentPolicy = ctx->GetOpenerPolicy();
2724 nsILoadInfo::CrossOriginOpenerPolicy resultPolicy =
2725 nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
2726 Unused << ComputeCrossOriginOpenerPolicy(documentPolicy, &resultPolicy);
2727 mComputedCrossOriginOpenerPolicy = resultPolicy;
2728
2729 // Add a permission to mark this site as high-value into the permission DB.
2730 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2731 mozilla::dom::AddHighValuePermission(
2732 resultOrigin, mozilla::dom::kHighValueCOOPPermission);
2733 }
2734
2735 // If bc's popup sandboxing flag set is not empty and potentialCOOP is
2736 // non-null, then navigate bc to a network error and abort these steps.
2737 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE &&
2738 mLoadInfo->GetSandboxFlags()) {
2739 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)
2740 "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)
2741 "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)
;
2742 return NS_ERROR_DOM_COOP_FAILED;
2743 }
2744
2745 // In xpcshell-tests we don't always have a current window global
2746 RefPtr<mozilla::dom::WindowGlobalParent> currentWindowGlobal =
2747 ctx->Canonical()->GetCurrentWindowGlobal();
2748 if (!currentWindowGlobal) {
2749 return NS_OK;
2750 }
2751
2752 // We use the top window principal as the documentOrigin
2753 nsCOMPtr<nsIPrincipal> documentOrigin =
2754 currentWindowGlobal->DocumentPrincipal();
2755
2756 bool compareResult = CompareCrossOriginOpenerPolicies(
2757 documentPolicy, documentOrigin, resultPolicy, resultOrigin);
2758
2759 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
2760 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)
2761 ("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)
2762 "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)
2763 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)
;
2764 nsAutoCString docOrigin("(null)");
2765 nsCOMPtr<nsIURI> uri = documentOrigin->GetURI();
2766 if (uri) {
2767 uri->GetSpec(docOrigin);
2768 }
2769 nsAutoCString resOrigin("(null)");
2770 uri = resultOrigin->GetURI();
2771 if (uri) {
2772 uri->GetSpec(resOrigin);
2773 }
2774 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)
;
2775 }
2776
2777 if (compareResult) {
2778 return NS_OK;
2779 }
2780
2781 // If one of the following is false:
2782 // - document's policy is same-origin-allow-popups
2783 // - resultPolicy is null
2784 // - doc is the initial about:blank document
2785 // then we have a mismatch.
2786
2787 if (documentPolicy != nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_ALLOW_POPUPS) {
2788 StoreHasCrossOriginOpenerPolicyMismatch(true);
2789 return NS_OK;
2790 }
2791
2792 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2793 StoreHasCrossOriginOpenerPolicyMismatch(true);
2794 return NS_OK;
2795 }
2796
2797 if (!currentWindowGlobal->IsInitialDocument()) {
2798 StoreHasCrossOriginOpenerPolicyMismatch(true);
2799 return NS_OK;
2800 }
2801
2802 return NS_OK;
2803}
2804
2805nsresult HttpBaseChannel::ProcessCrossOriginSecurityHeaders() {
2806 StoreProcessCrossOriginSecurityHeadersCalled(true);
2807 nsresult rv = ProcessCrossOriginEmbedderPolicyHeader();
2808 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2809 return rv;
2810 }
2811 rv = ProcessCrossOriginResourcePolicyHeader();
2812 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2813 return rv;
2814 }
2815 return ComputeCrossOriginOpenerPolicyMismatch();
2816}
2817
2818enum class Report { Error, Warning };
2819
2820// Helper Function to report messages to the console when the loaded
2821// script had a wrong MIME type.
2822void ReportMimeTypeMismatch(HttpBaseChannel* aChannel, const char* aMessageName,
2823 nsIURI* aURI, const nsACString& aContentType,
2824 Report report) {
2825 NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
2826 NS_ConvertUTF8toUTF16 contentType(aContentType);
2827
2828 aChannel->LogMimeTypeMismatch(nsCString(aMessageName),
2829 report == Report::Warning, spec, contentType);
2830}
2831
2832// Check and potentially enforce X-Content-Type-Options: nosniff
2833nsresult ProcessXCTO(HttpBaseChannel* aChannel, nsIURI* aURI,
2834 nsHttpResponseHead* aResponseHead,
2835 nsILoadInfo* aLoadInfo) {
2836 if (!aURI || !aResponseHead || !aLoadInfo) {
2837 // if there is no uri, no response head or no loadInfo, then there is
2838 // nothing to do
2839 return NS_OK;
2840 }
2841
2842 // 1) Query the XCTO header and check if 'nosniff' is the first value.
2843 nsAutoCString contentTypeOptionsHeader;
2844 if (!aResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader)) {
2845 // if failed to get XCTO header, then there is nothing to do.
2846 return NS_OK;
2847 }
2848
2849 // let's compare the header (ignoring case)
2850 // e.g. "NoSniFF" -> "nosniff"
2851 // if it's not 'nosniff' then there is nothing to do here
2852 if (!contentTypeOptionsHeader.EqualsIgnoreCase("nosniff")) {
2853 // since we are getting here, the XCTO header was sent;
2854 // a non matching value most likely means a mistake happenend;
2855 // e.g. sending 'nosnif' instead of 'nosniff', let's log a warning.
2856 AutoTArray<nsString, 1> params;
2857 CopyUTF8toUTF16(contentTypeOptionsHeader, *params.AppendElement());
2858 RefPtr<dom::Document> doc;
2859 aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
2860 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "XCTO"_ns, doc,
2861 nsContentUtils::eSECURITY_PROPERTIES,
2862 "XCTOHeaderValueMissing", params);
2863 return NS_OK;
2864 }
2865
2866 // 2) Query the content type from the channel
2867 nsAutoCString contentType;
2868 aResponseHead->ContentType(contentType);
2869
2870 // 3) Compare the expected MIME type with the actual type
2871 if (aLoadInfo->GetExternalContentPolicyType() ==
2872 ExtContentPolicy::TYPE_STYLESHEET) {
2873 if (contentType.EqualsLiteral(TEXT_CSS"text/css")) {
2874 return NS_OK;
2875 }
2876 ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
2877 Report::Error);
2878 return NS_ERROR_CORRUPTED_CONTENT;
2879 }
2880
2881 if (aLoadInfo->GetExternalContentPolicyType() ==
2882 ExtContentPolicy::TYPE_SCRIPT) {
2883 if (nsContentUtils::IsJavascriptMIMEType(
2884 NS_ConvertUTF8toUTF16(contentType))) {
2885 return NS_OK;
2886 }
2887 ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
2888 Report::Error);
2889 return NS_ERROR_CORRUPTED_CONTENT;
2890 }
2891
2892 auto policyType = aLoadInfo->GetExternalContentPolicyType();
2893 if (policyType == ExtContentPolicy::TYPE_DOCUMENT ||
2894 policyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
2895 // If the header XCTO nosniff is set for any browsing context, then
2896 // we set the skipContentSniffing flag on the Loadinfo. Within
2897 // GetMIMETypeFromContent we then bail early and do not do any sniffing.
2898 aLoadInfo->SetSkipContentSniffing(true);
2899 return NS_OK;
2900 }
2901
2902 return NS_OK;
2903}
2904
2905// Ensure that a load of type script has correct MIME type
2906nsresult EnsureMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
2907 nsHttpResponseHead* aResponseHead,
2908 nsILoadInfo* aLoadInfo) {
2909 if (!aURI || !aResponseHead || !aLoadInfo) {
2910 // if there is no uri, no response head or no loadInfo, then there is
2911 // nothing to do
2912 return NS_OK;
2913 }
2914
2915 if (aLoadInfo->GetExternalContentPolicyType() !=
2916 ExtContentPolicy::TYPE_SCRIPT) {
2917 // if this is not a script load, then there is nothing to do
2918 return NS_OK;
2919 }
2920
2921 nsAutoCString contentType;
2922 aResponseHead->ContentType(contentType);
2923 NS_ConvertUTF8toUTF16 typeString(contentType);
2924
2925 if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
2926 // script load has type script
2927 AccumulateCategorical(
2928 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
2929 return NS_OK;
2930 }
2931
2932 switch (aLoadInfo->InternalContentPolicyType()) {
2933 case nsIContentPolicy::TYPE_SCRIPT:
2934 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
2935 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
2936 case nsIContentPolicy::TYPE_INTERNAL_MODULE:
2937 case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
2938 case nsIContentPolicy::TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT:
2939 case nsIContentPolicy::TYPE_INTERNAL_FRAME_MESSAGEMANAGER_SCRIPT:
2940 AccumulateCategorical(
2941 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::script_load);
2942 break;
2943 case nsIContentPolicy::TYPE_INTERNAL_WORKER:
2944 case nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE:
2945 case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
2946 AccumulateCategorical(
2947 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worker_load);
2948 break;
2949 case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
2950 AccumulateCategorical(
2951 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::serviceworker_load);
2952 break;
2953 case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
2954 AccumulateCategorical(
2955 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::importScript_load);
2956 break;
2957 case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
2958 case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
2959 AccumulateCategorical(
2960 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worklet_load);
2961 break;
2962 default:
2963 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"
, 2963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "unexpected script type" ")"); do
{ *((volatile int*)__null) = 2963; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
2964 break;
2965 }
2966
2967 if (aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(aURI)) {
2968 // same origin
2969 AccumulateCategorical(
2970 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::same_origin);
2971 } else {
2972 bool cors = false;
2973 nsAutoCString corsOrigin;
2974 nsresult rv = aResponseHead->GetHeader(
2975 nsHttp::ResolveAtom("Access-Control-Allow-Origin"_ns), corsOrigin);
2976 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2977 if (corsOrigin.Equals("*")) {
2978 cors = true;
2979 } else {
2980 nsCOMPtr<nsIURI> corsOriginURI;
2981 rv = NS_NewURI(getter_AddRefs(corsOriginURI), corsOrigin);
2982 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2983 if (aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(corsOriginURI)) {
2984 cors = true;
2985 }
2986 }
2987 }
2988 }
2989 if (cors) {
2990 // cors origin
2991 AccumulateCategorical(
2992 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::CORS_origin);
2993 } else {
2994 // cross origin
2995 AccumulateCategorical(
2996 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::cross_origin);
2997 }
2998 }
2999
3000 bool block = false;
3001 if (StringBeginsWith(contentType, "image/"_ns)) {
3002 // script load has type image
3003 AccumulateCategorical(
3004 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::image);
3005 block = true;
3006 } else if (StringBeginsWith(contentType, "audio/"_ns)) {
3007 // script load has type audio
3008 AccumulateCategorical(
3009 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::audio);
3010 block = true;
3011 } else if (StringBeginsWith(contentType, "video/"_ns)) {
3012 // script load has type video
3013 AccumulateCategorical(
3014 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::video);
3015 block = true;
3016 } else if (StringBeginsWith(contentType, "text/csv"_ns)) {
3017 // script load has type text/csv
3018 AccumulateCategorical(
3019 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_csv);
3020 block = true;
3021 }
3022
3023 if (block) {
3024 ReportMimeTypeMismatch(aChannel, "BlockScriptWithWrongMimeType2", aURI,
3025 contentType, Report::Error);
3026 return NS_ERROR_CORRUPTED_CONTENT;
3027 }
3028
3029 if (StringBeginsWith(contentType, "text/plain"_ns)) {
3030 // script load has type text/plain
3031 AccumulateCategorical(
3032 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
3033 } else if (StringBeginsWith(contentType, "text/xml"_ns)) {
3034 // script load has type text/xml
3035 AccumulateCategorical(
3036 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_xml);
3037 } else if (StringBeginsWith(contentType, "application/octet-stream"_ns)) {
3038 // script load has type application/octet-stream
3039 AccumulateCategorical(
3040 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_octet_stream);
3041 } else if (StringBeginsWith(contentType, "application/xml"_ns)) {
3042 // script load has type application/xml
3043 AccumulateCategorical(
3044 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_xml);
3045 } else if (StringBeginsWith(contentType, "application/json"_ns)) {
3046 // script load has type application/json
3047 AccumulateCategorical(
3048 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_json);
3049 } else if (StringBeginsWith(contentType, "text/json"_ns)) {
3050 // script load has type text/json
3051 AccumulateCategorical(
3052 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_json);
3053 } else if (StringBeginsWith(contentType, "text/html"_ns)) {
3054 // script load has type text/html
3055 AccumulateCategorical(
3056 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_html);
3057 } else if (contentType.IsEmpty()) {
3058 // script load has no type
3059 AccumulateCategorical(
3060 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::empty);
3061 } else {
3062 // script load has unknown type
3063 AccumulateCategorical(
3064 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::unknown);
3065 }
3066
3067 // We restrict importScripts() in worker code to JavaScript MIME types.
3068 nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
3069 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS ||
3070 internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE) {
3071 ReportMimeTypeMismatch(aChannel, "BlockImportScriptsWithWrongMimeType",
3072 aURI, contentType, Report::Error);
3073 return NS_ERROR_CORRUPTED_CONTENT;
3074 }
3075
3076 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
3077 internalType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
3078 // Do not block the load if the feature is not enabled.
3079 if (!StaticPrefs::security_block_Worker_with_wrong_mime()) {
3080 return NS_OK;
3081 }
3082
3083 ReportMimeTypeMismatch(aChannel, "BlockWorkerWithWrongMimeType", aURI,
3084 contentType, Report::Error);
3085 return NS_ERROR_CORRUPTED_CONTENT;
3086 }
3087
3088 // ES6 modules require a strict MIME type check.
3089 if (internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
3090 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD) {
3091 ReportMimeTypeMismatch(aChannel, "BlockModuleWithWrongMimeType", aURI,
3092 contentType, Report::Error);
3093 return NS_ERROR_CORRUPTED_CONTENT;
3094 }
3095
3096 return NS_OK;
3097}
3098
3099// Warn when a load of type script uses a wrong MIME type and
3100// wasn't blocked by EnsureMIMEOfScript or ProcessXCTO.
3101void WarnWrongMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
3102 nsHttpResponseHead* aResponseHead,
3103 nsILoadInfo* aLoadInfo) {
3104 if (!aURI || !aResponseHead || !aLoadInfo) {
3105 // If there is no uri, no response head or no loadInfo, then there is
3106 // nothing to do.
3107 return;
3108 }
3109
3110 if (aLoadInfo->GetExternalContentPolicyType() !=
3111 ExtContentPolicy::TYPE_SCRIPT) {
3112 // If this is not a script load, then there is nothing to do.
3113 return;
3114 }
3115
3116 bool succeeded;
3117 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"
, 3117); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(aChannel->GetRequestSucceeded(&succeeded))"
")"); do { *((volatile int*)__null) = 3117; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3118 if (!succeeded) {
3119 // Do not warn for failed loads: HTTP error pages are usually in HTML.
3120 return;
3121 }
3122
3123 nsAutoCString contentType;
3124 aResponseHead->ContentType(contentType);
3125 NS_ConvertUTF8toUTF16 typeString(contentType);
3126 if (!nsContentUtils::IsJavascriptMIMEType(typeString)) {
3127 ReportMimeTypeMismatch(aChannel, "WarnScriptWithWrongMimeType", aURI,
3128 contentType, Report::Warning);
3129 }
3130}
3131
3132nsresult HttpBaseChannel::ValidateMIMEType() {
3133 nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
3134 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3135 return rv;
3136 }
3137
3138 rv = ProcessXCTO(this, mURI, mResponseHead.get(), mLoadInfo);
3139 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3140 return rv;
3141 }
3142
3143 WarnWrongMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
3144 return NS_OK;
3145}
3146
3147bool HttpBaseChannel::ShouldFilterOpaqueResponse(
3148 OpaqueResponseFilterFetch aFilterType) const {
3149 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"
, 3149); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "ShouldBlockOpaqueResponse()"
")"); do { *((volatile int*)__null) = 3149; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3150
3151 if (!mLoadInfo || ConfiguredFilterFetchResponseBehaviour() != aFilterType) {
3152 return false;
3153 }
3154
3155 // We should filter a response in the parent if it is opaque and is the result
3156 // of a fetch() function from the Fetch specification.
3157 return mLoadInfo->InternalContentPolicyType() == nsIContentPolicy::TYPE_FETCH;
3158}
3159
3160bool HttpBaseChannel::ShouldBlockOpaqueResponse() const {
3161 if (!mURI || !mResponseHead || !mLoadInfo) {
3162 // if there is no uri, no response head or no loadInfo, then there is
3163 // nothing to do
3164 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)
;
3165 return false;
3166 }
3167
3168 nsCOMPtr<nsIPrincipal> principal = mLoadInfo->GetLoadingPrincipal();
3169 if (!principal || principal->IsSystemPrincipal()) {
3170 // If it's a top-level load or a system principal, then there is nothing to
3171 // do.
3172 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)
;
3173 return false;
3174 }
3175
3176 // Check if the response is a opaque response, which means requestMode should
3177 // be RequestMode::No_cors and responseType should be ResponseType::Opaque.
3178 nsContentPolicyType contentPolicy = mLoadInfo->InternalContentPolicyType();
3179
3180 // Skip the RequestMode would be RequestMode::Navigate
3181 if (contentPolicy == nsIContentPolicy::TYPE_DOCUMENT ||
3182 contentPolicy == nsIContentPolicy::TYPE_SUBDOCUMENT ||
3183 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_FRAME ||
3184 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_IFRAME ||
3185 // Skip the RequestMode would be RequestMode::Same_origin
3186 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
3187 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
3188 return false;
3189 }
3190
3191 uint32_t securityMode = mLoadInfo->GetSecurityMode();
3192 // Skip when RequestMode would not be RequestMode::no_cors
3193 if (securityMode !=
3194 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT &&
3195 securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL) {
3196 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)
;
3197 return false;
3198 }
3199
3200 // Only continue when ResponseType would be ResponseType::Opaque
3201 if (mLoadInfo->GetTainting() != mozilla::LoadTainting::Opaque) {
3202 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)
;
3203 return false;
3204 }
3205
3206 auto extContentPolicyType = mLoadInfo->GetExternalContentPolicyType();
3207 if (extContentPolicyType == ExtContentPolicy::TYPE_OBJECT ||
3208 extContentPolicyType == ExtContentPolicy::TYPE_OBJECT_SUBREQUEST ||
3209 extContentPolicyType == ExtContentPolicy::TYPE_WEBSOCKET ||
3210 extContentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
3211 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)
;
3212 return false;
3213 }
3214
3215 // Ignore the request from object or embed elements
3216 if (mLoadInfo->GetIsFromObjectOrEmbed()) {
3217 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)
;
3218 return false;
3219 }
3220
3221 // Exclude no_cors System XHR
3222 if (extContentPolicyType == ExtContentPolicy::TYPE_XMLHTTPREQUEST) {
3223 if (securityMode ==
3224 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT) {
3225 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)
;
3226 return false;
3227 }
3228 }
3229
3230 uint32_t httpsOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
3231 if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_BYPASS_ORB) {
3232 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)
;
3233 return false;
3234 }
3235
3236 bool isInDevToolsContext;
3237 mLoadInfo->GetIsInDevToolsContext(&isInDevToolsContext);
3238 if (isInDevToolsContext) {
3239 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)
;
3240 return false;
3241 }
3242
3243 return true;
3244}
3245
3246OpaqueResponse HttpBaseChannel::BlockOrFilterOpaqueResponse(
3247 OpaqueResponseBlocker* aORB, const nsAString& aReason,
3248 const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
3249 const char* aFormat, ...) {
3250 NimbusFeatures::RecordExposureEvent("opaqueResponseBlocking"_ns, true);
3251
3252 const bool shouldFilter =
3253 ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::BlockedByORB);
3254
3255 if (MOZ_UNLIKELY(MOZ_LOG_TEST(GetORBLog(), LogLevel::Debug))(__builtin_expect(!!((__builtin_expect(!!(mozilla::detail::log_test
(GetORBLog(), LogLevel::Debug)), 0))), 0))
) {
3256 va_list ap;
3257 va_start(ap, aFormat)__builtin_va_start(ap, aFormat);
3258 nsVprintfCString logString(aFormat, ap);
3259 va_end(ap)__builtin_va_end(ap);
3260
3261 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)
;
3262 }
3263
3264 if (shouldFilter) {
3265 Telemetry::AccumulateCategorical(
3266 Telemetry::LABELS_ORB_BLOCK_INITIATOR::FILTERED_FETCH);
3267 // The existence of `mORB` depends on `BlockOrFilterOpaqueResponse` being
3268 // called before or after sniffing has completed.
3269 // Another requirement is that `OpaqueResponseFilter` must come after
3270 // `OpaqueResponseBlocker`, which is why in the case of having an
3271 // `OpaqueResponseBlocker` we let it handle creating an
3272 // `OpaqueResponseFilter`.
3273 if (aORB) {
3274 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"
, 3274); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mORB || aORB == mORB"
")"); do { *((volatile int*)__null) = 3274; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3275 aORB->FilterResponse();
3276 } else {
3277 mListener = new OpaqueResponseFilter(mListener);
3278 }
3279 return OpaqueResponse::Allow;
3280 }
3281
3282 LogORBError(aReason, aTelemetryReason);
3283 return OpaqueResponse::Block;
3284}
3285
3286// The specification for ORB is currently being written:
3287// https://whatpr.org/fetch/1442.html#orb-algorithm
3288// The `opaque-response-safelist check` is implemented in:
3289// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
3290// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3291// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
3292// * `OpaqueResponseBlocker::ValidateJavaScript`
3293OpaqueResponse
3294HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff() {
3295 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"
, 3295); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 3295; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3296
3297 // https://whatpr.org/fetch/1442.html#http-fetch, step 6.4
3298 if (!ShouldBlockOpaqueResponse()) {
3299 return OpaqueResponse::Allow;
3300 }
3301
3302 // Regardless of if ORB is enabled or not, we check if we should filter the
3303 // response in the parent. This way data won't reach a content process that
3304 // will create a filtered `Response` object. This is enabled when
3305 // 'browser.opaqueResponseBlocking.filterFetchResponse' is
3306 // `OpaqueResponseFilterFetch::All`.
3307 // See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
3308 if (ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::All)) {
3309 mListener = new OpaqueResponseFilter(mListener);
3310
3311 // If we're filtering a response in the parent, there will be no data to
3312 // determine if it should be blocked or not so the only option we have is to
3313 // allow it.
3314 return OpaqueResponse::Allow;
3315 }
3316
3317 if (!mCachedOpaqueResponseBlockingPref) {
3318 return OpaqueResponse::Allow;
3319 }
3320
3321 // If ORB is enabled, we check if we should filter the response in the parent.
3322 // This way data won't reach a content process that will create a filtered
3323 // `Response` object. We allow ORB to determine if the response should be
3324 // blocked or filtered, but regardless no data should reach the content
3325 // process. This is enabled when
3326 // 'browser.opaqueResponseBlocking.filterFetchResponse' is
3327 // `OpaqueResponseFilterFetch::AllowedByORB`.
3328 // See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
3329 if (ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::AllowedByORB)) {
3330 mListener = new OpaqueResponseFilter(mListener);
3331 }
3332
3333 Telemetry::ScalarAdd(
3334 Telemetry::ScalarID::
3335 OPAQUE_RESPONSE_BLOCKING_CROSS_ORIGIN_OPAQUE_RESPONSE_COUNT,
3336 1);
3337
3338 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)
;
3339
3340 // https://whatpr.org/fetch/1442.html#orb-algorithm
3341 // Step 1
3342 nsAutoCString contentType;
3343 mResponseHead->ContentType(contentType);
3344
3345 // Step 2
3346 nsAutoCString contentTypeOptionsHeader;
3347 bool nosniff =
3348 mResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader) &&
3349 contentTypeOptionsHeader.EqualsIgnoreCase("nosniff");
3350
3351 // Step 3
3352 switch (GetOpaqueResponseBlockedReason(contentType, mResponseHead->Status(),
3353 nosniff)) {
3354 case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED:
3355 // Step 3.1
3356 return OpaqueResponse::Allow;
3357 case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED_SPEC_BREAKING:
3358 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)
;
3359 return OpaqueResponse::Allow;
3360 case OpaqueResponseBlockedReason::BLOCKED_BLOCKLISTED_NEVER_SNIFFED:
3361 return BlockOrFilterOpaqueResponse(
3362 mORB, u"mimeType is an opaque-blocklisted-never-sniffed MIME type"_ns,
3363 OpaqueResponseBlockedTelemetryReason::MIME_NEVER_SNIFFED,
3364 "BLOCKED_BLOCKLISTED_NEVER_SNIFFED");
3365 case OpaqueResponseBlockedReason::BLOCKED_206_AND_BLOCKLISTED:
3366 // Step 3.3
3367 return BlockOrFilterOpaqueResponse(
3368 mORB,
3369 u"response's status is 206 and mimeType is an opaque-blocklisted MIME type"_ns,
3370 OpaqueResponseBlockedTelemetryReason::RESP_206_BLCLISTED,
3371 "BLOCKED_206_AND_BLOCKEDLISTED");
3372 case OpaqueResponseBlockedReason::
3373 BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN:
3374 // Step 3.4
3375 return BlockOrFilterOpaqueResponse(
3376 mORB,
3377 u"nosniff is true and mimeType is an opaque-blocklisted MIME type or its essence is 'text/plain'"_ns,
3378 OpaqueResponseBlockedTelemetryReason::NOSNIFF_BLC_OR_TEXTP,
3379 "BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN");
3380 default:
3381 break;
3382 }
3383
3384 // Step 4
3385 // If it's a media subsequent request, we assume that it will only be made
3386 // after a successful initial request.
3387 bool isMediaRequest;
3388 mLoadInfo->GetIsMediaRequest(&isMediaRequest);
3389 if (isMediaRequest) {
3390 bool isMediaInitialRequest;
3391 mLoadInfo->GetIsMediaInitialRequest(&isMediaInitialRequest);
3392 if (!isMediaInitialRequest) {
3393 return OpaqueResponse::Allow;
3394 }
3395 }
3396
3397 // Step 5
3398 if (mResponseHead->Status() == 206 &&
3399 !IsFirstPartialResponse(*mResponseHead)) {
3400 return BlockOrFilterOpaqueResponse(
3401 mORB, u"response status is 206 and not first partial response"_ns,
3402 OpaqueResponseBlockedTelemetryReason::RESP_206_BLCLISTED,
3403 "Is not a valid partial response given 0");
3404 }
3405
3406 // Setup for steps 6, 7, 8 and 10.
3407 // Steps 6 and 7 are handled by the sniffer framework.
3408 // Steps 8 and 10 by are handled by
3409 // `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3410 if (mLoadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS) {
3411 mSnifferCategoryType = SnifferCategoryType::All;
3412 } else {
3413 mSnifferCategoryType = SnifferCategoryType::OpaqueResponseBlocking;
3414 }
3415
3416 mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
3417 nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
3418
3419 // Install an input stream listener that performs ORB checks that depend on
3420 // inspecting the incoming data. It is crucial that `OnStartRequest` is called
3421 // on this listener either after sniffing is completed or that we skip
3422 // sniffing, otherwise `OpaqueResponseBlocker` will allow responses that it
3423 // shouldn't.
3424 mORB = new OpaqueResponseBlocker(mListener, this, contentType, nosniff);
3425 mListener = mORB;
3426
3427 nsAutoCString contentEncoding;
3428 nsresult rv =
3429 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
3430
3431 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !contentEncoding.IsEmpty()) {
3432 return OpaqueResponse::SniffCompressed;
3433 }
3434 mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
3435 nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
3436 return OpaqueResponse::Sniff;
3437}
3438
3439// The specification for ORB is currently being written:
3440// https://whatpr.org/fetch/1442.html#orb-algorithm
3441// The `opaque-response-safelist check` is implemented in:
3442// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
3443// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3444// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
3445// * `OpaqueResponseBlocker::ValidateJavaScript`
3446OpaqueResponse HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff(
3447 const nsACString& aContentType, bool aNoSniff) {
3448 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)
;
3449
3450 // https://whatpr.org/fetch/1442.html#orb-algorithm
3451 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"
, 3451); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 3451; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3452 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"
, 3452); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedOpaqueResponseBlockingPref"
")"); do { *((volatile int*)__null) = 3452; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3453
3454 // Step 9
3455 bool isMediaRequest;
3456 mLoadInfo->GetIsMediaRequest(&isMediaRequest);
3457 if (isMediaRequest) {
3458 return BlockOrFilterOpaqueResponse(
3459 mORB, u"after sniff: media request"_ns,
3460 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_MEDIA,
3461 "media request");
3462 }
3463
3464 // Step 11
3465 if (aNoSniff) {
3466 return BlockOrFilterOpaqueResponse(
3467 mORB, u"after sniff: nosniff is true"_ns,
3468 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_NOSNIFF, "nosniff");
3469 }
3470
3471 // Step 12
3472 if (mResponseHead &&
3473 (mResponseHead->Status() < 200 || mResponseHead->Status() > 299)) {
3474 return BlockOrFilterOpaqueResponse(
3475 mORB, u"after sniff: status code is not in allowed range"_ns,
3476 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_STA_CODE,
3477 "status code (%d) is not allowed", mResponseHead->Status());
3478 }
3479
3480 // Step 13
3481 if (!mResponseHead || aContentType.IsEmpty()) {
3482 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)
;
3483 return OpaqueResponse::Allow;
3484 }
3485
3486 // Step 14
3487 if (StringBeginsWith(aContentType, "image/"_ns) ||
3488 StringBeginsWith(aContentType, "video/"_ns) ||
3489 StringBeginsWith(aContentType, "audio/"_ns)) {
3490 return BlockOrFilterOpaqueResponse(
3491 mORB,
3492 u"after sniff: content-type declares image/video/audio, but sniffing fails"_ns,
3493 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_CT_FAIL,
3494 "ContentType is image/video/audio");
3495 }
3496
3497 return OpaqueResponse::Sniff;
3498}
3499
3500bool HttpBaseChannel::NeedOpaqueResponseAllowedCheckAfterSniff() const {
3501 return mORB ? mORB->IsSniffing() : false;
3502}
3503
3504void HttpBaseChannel::BlockOpaqueResponseAfterSniff(
3505 const nsAString& aReason,
3506 const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
3507 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"
, 3507); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { *((volatile int*)__null) = 3507; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3508 LogORBError(aReason, aTelemetryReason);
3509 mORB->BlockResponse(this, NS_ERROR_FAILURE);
3510}
3511
3512void HttpBaseChannel::AllowOpaqueResponseAfterSniff() {
3513 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"
, 3513); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { *((volatile int*)__null) = 3513; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3514 mORB->AllowResponse();
3515}
3516
3517void HttpBaseChannel::SetChannelBlockedByOpaqueResponse() {
3518 mChannelBlockedByOpaqueResponse = true;
3519
3520 RefPtr<dom::BrowsingContext> browsingContext =
3521 dom::BrowsingContext::GetCurrentTopByBrowserId(mBrowserId);
3522 if (!browsingContext) {
3523 return;
3524 }
3525
3526 dom::WindowContext* windowContext = browsingContext->GetTopWindowContext();
3527 if (windowContext) {
3528 windowContext->Canonical()->SetShouldReportHasBlockedOpaqueResponse(
3529 mLoadInfo->InternalContentPolicyType());
3530 }
3531}
3532
3533NS_IMETHODIMPnsresult
3534HttpBaseChannel::SetCookie(const nsACString& aCookieHeader) {
3535 if (mLoadFlags & LOAD_ANONYMOUS) return NS_OK;
3536
3537 if (IsBrowsingContextDiscarded()) {
3538 return NS_OK;
3539 }
3540
3541 // empty header isn't an error
3542 if (aCookieHeader.IsEmpty()) {
3543 return NS_OK;
3544 }
3545
3546 nsICookieService* cs = gHttpHandler->GetCookieService();
3547 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"
, 3547); return NS_ERROR_FAILURE; } } while (false)
;
3548
3549 nsresult rv = cs->SetCookieStringFromHttp(mURI, aCookieHeader, this);
3550 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3551 NotifySetCookie(aCookieHeader);
3552 }
3553 return rv;
3554}
3555
3556NS_IMETHODIMPnsresult
3557HttpBaseChannel::GetThirdPartyFlags(uint32_t* aFlags) {
3558 *aFlags = LoadThirdPartyFlags();
3559 return NS_OK;
3560}
3561
3562NS_IMETHODIMPnsresult
3563HttpBaseChannel::SetThirdPartyFlags(uint32_t aFlags) {
3564 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"
, 3564); 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"
, 3564, 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"
, 3564); } } 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"
, 3564); 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"
, 3564); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
3565
3566 StoreThirdPartyFlags(aFlags);
3567 return NS_OK;
3568}
3569
3570NS_IMETHODIMPnsresult
3571HttpBaseChannel::GetForceAllowThirdPartyCookie(bool* aForce) {
3572 *aForce = !!(LoadThirdPartyFlags() &
3573 nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3574 return NS_OK;
3575}
3576
3577NS_IMETHODIMPnsresult
3578HttpBaseChannel::SetForceAllowThirdPartyCookie(bool aForce) {
3579 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"
, 3579); 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"
, 3579, 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"
, 3579); } } 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"
, 3579); 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"
, 3579); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
3580
3581 if (aForce) {
3582 StoreThirdPartyFlags(LoadThirdPartyFlags() |
3583 nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3584 } else {
3585 StoreThirdPartyFlags(LoadThirdPartyFlags() &
3586 ~nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3587 }
3588
3589 return NS_OK;
3590}
3591
3592NS_IMETHODIMPnsresult
3593HttpBaseChannel::GetCanceled(bool* aCanceled) {
3594 *aCanceled = mCanceled;
3595 return NS_OK;
3596}
3597
3598NS_IMETHODIMPnsresult
3599HttpBaseChannel::GetChannelIsForDownload(bool* aChannelIsForDownload) {
3600 *aChannelIsForDownload = LoadChannelIsForDownload();
3601 return NS_OK;
3602}
3603
3604NS_IMETHODIMPnsresult
3605HttpBaseChannel::SetChannelIsForDownload(bool aChannelIsForDownload) {
3606 StoreChannelIsForDownload(aChannelIsForDownload);
3607 return NS_OK;
3608}
3609
3610NS_IMETHODIMPnsresult
3611HttpBaseChannel::SetCacheKeysRedirectChain(nsTArray<nsCString>* cacheKeys) {
3612 auto RedirectedCachekeys = mRedirectedCachekeys.Lock();
3613 auto& ref = RedirectedCachekeys.ref();
3614 ref = WrapUnique(cacheKeys);
3615 return NS_OK;
3616}
3617
3618NS_IMETHODIMPnsresult
3619HttpBaseChannel::GetLocalAddress(nsACString& addr) {
3620 if (mSelfAddr.raw.family == PR_AF_UNSPEC0) return NS_ERROR_NOT_AVAILABLE;
3621
3622 addr.SetLength(kIPv6CStrBufSize);
3623 mSelfAddr.ToStringBuffer(addr.BeginWriting(), kIPv6CStrBufSize);
3624 addr.SetLength(strlen(addr.BeginReading()));
3625
3626 return NS_OK;
3627}
3628
3629NS_IMETHODIMPnsresult
3630HttpBaseChannel::TakeAllSecurityMessages(
3631 nsCOMArray<nsISecurityConsoleMessage>& aMessages) {
3632 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"
, 3632); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3632; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3633
3634 aMessages.Clear();
3635 for (const auto& pair : mSecurityConsoleMessages) {
3636 nsresult rv;
3637 nsCOMPtr<nsISecurityConsoleMessage> message =
3638 do_CreateInstance(NS_SECURITY_CONSOLE_MESSAGE_CONTRACTID"@mozilla.org/securityconsole/message;1", &rv);
3639 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"
, 3639); return rv; } } while (false)
;
3640
3641 message->SetTag(pair.first);
3642 message->SetCategory(pair.second);
3643 aMessages.AppendElement(message);
3644 }
3645
3646 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"
, 3646); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSecurityConsoleMessages.Length() == aMessages.Length()"
")"); do { *((volatile int*)__null) = 3646; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3647 mSecurityConsoleMessages.Clear();
3648
3649 return NS_OK;
3650}
3651
3652/* Please use this method with care. This can cause the message
3653 * queue to grow large and cause the channel to take up a lot
3654 * of memory. Use only static string messages and do not add
3655 * server side data to the queue, as that can be large.
3656 * Add only a limited number of messages to the queue to keep
3657 * the channel size down and do so only in rare erroneous situations.
3658 * More information can be found here:
3659 * https://bugzilla.mozilla.org/show_bug.cgi?id=846918
3660 */
3661nsresult HttpBaseChannel::AddSecurityMessage(
3662 const nsAString& aMessageTag, const nsAString& aMessageCategory) {
3663 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"
, 3663); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3663; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3664
3665 nsresult rv;
3666
3667 // nsSecurityConsoleMessage is not thread-safe refcounted.
3668 // Delay the object construction until requested.
3669 // See TakeAllSecurityMessages()
3670 std::pair<nsString, nsString> pair(aMessageTag, aMessageCategory);
3671 mSecurityConsoleMessages.AppendElement(std::move(pair));
3672
3673 nsCOMPtr<nsIConsoleService> console(
3674 do_GetService(NS_CONSOLESERVICE_CONTRACTID"@mozilla.org/consoleservice;1"));
3675 if (!console) {
3676 return NS_ERROR_FAILURE;
3677 }
3678
3679 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
3680
3681 auto innerWindowID = loadInfo->GetInnerWindowID();
3682
3683 nsAutoString errorText;
3684 rv = nsContentUtils::GetLocalizedString(
3685 nsContentUtils::eSECURITY_PROPERTIES,
3686 NS_ConvertUTF16toUTF8(aMessageTag).get(), errorText);
3687 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"
, 3687); return rv; } } while (false)
;
3688
3689 nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID"@mozilla.org/scripterror;1"));
3690 error->InitWithSourceURI(
3691 errorText, mURI, u""_ns, 0, 0, nsIScriptError::warningFlag,
3692 NS_ConvertUTF16toUTF8(aMessageCategory), innerWindowID);
3693
3694 console->LogMessage(error);
3695
3696 return NS_OK;
3697}
3698
3699NS_IMETHODIMPnsresult
3700HttpBaseChannel::GetLocalPort(int32_t* port) {
3701 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"
, 3701); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3702
3703 if (mSelfAddr.raw.family == PR_AF_INET2) {
3704 *port = (int32_t)ntohs(mSelfAddr.inet.port)__bswap_16 (mSelfAddr.inet.port);
3705 } else if (mSelfAddr.raw.family == PR_AF_INET610) {
3706 *port = (int32_t)ntohs(mSelfAddr.inet6.port)__bswap_16 (mSelfAddr.inet6.port);
3707 } else {
3708 return NS_ERROR_NOT_AVAILABLE;
3709 }
3710
3711 return NS_OK;
3712}
3713
3714NS_IMETHODIMPnsresult
3715HttpBaseChannel::GetRemoteAddress(nsACString& addr) {
3716 if (mPeerAddr.raw.family == PR_AF_UNSPEC0) return NS_ERROR_NOT_AVAILABLE;
3717
3718 addr.SetLength(kIPv6CStrBufSize);
3719 mPeerAddr.ToStringBuffer(addr.BeginWriting(), kIPv6CStrBufSize);
3720 addr.SetLength(strlen(addr.BeginReading()));
3721
3722 return NS_OK;
3723}
3724
3725NS_IMETHODIMPnsresult
3726HttpBaseChannel::GetRemotePort(int32_t* port) {
3727 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"
, 3727); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3728
3729 if (mPeerAddr.raw.family == PR_AF_INET2) {
3730 *port = (int32_t)ntohs(mPeerAddr.inet.port)__bswap_16 (mPeerAddr.inet.port);
3731 } else if (mPeerAddr.raw.family == PR_AF_INET610) {
3732 *port = (int32_t)ntohs(mPeerAddr.inet6.port)__bswap_16 (mPeerAddr.inet6.port);
3733 } else {
3734 return NS_ERROR_NOT_AVAILABLE;
3735 }
3736
3737 return NS_OK;
3738}
3739
3740NS_IMETHODIMPnsresult
3741HttpBaseChannel::HTTPUpgrade(const nsACString& aProtocolName,
3742 nsIHttpUpgradeListener* aListener) {
3743 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"
, 3743); return NS_ERROR_INVALID_ARG; } } while (false)
;
3744 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"
, 3744); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3745
3746 mUpgradeProtocol = aProtocolName;
3747 mUpgradeProtocolCallback = aListener;
3748 return NS_OK;
3749}
3750
3751NS_IMETHODIMPnsresult
3752HttpBaseChannel::GetOnlyConnect(bool* aOnlyConnect) {
3753 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"
, 3753); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3754
3755 *aOnlyConnect = mCaps & NS_HTTP_CONNECT_ONLY(1 << 16);
3756 return NS_OK;
3757}
3758
3759NS_IMETHODIMPnsresult
3760HttpBaseChannel::SetConnectOnly() {
3761 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"
, 3761); 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"
, 3761, 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"
, 3761); } } 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"
, 3761); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 3761; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
3762
3763 if (!mUpgradeProtocolCallback) {
3764 return NS_ERROR_FAILURE;
3765 }
3766
3767 mCaps |= NS_HTTP_CONNECT_ONLY(1 << 16);
3768 mProxyResolveFlags = nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY |
3769 nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL;
3770 return SetLoadFlags(nsIRequest::INHIBIT_CACHING | nsIChannel::LOAD_ANONYMOUS |
3771 nsIRequest::LOAD_BYPASS_CACHE |
3772 nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
3773}
3774
3775NS_IMETHODIMPnsresult
3776HttpBaseChannel::GetAllowSpdy(bool* aAllowSpdy) {
3777 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"
, 3777); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3778
3779 *aAllowSpdy = LoadAllowSpdy();
3780 return NS_OK;
3781}
3782
3783NS_IMETHODIMPnsresult
3784HttpBaseChannel::SetAllowSpdy(bool aAllowSpdy) {
3785 StoreAllowSpdy(aAllowSpdy);
3786 return NS_OK;
3787}
3788
3789NS_IMETHODIMPnsresult
3790HttpBaseChannel::GetAllowHttp3(bool* aAllowHttp3) {
3791 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"
, 3791); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3792
3793 *aAllowHttp3 = LoadAllowHttp3();
3794 return NS_OK;
3795}
3796
3797NS_IMETHODIMPnsresult
3798HttpBaseChannel::SetAllowHttp3(bool aAllowHttp3) {
3799 StoreAllowHttp3(aAllowHttp3);
3800 return NS_OK;
3801}
3802
3803NS_IMETHODIMPnsresult
3804HttpBaseChannel::GetAllowAltSvc(bool* aAllowAltSvc) {
3805 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"
, 3805); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3806
3807 *aAllowAltSvc = LoadAllowAltSvc();
3808 return NS_OK;
3809}
3810
3811NS_IMETHODIMPnsresult
3812HttpBaseChannel::SetAllowAltSvc(bool aAllowAltSvc) {
3813 StoreAllowAltSvc(aAllowAltSvc);
3814 return NS_OK;
3815}
3816
3817NS_IMETHODIMPnsresult
3818HttpBaseChannel::GetBeConservative(bool* aBeConservative) {
3819 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"
, 3819); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3820
3821 *aBeConservative = LoadBeConservative();
3822 return NS_OK;
3823}
3824
3825NS_IMETHODIMPnsresult
3826HttpBaseChannel::SetBeConservative(bool aBeConservative) {
3827 StoreBeConservative(aBeConservative);
3828 return NS_OK;
3829}
3830
3831bool HttpBaseChannel::BypassProxy() {
3832 return StaticPrefs::network_proxy_allow_bypass() && LoadBypassProxy();
3833}
3834
3835NS_IMETHODIMPnsresult
3836HttpBaseChannel::GetBypassProxy(bool* aBypassProxy) {
3837 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"
, 3837); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3838
3839 *aBypassProxy = BypassProxy();
3840 return NS_OK;
3841}
3842
3843NS_IMETHODIMPnsresult
3844HttpBaseChannel::SetBypassProxy(bool aBypassProxy) {
3845 if (StaticPrefs::network_proxy_allow_bypass()) {
3846 StoreBypassProxy(aBypassProxy);
3847 } else {
3848 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"
, 3848)
;
3849 return NS_ERROR_FAILURE;
3850 }
3851 return NS_OK;
3852}
3853
3854NS_IMETHODIMPnsresult
3855HttpBaseChannel::GetIsTRRServiceChannel(bool* aIsTRRServiceChannel) {
3856 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"
, 3856); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3857
3858 *aIsTRRServiceChannel = LoadIsTRRServiceChannel();
3859 return NS_OK;
3860}
3861
3862NS_IMETHODIMPnsresult
3863HttpBaseChannel::SetIsTRRServiceChannel(bool aIsTRRServiceChannel) {
3864 StoreIsTRRServiceChannel(aIsTRRServiceChannel);
3865 return NS_OK;
3866}
3867
3868NS_IMETHODIMPnsresult
3869HttpBaseChannel::GetIsResolvedByTRR(bool* aResolvedByTRR) {
3870 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"
, 3870); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3871 *aResolvedByTRR = LoadResolvedByTRR();
3872 return NS_OK;
3873}
3874
3875NS_IMETHODIMPnsresult
3876HttpBaseChannel::GetEffectiveTRRMode(nsIRequest::TRRMode* aEffectiveTRRMode) {
3877 *aEffectiveTRRMode = mEffectiveTRRMode;
3878 return NS_OK;
3879}
3880
3881NS_IMETHODIMPnsresult
3882HttpBaseChannel::GetTrrSkipReason(nsITRRSkipReason::value* aTrrSkipReason) {
3883 *aTrrSkipReason = mTRRSkipReason;
3884 return NS_OK;
3885}
3886
3887NS_IMETHODIMPnsresult
3888HttpBaseChannel::GetIsLoadedBySocketProcess(bool* aResult) {
3889 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"
, 3889); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3890 *aResult = LoadLoadedBySocketProcess();
3891 return NS_OK;
3892}
3893
3894NS_IMETHODIMPnsresult
3895HttpBaseChannel::GetTlsFlags(uint32_t* aTlsFlags) {
3896 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"
, 3896); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3897
3898 *aTlsFlags = mTlsFlags;
3899 return NS_OK;
3900}
3901
3902NS_IMETHODIMPnsresult
3903HttpBaseChannel::SetTlsFlags(uint32_t aTlsFlags) {
3904 mTlsFlags = aTlsFlags;
3905 return NS_OK;
3906}
3907
3908NS_IMETHODIMPnsresult
3909HttpBaseChannel::GetApiRedirectToURI(nsIURI** aResult) {
3910 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"
, 3910); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3911 *aResult = do_AddRef(mAPIRedirectToURI).take();
3912 return NS_OK;
3913}
3914
3915NS_IMETHODIMPnsresult
3916HttpBaseChannel::GetResponseTimeoutEnabled(bool* aEnable) {
3917 if (NS_WARN_IF(!aEnable)NS_warn_if_impl(!aEnable, "!aEnable", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3917)
) {
3918 return NS_ERROR_NULL_POINTER;
3919 }
3920 *aEnable = LoadResponseTimeoutEnabled();
3921 return NS_OK;
3922}
3923
3924NS_IMETHODIMPnsresult
3925HttpBaseChannel::SetResponseTimeoutEnabled(bool aEnable) {
3926 StoreResponseTimeoutEnabled(aEnable);
3927 return NS_OK;
3928}
3929
3930NS_IMETHODIMPnsresult
3931HttpBaseChannel::GetInitialRwin(uint32_t* aRwin) {
3932 if (NS_WARN_IF(!aRwin)NS_warn_if_impl(!aRwin, "!aRwin", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3932)
) {
3933 return NS_ERROR_NULL_POINTER;
3934 }
3935 *aRwin = mInitialRwin;
3936 return NS_OK;
3937}
3938
3939NS_IMETHODIMPnsresult
3940HttpBaseChannel::SetInitialRwin(uint32_t aRwin) {
3941 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"
, 3941); 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"
, 3941, 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"
, 3941); } } 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"
, 3941); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 3941; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
3942 mInitialRwin = aRwin;
3943 return NS_OK;
3944}
3945
3946NS_IMETHODIMPnsresult
3947HttpBaseChannel::ForcePending(bool aForcePending) {
3948 StoreForcePending(aForcePending);
3949 return NS_OK;
3950}
3951
3952NS_IMETHODIMPnsresult
3953HttpBaseChannel::GetLastModifiedTime(PRTime* lastModifiedTime) {
3954 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
3955 uint32_t lastMod;
3956 nsresult rv = mResponseHead->GetLastModifiedValue(&lastMod);
3957 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"
, 3957); return rv; } } while (false)
;
3958 *lastModifiedTime = lastMod;
3959 return NS_OK;
3960}
3961
3962NS_IMETHODIMPnsresult
3963HttpBaseChannel::GetCorsIncludeCredentials(bool* aInclude) {
3964 *aInclude = LoadCorsIncludeCredentials();
3965 return NS_OK;
3966}
3967
3968NS_IMETHODIMPnsresult
3969HttpBaseChannel::SetCorsIncludeCredentials(bool aInclude) {
3970 StoreCorsIncludeCredentials(aInclude);
3971 return NS_OK;
3972}
3973
3974NS_IMETHODIMPnsresult
3975HttpBaseChannel::GetRequestMode(RequestMode* aMode) {
3976 *aMode = mRequestMode;
3977 return NS_OK;
3978}
3979
3980NS_IMETHODIMPnsresult
3981HttpBaseChannel::SetRequestMode(RequestMode aMode) {
3982 mRequestMode = aMode;
3983 return NS_OK;
3984}
3985
3986NS_IMETHODIMPnsresult
3987HttpBaseChannel::GetRedirectMode(uint32_t* aMode) {
3988 *aMode = mRedirectMode;
3989 return NS_OK;
3990}
3991
3992NS_IMETHODIMPnsresult
3993HttpBaseChannel::SetRedirectMode(uint32_t aMode) {
3994 mRedirectMode = aMode;
3995 return NS_OK;
3996}
3997
3998namespace {
3999
4000bool ContainsAllFlags(uint32_t aLoadFlags, uint32_t aMask) {
4001 return (aLoadFlags & aMask) == aMask;
4002}
4003
4004} // anonymous namespace
4005
4006NS_IMETHODIMPnsresult
4007HttpBaseChannel::GetFetchCacheMode(uint32_t* aFetchCacheMode) {
4008 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"
, 4008); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4009
4010 // Otherwise try to guess an appropriate cache mode from the load flags.
4011 if (ContainsAllFlags(mLoadFlags, INHIBIT_CACHING | LOAD_BYPASS_CACHE)) {
4012 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE;
4013 } else if (ContainsAllFlags(mLoadFlags, LOAD_BYPASS_CACHE)) {
4014 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD;
4015 } else if (ContainsAllFlags(mLoadFlags, VALIDATE_ALWAYS) ||
4016 LoadForceValidateCacheContent()) {
4017 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE;
4018 } else if (ContainsAllFlags(
4019 mLoadFlags,
4020 VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE)) {
4021 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED;
4022 } else if (ContainsAllFlags(mLoadFlags, VALIDATE_NEVER)) {
4023 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE;
4024 } else {
4025 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT;
4026 }
4027
4028 return NS_OK;
4029}
4030
4031namespace {
4032
4033void SetCacheFlags(uint32_t& aLoadFlags, uint32_t aFlags) {
4034 // First, clear any possible cache related flags.
4035 uint32_t allPossibleFlags =
4036 nsIRequest::INHIBIT_CACHING | nsIRequest::LOAD_BYPASS_CACHE |
4037 nsIRequest::VALIDATE_ALWAYS | nsIRequest::LOAD_FROM_CACHE |
4038 nsICachingChannel::LOAD_ONLY_FROM_CACHE;
4039 aLoadFlags &= ~allPossibleFlags;
4040
4041 // Then set the new flags.
4042 aLoadFlags |= aFlags;
4043}
4044
4045} // anonymous namespace
4046
4047NS_IMETHODIMPnsresult
4048HttpBaseChannel::SetFetchCacheMode(uint32_t aFetchCacheMode) {
4049 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"
, 4049); 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"
, 4049, 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"
, 4049); } } 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"
, 4049); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 4049; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
4050
4051 // Now, set the load flags that implement each cache mode.
4052 switch (aFetchCacheMode) {
4053 case nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT:
4054 // The "default" mode means to use the http cache normally and
4055 // respect any http cache-control headers. We effectively want
4056 // to clear our cache related load flags.
4057 SetCacheFlags(mLoadFlags, 0);
4058 break;
4059 case nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE:
4060 // no-store means don't consult the cache on the way to the network, and
4061 // don't store the response in the cache even if it's cacheable.
4062 SetCacheFlags(mLoadFlags, INHIBIT_CACHING | LOAD_BYPASS_CACHE);
4063 break;
4064 case nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD:
4065 // reload means don't consult the cache on the way to the network, but
4066 // do store the response in the cache if possible.
4067 SetCacheFlags(mLoadFlags, LOAD_BYPASS_CACHE);
4068 break;
4069 case nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE:
4070 // no-cache means always validate what's in the cache.
4071 SetCacheFlags(mLoadFlags, VALIDATE_ALWAYS);
4072 break;
4073 case nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE:
4074 // force-cache means don't validate unless if the response would vary.
4075 SetCacheFlags(mLoadFlags, VALIDATE_NEVER);
4076 break;
4077 case nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED:
4078 // only-if-cached means only from cache, no network, no validation,
4079 // generate a network error if the document was't in the cache. The
4080 // privacy implications of these flags (making it fast/easy to check if
4081 // the user has things in their cache without any network traffic side
4082 // effects) are addressed in the Request constructor which
4083 // enforces/requires same-origin request mode.
4084 SetCacheFlags(mLoadFlags,
4085 VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE);
4086 break;
4087 }
4088
4089#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED1
4090 uint32_t finalMode = 0;
4091 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"
, 4091); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(GetFetchCacheMode(&finalMode))" ")")
; do { *((volatile int*)__null) = 4091; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4092 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"
, 4092); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "finalMode == aFetchCacheMode"
")"); do { *((volatile int*)__null) = 4092; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4093#endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED
4094
4095 return NS_OK;
4096}
4097
4098NS_IMETHODIMPnsresult
4099HttpBaseChannel::SetIntegrityMetadata(const nsAString& aIntegrityMetadata) {
4100 mIntegrityMetadata = aIntegrityMetadata;
4101 return NS_OK;
4102}
4103
4104NS_IMETHODIMPnsresult
4105HttpBaseChannel::GetIntegrityMetadata(nsAString& aIntegrityMetadata) {
4106 aIntegrityMetadata = mIntegrityMetadata;
4107 return NS_OK;
4108}
4109
4110//-----------------------------------------------------------------------------
4111// HttpBaseChannel::nsISupportsPriority
4112//-----------------------------------------------------------------------------
4113
4114NS_IMETHODIMPnsresult
4115HttpBaseChannel::GetPriority(int32_t* value) {
4116 *value = mPriority;
4117 return NS_OK;
4118}
4119
4120NS_IMETHODIMPnsresult
4121HttpBaseChannel::AdjustPriority(int32_t delta) {
4122 return SetPriority(mPriority + delta);
4123}
4124
4125//-----------------------------------------------------------------------------
4126// HttpBaseChannel::nsIResumableChannel
4127//-----------------------------------------------------------------------------
4128
4129NS_IMETHODIMPnsresult
4130HttpBaseChannel::GetEntityID(nsACString& aEntityID) {
4131 // Don't return an entity ID for Non-GET requests which require
4132 // additional data
4133 if (!mRequestHead.IsGet()) {
4134 return NS_ERROR_NOT_RESUMABLE;
4135 }
4136
4137 uint64_t size = UINT64_MAX(18446744073709551615UL);
4138 nsAutoCString etag, lastmod;
4139 if (mResponseHead) {
4140 // Don't return an entity if the server sent the following header:
4141 // Accept-Ranges: none
4142 // Not sending the Accept-Ranges header means we can still try
4143 // sending range requests.
4144 nsAutoCString acceptRanges;
4145 Unused << mResponseHead->GetHeader(nsHttp::Accept_Ranges, acceptRanges);
4146 if (!acceptRanges.IsEmpty() &&
4147 !nsHttp::FindToken(acceptRanges.get(), "bytes",
4148 HTTP_HEADER_VALUE_SEPS" \t" ",")) {
4149 return NS_ERROR_NOT_RESUMABLE;
4150 }
4151
4152 size = mResponseHead->TotalEntitySize();
4153 Unused << mResponseHead->GetHeader(nsHttp::Last_Modified, lastmod);
4154 Unused << mResponseHead->GetHeader(nsHttp::ETag, etag);
4155 }
4156 nsCString entityID;
4157 NS_EscapeURL(etag.BeginReading(), etag.Length(),
4158 esc_AlwaysCopy | esc_FileBaseName | esc_Forced, entityID);
4159 entityID.Append('/');
4160 entityID.AppendInt(int64_t(size));
4161 entityID.Append('/');
4162 entityID.Append(lastmod);
4163 // NOTE: Appending lastmod as the last part avoids having to escape it
4164
4165 aEntityID = entityID;
4166
4167 return NS_OK;
4168}
4169
4170//-----------------------------------------------------------------------------
4171// HttpBaseChannel::nsIConsoleReportCollector
4172//-----------------------------------------------------------------------------
4173
4174void HttpBaseChannel::AddConsoleReport(
4175 uint32_t aErrorFlags, const nsACString& aCategory,
4176 nsContentUtils::PropertiesFile aPropertiesFile,
4177 const nsACString& aSourceFileURI, uint32_t aLineNumber,
4178 uint32_t aColumnNumber, const nsACString& aMessageName,
4179 const nsTArray<nsString>& aStringParams) {
4180 mReportCollector->AddConsoleReport(aErrorFlags, aCategory, aPropertiesFile,
4181 aSourceFileURI, aLineNumber, aColumnNumber,
4182 aMessageName, aStringParams);
4183
4184 // If this channel is already part of a loadGroup, we can flush this console
4185 // report immediately.
4186 HttpBaseChannel::MaybeFlushConsoleReports();
4187}
4188
4189void HttpBaseChannel::FlushReportsToConsole(uint64_t aInnerWindowID,
4190 ReportAction aAction) {
4191 mReportCollector->FlushReportsToConsole(aInnerWindowID, aAction);
4192}
4193
4194void HttpBaseChannel::FlushReportsToConsoleForServiceWorkerScope(
4195 const nsACString& aScope, ReportAction aAction) {
4196 mReportCollector->FlushReportsToConsoleForServiceWorkerScope(aScope, aAction);
4197}
4198
4199void HttpBaseChannel::FlushConsoleReports(dom::Document* aDocument,
4200 ReportAction aAction) {
4201 mReportCollector->FlushConsoleReports(aDocument, aAction);
4202}
4203
4204void HttpBaseChannel::FlushConsoleReports(nsILoadGroup* aLoadGroup,
4205 ReportAction aAction) {
4206 mReportCollector->FlushConsoleReports(aLoadGroup, aAction);
4207}
4208
4209void HttpBaseChannel::FlushConsoleReports(
4210 nsIConsoleReportCollector* aCollector) {
4211 mReportCollector->FlushConsoleReports(aCollector);
4212}
4213
4214void HttpBaseChannel::StealConsoleReports(
4215 nsTArray<net::ConsoleReportCollected>& aReports) {
4216 mReportCollector->StealConsoleReports(aReports);
4217}
4218
4219void HttpBaseChannel::ClearConsoleReports() {
4220 mReportCollector->ClearConsoleReports();
4221}
4222
4223bool HttpBaseChannel::IsNavigation() {
4224 return LoadForceMainDocumentChannel() || (mLoadFlags & LOAD_DOCUMENT_URI);
4225}
4226
4227bool HttpBaseChannel::BypassServiceWorker() const {
4228 return mLoadFlags & LOAD_BYPASS_SERVICE_WORKER;
4229}
4230
4231bool HttpBaseChannel::ShouldIntercept(nsIURI* aURI) {
4232 nsCOMPtr<nsINetworkInterceptController> controller;
4233 GetCallback(controller);
4234 bool shouldIntercept = false;
4235
4236 if (!StaticPrefs::dom_serviceWorkers_enabled()) {
4237 return false;
4238 }
4239
4240 // We should never intercept internal redirects. The ServiceWorker code
4241 // can trigger interntal redirects as the result of a FetchEvent. If
4242 // we re-intercept then an infinite loop can occur.
4243 //
4244 // Its also important that we do not set the LOAD_BYPASS_SERVICE_WORKER
4245 // flag because an internal redirect occurs. Its possible that another
4246 // interception should occur after the internal redirect. For example,
4247 // if the ServiceWorker chooses not to call respondWith() the channel
4248 // will be reset with an internal redirect. If the request is a navigation
4249 // and the network then triggers a redirect its possible the new URL
4250 // should be intercepted again.
4251 //
4252 // Note, HSTS upgrade redirects are often treated the same as internal
4253 // redirects. In this case, however, we intentionally allow interception
4254 // of HSTS upgrade redirects. This matches the expected spec behavior and
4255 // does not run the risk of infinite loops as described above.
4256 bool internalRedirect =
4257 mLastRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL;
4258
4259 if (controller && mLoadInfo && !BypassServiceWorker() && !internalRedirect) {
4260 nsresult rv = controller->ShouldPrepareForIntercept(
4261 aURI ? aURI : mURI.get(), this, &shouldIntercept);
4262 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4263 return false;
4264 }
4265 }
4266 return shouldIntercept;
4267}
4268
4269void HttpBaseChannel::AddAsNonTailRequest() {
4270 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"
, 4270); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4270; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4271
4272 if (EnsureRequestContext()) {
4273 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)
4274 "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)
4275 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)
;
4276
4277 if (!LoadAddedAsNonTailRequest()) {
4278 mRequestContext->AddNonTailRequest();
4279 StoreAddedAsNonTailRequest(true);
4280 }
4281 }
4282}
4283
4284void HttpBaseChannel::RemoveAsNonTailRequest() {
4285 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"
, 4285); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4285; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4286
4287 if (mRequestContext) {
4288 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)
4289 ("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)
4290 "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)
4291 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)
;
4292
4293 if (LoadAddedAsNonTailRequest()) {
4294 mRequestContext->RemoveNonTailRequest();
4295 StoreAddedAsNonTailRequest(false);
4296 }
4297 }
4298}
4299
4300#ifdef DEBUG1
4301void HttpBaseChannel::AssertPrivateBrowsingId() {
4302 nsCOMPtr<nsILoadContext> loadContext;
4303 NS_QueryNotificationCallbacks(this, loadContext);
4304
4305 if (!loadContext) {
4306 return;
4307 }
4308
4309 // We skip testing of favicon loading here since it could be triggered by XUL
4310 // image which uses SystemPrincipal. The SystemPrincpal doesn't have
4311 // mPrivateBrowsingId.
4312 if (mLoadInfo->GetLoadingPrincipal() &&
4313 mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal() &&
4314 mLoadInfo->InternalContentPolicyType() ==
4315 nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
4316 return;
4317 }
4318
4319 OriginAttributes docShellAttrs;
4320 loadContext->GetOriginAttributes(docShellAttrs);
4321 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"
, 4324); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4324; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4322 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"
, 4324); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4324; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4323 "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"
, 4324); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4324; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4324 "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"
, 4324); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4324; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
4325}
4326#endif
4327
4328already_AddRefed<nsILoadInfo> HttpBaseChannel::CloneLoadInfoForRedirect(
4329 nsIURI* aNewURI, uint32_t aRedirectFlags) {
4330 // make a copy of the loadinfo, append to the redirectchain
4331 // this will be set on the newly created channel for the redirect target.
4332 nsCOMPtr<nsILoadInfo> newLoadInfo =
4333 static_cast<mozilla::net::LoadInfo*>(mLoadInfo.get())->Clone();
4334
4335 ExtContentPolicyType contentPolicyType =
4336 mLoadInfo->GetExternalContentPolicyType();
4337 if (contentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
4338 contentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
4339 // Reset PrincipalToInherit to a null principal. We'll credit the the
4340 // redirecting resource's result principal as the new principal's precursor.
4341 // This means that a data: URI will end up loading in a process based on the
4342 // redirected-from URI.
4343 nsCOMPtr<nsIPrincipal> redirectPrincipal;
4344 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
4345 this, getter_AddRefs(redirectPrincipal));
4346 nsCOMPtr<nsIPrincipal> nullPrincipalToInherit =
4347 NullPrincipal::CreateWithInheritedAttributes(redirectPrincipal);
4348 newLoadInfo->SetPrincipalToInherit(nullPrincipalToInherit);
4349 }
4350
4351 bool isTopLevelDoc = newLoadInfo->GetExternalContentPolicyType() ==
4352 ExtContentPolicy::TYPE_DOCUMENT;
4353
4354 if (isTopLevelDoc) {
4355 // re-compute the origin attributes of the loadInfo if it's top-level load.
4356 nsCOMPtr<nsILoadContext> loadContext;
4357 NS_QueryNotificationCallbacks(this, loadContext);
4358 OriginAttributes docShellAttrs;
4359 if (loadContext) {
4360 loadContext->GetOriginAttributes(docShellAttrs);
4361 }
4362
4363 OriginAttributes attrs = newLoadInfo->GetOriginAttributes();
4364
4365 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"
, 4367); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4367; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4366 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"
, 4367); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4367; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4367 "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"
, 4367); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4367; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4368 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"
, 4370); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4370; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4369 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"
, 4370); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4370; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4370 "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"
, 4370); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4370; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4371 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"
, 4374); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4374; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4372 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"
, 4374); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4374; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4373 "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"
, 4374); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4374; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4374 "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"
, 4374); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4374; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4375
4376 attrs = docShellAttrs;
4377 attrs.SetFirstPartyDomain(true, aNewURI);
4378 newLoadInfo->SetOriginAttributes(attrs);
4379
4380 // re-compute the upgrade insecure requests bit for document navigations
4381 // since it should only apply to same-origin navigations (redirects).
4382 // we only do this if the CSP of the triggering element (the cspToInherit)
4383 // uses 'upgrade-insecure-requests', otherwise UIR does not apply.
4384 nsCOMPtr<nsIContentSecurityPolicy> csp = newLoadInfo->GetCspToInherit();
4385 if (csp) {
4386 bool upgradeInsecureRequests = false;
4387 csp->GetUpgradeInsecureRequests(&upgradeInsecureRequests);
4388 if (upgradeInsecureRequests) {
4389 nsCOMPtr<nsIPrincipal> resultPrincipal =
4390 BasePrincipal::CreateContentPrincipal(
4391 aNewURI, newLoadInfo->GetOriginAttributes());
4392 bool isConsideredSameOriginforUIR =
4393 nsContentSecurityUtils::IsConsideredSameOriginForUIR(
4394 newLoadInfo->TriggeringPrincipal(), resultPrincipal);
4395 static_cast<mozilla::net::LoadInfo*>(newLoadInfo.get())
4396 ->SetUpgradeInsecureRequests(isConsideredSameOriginforUIR);
4397 }
4398 }
4399 }
4400
4401 // Leave empty, we want a 'clean ground' when creating the new channel.
4402 // This will be ensured to be either set by the protocol handler or set
4403 // to the redirect target URI properly after the channel creation.
4404 newLoadInfo->SetResultPrincipalURI(nullptr);
4405
4406 bool isInternalRedirect =
4407 (aRedirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
4408 nsIChannelEventSink::REDIRECT_STS_UPGRADE));
4409
4410 // Reset our sandboxed null principal ID when cloning loadInfo for an
4411 // externally visible redirect.
4412 if (!isInternalRedirect) {
4413 // If we've redirected from http to something that isn't, clear
4414 // the "external" flag, as loads that now go to other apps should be
4415 // allowed to go ahead and not trip infinite-loop protection
4416 // (see bug 1717314 for context).
4417 if (!aNewURI->SchemeIs("http") && !aNewURI->SchemeIs("https")) {
4418 newLoadInfo->SetLoadTriggeredFromExternal(false);
4419 }
4420 newLoadInfo->ResetSandboxedNullPrincipalID();
4421 }
4422
4423 newLoadInfo->AppendRedirectHistoryEntry(this, isInternalRedirect);
4424
4425 return newLoadInfo.forget();
4426}
4427
4428//-----------------------------------------------------------------------------
4429// nsHttpChannel::nsITraceableChannel
4430//-----------------------------------------------------------------------------
4431
4432NS_IMETHODIMPnsresult
4433HttpBaseChannel::SetNewListener(nsIStreamListener* aListener,
4434 bool aMustApplyContentConversion,
4435 nsIStreamListener** _retval) {
4436 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)
4437 "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)
4438 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)
;
4439
4440 if (!LoadTracingEnabled()) return NS_ERROR_FAILURE;
4441
4442 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"
, 4442); return NS_ERROR_UNEXPECTED; } } while (false)
;
4443 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"
, 4443); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4444
4445 nsCOMPtr<nsIStreamListener> wrapper = new nsStreamListenerWrapper(mListener);
4446
4447 wrapper.forget(_retval);
4448 mListener = aListener;
4449 if (aMustApplyContentConversion) {
4450 StoreListenerRequiresContentConversion(true);
4451 }
4452 return NS_OK;
4453}
4454
4455//-----------------------------------------------------------------------------
4456// HttpBaseChannel helpers
4457//-----------------------------------------------------------------------------
4458
4459void HttpBaseChannel::ReleaseListeners() {
4460 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"
, 4461); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentThread->IsOnCurrentThread()"
") (" "Should only be called on the current thread" ")"); do
{ *((volatile int*)__null) = 4461; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
4461 "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"
, 4461); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentThread->IsOnCurrentThread()"
") (" "Should only be called on the current thread" ")"); do
{ *((volatile int*)__null) = 4461; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
4462
4463 mListener = nullptr;
4464 mCallbacks = nullptr;
4465 mProgressSink = nullptr;
4466 mCompressListener = nullptr;
4467 mORB = nullptr;
4468}
4469
4470void HttpBaseChannel::DoNotifyListener() {
4471 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)
;
4472
4473 // In case nsHttpChannel::OnStartRequest wasn't called (e.g. due to flag
4474 // LOAD_ONLY_IF_MODIFIED) we want to set AfterOnStartRequestBegun to true
4475 // before notifying listener.
4476 if (!LoadAfterOnStartRequestBegun()) {
4477 StoreAfterOnStartRequestBegun(true);
4478 }
4479
4480 if (mListener && !LoadOnStartRequestCalled()) {
4481 nsCOMPtr<nsIStreamListener> listener = mListener;
4482 StoreOnStartRequestCalled(true);
4483 listener->OnStartRequest(this);
4484 }
4485 StoreOnStartRequestCalled(true);
4486
4487 // Make sure IsPending is set to false. At this moment we are done from
4488 // the point of view of our consumer and we have to report our self
4489 // as not-pending.
4490 StoreIsPending(false);
4491
4492 // notify "http-on-before-stop-request" observers
4493 gHttpHandler->OnBeforeStopRequest(this);
4494
4495 if (mListener && !LoadOnStopRequestCalled()) {
4496 nsCOMPtr<nsIStreamListener> listener = mListener;
4497 StoreOnStopRequestCalled(true);
4498 listener->OnStopRequest(this, mStatus);
4499 }
4500 StoreOnStopRequestCalled(true);
4501
4502 // notify "http-on-stop-request" observers
4503 gHttpHandler->OnStopRequest(this);
4504
4505 // This channel has finished its job, potentially release any tail-blocked
4506 // requests with this.
4507 RemoveAsNonTailRequest();
4508
4509 // We have to make sure to drop the references to listeners and callbacks
4510 // no longer needed.
4511 ReleaseListeners();
4512
4513 DoNotifyListenerCleanup();
4514
4515 // If this is a navigation, then we must let the docshell flush the reports
4516 // to the console later. The LoadDocument() is pointing at the detached
4517 // document that started the navigation. We want to show the reports on the
4518 // new document. Otherwise the console is wiped and the user never sees
4519 // the information.
4520 if (!IsNavigation()) {
4521 if (mLoadGroup) {
4522 FlushConsoleReports(mLoadGroup);
4523 } else {
4524 RefPtr<dom::Document> doc;
4525 mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
4526 FlushConsoleReports(doc);
4527 }
4528 }
4529}
4530
4531void HttpBaseChannel::AddCookiesToRequest() {
4532 if (mLoadFlags & LOAD_ANONYMOUS) {
4533 return;
4534 }
4535
4536 bool useCookieService = (XRE_IsParentProcess());
4537 nsAutoCString cookie;
4538 if (useCookieService) {
4539 nsICookieService* cs = gHttpHandler->GetCookieService();
4540 if (cs) {
4541 cs->GetCookieStringFromHttp(mURI, this, cookie);
4542 }
4543
4544 if (cookie.IsEmpty()) {
4545 cookie = mUserSetCookieHeader;
4546 } else if (!mUserSetCookieHeader.IsEmpty()) {
4547 cookie.AppendLiteral("; ");
4548 cookie.Append(mUserSetCookieHeader);
4549 }
4550 } else {
4551 cookie = mUserSetCookieHeader;
4552 }
4553
4554 // If we are in the child process, we want the parent seeing any
4555 // cookie headers that might have been set by SetRequestHeader()
4556 SetRequestHeader(nsHttp::Cookie.val(), cookie, false);
4557}
4558
4559/* static */
4560void HttpBaseChannel::PropagateReferenceIfNeeded(
4561 nsIURI* aURI, nsCOMPtr<nsIURI>& aRedirectURI) {
4562 bool hasRef = false;
4563 nsresult rv = aRedirectURI->GetHasRef(&hasRef);
4564 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !hasRef) {
4565 nsAutoCString ref;
4566 aURI->GetRef(ref);
4567 if (!ref.IsEmpty()) {
4568 // NOTE: SetRef will fail if mRedirectURI is immutable
4569 // (e.g. an about: URI)... Oh well.
4570 Unused << NS_MutateURI(aRedirectURI).SetRef(ref).Finalize(aRedirectURI);
4571 }
4572 }
4573}
4574
4575bool HttpBaseChannel::ShouldRewriteRedirectToGET(
4576 uint32_t httpStatus, nsHttpRequestHead::ParsedMethodType method) {
4577 // for 301 and 302, only rewrite POST
4578 if (httpStatus == 301 || httpStatus == 302) {
4579 return method == nsHttpRequestHead::kMethod_Post;
4580 }
4581
4582 // rewrite for 303 unless it was HEAD
4583 if (httpStatus == 303) return method != nsHttpRequestHead::kMethod_Head;
4584
4585 // otherwise, such as for 307, do not rewrite
4586 return false;
4587}
4588
4589NS_IMETHODIMPnsresult
4590HttpBaseChannel::ShouldStripRequestBodyHeader(const nsACString& aMethod,
4591 bool* aResult) {
4592 *aResult = false;
4593 uint32_t httpStatus = 0;
4594 if (NS_FAILED(GetResponseStatus(&httpStatus))((bool)(__builtin_expect(!!(NS_FAILED_impl(GetResponseStatus(
&httpStatus))), 0)))
) {
4595 return NS_OK;
4596 }
4597
4598 nsAutoCString method(aMethod);
4599 nsHttpRequestHead::ParsedMethodType parsedMethod;
4600 nsHttpRequestHead::ParseMethod(method, parsedMethod);
4601 // Fetch 4.4.11, which is slightly different than the perserved method
4602 // algrorithm: strip request-body-header for GET->GET redirection for 303.
4603 *aResult =
4604 ShouldRewriteRedirectToGET(httpStatus, parsedMethod) &&
4605 !(httpStatus == 303 && parsedMethod == nsHttpRequestHead::kMethod_Get);
4606
4607 return NS_OK;
4608}
4609
4610HttpBaseChannel::ReplacementChannelConfig
4611HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod,
4612 uint32_t aRedirectFlags,
4613 ReplacementReason aReason) {
4614 ReplacementChannelConfig config;
4615 config.redirectFlags = aRedirectFlags;
4616 config.classOfService = mClassOfService;
4617
4618 if (mPrivateBrowsingOverriden) {
4619 config.privateBrowsing = Some(mPrivateBrowsing);
4620 }
4621
4622 if (mReferrerInfo) {
4623 // When cloning for a document channel replacement (parent process
4624 // copying values for a new content process channel), this happens after
4625 // OnStartRequest so we have the headers for the response available.
4626 // We don't want to apply them to the referrer for the channel though,
4627 // since that is the referrer for the current document, and the header
4628 // should only apply to navigations from the current document.
4629 if (aReason == ReplacementReason::DocumentChannel) {
4630 config.referrerInfo = mReferrerInfo;
4631 } else {
4632 dom::ReferrerPolicy referrerPolicy = dom::ReferrerPolicy::_empty;
4633 nsAutoCString tRPHeaderCValue;
4634 Unused << GetResponseHeader("referrer-policy"_ns, tRPHeaderCValue);
4635 NS_ConvertUTF8toUTF16 tRPHeaderValue(tRPHeaderCValue);
4636
4637 if (!tRPHeaderValue.IsEmpty()) {
4638 referrerPolicy =
4639 dom::ReferrerInfo::ReferrerPolicyFromHeaderString(tRPHeaderValue);
4640 }
4641
4642 // In case we are here because an upgrade happened through mixed content
4643 // upgrading, CSP upgrade-insecure-requests, HTTPS-Only or HTTPS-First, we
4644 // have to recalculate the referrer based on the original referrer to
4645 // account for the different scheme. This does NOT apply to HSTS.
4646 // See Bug 1857894 and order of https://fetch.spec.whatwg.org/#main-fetch.
4647 // Otherwise, if we have a new referrer policy, we want to recalculate the
4648 // referrer based on the old computed referrer (Bug 1678545).
4649 bool wasNonHSTSUpgrade =
4650 (aRedirectFlags & nsIChannelEventSink::REDIRECT_STS_UPGRADE) &&
4651 (!mLoadInfo->GetHstsStatus());
4652 if (wasNonHSTSUpgrade) {
4653 nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetOriginalReferrer();
4654 config.referrerInfo =
4655 new dom::ReferrerInfo(referrer, mReferrerInfo->ReferrerPolicy(),
4656 mReferrerInfo->GetSendReferrer());
4657 } else if (referrerPolicy != dom::ReferrerPolicy::_empty) {
4658 nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetComputedReferrer();
4659 config.referrerInfo = new dom::ReferrerInfo(
4660 referrer, referrerPolicy, mReferrerInfo->GetSendReferrer());
4661 } else {
4662 config.referrerInfo = mReferrerInfo;
4663 }
4664 }
4665 }
4666
4667 nsCOMPtr<nsITimedChannel> oldTimedChannel(
4668 do_QueryInterface(static_cast<nsIHttpChannel*>(this)));
4669 if (oldTimedChannel) {
4670 config.timedChannelInfo = Some(dom::TimedChannelInfo());
4671 config.timedChannelInfo->timingEnabled() = LoadTimingEnabled();
4672 config.timedChannelInfo->redirectCount() = mRedirectCount;
4673 config.timedChannelInfo->internalRedirectCount() = mInternalRedirectCount;
4674 config.timedChannelInfo->asyncOpen() = mAsyncOpenTime;
4675 config.timedChannelInfo->channelCreation() = mChannelCreationTimestamp;
4676 config.timedChannelInfo->redirectStart() = mRedirectStartTimeStamp;
4677 config.timedChannelInfo->redirectEnd() = mRedirectEndTimeStamp;
4678 config.timedChannelInfo->initiatorType() = mInitiatorType;
4679 config.timedChannelInfo->allRedirectsSameOrigin() =
4680 LoadAllRedirectsSameOrigin();
4681 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() =
4682 LoadAllRedirectsPassTimingAllowCheck();
4683 // Execute the timing allow check to determine whether
4684 // to report the redirect timing info
4685 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
4686 // TYPE_DOCUMENT loads don't have a loadingPrincipal, so we can't set
4687 // AllRedirectsPassTimingAllowCheck on them.
4688 if (loadInfo->GetExternalContentPolicyType() !=
4689 ExtContentPolicy::TYPE_DOCUMENT) {
4690 nsCOMPtr<nsIPrincipal> principal = loadInfo->GetLoadingPrincipal();
4691 config.timedChannelInfo->timingAllowCheckForPrincipal() =
4692 Some(oldTimedChannel->TimingAllowCheck(principal));
4693 }
4694
4695 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() =
4696 LoadAllRedirectsPassTimingAllowCheck();
4697 config.timedChannelInfo->launchServiceWorkerStart() =
4698 mLaunchServiceWorkerStart;
4699 config.timedChannelInfo->launchServiceWorkerEnd() = mLaunchServiceWorkerEnd;
4700 config.timedChannelInfo->dispatchFetchEventStart() =
4701 mDispatchFetchEventStart;
4702 config.timedChannelInfo->dispatchFetchEventEnd() = mDispatchFetchEventEnd;
4703 config.timedChannelInfo->handleFetchEventStart() = mHandleFetchEventStart;
4704 config.timedChannelInfo->handleFetchEventEnd() = mHandleFetchEventEnd;
4705 config.timedChannelInfo->responseStart() =
4706 mTransactionTimings.responseStart;
4707 config.timedChannelInfo->responseEnd() = mTransactionTimings.responseEnd;
4708 }
4709
4710 if (aPreserveMethod) {
4711 // since preserveMethod is true, we need to ensure that the appropriate
4712 // request method gets set on the channel, regardless of whether or not
4713 // we set the upload stream above. This means SetRequestMethod() will
4714 // be called twice if ExplicitSetUploadStream() gets called above.
4715
4716 nsAutoCString method;
4717 mRequestHead.Method(method);
4718 config.method = Some(method);
4719
4720 if (mUploadStream) {
4721 // rewind upload stream
4722 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
4723 if (seekable) {
4724 seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
4725 }
4726 config.uploadStream = mUploadStream;
4727 }
4728 config.uploadStreamLength = mReqContentLength;
4729 config.uploadStreamHasHeaders = LoadUploadStreamHasHeaders();
4730
4731 nsAutoCString contentType;
4732 nsresult rv = mRequestHead.GetHeader(nsHttp::Content_Type, contentType);
4733 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4734 config.contentType = Some(contentType);
4735 }
4736
4737 nsAutoCString contentLength;
4738 rv = mRequestHead.GetHeader(nsHttp::Content_Length, contentLength);
4739 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4740 config.contentLength = Some(contentLength);
4741 }
4742 }
4743
4744 return config;
4745}
4746
4747/* static */ void HttpBaseChannel::ConfigureReplacementChannel(
4748 nsIChannel* newChannel, const ReplacementChannelConfig& config,
4749 ReplacementReason aReason) {
4750 nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(newChannel));
4751 if (cos) {
4752 cos->SetClassOfService(config.classOfService);
4753 }
4754
4755 // Try to preserve the privacy bit if it has been overridden
4756 if (config.privateBrowsing) {
4757 nsCOMPtr<nsIPrivateBrowsingChannel> newPBChannel =
4758 do_QueryInterface(newChannel);
4759 if (newPBChannel) {
4760 newPBChannel->SetPrivate(*config.privateBrowsing);
4761 }
4762 }
4763
4764 // Transfer the timing data (if we are dealing with an nsITimedChannel).
4765 nsCOMPtr<nsITimedChannel> newTimedChannel(do_QueryInterface(newChannel));
4766 if (config.timedChannelInfo && newTimedChannel) {
4767 newTimedChannel->SetTimingEnabled(config.timedChannelInfo->timingEnabled());
4768
4769 // If we're an internal redirect, or a document channel replacement,
4770 // then we shouldn't record any new timing for this and just copy
4771 // over the existing values.
4772 bool shouldHideTiming = aReason != ReplacementReason::Redirect;
4773 if (shouldHideTiming) {
4774 newTimedChannel->SetRedirectCount(
4775 config.timedChannelInfo->redirectCount());
4776 int32_t newCount = config.timedChannelInfo->internalRedirectCount() + 1;
4777 newTimedChannel->SetInternalRedirectCount(std::max(
4778 newCount, static_cast<int32_t>(
4779 config.timedChannelInfo->internalRedirectCount())));
4780 } else {
4781 int32_t newCount = config.timedChannelInfo->redirectCount() + 1;
4782 newTimedChannel->SetRedirectCount(std::max(
4783 newCount,
4784 static_cast<int32_t>(config.timedChannelInfo->redirectCount())));
4785 newTimedChannel->SetInternalRedirectCount(
4786 config.timedChannelInfo->internalRedirectCount());
4787 }
4788
4789 if (shouldHideTiming) {
4790 if (!config.timedChannelInfo->channelCreation().IsNull()) {
4791 newTimedChannel->SetChannelCreation(
4792 config.timedChannelInfo->channelCreation());
4793 }
4794
4795 if (!config.timedChannelInfo->asyncOpen().IsNull()) {
4796 newTimedChannel->SetAsyncOpen(config.timedChannelInfo->asyncOpen());
4797 }
4798 }
4799
4800 // If the RedirectStart is null, we will use the AsyncOpen value of the
4801 // previous channel (this is the first redirect in the redirects chain).
4802 if (config.timedChannelInfo->redirectStart().IsNull()) {
4803 // Only do this for real redirects. Internal redirects should be hidden.
4804 if (!shouldHideTiming) {
4805 newTimedChannel->SetRedirectStart(config.timedChannelInfo->asyncOpen());
4806 }
4807 } else {
4808 newTimedChannel->SetRedirectStart(
4809 config.timedChannelInfo->redirectStart());
4810 }
4811
4812 // For internal redirects just propagate the last redirect end time
4813 // forward. Otherwise the new redirect end time is the last response
4814 // end time.
4815 TimeStamp newRedirectEnd;
4816 if (shouldHideTiming) {
4817 newRedirectEnd = config.timedChannelInfo->redirectEnd();
4818 } else if (!config.timedChannelInfo->responseEnd().IsNull()) {
4819 newRedirectEnd = config.timedChannelInfo->responseEnd();
4820 } else {
4821 newRedirectEnd = TimeStamp::Now();
4822 }
4823 newTimedChannel->SetRedirectEnd(newRedirectEnd);
4824
4825 newTimedChannel->SetInitiatorType(config.timedChannelInfo->initiatorType());
4826
4827 nsCOMPtr<nsILoadInfo> loadInfo = newChannel->LoadInfo();
4828 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"
, 4828); AnnotateMozCrashReason("MOZ_ASSERT" "(" "loadInfo" ")"
); do { *((volatile int*)__null) = 4828; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4829
4830 newTimedChannel->SetAllRedirectsSameOrigin(
4831 config.timedChannelInfo->allRedirectsSameOrigin());
4832
4833 if (config.timedChannelInfo->timingAllowCheckForPrincipal()) {
4834 newTimedChannel->SetAllRedirectsPassTimingAllowCheck(
4835 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() &&
4836 *config.timedChannelInfo->timingAllowCheckForPrincipal());
4837 }
4838
4839 // Propagate service worker measurements across redirects. The
4840 // PeformanceResourceTiming.workerStart API expects to see the
4841 // worker start time after a redirect.
4842 newTimedChannel->SetLaunchServiceWorkerStart(
4843 config.timedChannelInfo->launchServiceWorkerStart());
4844 newTimedChannel->SetLaunchServiceWorkerEnd(
4845 config.timedChannelInfo->launchServiceWorkerEnd());
4846 newTimedChannel->SetDispatchFetchEventStart(
4847 config.timedChannelInfo->dispatchFetchEventStart());
4848 newTimedChannel->SetDispatchFetchEventEnd(
4849 config.timedChannelInfo->dispatchFetchEventEnd());
4850 newTimedChannel->SetHandleFetchEventStart(
4851 config.timedChannelInfo->handleFetchEventStart());
4852 newTimedChannel->SetHandleFetchEventEnd(
4853 config.timedChannelInfo->handleFetchEventEnd());
4854 }
4855
4856 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
4857 if (!httpChannel) {
4858 return; // no other options to set
4859 }
4860
4861 if (config.uploadStream) {
4862 nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(httpChannel);
4863 nsCOMPtr<nsIUploadChannel2> uploadChannel2 = do_QueryInterface(httpChannel);
4864 if (uploadChannel2 || uploadChannel) {
4865 // replicate original call to SetUploadStream...
4866 if (uploadChannel2) {
4867 const nsACString& ctype =
4868 config.contentType ? *config.contentType : VoidCString();
4869 // If header is not present mRequestHead.HasHeaderValue will truncated
4870 // it. But we want to end up with a void string, not an empty string,
4871 // because ExplicitSetUploadStream treats the former as "no header" and
4872 // the latter as "header with empty string value".
4873
4874 const nsACString& method =
4875 config.method ? *config.method : VoidCString();
4876
4877 uploadChannel2->ExplicitSetUploadStream(
4878 config.uploadStream, ctype, config.uploadStreamLength, method,
4879 config.uploadStreamHasHeaders);
4880 } else {
4881 if (config.uploadStreamHasHeaders) {
4882 uploadChannel->SetUploadStream(config.uploadStream, ""_ns,
4883 config.uploadStreamLength);
4884 } else {
4885 nsAutoCString ctype;
4886 if (config.contentType) {
4887 ctype = *config.contentType;
4888 } else {
4889 ctype = "application/octet-stream"_ns;
4890 }
4891 if (config.contentLength && !config.contentLength->IsEmpty()) {
4892 uploadChannel->SetUploadStream(
4893 config.uploadStream, ctype,
4894 nsCRT::atoll(config.contentLength->get()));
4895 }
4896 }
4897 }
4898 }
4899 }
4900
4901 if (config.referrerInfo) {
4902 DebugOnly<nsresult> success{};
4903 success = httpChannel->SetReferrerInfo(config.referrerInfo);
4904 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"
, 4904); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)), 1)))"
")"); do { *((volatile int*)__null) = 4904; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4905 }
4906
4907 if (config.method) {
4908 DebugOnly<nsresult> rv = httpChannel->SetRequestMethod(*config.method);
4909 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"
, 4909); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4909; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4910 }
4911}
4912
4913HttpBaseChannel::ReplacementChannelConfig::ReplacementChannelConfig(
4914 const dom::ReplacementChannelConfigInit& aInit) {
4915 redirectFlags = aInit.redirectFlags();
4916 classOfService = aInit.classOfService();
4917 privateBrowsing = aInit.privateBrowsing();
4918 method = aInit.method();
4919 referrerInfo = aInit.referrerInfo();
4920 timedChannelInfo = aInit.timedChannelInfo();
4921 uploadStream = aInit.uploadStream();
4922 uploadStreamLength = aInit.uploadStreamLength();
4923 uploadStreamHasHeaders = aInit.uploadStreamHasHeaders();
4924 contentType = aInit.contentType();
4925 contentLength = aInit.contentLength();
4926}
4927
4928dom::ReplacementChannelConfigInit
4929HttpBaseChannel::ReplacementChannelConfig::Serialize() {
4930 dom::ReplacementChannelConfigInit config;
4931 config.redirectFlags() = redirectFlags;
4932 config.classOfService() = classOfService;
4933 config.privateBrowsing() = privateBrowsing;
4934 config.method() = method;
4935 config.referrerInfo() = referrerInfo;
4936 config.timedChannelInfo() = timedChannelInfo;
4937 config.uploadStream() =
4938 uploadStream ? RemoteLazyInputStream::WrapStream(uploadStream) : nullptr;
4939 config.uploadStreamLength() = uploadStreamLength;
4940 config.uploadStreamHasHeaders() = uploadStreamHasHeaders;
4941 config.contentType() = contentType;
4942 config.contentLength() = contentLength;
4943
4944 return config;
4945}
4946
4947nsresult HttpBaseChannel::SetupReplacementChannel(nsIURI* newURI,
4948 nsIChannel* newChannel,
4949 bool preserveMethod,
4950 uint32_t redirectFlags) {
4951 nsresult rv;
4952
4953 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)
4954 ("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)
4955 "[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)
4956 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)
;
4957
4958 // Ensure the channel's loadInfo's result principal URI so that it's
4959 // either non-null or updated to the redirect target URI.
4960 // We must do this because in case the loadInfo's result principal URI
4961 // is null, it would be taken from OriginalURI of the channel. But we
4962 // overwrite it with the whole redirect chain first URI before opening
4963 // the target channel, hence the information would be lost.
4964 // If the protocol handler that created the channel wants to use
4965 // the originalURI of the channel as the principal URI, this fulfills
4966 // that request - newURI is the original URI of the channel.
4967 nsCOMPtr<nsILoadInfo> newLoadInfo = newChannel->LoadInfo();
4968 nsCOMPtr<nsIURI> resultPrincipalURI;
4969 rv = newLoadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
4970 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"
, 4970); return rv; } } while (false)
;
4971 if (!resultPrincipalURI) {
4972 rv = newLoadInfo->SetResultPrincipalURI(newURI);
4973 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"
, 4973); return rv; } } while (false)
;
4974 }
4975
4976 nsLoadFlags loadFlags = mLoadFlags;
4977 loadFlags |= LOAD_REPLACE;
4978
4979 // if the original channel was using SSL and this channel is not using
4980 // SSL, then no need to inhibit persistent caching. however, if the
4981 // original channel was not using SSL and has INHIBIT_PERSISTENT_CACHING
4982 // set, then allow the flag to apply to the redirected channel as well.
4983 // since we force set INHIBIT_PERSISTENT_CACHING on all HTTPS channels,
4984 // we only need to check if the original channel was using SSL.
4985 if (mURI->SchemeIs("https")) {
4986 loadFlags &= ~INHIBIT_PERSISTENT_CACHING;
4987 }
4988
4989 newChannel->SetLoadFlags(loadFlags);
4990
4991 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
4992
4993 ReplacementReason redirectType =
4994 (redirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL)
4995 ? ReplacementReason::InternalRedirect
4996 : ReplacementReason::Redirect;
4997 ReplacementChannelConfig config = CloneReplacementChannelConfig(
4998 preserveMethod, redirectFlags, redirectType);
4999 ConfigureReplacementChannel(newChannel, config, redirectType);
5000
5001 // Check whether or not this was a cross-domain redirect.
5002 nsCOMPtr<nsITimedChannel> newTimedChannel(do_QueryInterface(newChannel));
5003 bool sameOriginWithOriginalUri = SameOriginWithOriginalUri(newURI);
5004 if (config.timedChannelInfo && newTimedChannel) {
5005 newTimedChannel->SetAllRedirectsSameOrigin(
5006 config.timedChannelInfo->allRedirectsSameOrigin() &&
5007 sameOriginWithOriginalUri);
5008 }
5009
5010 newChannel->SetLoadGroup(mLoadGroup);
5011 newChannel->SetNotificationCallbacks(mCallbacks);
5012 // TODO: create tests for cross-origin redirect in bug 1662896.
5013 if (sameOriginWithOriginalUri) {
5014 newChannel->SetContentDisposition(mContentDispositionHint);
5015 if (mContentDispositionFilename) {
5016 newChannel->SetContentDispositionFilename(*mContentDispositionFilename);
5017 }
5018 }
5019
5020 if (!httpChannel) return NS_OK; // no other options to set
5021
5022 // Preserve the CORS preflight information.
5023 nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(newChannel);
5024 if (httpInternal) {
5025 httpInternal->SetLastRedirectFlags(redirectFlags);
5026
5027 if (LoadRequireCORSPreflight()) {
5028 httpInternal->SetCorsPreflightParameters(mUnsafeHeaders, false, false);
5029 }
5030 }
5031
5032 // convey the LoadAllowSTS() flags
5033 rv = httpChannel->SetAllowSTS(LoadAllowSTS());
5034 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"
, 5034); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5034; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5035
5036 // convey the Accept header value
5037 {
5038 nsAutoCString oldAcceptValue;
5039 nsresult hasHeader = mRequestHead.GetHeader(nsHttp::Accept, oldAcceptValue);
5040 if (NS_SUCCEEDED(hasHeader)((bool)(__builtin_expect(!!(!NS_FAILED_impl(hasHeader)), 1)))) {
5041 rv = httpChannel->SetRequestHeader("Accept"_ns, oldAcceptValue, false);
5042 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"
, 5042); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5042; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5043 }
5044 }
5045
5046 // convey the User-Agent header value
5047 // since we might be setting custom user agent from DevTools.
5048 if (httpInternal && mRequestMode == RequestMode::No_cors &&
5049 redirectType == ReplacementReason::Redirect) {
5050 nsAutoCString oldUserAgent;
5051 nsresult hasHeader =
5052 mRequestHead.GetHeader(nsHttp::User_Agent, oldUserAgent);
5053 if (NS_SUCCEEDED(hasHeader)((bool)(__builtin_expect(!!(!NS_FAILED_impl(hasHeader)), 1)))) {
5054 rv = httpChannel->SetRequestHeader("User-Agent"_ns, oldUserAgent, false);
5055 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"
, 5055); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5055; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5056 }
5057 }