bug 378637 part 9 - https proxy info added to connection info and reqeuest head r=hurley
authorPatrick McManus <mcmanus@ducksong.com>
Wed, 16 Apr 2014 09:23:20 -0400
changeset 183604 c3d1fc8d2c26
parent 183603 3b293e8b4713
child 183605 fe6cab453921
push id26799
push userphilringnalda@gmail.com
push date2014-05-18 00:55 +0000
treeherdermozilla-central@00ef3a7d7aa7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershurley
bugs378637
milestone32.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 378637 part 9 - https proxy info added to connection info and reqeuest head r=hurley
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnectionInfo.cpp
netwerk/protocol/http/nsHttpConnectionInfo.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpRequestHead.cpp
netwerk/protocol/http/nsHttpRequestHead.h
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -1204,20 +1204,20 @@ nsresult
 nsHttpChannel::ProcessResponse()
 {
     nsresult rv;
     uint32_t httpStatus = mResponseHead->Status();
 
     // Gather data on whether the transaction and page (if this is
     // the initial page load) is being loaded with SSL.
     Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_IS_SSL,
-                          mConnectionInfo->UsingSSL());
+                          mConnectionInfo->EndToEndSSL());
     if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
         Telemetry::Accumulate(Telemetry::HTTP_PAGELOAD_IS_SSL,
-                              mConnectionInfo->UsingSSL());
+                              mConnectionInfo->EndToEndSSL());
     }
 
     LOG(("nsHttpChannel::ProcessResponse [this=%p httpStatus=%u]\n",
         this, httpStatus));
 
     if (mTransaction->ProxyConnectFailed()) {
         // Only allow 407 (authentication required) to continue
         if (httpStatus != 407)
@@ -1320,17 +1320,17 @@ nsHttpChannel::ProcessResponse()
         }
         else {
             successfulReval = true;
         }
         break;
     case 401:
     case 407:
         rv = mAuthProvider->ProcessAuthentication(
-            httpStatus, mConnectionInfo->UsingSSL() &&
+            httpStatus, mConnectionInfo->EndToEndSSL() &&
                         mTransaction->ProxyConnectFailed());
         if (rv == NS_ERROR_IN_PROGRESS)  {
             // authentication prompt has been invoked and result
             // is expected asynchronously
             mAuthRetryPending = true;
             if (httpStatus == 407 || mTransaction->ProxyConnectFailed())
                 mProxyAuthPending = true;
 
@@ -3746,17 +3746,17 @@ nsHttpChannel::UpdateInhibitPersistentCa
 {
     // The no-store directive within the 'Cache-Control:' header indicates
     // that we must not store the response in a persistent cache.
     if (mResponseHead->NoStore())
         mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
 
     // Only cache SSL content on disk if the pref is set
     if (!gHttpHandler->IsPersistentHttpsCachingEnabled() &&
-        mConnectionInfo->UsingSSL())
+        mConnectionInfo->EndToEndSSL())
         mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
 }
 
 nsresult
 nsHttpChannel::InitOfflineCacheEntry()
 {
     // This function can be called even when we fail to connect (bug 551990)
 
@@ -4554,16 +4554,17 @@ nsHttpChannel::BeginConnect()
     LOG(("host=%s port=%d\n", host.get(), port));
     LOG(("uri=%s\n", mSpec.get()));
 
     nsCOMPtr<nsProxyInfo> proxyInfo;
     if (mProxyInfo)
         proxyInfo = do_QueryInterface(mProxyInfo);
 
     mConnectionInfo = new nsHttpConnectionInfo(host, port, username, proxyInfo, usingSSL);
+    mRequestHead.SetHTTPS(usingSSL);
 
     mAuthProvider =
         do_CreateInstance("@mozilla.org/network/http-channel-auth-provider;1",
                           &rv);
     if (NS_SUCCEEDED(rv))
         rv = mAuthProvider->Init(this);
     if (NS_FAILED(rv))
         return rv;
@@ -4828,17 +4829,17 @@ nsHttpChannel::GetResponseEnd(TimeStamp*
 
 //-----------------------------------------------------------------------------
 // nsHttpChannel::nsIHttpAuthenticableChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsHttpChannel::GetIsSSL(bool *aIsSSL)
 {
-    *aIsSSL = mConnectionInfo->UsingSSL();
+    *aIsSSL = mConnectionInfo->EndToEndSSL();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHttpChannel::GetProxyMethodIsConnect(bool *aProxyMethodIsConnect)
 {
     *aProxyMethodIsConnect = mConnectionInfo->UsingConnect();
     return NS_OK;
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -414,17 +414,17 @@ nsHttpConnection::SetupSSL(uint32_t caps
 
     if (mNPNComplete)
         return;
 
     // we flip this back to false if SetNPNList succeeds at the end
     // of this function
     mNPNComplete = true;
 
-    if (!mConnInfo->UsingSSL())
+    if (!mConnInfo->EndToEndSSL())
         return;
 
     LOG(("nsHttpConnection::SetupSSL Setting up "
          "Next Protocol Negotiation"));
     nsCOMPtr<nsISupports> securityInfo;
     nsresult rv =
         mSocketTransport->GetSecurityInfo(getter_AddRefs(securityInfo));
     if (NS_FAILED(rv))
@@ -889,34 +889,34 @@ nsHttpConnection::OnHeadersAvailable(nsA
     // it was successful.  If so, we have to reset the transaction and step-up
     // the socket connection if using SSL. Finally, we have to wake up the
     // socket write request.
     if (mProxyConnectStream) {
         MOZ_ASSERT(!mUsingSpdyVersion,
                    "SPDY NPN Complete while using proxy connect stream");
         mProxyConnectStream = 0;
         if (responseStatus == 200) {
-            LOG(("proxy CONNECT succeeded! ssl=%s\n",
-                 mConnInfo->UsingSSL() ? "true" :"false"));
+            LOG(("proxy CONNECT succeeded! endtoendssl=%s\n",
+                 mConnInfo->EndToEndSSL() ? "true" :"false"));
             *reset = true;
             nsresult rv;
-            if (mConnInfo->UsingSSL()) {
+            if (mConnInfo->EndToEndSSL()) {
                 rv = ProxyStartSSL();
                 if (NS_FAILED(rv)) // XXX need to handle this for real
                     LOG(("ProxyStartSSL failed [rv=%x]\n", rv));
             }
             mCompletedProxyConnect = true;
             mProxyConnectInProgress = false;
             rv = mSocketOut->AsyncWait(this, 0, 0, nullptr);
             // XXX what if this fails -- need to handle this error
             MOZ_ASSERT(NS_SUCCEEDED(rv), "mSocketOut->AsyncWait failed");
         }
         else {
-            LOG(("proxy CONNECT failed! ssl=%s\n",
-                 mConnInfo->UsingSSL() ? "true" :"false"));
+            LOG(("proxy CONNECT failed! endtoendssl=%s\n",
+                 mConnInfo->EndToEndSSL() ? "true" :"false"));
             mTransaction->SetProxyConnectFailed();
         }
     }
 
     const char *upgradeReq = requestHead->PeekHeader(nsHttp::Upgrade);
     // Don't use persistent connection for Upgrade unless there's an auth failure:
     // some proxies expect to see auth response on persistent connection.
     if (upgradeReq && responseStatus != 401 && responseStatus != 407) {
--- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp
@@ -18,28 +18,29 @@
 #include "prnetdb.h"
 
 namespace mozilla {
 namespace net {
 
 nsHttpConnectionInfo::nsHttpConnectionInfo(const nsACString &host, int32_t port,
                                            const nsACString &username,
                                            nsProxyInfo* proxyInfo,
-                                           bool usingSSL)
+                                           bool endToEndSSL)
     : mUsername(username)
     , mProxyInfo(proxyInfo)
-    , mUsingSSL(usingSSL)
+    , mEndToEndSSL(endToEndSSL)
     , mUsingConnect(false)
 {
     LOG(("Creating nsHttpConnectionInfo @%x\n", this));
 
-    mUsingHttpProxy = (proxyInfo && proxyInfo->IsHTTP());
+    mUsingHttpsProxy = (proxyInfo && proxyInfo->IsHTTPS());
+    mUsingHttpProxy = mUsingHttpsProxy || (proxyInfo && proxyInfo->IsHTTP());
 
     if (mUsingHttpProxy) {
-        mUsingConnect = mUsingSSL;  // SSL always uses CONNECT
+        mUsingConnect = mEndToEndSSL;  // SSL always uses CONNECT
         uint32_t resolveFlags = 0;
         if (NS_SUCCEEDED(mProxyInfo->GetResolveFlags(&resolveFlags)) &&
             resolveFlags & nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL) {
             mUsingConnect = true;
         }
     }
 
     SetOriginServer(host, port);
@@ -68,30 +69,40 @@ nsHttpConnectionInfo::SetOriginServer(co
         keyHost = ProxyHost();
         keyPort = ProxyPort();
     }
     else {
         keyHost = Host();
         keyPort = Port();
     }
 
+    // The hashkey has 4 fields followed by host connection info
+    // byte 0 is P/T/. {P,T} for Plaintext/TLS Proxy over HTTP
+    // byte 1 is S/. S is for end to end ssl such as https:// uris
+    // byte 2 is A/. A is for an anonymous channel (no cookies, etc..)
+    // byte 3 is P/. P is for a private browising channel
     mHashKey.AssignLiteral("....");
+
     mHashKey.Append(keyHost);
     mHashKey.Append(':');
     mHashKey.AppendInt(keyPort);
     if (!mUsername.IsEmpty()) {
         mHashKey.Append('[');
         mHashKey.Append(mUsername);
         mHashKey.Append(']');
     }
 
-    if (mUsingHttpProxy)
+    if (mUsingHttpsProxy) {
+        mHashKey.SetCharAt('T', 0);
+    } else if (mUsingHttpProxy) {
         mHashKey.SetCharAt('P', 0);
-    if (mUsingSSL)
+    }
+    if (mEndToEndSSL) {
         mHashKey.SetCharAt('S', 1);
+    }
 
     // NOTE: for transparent proxies (e.g., SOCKS) we need to encode the proxy
     // info in the hash key (this ensures that we will continue to speak the
     // right protocol even if our proxy preferences change).
     //
     // NOTE: for SSL tunnels add the proxy information to the cache key.
     // We cannot use the proxy as the host parameter (as we do for non SSL)
     // because this is a single host tunnel, but we need to include the proxy
@@ -108,17 +119,17 @@ nsHttpConnectionInfo::SetOriginServer(co
         mHashKey.AppendInt(ProxyPort());
         mHashKey.Append(')');
     }
 }
 
 nsHttpConnectionInfo*
 nsHttpConnectionInfo::Clone() const
 {
-    nsHttpConnectionInfo* clone = new nsHttpConnectionInfo(mHost, mPort, mUsername, mProxyInfo, mUsingSSL);
+    nsHttpConnectionInfo* clone = new nsHttpConnectionInfo(mHost, mPort, mUsername, mProxyInfo, mEndToEndSSL);
 
     // Make sure the anonymous and private flags are transferred!
     clone->SetAnonymous(GetAnonymous());
     clone->SetPrivate(GetPrivate());
 
     return clone;
 }
 
--- a/netwerk/protocol/http/nsHttpConnectionInfo.h
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.h
@@ -21,17 +21,17 @@ extern PRLogModuleInfo *gHttpLog;
 namespace mozilla { namespace net {
 
 class nsHttpConnectionInfo
 {
 public:
     nsHttpConnectionInfo(const nsACString &host, int32_t port,
                          const nsACString &username,
                          nsProxyInfo* proxyInfo,
-                         bool usingSSL=false);
+                         bool endToEndSSL = false);
 
     virtual ~nsHttpConnectionInfo()
     {
         PR_LOG(gHttpLog, 4, ("Destroying nsHttpConnectionInfo @%x\n", this));
     }
 
     const nsAFlatCString &HashKey() const { return mHashKey; }
 
@@ -60,42 +60,55 @@ public:
     {
         return mHashKey.Equals(info->HashKey());
     }
 
     const char   *Host() const           { return mHost.get(); }
     int32_t       Port() const           { return mPort; }
     const char   *Username() const       { return mUsername.get(); }
     nsProxyInfo  *ProxyInfo()            { return mProxyInfo; }
-    bool          UsingHttpProxy() const { return mUsingHttpProxy; }
-    bool          UsingSSL() const       { return mUsingSSL; }
-    bool          UsingConnect() const   { return mUsingConnect; }
-    int32_t       DefaultPort() const    { return mUsingSSL ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; }
+    int32_t       DefaultPort() const    { return mEndToEndSSL ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; }
     void          SetAnonymous(bool anon)
                                          { mHashKey.SetCharAt(anon ? 'A' : '.', 2); }
     bool          GetAnonymous() const   { return mHashKey.CharAt(2) == 'A'; }
     void          SetPrivate(bool priv)  { mHashKey.SetCharAt(priv ? 'P' : '.', 3); }
     bool          GetPrivate() const     { return mHashKey.CharAt(3) == 'P'; }
 
     const nsCString &GetHost() { return mHost; }
 
-    // Returns true for any kind of proxy (http, socks, etc..)
+    // Returns true for any kind of proxy (http, socks, https, etc..)
     bool UsingProxy();
 
+    // Returns true when proxying over HTTP or HTTPS
+    bool UsingHttpProxy() const { return mUsingHttpProxy || mUsingHttpsProxy; }
+
+    // Returns true when proxying over HTTPS
+    bool UsingHttpsProxy() const { return mUsingHttpsProxy; }
+
+    // Returns true when a resource is in SSL end to end (e.g. https:// uri)
+    bool EndToEndSSL() const { return mEndToEndSSL; }
+
+    // Returns true when at least first hop is SSL (e.g. proxy over https or https uri)
+    bool FirstHopSSL() const { return mEndToEndSSL || mUsingHttpsProxy; }
+
+    // Returns true when CONNECT is used to tunnel through the proxy (e.g. https:// or ws://)
+    bool UsingConnect() const { return mUsingConnect; }
+
     // Returns true when mHost is an RFC1918 literal.
     bool HostIsLocalIPLiteral() const;
 
 private:
     nsCString              mHashKey;
     nsCString              mHost;
     int32_t                mPort;
     nsCString              mUsername;
     nsCOMPtr<nsProxyInfo>  mProxyInfo;
     bool                   mUsingHttpProxy;
-    bool                   mUsingSSL;
+    bool                   mUsingHttpsProxy;
+    bool                   mEndToEndSSL;
     bool                   mUsingConnect;  // if will use CONNECT with http proxy
 
 // for nsRefPtr
     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHttpConnectionInfo)
 };
 
 }} // namespace mozilla::net
 
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -1304,17 +1304,17 @@ nsHttpConnectionMgr::RestrictConnections
                                          bool ignorePossibleSpdyConnections)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
 
     // If this host is trying to negotiate a SPDY session right now,
     // don't create any new ssl connections until the result of the
     // negotiation is known.
 
-    bool doRestrict = ent->mConnInfo->UsingSSL() &&
+    bool doRestrict = ent->mConnInfo->FirstHopSSL() &&
         gHttpHandler->IsSpdyEnabled() &&
         ((!ent->mTestedSpdy && !ignorePossibleSpdyConnections) ||
          ent->mUsingSpdy) &&
         (ent->mHalfOpens.Length() || ent->mActiveConns.Length());
 
     // If there are no restrictions, we are done
     if (!doRestrict)
         return false;
@@ -1887,20 +1887,22 @@ nsHttpConnectionMgr::BuildPipeline(nsCon
     pipeline->AddTransaction(firstTrans);
     NS_ADDREF(*result = pipeline);
     return NS_OK;
 }
 
 void
 nsHttpConnectionMgr::ReportProxyTelemetry(nsConnectionEntry *ent)
 {
-    enum { PROXY_NONE = 1, PROXY_HTTP = 2, PROXY_SOCKS = 3 };
+    enum { PROXY_NONE = 1, PROXY_HTTP = 2, PROXY_SOCKS = 3, PROXY_HTTPS = 4 };
 
     if (!ent->mConnInfo->UsingProxy())
         Telemetry::Accumulate(Telemetry::HTTP_PROXY_TYPE, PROXY_NONE);
+    else if (ent->mConnInfo->UsingHttpsProxy())
+        Telemetry::Accumulate(Telemetry::HTTP_PROXY_TYPE, PROXY_HTTPS);
     else if (ent->mConnInfo->UsingHttpProxy())
         Telemetry::Accumulate(Telemetry::HTTP_PROXY_TYPE, PROXY_HTTP);
     else
         Telemetry::Accumulate(Telemetry::HTTP_PROXY_TYPE, PROXY_SOCKS);
 }
 
 nsresult
 nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
@@ -2729,18 +2731,18 @@ nsHalfOpenSocket::nsHalfOpenSocket(nsCon
     , mTransaction(trans)
     , mCaps(caps)
     , mSpeculative(false)
     , mHasConnected(false)
     , mPrimaryConnectedOK(false)
     , mBackupConnectedOK(false)
 {
     MOZ_ASSERT(ent && trans, "constructor with null arguments");
-    LOG(("Creating nsHalfOpenSocket [this=%p trans=%p ent=%s]\n",
-         this, trans, ent->mConnInfo->Host()));
+    LOG(("Creating nsHalfOpenSocket [this=%p trans=%p ent=%s key=%s]\n",
+         this, trans, ent->mConnInfo->Host(), ent->mConnInfo->HashKey().get()));
 }
 
 nsHttpConnectionMgr::nsHalfOpenSocket::~nsHalfOpenSocket()
 {
     MOZ_ASSERT(!mStreamOut);
     MOZ_ASSERT(!mBackupStreamOut);
     MOZ_ASSERT(!mSynTimer);
     LOG(("Destroying nsHalfOpenSocket [this=%p]\n", this));
@@ -2754,17 +2756,17 @@ nsHttpConnectionMgr::
 nsHalfOpenSocket::SetupStreams(nsISocketTransport **transport,
                                nsIAsyncInputStream **instream,
                                nsIAsyncOutputStream **outstream,
                                bool isBackup)
 {
     nsresult rv;
 
     const char* types[1];
-    types[0] = (mEnt->mConnInfo->UsingSSL()) ?
+    types[0] = (mEnt->mConnInfo->EndToEndSSL()) ?
         "ssl" : gHttpHandler->DefaultSocketType();
     uint32_t typeCount = (types[0] != nullptr);
 
     nsCOMPtr<nsISocketTransport> socketTransport;
     nsCOMPtr<nsISocketTransportService> sts;
 
     sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -3080,20 +3082,20 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
         // After about 1 second allow for the possibility of restarting a
         // transaction due to server close. Keep at sub 1 second as that is the
         // minimum granularity we can expect a server to be timing out with.
         conn->SetIsReusedAfter(950);
 
         // if we are using ssl and no other transactions are waiting right now,
         // then form a null transaction to drive the SSL handshake to
         // completion. Afterwards the connection will be 100% ready for the next
-        // transaction to use it. Make an exception for SSL over HTTP proxy as the
-        // NullHttpTransaction does not know how to drive CONNECT.
-        if (mEnt->mConnInfo->UsingSSL() && !mEnt->mPendingQ.Length() &&
-            !mEnt->mConnInfo->UsingHttpProxy()) {
+        // transaction to use it. Make an exception for SSL tunneled HTTP proxy as the
+        // NullHttpTransaction does not know how to drive Connect
+        if (mEnt->mConnInfo->FirstHopSSL() && !mEnt->mPendingQ.Length() &&
+            !mEnt->mConnInfo->UsingConnect()) {
             LOG(("nsHalfOpenSocket::OnOutputStreamReady null transaction will "
                  "be used to finish SSL handshake on conn %p\n", conn.get()));
             nsRefPtr<NullHttpTransaction>  trans =
                 new NullHttpTransaction(mEnt->mConnInfo,
                                         callbacks,
                                         mCaps & ~NS_HTTP_ALLOW_PIPELINING);
 
             gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt);
@@ -3144,17 +3146,17 @@ nsHttpConnectionMgr::nsHalfOpenSocket::O
     // if we are doing spdy coalescing and haven't recorded the ip address
     // for this entry before then make the hash key if our dns lookup
     // just completed. We can't do coalescing if using a proxy because the
     // ip addresses are not available to the client.
 
     if (status == NS_NET_STATUS_CONNECTED_TO &&
         gHttpHandler->IsSpdyEnabled() &&
         gHttpHandler->CoalesceSpdy() &&
-        mEnt && mEnt->mConnInfo && mEnt->mConnInfo->UsingSSL() &&
+        mEnt && mEnt->mConnInfo && mEnt->mConnInfo->EndToEndSSL() &&
         !mEnt->mConnInfo->UsingProxy() &&
         mEnt->mCoalescingKey.IsEmpty()) {
 
         NetAddr addr;
         nsresult rv = mSocketTransport->GetPeerAddr(&addr);
         if (NS_SUCCEEDED(rv)) {
             mEnt->mCoalescingKey.SetCapacity(kIPv6CStrBufSize + 26);
             NetAddrToString(&addr, mEnt->mCoalescingKey.BeginWriting(), kIPv6CStrBufSize);
@@ -3538,17 +3540,17 @@ nsHttpConnectionMgr::ReadConnectionEntry
         data.idle.AppendElement(info);
     }
     for(uint32_t i = 0; i < ent->mHalfOpens.Length(); i++) {
         HalfOpenSockets hSocket;
         hSocket.speculative = ent->mHalfOpens[i]->IsSpeculative();
         data.halfOpens.AppendElement(hSocket);
     }
     data.spdy = ent->mUsingSpdy;
-    data.ssl = ent->mConnInfo->UsingSSL();
+    data.ssl = ent->mConnInfo->EndToEndSSL();
     args->AppendElement(data);
     return PL_DHASH_NEXT;
 }
 
 bool
 nsHttpConnectionMgr::GetConnectionData(nsTArray<HttpRetParams> *aArg)
 {
     mCT.Enumerate(ReadConnectionEntry, aArg);
--- a/netwerk/protocol/http/nsHttpRequestHead.cpp
+++ b/netwerk/protocol/http/nsHttpRequestHead.cpp
@@ -14,16 +14,17 @@
 
 namespace mozilla {
 namespace net {
 
 nsHttpRequestHead::nsHttpRequestHead()
     : mMethod(NS_LITERAL_CSTRING("GET"))
     , mVersion(NS_HTTP_VERSION_1_1)
     , mParsedMethod(kMethod_Get)
+    , mHTTPS(false)
 {
     MOZ_COUNT_CTOR(nsHttpRequestHead);
 }
 
 nsHttpRequestHead::~nsHttpRequestHead()
 {
     MOZ_COUNT_DTOR(nsHttpRequestHead);
 }
--- a/netwerk/protocol/http/nsHttpRequestHead.h
+++ b/netwerk/protocol/http/nsHttpRequestHead.h
@@ -28,16 +28,19 @@ public:
     void SetRequestURI(const nsCSubstring &s) { mRequestURI = s; }
 
     const nsHttpHeaderArray &Headers() const { return mHeaders; }
     nsHttpHeaderArray & Headers()          { return mHeaders; }
     const nsCString &Method()        const { return mMethod; }
     nsHttpVersion       Version()    const { return mVersion; }
     const nsCSubstring &RequestURI() const { return mRequestURI; }
 
+    void SetHTTPS(bool val) { mHTTPS = val; }
+    bool IsHTTPS() const { return mHTTPS; }
+
     const char *PeekHeader(nsHttpAtom h) const
     {
         return mHeaders.PeekHeader(h);
     }
     nsresult SetHeader(nsHttpAtom h, const nsACString &v, bool m=false) { return mHeaders.SetHeader(h, v, m); }
     nsresult GetHeader(nsHttpAtom h, nsACString &v) const
     {
         return mHeaders.GetHeader(h, v);
@@ -90,13 +93,14 @@ public:
 
 private:
     // All members must be copy-constructable and assignable
     nsHttpHeaderArray mHeaders;
     nsCString         mMethod;
     nsHttpVersion     mVersion;
     nsCString         mRequestURI;
     ParsedMethodType  mParsedMethod;
+    bool              mHTTPS;
 };
 
 }} // namespace mozilla::net
 
 #endif // nsHttpRequestHead_h__