Bug 1199049 - Part 2: Add a channel API for requesting CORS preflights; r=jduell
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 21 Aug 2015 17:31:56 -0400
changeset 294821 815732d94c8611c223ac3fbad37d0c852fd5d0c2
parent 294820 fd2477247c15a78ff3a2b2250728a0470caeec45
child 294822 712ee72787adb5731a3a2ba27a7b33079ace12a6
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjduell
bugs1199049
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1199049 - Part 2: Add a channel API for requesting CORS preflights; r=jduell
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/nsIHttpChannelInternal.idl
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -85,16 +85,18 @@ HttpBaseChannel::HttpBaseChannel()
   , mHttpHandler(gHttpHandler)
   , mReferrerPolicy(REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE)
   , mRedirectCount(0)
   , mForcePending(false)
   , mCorsIncludeCredentials(false)
   , mCorsMode(nsIHttpChannelInternal::CORS_MODE_NO_CORS)
   , mRedirectMode(nsIHttpChannelInternal::REDIRECT_MODE_FOLLOW)
   , mOnStartRequestCalled(false)
+  , mRequireCORSPreflight(false)
+  , mWithCredentials(false)
 {
   LOG(("Creating HttpBaseChannel @%x\n", this));
 
   // Subfields of unions cannot be targeted in an initializer list.
 #ifdef MOZ_VALGRIND
   // Zero the entire unions so that Valgrind doesn't complain when we send them
   // to another process.
   memset(&mSelfAddr, 0, sizeof(NetAddr));
@@ -2821,11 +2823,25 @@ HttpBaseChannel::EnsureSchedulingContext
         return false;
     }
 
     // Set the load group connection scope on the transaction
     rootLoadGroup->GetSchedulingContextID(&mSchedulingContextID);
     return true;
 }
 
+NS_IMETHODIMP
+HttpBaseChannel::SetCorsPreflightParameters(const nsTArray<nsCString>& aUnsafeHeaders,
+                                            bool aWithCredentials,
+                                            nsIPrincipal* aPrincipal)
+{
+  ENSURE_CALLED_BEFORE_CONNECT();
+
+  mRequireCORSPreflight = true;
+  mUnsafeHeaders = aUnsafeHeaders;
+  mWithCredentials = aWithCredentials;
+  mPreflightPrincipal = aPrincipal;
+  return NS_OK;
+}
+
 } // namespace net
 } // namespace mozilla
 
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -196,16 +196,19 @@ public:
   NS_IMETHOD GetCorsIncludeCredentials(bool* aInclude) override;
   NS_IMETHOD SetCorsIncludeCredentials(bool aInclude) override;
   NS_IMETHOD GetCorsMode(uint32_t* aCorsMode) override;
   NS_IMETHOD SetCorsMode(uint32_t aCorsMode) override;
   NS_IMETHOD GetRedirectMode(uint32_t* aRedirectMode) override;
   NS_IMETHOD SetRedirectMode(uint32_t aRedirectMode) override;
   NS_IMETHOD GetTopWindowURI(nsIURI **aTopWindowURI) override;
   NS_IMETHOD GetProxyURI(nsIURI **proxyURI) override;
+  NS_IMETHOD SetCorsPreflightParameters(const nsTArray<nsCString>& unsafeHeaders,
+                                        bool aWithCredentials,
+                                        nsIPrincipal* aPrincipal) override;
 
   inline void CleanRedirectCacheChainIfNecessary()
   {
       mRedirectedCachekeys = nullptr;
   }
   NS_IMETHOD HTTPUpgrade(const nsACString & aProtocolName,
                          nsIHttpUpgradeListener *aListener) override;
 
@@ -439,16 +442,21 @@ protected:
   // than once.
   bool mOnStartRequestCalled;
 
   // The network interface id that's associated with this channel.
   nsCString mNetworkInterfaceId;
 
   nsID mSchedulingContextID;
   bool EnsureSchedulingContextID();
+
+  bool                              mRequireCORSPreflight;
+  bool                              mWithCredentials;
+  nsTArray<nsCString>               mUnsafeHeaders;
+  nsCOMPtr<nsIPrincipal>            mPreflightPrincipal;
 };
 
 // Share some code while working around C++'s absurd inability to handle casting
 // of member functions between base/derived types.
 // - We want to store member function pointer to call at resume time, but one
 //   such function--HandleAsyncAbort--we want to share between the
 //   nsHttpChannel/HttpChannelChild.  Can't define it in base class, because
 //   then we'd have to cast member function ptr between base/derived class
--- a/netwerk/protocol/http/nsIHttpChannelInternal.idl
+++ b/netwerk/protocol/http/nsIHttpChannelInternal.idl
@@ -6,44 +6,45 @@
 #include "nsISupports.idl"
 
 %{C++
 template<class T> class nsTArray;
 template<class T> class nsCOMArray;
 class nsCString;
 %}
 [ptr] native StringArray(nsTArray<nsCString>);
+[ref] native StringArrayRef(const nsTArray<nsCString>);
 [ref] native securityMessagesArray(nsCOMArray<nsISecurityConsoleMessage>);
 
 interface nsIAsyncInputStream;
 interface nsIAsyncOutputStream;
 interface nsIPrincipal;
 interface nsIProxyInfo;
 interface nsISecurityConsoleMessage;
 interface nsISocketTransport;
 interface nsIURI;
 
 /**
  * The callback interface for nsIHttpChannelInternal::HTTPUpgrade()
  */
 
-[scriptable, uuid(7b48d081-1dc1-4d08-b7a5-81491bf28c0e)]
+[scriptable, uuid(5b515449-ab64-4dba-b3cd-da8fc2f83064)]
 interface nsIHttpUpgradeListener : nsISupports
 {
     void onTransportAvailable(in nsISocketTransport   aTransport,
                               in nsIAsyncInputStream  aSocketIn,
                               in nsIAsyncOutputStream aSocketOut);
 };
 
 /**
  * Dumping ground for http.  This interface will never be frozen.  If you are
  * using any feature exposed by this interface, be aware that this interface
  * will change and you will be broken.  You have been warned.
  */
-[scriptable, uuid(e2eebad8-e51f-473a-bbb7-8e2829376625)]
+[scriptable, uuid(46ef729f-4c9b-4084-b9e2-498992a31aee)]
 
 interface nsIHttpChannelInternal : nsISupports
 {
     /**
      * An http channel can own a reference to the document URI
      */
     attribute nsIURI documentURI;
 
@@ -259,9 +260,18 @@ interface nsIHttpChannelInternal : nsISu
      */
     attribute ACString networkInterfaceId;
 
     /**
      * Read the proxy URI, which, if non-null, will be used to resolve
      * proxies for this channel.
      */
     readonly attribute nsIURI proxyURI;
+
+    /**
+     * Make cross-origin CORS loads happen with a CORS preflight, and specify
+     * the CORS preflight parameters.
+     */
+    [noscript]
+    void setCorsPreflightParameters(in StringArrayRef unsafeHeaders,
+                                    in boolean withCredentials,
+                                    in nsIPrincipal preflightPrincipal);
 };