--- a/netwerk/base/nsISocketTransport.idl
+++ b/netwerk/base/nsISocketTransport.idl
@@ -217,16 +217,23 @@ interface nsISocketTransport : nsITransp
/**
* This flag is an explicit opt-in that allows a normally secure socket
* provider to use, at its discretion, an insecure algorithm. e.g.
* a TLS socket without authentication.
*/
const unsigned long MITM_OK = (1 << 6);
/**
+ * If set, do not use newer protocol features that might have interop problems
+ * on the Internet. Intended only for use with critical infra like the updater.
+ * default is false.
+ */
+ const unsigned long BE_CONSERVATIVE = (1 << 7);
+
+ /**
* Socket QoS/ToS markings. Valid values are IPTOS_DSCP_AFxx or
* IPTOS_CLASS_CSx (or IPTOS_DSCP_EF, but currently no supported
* services require expedited-forwarding).
* Not setting this value will leave the socket with the default
* ToS value, which on most systems if IPTOS_CLASS_CS0 (formerly
* IPTOS_PREC_ROUTINE).
*/
attribute octet QoSBits;
--- a/netwerk/base/nsSocketTransport2.cpp
+++ b/netwerk/base/nsSocketTransport2.cpp
@@ -1154,16 +1154,19 @@ nsSocketTransport::BuildSocket(PRFileDes
controlFlags |= nsISocketProvider::ANONYMOUS_CONNECT;
if (mConnectionFlags & nsISocketTransport::NO_PERMANENT_STORAGE)
controlFlags |= nsISocketProvider::NO_PERMANENT_STORAGE;
if (mConnectionFlags & nsISocketTransport::MITM_OK)
controlFlags |= nsISocketProvider::MITM_OK;
+ if (mConnectionFlags & nsISocketTransport::BE_CONSERVATIVE)
+ controlFlags |= nsISocketProvider::BE_CONSERVATIVE;
+
nsCOMPtr<nsISupports> secinfo;
if (i == 0) {
// if this is the first type, we'll want the
// service to allocate a new socket
// when https proxying we want to just connect to the proxy as if
// it were the end host (i.e. expect the proxy's cert)
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -112,16 +112,17 @@ struct HttpChannelOpenArgs
uint32_t thirdPartyFlags;
bool resumeAt;
uint64_t startPos;
nsCString entityID;
bool chooseApplicationCache;
nsCString appCacheClientID;
bool allowSpdy;
bool allowAltSvc;
+ bool beConservative;
OptionalLoadInfoArgs loadInfo;
OptionalHttpResponseHead synthesizedResponseHead;
nsCString synthesizedSecurityInfoSerialization;
uint32_t cacheKey;
nsCString requestContextID;
OptionalCorsPreflightArgs preflightArgs;
uint32_t initialRwin;
bool blockAuthPrompt;
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -82,16 +82,17 @@ HttpBaseChannel::HttpBaseChannel()
, mInheritApplicationCache(true)
, mChooseApplicationCache(false)
, mLoadedFromApplicationCache(false)
, mChannelIsForDownload(false)
, mTracingEnabled(true)
, mTimingEnabled(false)
, mAllowSpdy(true)
, mAllowAltSvc(true)
+ , mBeConservative(false)
, mResponseTimeoutEnabled(true)
, mAllRedirectsSameOrigin(true)
, mAllRedirectsPassTimingAllowCheck(true)
, mResponseCouldBeSynthesized(false)
, mBlockAuthPrompt(false)
, mAllowStaleCacheContent(false)
, mSuspendCount(0)
, mInitialRwin(0)
@@ -2300,16 +2301,32 @@ HttpBaseChannel::GetAllowAltSvc(bool *aA
NS_IMETHODIMP
HttpBaseChannel::SetAllowAltSvc(bool aAllowAltSvc)
{
mAllowAltSvc = aAllowAltSvc;
return NS_OK;
}
NS_IMETHODIMP
+HttpBaseChannel::GetBeConservative(bool *aBeConservative)
+{
+ NS_ENSURE_ARG_POINTER(aBeConservative);
+
+ *aBeConservative = mBeConservative;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+HttpBaseChannel::SetBeConservative(bool aBeConservative)
+{
+ mBeConservative = aBeConservative;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
HttpBaseChannel::GetApiRedirectToURI(nsIURI ** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_IF_ADDREF(*aResult = mAPIRedirectToURI);
return NS_OK;
}
NS_IMETHODIMP
@@ -3064,20 +3081,21 @@ HttpBaseChannel::SetupReplacementChannel
false);
}
}
// share the request context - see bug 1236650
httpChannel->SetRequestContextID(mRequestContextID);
if (httpInternal) {
- // Convey third party cookie and spdy flags.
+ // Convey third party cookie, conservative, and spdy flags.
httpInternal->SetThirdPartyFlags(mThirdPartyFlags);
httpInternal->SetAllowSpdy(mAllowSpdy);
httpInternal->SetAllowAltSvc(mAllowAltSvc);
+ httpInternal->SetBeConservative(mBeConservative);
RefPtr<nsHttpChannel> realChannel;
CallQueryInterface(newChannel, realChannel.StartAssignment());
if (realChannel) {
realChannel->SetTopWindowURI(mTopWindowURI);
}
// update the DocumentURI indicator since we are being redirected.
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -206,16 +206,18 @@ public:
NS_IMETHOD GetLocalAddress(nsACString& addr) override;
NS_IMETHOD GetLocalPort(int32_t* port) override;
NS_IMETHOD GetRemoteAddress(nsACString& addr) override;
NS_IMETHOD GetRemotePort(int32_t* port) override;
NS_IMETHOD GetAllowSpdy(bool *aAllowSpdy) override;
NS_IMETHOD SetAllowSpdy(bool aAllowSpdy) override;
NS_IMETHOD GetAllowAltSvc(bool *aAllowAltSvc) override;
NS_IMETHOD SetAllowAltSvc(bool aAllowAltSvc) override;
+ NS_IMETHOD GetBeConservative(bool *aBeConservative) override;
+ NS_IMETHOD SetBeConservative(bool aBeConservative) override;
NS_IMETHOD GetApiRedirectToURI(nsIURI * *aApiRedirectToURI) override;
virtual nsresult AddSecurityMessage(const nsAString &aMessageTag, const nsAString &aMessageCategory);
NS_IMETHOD TakeAllSecurityMessages(nsCOMArray<nsISecurityConsoleMessage> &aMessages) override;
NS_IMETHOD GetResponseTimeoutEnabled(bool *aEnable) override;
NS_IMETHOD SetResponseTimeoutEnabled(bool aEnable) override;
NS_IMETHOD GetInitialRwin(uint32_t* aRwin) override;
NS_IMETHOD SetInitialRwin(uint32_t aRwin) override;
NS_IMETHOD GetNetworkInterfaceId(nsACString& aNetworkInterfaceId) override;
@@ -454,16 +456,17 @@ protected:
uint32_t mChooseApplicationCache : 1;
uint32_t mLoadedFromApplicationCache : 1;
uint32_t mChannelIsForDownload : 1;
uint32_t mTracingEnabled : 1;
// True if timing collection is enabled
uint32_t mTimingEnabled : 1;
uint32_t mAllowSpdy : 1;
uint32_t mAllowAltSvc : 1;
+ uint32_t mBeConservative : 1;
uint32_t mResponseTimeoutEnabled : 1;
// A flag that should be false only if a cross-domain redirect occurred
uint32_t mAllRedirectsSameOrigin : 1;
// Is 1 if no redirects have occured or if all redirects
// pass the Resource Timing timing-allow-check
uint32_t mAllRedirectsPassTimingAllowCheck : 1;
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -2079,16 +2079,17 @@ HttpChannelChild::ContinueAsyncOpen()
openArgs.thirdPartyFlags() = mThirdPartyFlags;
openArgs.resumeAt() = mSendResumeAt;
openArgs.startPos() = mStartPos;
openArgs.entityID() = mEntityID;
openArgs.chooseApplicationCache() = mChooseApplicationCache;
openArgs.appCacheClientID() = appCacheClientId;
openArgs.allowSpdy() = mAllowSpdy;
openArgs.allowAltSvc() = mAllowAltSvc;
+ openArgs.beConservative() = mBeConservative;
openArgs.initialRwin() = mInitialRwin;
uint32_t cacheKey = 0;
if (mCacheKey) {
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(mCacheKey);
if (!container) {
return NS_ERROR_ILLEGAL_VALUE;
}
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -118,17 +118,17 @@ HttpChannelParent::Init(const HttpChanne
return DoAsyncOpen(a.uri(), a.original(), a.doc(), a.referrer(),
a.referrerPolicy(), a.apiRedirectTo(), a.topWindowURI(),
a.loadFlags(), a.requestHeaders(),
a.requestMethod(), a.uploadStream(),
a.uploadStreamHasHeaders(), a.priority(), a.classOfService(),
a.redirectionLimit(), a.allowPipelining(), a.allowSTS(),
a.thirdPartyFlags(), a.resumeAt(), a.startPos(),
a.entityID(), a.chooseApplicationCache(),
- a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(),
+ a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(), a.beConservative(),
a.loadInfo(), a.synthesizedResponseHead(),
a.synthesizedSecurityInfoSerialization(),
a.cacheKey(), a.requestContextID(), a.preflightArgs(),
a.initialRwin(), a.blockAuthPrompt(),
a.suspendAfterSynthesizeResponse(),
a.allowStaleCacheContent(), a.contentTypeHint(),
a.channelId(), a.preferredAlternativeType());
}
@@ -310,16 +310,17 @@ HttpChannelParent::DoAsyncOpen( const U
const uint32_t& thirdPartyFlags,
const bool& doResumeAt,
const uint64_t& startPos,
const nsCString& entityID,
const bool& chooseApplicationCache,
const nsCString& appCacheClientID,
const bool& allowSpdy,
const bool& allowAltSvc,
+ const bool& beConservative,
const OptionalLoadInfoArgs& aLoadInfoArgs,
const OptionalHttpResponseHead& aSynthesizedResponseHead,
const nsCString& aSecurityInfoSerialization,
const uint32_t& aCacheKey,
const nsCString& aRequestContextID,
const OptionalCorsPreflightArgs& aCorsPreflightArgs,
const uint32_t& aInitialRwin,
const bool& aBlockAuthPrompt,
@@ -520,16 +521,17 @@ HttpChannelParent::DoAsyncOpen( const U
mChannel->SetClassFlags(classOfService);
}
mChannel->SetRedirectionLimit(redirectionLimit);
mChannel->SetAllowPipelining(allowPipelining);
mChannel->SetAllowSTS(allowSTS);
mChannel->SetThirdPartyFlags(thirdPartyFlags);
mChannel->SetAllowSpdy(allowSpdy);
mChannel->SetAllowAltSvc(allowAltSvc);
+ mChannel->SetBeConservative(beConservative);
mChannel->SetInitialRwin(aInitialRwin);
mChannel->SetBlockAuthPrompt(aBlockAuthPrompt);
nsCOMPtr<nsIApplicationCacheChannel> appCacheChan =
do_QueryObject(mChannel);
nsCOMPtr<nsIApplicationCacheService> appCacheService =
do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID);
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -124,16 +124,17 @@ protected:
const uint32_t& thirdPartyFlags,
const bool& doResumeAt,
const uint64_t& startPos,
const nsCString& entityID,
const bool& chooseApplicationCache,
const nsCString& appCacheClientID,
const bool& allowSpdy,
const bool& allowAltSvc,
+ const bool& beConservative,
const OptionalLoadInfoArgs& aLoadInfoArgs,
const OptionalHttpResponseHead& aSynthesizedResponseHead,
const nsCString& aSecurityInfoSerialization,
const uint32_t& aCacheKey,
const nsCString& aRequestContextID,
const OptionalCorsPreflightArgs& aCorsPreflightArgs,
const uint32_t& aInitialRwin,
const bool& aBlockAuthPrompt,
--- a/netwerk/protocol/http/nsHttp.h
+++ b/netwerk/protocol/http/nsHttp.h
@@ -83,16 +83,21 @@ typedef uint8_t nsHttpVersion;
// This flag indicates the transaction should accept associated pushes
#define NS_HTTP_ONPUSH_LISTENER (1<<9)
// Transactions with this flag should react to errors without side effects
// First user is to prevent clearing of alt-svc cache on failed probe
#define NS_HTTP_ERROR_SOFTLY (1<<10)
+// This corresponds to nsIHttpChannelInternal.beConservative
+// it disables any cutting edge features that we are worried might result in
+// interop problems with critical infrastructure
+#define NS_HTTP_BE_CONSERVATIVE (1<<11)
+
//-----------------------------------------------------------------------------
// some default values
//-----------------------------------------------------------------------------
#define NS_HTTP_DEFAULT_PORT 80
#define NS_HTTPS_DEFAULT_PORT 443
#define NS_HTTP_HEADER_SEPS ", \t"
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -370,16 +370,17 @@ nsHttpChannel::Connect()
if (mUpgradeProtocolCallback) {
mCaps |= NS_HTTP_DISALLOW_SPDY;
}
// Finalize ConnectionInfo flags before SpeculativeConnect
mConnectionInfo->SetAnonymous((mLoadFlags & LOAD_ANONYMOUS) != 0);
mConnectionInfo->SetPrivate(mPrivateBrowsing);
mConnectionInfo->SetNoSpdy(mCaps & NS_HTTP_DISALLOW_SPDY);
+ mConnectionInfo->SetBeConservative((mCaps & NS_HTTP_BE_CONSERVATIVE) || mBeConservative);
// Consider opening a TCP connection right away.
SpeculativeConnect();
// Don't allow resuming when cache must be used
if (mResuming && (mLoadFlags & LOAD_ONLY_FROM_CACHE)) {
LOG(("Resuming from cache is not supported yet"));
return NS_ERROR_DOCUMENT_NOT_CACHED;
@@ -784,18 +785,22 @@ nsHttpChannel::SetupTransaction()
if (!mAllowPipelining ||
(mLoadFlags & (LOAD_INITIAL_DOCUMENT_URI | INHIBIT_PIPELINE)) ||
!SafeForPipelining(mRequestHead.ParsedMethod(), method)) {
LOG((" pipelining disallowed\n"));
mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
}
}
- if (!mAllowSpdy)
+ if (!mAllowSpdy) {
mCaps |= NS_HTTP_DISALLOW_SPDY;
+ }
+ if (mBeConservative) {
+ mCaps |= NS_HTTP_BE_CONSERVATIVE;
+ }
// Use the URI path if not proxying (transparent proxying such as proxy
// CONNECT does not count here). Also figure out what HTTP version to use.
nsAutoCString buf, path;
nsCString* requestURI;
// This is the normal e2e H1 path syntax "/index.html"
rv = mURI->GetPath(path);
--- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp
@@ -140,18 +140,19 @@ void nsHttpConnectionInfo::BuildHashKey(
// 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
// byte 4 is I/. I is for insecure scheme on TLS for http:// uris
// byte 5 is X/. X is for disallow_spdy flag
+ // byte 6 is C/. C is for be Conservative
- mHashKey.AssignLiteral("......");
+ mHashKey.AssignLiteral(".......");
mHashKey.Append(keyHost);
if (!mNetworkInterfaceId.IsEmpty()) {
mHashKey.Append('(');
mHashKey.Append(mNetworkInterfaceId);
mHashKey.Append(')');
}
mHashKey.Append(':');
mHashKey.AppendInt(keyPort);
@@ -252,16 +253,17 @@ nsHttpConnectionInfo::Clone() const
clone->SetNetworkInterfaceId(mNetworkInterfaceId);
}
// Make sure the anonymous, insecure-scheme, and private flags are transferred
clone->SetAnonymous(GetAnonymous());
clone->SetPrivate(GetPrivate());
clone->SetInsecureScheme(GetInsecureScheme());
clone->SetNoSpdy(GetNoSpdy());
+ clone->SetBeConservative(GetBeConservative());
MOZ_ASSERT(clone->Equals(this));
return clone;
}
void
nsHttpConnectionInfo::CloneAsDirectRoute(nsHttpConnectionInfo **outCI)
{
@@ -274,16 +276,17 @@ nsHttpConnectionInfo::CloneAsDirectRoute
new nsHttpConnectionInfo(mOrigin, mOriginPort,
EmptyCString(), mUsername, mProxyInfo,
mOriginAttributes, mEndToEndSSL);
// Make sure the anonymous, insecure-scheme, and private flags are transferred
clone->SetAnonymous(GetAnonymous());
clone->SetPrivate(GetPrivate());
clone->SetInsecureScheme(GetInsecureScheme());
clone->SetNoSpdy(GetNoSpdy());
+ clone->SetBeConservative(GetBeConservative());
if (!mNetworkInterfaceId.IsEmpty()) {
clone->SetNetworkInterfaceId(mNetworkInterfaceId);
}
clone.forget(outCI);
}
nsresult
nsHttpConnectionInfo::CreateWildCard(nsHttpConnectionInfo **outParam)
--- a/netwerk/protocol/http/nsHttpConnectionInfo.h
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.h
@@ -113,16 +113,20 @@ public:
void SetInsecureScheme(bool insecureScheme)
{ mHashKey.SetCharAt(insecureScheme ? 'I' : '.', 4); }
bool GetInsecureScheme() const { return mHashKey.CharAt(4) == 'I'; }
void SetNoSpdy(bool aNoSpdy)
{ mHashKey.SetCharAt(aNoSpdy ? 'X' : '.', 5); }
bool GetNoSpdy() const { return mHashKey.CharAt(5) == 'X'; }
+ void SetBeConservative(bool aBeConservative)
+ { mHashKey.SetCharAt(aBeConservative ? 'C' : '.', 6); }
+ bool GetBeConservative() const { return mHashKey.CharAt(6) == 'C'; }
+
const nsCString &GetNetworkInterfaceId() const { return mNetworkInterfaceId; }
const nsCString &GetNPNToken() { return mNPNToken; }
const nsCString &GetUsername() { return mUsername; }
const NeckoOriginAttributes &GetOriginAttributes() { return mOriginAttributes; }
// Returns true for any kind of proxy (http, socks, https, etc..)
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -3057,16 +3057,21 @@ nsHalfOpenSocket::SetupStreams(nsISocket
tmpFlags = nsISocketTransport::BYPASS_CACHE;
if (mCaps & NS_HTTP_LOAD_ANONYMOUS)
tmpFlags |= nsISocketTransport::ANONYMOUS_CONNECT;
if (ci->GetPrivate())
tmpFlags |= nsISocketTransport::NO_PERMANENT_STORAGE;
+ if ((mCaps & NS_HTTP_BE_CONSERVATIVE) || ci->GetBeConservative()) {
+ LOG(("Setting Socket to BE_CONSERVATIVE"));
+ tmpFlags |= nsISocketTransport::BE_CONSERVATIVE;
+ }
+
// For backup connections, we disable IPv6. That's because some users have
// broken IPv6 connectivity (leading to very long timeouts), and disabling
// IPv6 on the backup connection gives them a much better user experience
// with dual-stack hosts, though they still pay the 250ms delay for each new
// connection. This strategy is also known as "happy eyeballs".
if (mEnt->mPreferIPv6) {
tmpFlags |= nsISocketTransport::DISABLE_IPV4;
}
--- a/netwerk/protocol/http/nsIHttpChannelInternal.idl
+++ b/netwerk/protocol/http/nsIHttpChannelInternal.idl
@@ -200,16 +200,23 @@ interface nsIHttpChannelInternal : nsISu
readonly attribute nsIURI apiRedirectToURI;
/**
* Enable/Disable use of Alternate Services with this channel.
* The network.http.altsvc.enabled preference is still a pre-requisite.
*/
attribute boolean allowAltSvc;
+ /**
+ * If true, do not use newer protocol features that might have interop problems
+ * on the Internet. Intended only for use with critical infra like the updater.
+ * default is false.
+ */
+ attribute boolean beConservative;
+
readonly attribute PRTime lastModifiedTime;
/**
* Force a channel that has not been AsyncOpen'ed to skip any check for possible
* interception and proceed immediately to open a previously-synthesized cache
* entry using the provided ID.
*/
void forceIntercepted(in uint64_t aInterceptionID);
--- a/netwerk/socket/nsISocketProvider.idl
+++ b/netwerk/socket/nsISocketProvider.idl
@@ -100,16 +100,23 @@ interface nsISocketProvider : nsISupport
const unsigned long NO_PERMANENT_STORAGE = 1 << 2;
/**
* This flag is an explicit opt-in that allows a normally secure socket
* provider to use, at its discretion, an insecure algorithm. e.g.
* a TLS socket without authentication.
*/
const unsigned long MITM_OK = 1 << 3;
+
+ /**
+ * If set, do not use newer protocol features that might have interop problems
+ * on the Internet. Intended only for use with critical infra like the updater.
+ * default is false.
+ */
+ const unsigned long BE_CONSERVATIVE = 1 << 4;
};
%{C++
/**
* nsISocketProvider implementations should be registered with XPCOM under a
* contract ID of the form: "@mozilla.org/network/socket;2?type=foo"
*/
#define NS_NETWORK_SOCKET_CONTRACTID_PREFIX \
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -2376,16 +2376,24 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, b
}
}
SSLVersionRange range;
if (SSL_VersionRangeGet(fd, &range) != SECSuccess) {
return NS_ERROR_FAILURE;
}
+ if ((infoObject->GetProviderFlags() & nsISocketProvider::BE_CONSERVATIVE) &&
+ (range.max > SSL_LIBRARY_VERSION_TLS_1_2)) {
+ MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
+ ("[%p] nsSSLIOLayerSetOptions: range.max limited to 1.2 due to BE_CONSERVATIVE flag\n",
+ fd));
+ range.max = SSL_LIBRARY_VERSION_TLS_1_2;
+ }
+
uint16_t maxEnabledVersion = range.max;
infoObject->SharedState().IOLayerHelpers()
.adjustForTLSIntolerance(infoObject->GetHostName(), infoObject->GetPort(),
range);
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("[%p] nsSSLIOLayerSetOptions: using TLS version range (0x%04x,0x%04x)\n",
fd, static_cast<unsigned int>(range.min),
static_cast<unsigned int>(range.max)));
@@ -2455,16 +2463,19 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, b
peerId.AppendLiteral("anon:");
}
if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) {
peerId.AppendLiteral("private:");
}
if (flags & nsISocketProvider::MITM_OK) {
peerId.AppendLiteral("bypassAuth:");
}
+ if (flags & nsISocketProvider::BE_CONSERVATIVE) {
+ peerId.AppendLiteral("beConservative:");
+ }
peerId.Append(host);
peerId.Append(':');
peerId.AppendInt(port);
nsAutoCString suffix;
infoObject->GetOriginAttributes().CreateSuffix(suffix);
peerId.Append(suffix);
if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) {
return NS_ERROR_FAILURE;
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -3255,16 +3255,18 @@ Checker.prototype = {
this._request = new XMLHttpRequest();
this._request.open("GET", url, true);
this._request.channel.notificationCallbacks = new gCertUtils.BadCertHandler(false);
// Prevent the request from reading from the cache.
this._request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
// Prevent the request from writing to the cache.
this._request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
+ // Disable cutting edge features, like TLS 1.3, where middleboxes might brick us
+ this._request.channel.QueryInterface(Ci.nsIHttpChannelInternal).beConservative = true;
this._request.overrideMimeType("text/xml");
// The Cache-Control header is only interpreted by proxies and the
// final destination. It does not help if a resource is already
// cached locally.
this._request.setRequestHeader("Cache-Control", "no-cache");
// HTTP/1.0 servers might not implement Cache-Control and
// might only implement Pragma: no-cache