DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (c68fe15a81fc)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
/* -*- 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
/* 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 "nsIStreamListener.h"
#include "nsIInterfaceRequestor.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIURI.h"
#include "nsTArray.h"
#include "nsTArray.h"
#include "nsIInterfaceRequestor.h"
#include "nsIChannelEventSink.h"
#include "nsIHttpChannel.h"
#include "nsIThreadRetargetableStreamListener.h"
#include "mozilla/Attributes.h"
#include "mozilla/Attributes.h"
#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h"

class nsIURI;
class nsIPrincipal;
class nsIPrincipal;
class nsINetworkInterceptController;
class nsICorsPreflightCallback;

namespace mozilla {
namespace net {
class HttpChannelParent;
class HttpChannelParent;
class nsHttpChannel;
}  // namespace net
}  // namespace mozilla

enum class DataURIHandling { Allow, Disallow };
enum class DataURIHandling { Allow, Disallow };

enum class UpdateType {
  Default,
  StripRequestBodyHeader,
                                  public nsIInterfaceRequestor,
  InternalOrHSTSRedirect
};

class nsCORSListenerProxy final : public nsIStreamListener,
                                  public nsIInterfaceRequestor,
                      nsIPrincipal* aRequestingPrincipal,
                                  public nsIChannelEventSink,
                                  public nsIThreadRetargetableStreamListener {
 public:
  nsCORSListenerProxy(nsIStreamListener* aOuter,
                      nsIPrincipal* aRequestingPrincipal,
  NS_DECL_NSISTREAMLISTENER
                      bool aWithCredentials);

  NS_DECL_THREADSAFE_ISUPPORTS
  NS_DECL_NSIREQUESTOBSERVER
  NS_DECL_NSISTREAMLISTENER
  static void Shutdown();
  NS_DECL_NSIINTERFACEREQUESTOR
  NS_DECL_NSICHANNELEVENTSINK
  NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER

  static void Shutdown();

  void SetInterceptController(
  [[nodiscard]] nsresult Init(nsIChannel* aChannel,
                              DataURIHandling aAllowDataURI);

  // When CORS blocks a request, log the message to the web console, or the
  void SetInterceptController(
  // browser console if no valid inner window ID is found.
      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,
                                    const nsACString& aCategory);
                                    bool aPrivateBrowsing,
                                    bool aFromChromeContext,
                                    const nsAString& aMessage,
                                    const nsACString& aCategory);

  // Only nsHttpChannel can invoke CORS preflights
 private:
  // Only HttpChannelParent can call RemoveFromCorsPreflightCache
  friend class mozilla::net::HttpChannelParent;
  // Only nsHttpChannel can invoke CORS preflights
  friend class mozilla::net::nsHttpChannel;
  [[nodiscard]] static nsresult StartCORSPreflight(

  static void RemoveFromCorsPreflightCache(nsIURI* aURI,
                                           nsIPrincipal* aRequestingPrincipal);
  [[nodiscard]] static nsresult StartCORSPreflight(

      nsIChannel* aRequestChannel, nsICorsPreflightCallback* aCallback,
      nsTArray<nsCString>& aACUnsafeHeaders, nsIChannel** aPreflightChannel);

  ~nsCORSListenerProxy() = default;

  [[nodiscard]] nsresult CheckPreflightNeeded(nsIChannel* aChannel,
  [[nodiscard]] nsresult UpdateChannel(nsIChannel* aChannel,
                                       DataURIHandling aAllowDataURI,
                                       UpdateType aUpdateType);
  [[nodiscard]] nsresult CheckRequestApproved(nsIRequest* aRequest);
  [[nodiscard]] nsresult CheckPreflightNeeded(nsIChannel* aChannel,
  // The principal that originally kicked off the request
                                              UpdateType aUpdateType);

  nsCOMPtr<nsIStreamListener> mOuterListener;
  // The principal that originally kicked off the request
  nsCOMPtr<nsIPrincipal> mRequestingPrincipal;
  nsCOMPtr<nsIInterfaceRequestor> mOuterNotificationCallbacks;
  // 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;
  // promise that the CSP directive 'upgrade-insecure-requests' upgrades
  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
  // creator nsIHttpChannel in order to find the way back to the child. Released
  // a request might not be marked as cross site request based on that promise.
  bool mHasBeenCrossSite;
  // 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().
#endif
  nsCOMPtr<nsIHttpChannel> mHttpChannel;
#ifdef DEBUG
  bool mInited;
#endif

  mutable mozilla::Mutex mMutex;
  // 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;
};

#endif