diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-04-05 20:01:10 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-04-05 20:01:10 +0200 |
commit | c3b63b831cd2c64700e875b28540212c7c881ac6 (patch) | |
tree | edd98fcbd2004d3b562904f822bf6c3322fc7f52 /netwerk | |
parent | d432e068a21c815d5d5e7bcbc1cc8c6e77a7d1e0 (diff) | |
parent | cc07da9cb4d6e7a53f8d953427ffc2bca2e0c2df (diff) | |
download | UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.gz UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.lz UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.tar.xz UXP-c3b63b831cd2c64700e875b28540212c7c881ac6.zip |
Merge branch 'master' into 816
Diffstat (limited to 'netwerk')
22 files changed, 360 insertions, 176 deletions
diff --git a/netwerk/base/nsProtocolProxyService.cpp b/netwerk/base/nsProtocolProxyService.cpp index 26eca0e88..237a2a3bd 100644 --- a/netwerk/base/nsProtocolProxyService.cpp +++ b/netwerk/base/nsProtocolProxyService.cpp @@ -1841,6 +1841,13 @@ nsProtocolProxyService::Resolve_Internal(nsIChannel *channel, if (mPACMan && mPACMan->IsPACURI(uri)) return NS_OK; + // If proxies are enabled and this host:port combo is supposed to use a
+ // proxy, check for a proxy.
+ if ((mProxyConfig == PROXYCONFIG_DIRECT) ||
+ !CanUseProxy(uri, info.defaultPort)) {
+ return NS_OK;
+ }
+ bool mainThreadOnly; if (mSystemProxySettings && mProxyConfig == PROXYCONFIG_SYSTEM && diff --git a/netwerk/base/nsStandardURL.h b/netwerk/base/nsStandardURL.h index 0ca345572..eba85528c 100644 --- a/netwerk/base/nsStandardURL.h +++ b/netwerk/base/nsStandardURL.h @@ -72,7 +72,6 @@ public: static void InitGlobalObjects(); static void ShutdownGlobalObjects(); -public: /* internal -- HPUX compiler can't handle this being private */ // // location and length of an url segment relative to mSpec // diff --git a/netwerk/base/nsUDPSocket.cpp b/netwerk/base/nsUDPSocket.cpp index 06ecbf9ee..8b6a81bf5 100644 --- a/netwerk/base/nsUDPSocket.cpp +++ b/netwerk/base/nsUDPSocket.cpp @@ -172,7 +172,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsUDPMessage) NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsUDPMessage) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsUDPMessage) diff --git a/netwerk/base/security-prefs.js b/netwerk/base/security-prefs.js index 7d63267a6..ef78ddccb 100644 --- a/netwerk/base/security-prefs.js +++ b/netwerk/base/security-prefs.js @@ -17,6 +17,11 @@ pref("security.ssl.false_start.require-npn", false); pref("security.ssl.enable_npn", true); pref("security.ssl.enable_alpn", true); +// TLS 1.3 cipher suites +pref("security.tls13.aes_128_gcm_sha256", true); +pref("security.tls13.chacha20_poly1305_sha256", true); +pref("security.tls13.aes_256_gcm_sha384", true); + // TLS 1.0-1.2 cipher suites pref("security.ssl3.ecdhe_rsa_aes_128_gcm_sha256", true); pref("security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256", true); @@ -36,11 +41,14 @@ pref("security.ssl3.rsa_camellia_128_sha", true); pref("security.ssl3.rsa_camellia_256_sha", true); pref("security.ssl3.rsa_aes_128_sha", true); pref("security.ssl3.rsa_aes_256_sha", true); -// Weak / deprecated + +// Deprecated pref("security.ssl3.dhe_rsa_aes_256_sha", false); pref("security.ssl3.dhe_rsa_aes_128_sha", false); pref("security.ssl3.rsa_aes_128_gcm_sha256", false); pref("security.ssl3.rsa_aes_128_sha256", false); + +// Weak/broken (requires fallback_hosts) pref("security.ssl3.rsa_des_ede3_sha", false); pref("security.ssl3.rsa_rc4_128_sha", false); pref("security.ssl3.rsa_rc4_128_md5", false); @@ -109,10 +117,6 @@ pref("security.webauth.u2f", false); pref("security.webauth.u2f_enable_softtoken", false); pref("security.webauth.u2f_enable_usbtoken", false); -pref("security.ssl.errorReporting.enabled", true); -pref("security.ssl.errorReporting.url", "https://incoming.telemetry.mozilla.org/submit/sslreports/"); -pref("security.ssl.errorReporting.automatic", false); - // OCSP must-staple pref("security.ssl.enable_ocsp_must_staple", true); diff --git a/netwerk/mime/nsMimeTypes.h b/netwerk/mime/nsMimeTypes.h index 215d20507..57a85e9bc 100644 --- a/netwerk/mime/nsMimeTypes.h +++ b/netwerk/mime/nsMimeTypes.h @@ -107,6 +107,9 @@ #define IMAGE_TIFF "image/tiff" #define IMAGE_BMP "image/bmp" #define IMAGE_BMP_MS "image/x-ms-bmp" +// This is used internally to represent Windows clipboard BMPs which remove +// part of the header. +#define IMAGE_BMP_MS_CLIPBOARD "image/x-ms-clipboard-bmp" #define IMAGE_ICO "image/x-icon" #define IMAGE_ICO_MS "image/vnd.microsoft.icon" #define IMAGE_ICON_MS "image/icon" diff --git a/netwerk/protocol/ftp/FTPChannelChild.cpp b/netwerk/protocol/ftp/FTPChannelChild.cpp index f8284aae3..f52586744 100644 --- a/netwerk/protocol/ftp/FTPChannelChild.cpp +++ b/netwerk/protocol/ftp/FTPChannelChild.cpp @@ -516,33 +516,6 @@ FTPChannelChild::RecvOnStopRequest(const nsresult& aChannelStatus, return true; } -class nsFtpChildAsyncAlert : public Runnable -{ -public: - nsFtpChildAsyncAlert(nsIPrompt *aPrompter, nsString aResponseMsg) - : mPrompter(aPrompter) - , mResponseMsg(aResponseMsg) - { - MOZ_COUNT_CTOR(nsFtpChildAsyncAlert); - } -protected: - virtual ~nsFtpChildAsyncAlert() - { - MOZ_COUNT_DTOR(nsFtpChildAsyncAlert); - } -public: - NS_IMETHOD Run() override - { - if (mPrompter) { - mPrompter->Alert(nullptr, mResponseMsg.get()); - } - return NS_OK; - } -private: - nsCOMPtr<nsIPrompt> mPrompter; - nsString mResponseMsg; -}; - class MaybeDivertOnStopFTPEvent : public ChannelEvent { public: @@ -600,19 +573,7 @@ FTPChannelChild::DoOnStopRequest(const nsresult& aChannelStatus, (void)mListener->OnStopRequest(this, mListenerContext, aChannelStatus); if (NS_FAILED(aChannelStatus) && !aErrorMsg.IsEmpty()) { - nsCOMPtr<nsIPrompt> prompter; - GetCallback(prompter); - if (prompter) { - nsCOMPtr<nsIRunnable> alertEvent; - if (aUseUTF8) { - alertEvent = new nsFtpChildAsyncAlert(prompter, - NS_ConvertUTF8toUTF16(aErrorMsg)); - } else { - alertEvent = new nsFtpChildAsyncAlert(prompter, - NS_ConvertASCIItoUTF16(aErrorMsg)); - } - NS_DispatchToMainThread(alertEvent); - } + NS_ERROR("FTP error on stop request."); } mListener = nullptr; diff --git a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp index 2ae12846a..0dae7ca92 100644 --- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp +++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp @@ -29,7 +29,6 @@ #include "nsIStreamListenerTee.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" -#include "nsIStringBundle.h" #include "nsAuthInformationHolder.h" #include "nsIProtocolProxyService.h" #include "nsICancelable.h" @@ -926,38 +925,7 @@ nsFtpState::R_syst() { mServerType = FTP_VMS_TYPE; } else { NS_ERROR("Server type list format unrecognized."); - // Guessing causes crashes. - // (Of course, the parsing code should be more robust...) - nsCOMPtr<nsIStringBundleService> bundleService = - do_GetService(NS_STRINGBUNDLE_CONTRACTID); - if (!bundleService) - return FTP_ERROR; - - nsCOMPtr<nsIStringBundle> bundle; - nsresult rv = bundleService->CreateBundle(NECKO_MSGS_URL, - getter_AddRefs(bundle)); - if (NS_FAILED(rv)) - return FTP_ERROR; - - char16_t* ucs2Response = ToNewUnicode(mResponseMsg); - const char16_t *formatStrings[1] = { ucs2Response }; - NS_NAMED_LITERAL_STRING(name, "UnsupportedFTPServer"); - - nsXPIDLString formattedString; - rv = bundle->FormatStringFromName(name.get(), formatStrings, 1, - getter_Copies(formattedString)); - free(ucs2Response); - if (NS_FAILED(rv)) - return FTP_ERROR; - - // TODO(darin): this code should not be dictating UI like this! - nsCOMPtr<nsIPrompt> prompter; - mChannel->GetCallback(prompter); - if (prompter) - prompter->Alert(nullptr, formattedString.get()); - - // since we just alerted the user, clear mResponseMsg, - // which is displayed to the user. + // clear mResponseMsg, which is displayed to the user. mResponseMsg = ""; return FTP_ERROR; } @@ -1779,34 +1747,6 @@ nsFtpState::KillControlConnection() mControlConnection = nullptr; } -class nsFtpAsyncAlert : public Runnable -{ -public: - nsFtpAsyncAlert(nsIPrompt *aPrompter, nsString aResponseMsg) - : mPrompter(aPrompter) - , mResponseMsg(aResponseMsg) - { - MOZ_COUNT_CTOR(nsFtpAsyncAlert); - } -protected: - virtual ~nsFtpAsyncAlert() - { - MOZ_COUNT_DTOR(nsFtpAsyncAlert); - } -public: - NS_IMETHOD Run() override - { - if (mPrompter) { - mPrompter->Alert(nullptr, mResponseMsg.get()); - } - return NS_OK; - } -private: - nsCOMPtr<nsIPrompt> mPrompter; - nsString mResponseMsg; -}; - - nsresult nsFtpState::StopProcessing() { @@ -1818,23 +1758,8 @@ nsFtpState::StopProcessing() LOG_INFO(("FTP:(%x) nsFtpState stopping", this)); if (NS_FAILED(mInternalError) && !mResponseMsg.IsEmpty()) { - // check to see if the control status is bad. - // web shell wont throw an alert. we better: - - // XXX(darin): this code should not be dictating UI like this! - nsCOMPtr<nsIPrompt> prompter; - mChannel->GetCallback(prompter); - if (prompter) { - nsCOMPtr<nsIRunnable> alertEvent; - if (mUseUTF8) { - alertEvent = new nsFtpAsyncAlert(prompter, - NS_ConvertUTF8toUTF16(mResponseMsg)); - } else { - alertEvent = new nsFtpAsyncAlert(prompter, - NS_ConvertASCIItoUTF16(mResponseMsg)); - } - NS_DispatchToMainThread(alertEvent); - } + NS_ERROR("FTP: bad control status."); + // check to see if the control status is bad; forward the error message. nsCOMPtr<nsIFTPChannelParentInternal> ftpChanP; mChannel->GetCallback(ftpChanP); if (ftpChanP) { diff --git a/netwerk/protocol/http/AlternateServices.cpp b/netwerk/protocol/http/AlternateServices.cpp index b3e6babe3..ee2fa9331 100644 --- a/netwerk/protocol/http/AlternateServices.cpp +++ b/netwerk/protocol/http/AlternateServices.cpp @@ -654,8 +654,13 @@ private: { nsID channelId; nsLoadFlags flags; + + nsContentPolicyType contentPolicyType = + loadInfo ? loadInfo->GetExternalContentPolicyType() + : nsIContentPolicy::TYPE_OTHER; + if (NS_FAILED(gHttpHandler->NewChannelId(&channelId)) || - NS_FAILED(chan->Init(uri, caps, nullptr, 0, nullptr, channelId)) || + NS_FAILED(chan->Init(uri, caps, nullptr, 0, nullptr, channelId, contentPolicyType)) || NS_FAILED(chan->SetAllowAltSvc(false)) || NS_FAILED(chan->SetRedirectMode(nsIHttpChannelInternal::REDIRECT_MODE_ERROR)) || NS_FAILED(chan->SetLoadInfo(loadInfo)) || diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 9e43d89e0..86e177e71 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -151,7 +151,8 @@ HttpBaseChannel::Init(nsIURI *aURI, nsProxyInfo *aProxyInfo, uint32_t aProxyResolveFlags, nsIURI *aProxyURI, - const nsID& aChannelId) + const nsID& aChannelId, + nsContentPolicyType aContentPolicyType) { LOG(("HttpBaseChannel::Init [this=%p]\n", this)); @@ -200,7 +201,7 @@ HttpBaseChannel::Init(nsIURI *aURI, rv = mRequestHead.SetHeader(nsHttp::Host, hostLine); if (NS_FAILED(rv)) return rv; - rv = gHttpHandler->AddStandardRequestHeaders(&mRequestHead, isHTTPS); + rv = gHttpHandler->AddStandardRequestHeaders(&mRequestHead, isHTTPS, aContentPolicyType); if (NS_FAILED(rv)) return rv; nsAutoCString type; diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index 9aa696a70..8def0f23c 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -99,7 +99,8 @@ public: virtual nsresult Init(nsIURI *aURI, uint32_t aCaps, nsProxyInfo *aProxyInfo, uint32_t aProxyResolveFlags, nsIURI *aProxyURI, - const nsID& aChannelId); + const nsID& aChannelId, + nsContentPolicyType aContentPolicyType); // nsIRequest NS_IMETHOD GetName(nsACString& aName) override; diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp index 4cc24a07f..6880e0187 100644 --- a/netwerk/protocol/http/TunnelUtils.cpp +++ b/netwerk/protocol/http/TunnelUtils.cpp @@ -23,6 +23,7 @@ #include "nsNetCID.h" #include "nsServiceManagerUtils.h" #include "nsComponentManagerUtils.h" +#include "nsSocketTransport2.h" namespace mozilla { namespace net { @@ -42,6 +43,7 @@ TLSFilterTransaction::TLSFilterTransaction(nsAHttpTransaction *aWrapped, , mSegmentReader(aReader) , mSegmentWriter(aWriter) , mForce(false) + , mReadSegmentReturnValue(NS_OK) , mNudgeCounter(0) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); @@ -130,6 +132,19 @@ TLSFilterTransaction::Close(nsresult aReason) } mTransaction->Close(aReason); mTransaction = nullptr; + + RefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans)); + SpdyConnectTransaction *trans = baseTrans + ? baseTrans->QuerySpdyConnectTransaction() + : nullptr; + + LOG(("TLSFilterTransaction::Close %p aReason=%" PRIx32 " trans=%p\n", + this, static_cast<uint32_t>(aReason), trans)); + + if (trans) { + trans->Close(aReason); + trans = nullptr; + } } nsresult @@ -140,7 +155,7 @@ TLSFilterTransaction::OnReadSegment(const char *aData, LOG(("TLSFilterTransaction %p OnReadSegment %d (buffered %d)\n", this, aCount, mEncryptedTextUsed)); - mReadSegmentBlocked = false; + mReadSegmentReturnValue = NS_OK; MOZ_ASSERT(mSegmentReader); if (!mSecInfo) { return NS_ERROR_FAILURE; @@ -188,10 +203,12 @@ TLSFilterTransaction::OnReadSegment(const char *aData, return NS_OK; } // mTransaction ReadSegments actually obscures this code, so - // keep it in a member var for this::ReadSegments to insepct. Similar + // keep it in a member var for this::ReadSegments to inspect. Similar // to nsHttpConnection::mSocketOutCondition - mReadSegmentBlocked = (PR_GetError() == PR_WOULD_BLOCK_ERROR); - return mReadSegmentBlocked ? NS_BASE_STREAM_WOULD_BLOCK : NS_ERROR_FAILURE; + PRErrorCode code = PR_GetError(); + mReadSegmentReturnValue = ErrorAccordingToNSPR(code); + + return mReadSegmentReturnValue; } aCount -= written; aData += written; @@ -273,10 +290,18 @@ TLSFilterTransaction::OnWriteSegment(char *aData, mFilterReadCode = NS_OK; int32_t bytesRead = PR_Read(mFD, aData, aCount); if (bytesRead == -1) { - if (PR_GetError() == PR_WOULD_BLOCK_ERROR) { + PRErrorCode code = PR_GetError(); + if (code == PR_WOULD_BLOCK_ERROR) { return NS_BASE_STREAM_WOULD_BLOCK; } - return NS_ERROR_FAILURE; + // If reading from the socket succeeded (NS_SUCCEEDED(mFilterReadCode)), + // but the nss layer encountered an error remember the error. + if (NS_SUCCEEDED(mFilterReadCode)) { + mFilterReadCode = ErrorAccordingToNSPR(code); + LOG(("TLSFilterTransaction::OnWriteSegment %p nss error %" PRIx32 ".\n", + this, static_cast<uint32_t>(mFilterReadCode))); + } + return mFilterReadCode; } *outCountRead = bytesRead; @@ -303,7 +328,7 @@ TLSFilterTransaction::FilterInput(char *aBuf, int32_t aAmount) if (NS_SUCCEEDED(mFilterReadCode) && outCountRead) { LOG(("TLSFilterTransaction::FilterInput rv=%x read=%d input from net " "1 layer stripped, 1 still on\n", mFilterReadCode, outCountRead)); - if (mReadSegmentBlocked) { + if (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK) { mNudgeCounter = 0; } } @@ -325,19 +350,18 @@ TLSFilterTransaction::ReadSegments(nsAHttpSegmentReader *aReader, return NS_ERROR_UNEXPECTED; } - mReadSegmentBlocked = false; + mReadSegmentReturnValue = NS_OK; mSegmentReader = aReader; nsresult rv = mTransaction->ReadSegments(this, aCount, outCountRead); LOG(("TLSFilterTransaction %p called trans->ReadSegments rv=%x %d\n", this, rv, *outCountRead)); - if (NS_SUCCEEDED(rv) && mReadSegmentBlocked) { - rv = NS_BASE_STREAM_WOULD_BLOCK; + if (NS_SUCCEEDED(rv) && (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK)) { LOG(("TLSFilterTransaction %p read segment blocked found rv=%x\n", - this, rv)); + this, static_cast<uint32_t>(rv))); Connection()->ForceSend(); } - return rv; + return NS_SUCCEEDED(rv) ? mReadSegmentReturnValue : rv; } nsresult @@ -442,7 +466,10 @@ TLSFilterTransaction::Notify(nsITimer *timer) if (timer != mTimer) { return NS_ERROR_UNEXPECTED; } - StartTimerCallback(); + nsresult rv = StartTimerCallback(); + if (NS_FAILED(rv)) { + Close(rv); + } return NS_OK; } @@ -456,7 +483,7 @@ TLSFilterTransaction::StartTimerCallback() // This class can be called re-entrantly, so cleanup m* before ->on() RefPtr<NudgeTunnelCallback> cb(mNudgeCallback); mNudgeCallback = nullptr; - cb->OnTunnelNudged(this); + return cb->OnTunnelNudged(this); } return NS_OK; } @@ -675,10 +702,12 @@ TLSFilterTransaction::TakeSubTransactions( } nsresult -TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans) +TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans, + nsAHttpTransaction *aSpdyConnectTransaction) { - LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p\n", - this, aTrans)); + LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p, " + "aSpdyConnectTransaction=%p\n", + this, aTrans, aSpdyConnectTransaction)); mTransaction = aTrans; nsCOMPtr<nsIInterfaceRequestor> callbacks; @@ -688,6 +717,8 @@ TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans) secCtrl->SetNotificationCallbacks(callbacks); } + mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction); + return NS_OK; } @@ -1075,7 +1106,7 @@ SpdyConnectTransaction::MapStreamToHttpConnection(nsISocketTransport *aTransport if (mForcePlainText) { mTunneledConn->ForcePlainText(); } else { - mTunneledConn->SetupSecondaryTLS(); + mTunneledConn->SetupSecondaryTLS(this); mTunneledConn->SetInSpdyTunnel(true); } diff --git a/netwerk/protocol/http/TunnelUtils.h b/netwerk/protocol/http/TunnelUtils.h index 20cfaf7ee..4a003082e 100644 --- a/netwerk/protocol/http/TunnelUtils.h +++ b/netwerk/protocol/http/TunnelUtils.h @@ -93,10 +93,11 @@ class TLSFilterTransaction; class NudgeTunnelCallback : public nsISupports { public: - virtual void OnTunnelNudged(TLSFilterTransaction *) = 0; + virtual nsresult OnTunnelNudged(TLSFilterTransaction *) = 0; }; -#define NS_DECL_NUDGETUNNELCALLBACK void OnTunnelNudged(TLSFilterTransaction *) override; +#define NS_DECL_NUDGETUNNELCALLBACK \ + nsresult OnTunnelNudged(TLSFilterTransaction *) override; class TLSFilterTransaction final : public nsAHttpTransaction @@ -121,7 +122,8 @@ public: nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment) override; nsresult GetTransactionSecurityInfo(nsISupports **) override; nsresult NudgeTunnel(NudgeTunnelCallback *callback); - nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans); + MOZ_MUST_USE nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans, + nsAHttpTransaction *aSpdyConnectTransaction = nullptr); void newIODriver(nsIAsyncInputStream *aSocketIn, nsIAsyncOutputStream *aSocketOut, nsIAsyncInputStream **outSocketIn, @@ -153,6 +155,7 @@ private: private: RefPtr<nsAHttpTransaction> mTransaction; + nsWeakPtr mWeakTrans; // SpdyConnectTransaction * nsCOMPtr<nsISupports> mSecInfo; nsCOMPtr<nsITimer> mTimer; RefPtr<NudgeTunnelCallback> mNudgeCallback; @@ -168,7 +171,7 @@ private: nsresult mFilterReadCode; bool mForce; - bool mReadSegmentBlocked; + nsresult mReadSegmentReturnValue; uint32_t mNudgeCounter; }; diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index a890c51b3..481df5ff0 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -324,10 +324,16 @@ nsHttpChannel::Init(nsIURI *uri, nsProxyInfo *proxyInfo, uint32_t proxyResolveFlags, nsIURI *proxyURI, - const nsID& channelId) -{ - nsresult rv = HttpBaseChannel::Init(uri, caps, proxyInfo, - proxyResolveFlags, proxyURI, channelId); + const nsID& channelId, + nsContentPolicyType aContentPolicyType) +{ + nsresult rv = HttpBaseChannel::Init(uri, + caps, + proxyInfo, + proxyResolveFlags, + proxyURI, + channelId, + aContentPolicyType); if (NS_FAILED(rv)) return rv; diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index 554875b1c..0038e1f71 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -123,7 +123,8 @@ public: virtual nsresult Init(nsIURI *aURI, uint32_t aCaps, nsProxyInfo *aProxyInfo, uint32_t aProxyResolveFlags, nsIURI *aProxyURI, - const nsID& aChannelId) override; + const nsID& aChannelId, + nsContentPolicyType aContentPolicyType) override; nsresult OnPush(const nsACString &uri, Http2PushedStream *pushedStream); diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp index 8ccba76e2..505d849c0 100644 --- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -535,16 +535,16 @@ npnComplete: return true; } -void +nsresult nsHttpConnection::OnTunnelNudged(TLSFilterTransaction *trans) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); LOG(("nsHttpConnection::OnTunnelNudged %p\n", this)); if (trans != mTLSFilter) { - return; + return NS_OK; } LOG(("nsHttpConnection::OnTunnelNudged %p Calling OnSocketWritable\n", this)); - OnSocketWritable(); + return OnSocketWritable(); } // called on the socket thread @@ -639,7 +639,9 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri } if (mTLSFilter) { - mTLSFilter->SetProxiedTransaction(trans); + RefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans)); + rv = mTLSFilter->SetProxiedTransaction(trans, baseTrans); + NS_ENSURE_SUCCESS(rv, rv); mTransaction = mTLSFilter; } @@ -1979,7 +1981,7 @@ nsHttpConnection::OnSocketReadable() // negotiation are known (which is determined from the write path). // If the server speaks SPDY it is likely the readable data here is // a spdy settings frame and without NPN it would be misinterpreted - // as HTTP/* + // as HTTP LOG(("nsHttpConnection::OnSocketReadable %p return due to inactive " "tunnel setup but incomplete NPN state\n", this)); @@ -2019,12 +2021,14 @@ nsHttpConnection::OnSocketReadable() } void -nsHttpConnection::SetupSecondaryTLS() +nsHttpConnection::SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_ASSERT(!mTLSFilter); - LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d\n", - this, mConnInfo->Origin(), mConnInfo->OriginPort())); + LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d " + "aSpdyConnectTransaction=%p\n", + this, mConnInfo->Origin(), mConnInfo->OriginPort(), + aSpdyConnectTransaction)); nsHttpConnectionInfo *ci = nullptr; if (mTransaction) { @@ -2041,6 +2045,7 @@ nsHttpConnection::SetupSecondaryTLS() if (mTransaction) { mTransaction = mTLSFilter; } + mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction); } void diff --git a/netwerk/protocol/http/nsHttpConnection.h b/netwerk/protocol/http/nsHttpConnection.h index 08eea1de2..ce7523eb5 100644 --- a/netwerk/protocol/http/nsHttpConnection.h +++ b/netwerk/protocol/http/nsHttpConnection.h @@ -202,7 +202,7 @@ public: static nsresult MakeConnectString(nsAHttpTransaction *trans, nsHttpRequestHead *request, nsACString &result); - void SetupSecondaryTLS(); + void SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction = nullptr); void SetInSpdyTunnel(bool arg); // Check active connections for traffic (or not). SPDY connections send a @@ -281,6 +281,7 @@ private: // transaction is open, otherwise it is null. RefPtr<nsAHttpTransaction> mTransaction; RefPtr<TLSFilterTransaction> mTLSFilter; + nsWeakPtr mWeakTrans; // SpdyConnectTransaction * RefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 477961454..0f4c94202 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -468,7 +468,9 @@ nsHttpHandler::InitConnectionMgr() } nsresult -nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, bool isSecure) +nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, + bool isSecure, + nsContentPolicyType aContentPolicyType) { nsresult rv; @@ -481,7 +483,20 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, bool isSecu // Add the "Accept" header. Note, this is set as an override because the // service worker expects to see it. The other "default" headers are // hidden from service worker interception. - rv = request->SetHeader(nsHttp::Accept, mAccept, + nsAutoCString accept; + if (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || + aContentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) { + accept.Assign(mAcceptNavigation); + } else if (aContentPolicyType == nsIContentPolicy::TYPE_IMAGE || + aContentPolicyType == nsIContentPolicy::TYPE_IMAGESET) { + accept.Assign(mAcceptImage); + } else if (aContentPolicyType == nsIContentPolicy::TYPE_STYLESHEET) { + accept.Assign(mAcceptStyle); + } else { + accept.Assign(mAcceptDefault); + } + + rv = request->SetHeader(nsHttp::Accept, accept, false, nsHttpHeaderArray::eVarietyRequestOverride); if (NS_FAILED(rv)) return rv; @@ -1268,12 +1283,36 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref) mQoSBits = (uint8_t) clamped(val, 0, 0xff); } + if (PREF_CHANGED(HTTP_PREF("accept.navigation"))) { + nsXPIDLCString accept; + rv = prefs->GetCharPref(HTTP_PREF("accept.navigation"), + getter_Copies(accept)); + if (NS_SUCCEEDED(rv)) + SetAccept(accept, ACCEPT_NAVIGATION); + } + + if (PREF_CHANGED(HTTP_PREF("accept.image"))) { + nsXPIDLCString accept; + rv = prefs->GetCharPref(HTTP_PREF("accept.image"), + getter_Copies(accept)); + if (NS_SUCCEEDED(rv)) + SetAccept(accept, ACCEPT_IMAGE); + } + + if (PREF_CHANGED(HTTP_PREF("accept.style"))) { + nsXPIDLCString accept; + rv = prefs->GetCharPref(HTTP_PREF("accept.style"), + getter_Copies(accept)); + if (NS_SUCCEEDED(rv)) + SetAccept(accept, ACCEPT_STYLE); + } + if (PREF_CHANGED(HTTP_PREF("accept.default"))) { nsXPIDLCString accept; rv = prefs->GetCharPref(HTTP_PREF("accept.default"), getter_Copies(accept)); if (NS_SUCCEEDED(rv)) - SetAccept(accept); + SetAccept(accept, ACCEPT_DEFAULT); } if (PREF_CHANGED(HTTP_PREF("accept-encoding"))) { @@ -1897,9 +1936,21 @@ nsHttpHandler::SetAcceptLanguages() } nsresult -nsHttpHandler::SetAccept(const char *aAccept) +nsHttpHandler::SetAccept(const char *aAccept, AcceptType aType) { - mAccept = aAccept; + switch (aType) { + case ACCEPT_NAVIGATION: + mAcceptNavigation = aAccept; + break; + case ACCEPT_IMAGE: + mAcceptImage = aAccept; + break; + case ACCEPT_STYLE: + mAcceptStyle = aAccept; + break; + case ACCEPT_DEFAULT: + mAcceptDefault = aAccept; + } return NS_OK; } @@ -2057,7 +2108,11 @@ nsHttpHandler::NewProxiedChannel2(nsIURI *uri, rv = NewChannelId(&channelId); NS_ENSURE_SUCCESS(rv, rv); - rv = httpChannel->Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI, channelId); + nsContentPolicyType contentPolicyType = + aLoadInfo ? aLoadInfo->GetExternalContentPolicyType() + : nsIContentPolicy::TYPE_OTHER; + + rv = httpChannel->Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI, channelId, contentPolicyType); if (NS_FAILED(rv)) return rv; diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index f1ec0f947..67b9ebe0e 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -15,6 +15,7 @@ #include "nsCOMPtr.h" #include "nsWeakReference.h" +#include "nsIContentPolicy.h" #include "nsIHttpProtocolHandler.h" #include "nsIObserver.h" #include "nsISpeculativeConnect.h" @@ -50,6 +51,14 @@ enum FrameCheckLevel { FRAMECHECK_STRICT }; +// Fetch spec different http Accept types +enum AcceptType { + ACCEPT_NAVIGATION, + ACCEPT_IMAGE, + ACCEPT_STYLE, + ACCEPT_DEFAULT, +}; + //----------------------------------------------------------------------------- // nsHttpHandler - protocol handler for HTTP and HTTPS //----------------------------------------------------------------------------- @@ -70,7 +79,7 @@ public: nsHttpHandler(); nsresult Init(); - nsresult AddStandardRequestHeaders(nsHttpRequestHead *, bool isSecure); + nsresult AddStandardRequestHeaders(nsHttpRequestHead *, bool isSecure, nsContentPolicyType aContentPolicyType); nsresult AddConnectionHeader(nsHttpRequestHead *, uint32_t capabilities); bool IsAcceptableEncoding(const char *encoding, bool isSecure); @@ -385,7 +394,7 @@ private: void InitUserAgentComponents(); void PrefsChanged(nsIPrefBranch *prefs, const char *pref); - nsresult SetAccept(const char *); + nsresult SetAccept(const char *, AcceptType aType); nsresult SetAcceptLanguages(); nsresult SetAcceptEncodings(const char *, bool mIsSecure); @@ -394,8 +403,8 @@ private: void NotifyObservers(nsIHttpChannel *chan, const char *event); static void TimerCallback(nsITimer * aTimer, void * aClosure); + private: - // cached services nsMainThreadPtrHandle<nsIIOService> mIOService; nsMainThreadPtrHandle<nsIStreamConverterService> mStreamConvSvc; @@ -460,7 +469,10 @@ private: bool mPipeliningOverSSL; bool mEnforceAssocReq; - nsCString mAccept; + nsCString mAcceptNavigation; + nsCString mAcceptImage; + nsCString mAcceptStyle; + nsCString mAcceptDefault; nsCString mAcceptLanguages; nsCString mHttpAcceptEncodings; nsCString mHttpsAcceptEncodings; diff --git a/netwerk/sctp/datachannel/DataChannel.cpp b/netwerk/sctp/datachannel/DataChannel.cpp index ebc430f8c..19be43d1c 100644 --- a/netwerk/sctp/datachannel/DataChannel.cpp +++ b/netwerk/sctp/datachannel/DataChannel.cpp @@ -1928,12 +1928,21 @@ DataChannelConnection::ReceiveCallback(struct socket* sock, void *data, size_t d if (!data) { usrsctp_close(sock); // SCTP has finished shutting down } else { - mLock.AssertCurrentThreadOwns(); + bool locked = false; + if (!IsSTSThread()) { + mLock.Lock(); + locked = true; + } else { + mLock.AssertCurrentThreadOwns(); + } if (flags & MSG_NOTIFICATION) { HandleNotification(static_cast<union sctp_notification *>(data), datalen); } else { HandleMessage(data, datalen, ntohl(rcv.rcv_ppid), rcv.rcv_sid); } + if (locked) { + mLock.Unlock(); + } } // sctp allocates 'data' with malloc(), and expects the receiver to free // it (presumably with free). diff --git a/netwerk/test/mochitests/mochitest.ini b/netwerk/test/mochitests/mochitest.ini index f8a919031..3cd5a674b 100644 --- a/netwerk/test/mochitests/mochitest.ini +++ b/netwerk/test/mochitests/mochitest.ini @@ -25,3 +25,5 @@ support-files = [test_viewsource_unlinkable.html] [test_xhr_method_case.html] [test_1396395.html] +[test_accept_header.html] +support-files = test_accept_header.sjs diff --git a/netwerk/test/mochitests/test_accept_header.html b/netwerk/test/mochitests/test_accept_header.html new file mode 100644 index 000000000..b8434230f --- /dev/null +++ b/netwerk/test/mochitests/test_accept_header.html @@ -0,0 +1,106 @@ +<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Accept header</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script>
+
+// All the requests are sent to test_accept_header.sjs which will return
+// different content based on the queryString. When the queryString is 'get',
+// test_accept_header.sjs returns a JSON object with the latest request and its
+// accept header value.
+
+function test_last_request_and_continue(query, expected) {
+ fetch("test_accept_header.sjs?get").then(r => r.json()).then(json => {
+ is(json.type, query, "Expected: " + query);
+ is(json.accept, expected, "Accept header: " + expected);
+ next();
+ });
+}
+
+function test_iframe() {
+ let observer = new PerformanceObserver(function(list, obj) {
+ obj.disconnect();
+
+ list.getEntries().forEach(entry => {
+ if (entry.name.endsWith("test_accept_header.sjs?iframe")) {
+ obj.disconnect();
+ test_last_request_and_continue("iframe", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
+ }
+ });
+ });
+
+ observer.observe({entryTypes: ["resource"]});
+
+ let ifr = document.createElement("iframe");
+ ifr.src = "test_accept_header.sjs?iframe";
+ document.body.appendChild(ifr);
+}
+
+function test_image() {
+ let i = new Image();
+ i.src = "test_accept_header.sjs?image";
+ i.onload = function() {
+ // Fetch spec says we should have: "image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5"
+ test_last_request_and_continue("image", "image/webp,image/png,image/*;q=0.8,*/*;q=0.5");
+ }
+}
+
+function test_style() {
+ let observer = new PerformanceObserver(function(list, obj) {
+ obj.disconnect();
+
+ list.getEntries().forEach(entry => {
+ if (entry.name.endsWith("test_accept_header.sjs?style")) {
+ obj.disconnect();
+ test_last_request_and_continue("style", "text/css,*/*;q=0.1");
+ }
+ });
+ });
+
+ observer.observe({entryTypes: ["resource"]});
+
+ let head = document.getElementsByTagName("head")[0];
+ let link = document.createElement("link");
+ link.rel = "stylesheet";
+ link.type = "text/css";
+ link.href = "test_accept_header.sjs?style";
+ head.appendChild(link);
+}
+
+function test_worker() {
+ let w = new Worker("test_accept_header.sjs?worker");
+ w.onmessage = function() {
+ test_last_request_and_continue("worker", "*/*");
+ }
+}
+
+let tests = [
+ test_iframe,
+ test_image,
+ test_style,
+ test_worker,
+];
+
+function next() {
+ if (tests.length == 0) {
+ SimpleTest.finish();
+ return;
+ }
+
+ let test = tests.shift();
+ test();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+SpecialPowers.pushPrefEnv({ "set": [
+ [ "dom.enable_performance_observer", true ]
+]}, next);
+
+</script>
+</body>
+</html>
diff --git a/netwerk/test/mochitests/test_accept_header.sjs b/netwerk/test/mochitests/test_accept_header.sjs new file mode 100644 index 000000000..035c886aa --- /dev/null +++ b/netwerk/test/mochitests/test_accept_header.sjs @@ -0,0 +1,48 @@ +function handleRequest(request, response) {
+ response.setStatusLine(request.httpVersion, "200", "OK");
+
+ if (request.queryString == "worker") {
+ response.setHeader("Content-Type", "application/json", false);
+ response.write("postMessage(42)");
+
+ setState("data", JSON.stringify({type: "worker", accept: request.getHeader("Accept") }));
+ return;
+ }
+
+ if (request.queryString == "image") {
+ // A 1x1 PNG image.
+ // Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
+ const IMAGE = atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" +
+ "ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=");
+
+ response.setHeader("Content-Type", "image/png", false);
+ response.write(IMAGE);
+
+ setState("data", JSON.stringify({type: "image", accept: request.getHeader("Accept") }));
+ return;
+ }
+
+ if (request.queryString == "style") {
+ response.setHeader("Content-Type", "text/css", false);
+ response.write("");
+
+ setState("data", JSON.stringify({type: "style", accept: request.getHeader("Accept") }));
+ return;
+ }
+
+ if (request.queryString == "iframe") {
+ response.setHeader("Content-Type", "text/html", false);
+ response.write("<h1>Hello world!</h1>");
+
+ setState("data", JSON.stringify({type: "iframe", accept: request.getHeader("Accept") }));
+ return;
+ }
+
+ if (request.queryString == "get") {
+ response.setHeader("Content-Type", "text/javascript", false);
+ response.write(getState("data"));
+
+ setState("data", "");
+ return;
+ }
+}
|