diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /netwerk/protocol/http/nsCORSListenerProxy.h | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'netwerk/protocol/http/nsCORSListenerProxy.h')
-rw-r--r-- | netwerk/protocol/http/nsCORSListenerProxy.h | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/netwerk/protocol/http/nsCORSListenerProxy.h b/netwerk/protocol/http/nsCORSListenerProxy.h new file mode 100644 index 0000000000..3f8c13ea64 --- /dev/null +++ b/netwerk/protocol/http/nsCORSListenerProxy.h @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsCORSListenerProxy_h__ +#define nsCORSListenerProxy_h__ + +#include "nsIStreamListener.h" +#include "nsIInterfaceRequestor.h" +#include "nsCOMPtr.h" +#include "nsString.h" +#include "nsIURI.h" +#include "nsTArray.h" +#include "nsIInterfaceRequestor.h" +#include "nsIChannelEventSink.h" +#include "nsIThreadRetargetableStreamListener.h" +#include "mozilla/Attributes.h" +#include "mozilla/Atomics.h" +#include "mozilla/Mutex.h" + +class nsIHttpChannel; +class nsIURI; +class nsIPrincipal; +class nsINetworkInterceptController; +class nsICorsPreflightCallback; + +namespace mozilla { +namespace net { +class HttpChannelParent; +class nsHttpChannel; +} // namespace net +} // namespace mozilla + +enum class DataURIHandling { Allow, Disallow }; + +enum class UpdateType { + Default, + StripRequestBodyHeader, + InternalOrHSTSRedirect +}; + +class nsCORSListenerProxy final : public nsIStreamListener, + public nsIInterfaceRequestor, + public nsIChannelEventSink, + public nsIThreadRetargetableStreamListener { + public: + nsCORSListenerProxy(nsIStreamListener* aOuter, + nsIPrincipal* aRequestingPrincipal, + bool aWithCredentials); + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSIINTERFACEREQUESTOR + NS_DECL_NSICHANNELEVENTSINK + NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER + + static void Shutdown(); + static void ClearCache(); + static void ClearPrivateBrowsingCache(); + + [[nodiscard]] nsresult Init(nsIChannel* aChannel, + DataURIHandling aAllowDataURI); + + void SetInterceptController( + nsINetworkInterceptController* aInterceptController); + + // When CORS blocks a request, log the message to the web console, or the + // browser console if no valid inner window ID is found. + static void LogBlockedCORSRequest(uint64_t aInnerWindowID, + bool aPrivateBrowsing, + bool aFromChromeContext, + const nsAString& aMessage, + const nsACString& aCategory, + bool aIsWarning = false); + + private: + // Only HttpChannelParent can call RemoveFromCorsPreflightCache + friend class mozilla::net::HttpChannelParent; + // Only nsHttpChannel can invoke CORS preflights + friend class mozilla::net::nsHttpChannel; + + static void RemoveFromCorsPreflightCache( + nsIURI* aURI, nsIPrincipal* aRequestingPrincipal, + const mozilla::OriginAttributes& aOriginAttributes); + [[nodiscard]] static nsresult StartCORSPreflight( + nsIChannel* aRequestChannel, nsICorsPreflightCallback* aCallback, + nsTArray<nsCString>& aUnsafeHeaders, nsIChannel** aPreflightChannel); + + ~nsCORSListenerProxy() = default; + + [[nodiscard]] nsresult UpdateChannel(nsIChannel* aChannel, + DataURIHandling aAllowDataURI, + UpdateType aUpdateType); + [[nodiscard]] nsresult CheckRequestApproved(nsIRequest* aRequest); + [[nodiscard]] nsresult CheckPreflightNeeded(nsIChannel* aChannel, + UpdateType aUpdateType); + + nsCOMPtr<nsIStreamListener> mOuterListener; + // The principal that originally kicked off the request + nsCOMPtr<nsIPrincipal> mRequestingPrincipal; + // The principal to use for our Origin header ("source origin" in spec terms). + // This can get changed during redirects, unlike mRequestingPrincipal. + nsCOMPtr<nsIPrincipal> mOriginHeaderPrincipal; + nsCOMPtr<nsIInterfaceRequestor> mOuterNotificationCallbacks; + nsCOMPtr<nsINetworkInterceptController> mInterceptController; + bool mWithCredentials; + mozilla::Atomic<bool, mozilla::Relaxed> mRequestApproved; + // Please note that the member variable mHasBeenCrossSite may rely on the + // promise that the CSP directive 'upgrade-insecure-requests' upgrades + // an http: request to https: in nsHttpChannel::Connect() and hence + // a request might not be marked as cross site request based on that promise. + bool mHasBeenCrossSite; + bool mIsRedirect = false; + // Under e10s, logging happens in the child process. Keep a reference to the + // creator nsIHttpChannel in order to find the way back to the child. Released + // in OnStopRequest(). + nsCOMPtr<nsIHttpChannel> mHttpChannel; +#ifdef DEBUG + bool mInited; +#endif + + // only locking mOuterListener, because it can be used on different threads. + // We guarantee that OnStartRequest, OnDataAvailable and OnStopReques will be + // called in order, but to make tsan happy we will lock mOuterListener. + mutable mozilla::Mutex mMutex MOZ_UNANNOTATED; +}; + +#endif |