summaryrefslogtreecommitdiffstats
path: root/netwerk
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk')
-rw-r--r--netwerk/base/nsProtocolProxyService.cpp7
-rw-r--r--netwerk/base/nsStandardURL.h1
-rw-r--r--netwerk/base/nsUDPSocket.cpp1
-rw-r--r--netwerk/base/security-prefs.js14
-rw-r--r--netwerk/mime/nsMimeTypes.h3
-rw-r--r--netwerk/protocol/ftp/FTPChannelChild.cpp41
-rw-r--r--netwerk/protocol/ftp/nsFtpConnectionThread.cpp81
-rw-r--r--netwerk/protocol/http/AlternateServices.cpp7
-rw-r--r--netwerk/protocol/http/HttpBaseChannel.cpp5
-rw-r--r--netwerk/protocol/http/HttpBaseChannel.h3
-rw-r--r--netwerk/protocol/http/TunnelUtils.cpp67
-rw-r--r--netwerk/protocol/http/TunnelUtils.h11
-rw-r--r--netwerk/protocol/http/nsHttpChannel.cpp14
-rw-r--r--netwerk/protocol/http/nsHttpChannel.h3
-rw-r--r--netwerk/protocol/http/nsHttpConnection.cpp21
-rw-r--r--netwerk/protocol/http/nsHttpConnection.h3
-rw-r--r--netwerk/protocol/http/nsHttpHandler.cpp67
-rw-r--r--netwerk/protocol/http/nsHttpHandler.h20
-rw-r--r--netwerk/sctp/datachannel/DataChannel.cpp11
-rw-r--r--netwerk/test/mochitests/mochitest.ini2
-rw-r--r--netwerk/test/mochitests/test_accept_header.html106
-rw-r--r--netwerk/test/mochitests/test_accept_header.sjs48
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;
+ }
+}