mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-06 00:31:27 +00:00
bug 1130874 - update h2 alternate service extension to draft-06 r=hurley
This commit is contained in:
parent
9ec922dcb3
commit
bfa57d2872
@ -7,6 +7,7 @@
|
||||
#include "HttpLog.h"
|
||||
|
||||
#include "AlternateServices.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsHttpConnectionInfo.h"
|
||||
#include "nsHttpHandler.h"
|
||||
#include "nsThreadUtils.h"
|
||||
@ -18,6 +19,81 @@
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
void
|
||||
AltSvcMapping::ProcessHeader(const nsCString &buf, const nsCString &originScheme,
|
||||
const nsCString &originHost, int32_t originPort,
|
||||
const nsACString &username, bool privateBrowsing,
|
||||
nsIInterfaceRequestor *callbacks, nsProxyInfo *proxyInfo,
|
||||
uint32_t caps)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
LOG(("AltSvcMapping::ProcessHeader: %s\n", buf.get()));
|
||||
if (!callbacks) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isHttp = originScheme.Equals(NS_LITERAL_CSTRING("http"));
|
||||
if (isHttp && !gHttpHandler->AllowAltSvcOE()) {
|
||||
LOG(("Alt-Svc Response Header for http:// origin but OE disabled\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(("Alt-Svc Response Header %s\n", buf.get()));
|
||||
ParsedHeaderValueListList parsedAltSvc(buf);
|
||||
|
||||
for (uint32_t index = 0; index < parsedAltSvc.mValues.Length(); ++index) {
|
||||
uint32_t maxage = 86400; // default
|
||||
nsAutoCString hostname; // Always empty in the header form
|
||||
nsAutoCString npnToken;
|
||||
int32_t portno = originPort;
|
||||
|
||||
for (uint32_t pairIndex = 0;
|
||||
pairIndex < parsedAltSvc.mValues[index].mValues.Length();
|
||||
++pairIndex) {
|
||||
nsDependentCSubstring ¤tName =
|
||||
parsedAltSvc.mValues[index].mValues[pairIndex].mName;
|
||||
nsDependentCSubstring ¤tValue =
|
||||
parsedAltSvc.mValues[index].mValues[pairIndex].mValue;
|
||||
|
||||
if (!pairIndex) {
|
||||
// h2=:443
|
||||
npnToken = currentName;
|
||||
int32_t colonIndex = currentValue.FindChar(':');
|
||||
if (colonIndex >= 0) {
|
||||
portno =
|
||||
atoi(PromiseFlatCString(currentValue).get() + colonIndex + 1);
|
||||
} else {
|
||||
colonIndex = 0;
|
||||
}
|
||||
hostname.Assign(currentValue.BeginReading(), colonIndex);
|
||||
} else if (currentName.Equals(NS_LITERAL_CSTRING("ma"))) {
|
||||
maxage = atoi(PromiseFlatCString(currentValue).get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// unescape modifies a c string in place, so afterwards
|
||||
// update nsCString length
|
||||
nsUnescape(npnToken.BeginWriting());
|
||||
npnToken.SetLength(strlen(npnToken.BeginReading()));
|
||||
|
||||
uint32_t spdyIndex;
|
||||
SpdyInformation *spdyInfo = gHttpHandler->SpdyInfo();
|
||||
if (!(NS_SUCCEEDED(spdyInfo->GetNPNIndex(npnToken, &spdyIndex)) &&
|
||||
spdyInfo->ProtocolEnabled(spdyIndex))) {
|
||||
LOG(("Alt Svc unknown protocol %s, ignoring", npnToken.get()));
|
||||
continue;
|
||||
}
|
||||
|
||||
nsRefPtr<AltSvcMapping> mapping = new AltSvcMapping(originScheme,
|
||||
originHost, originPort,
|
||||
username, privateBrowsing,
|
||||
NowInSeconds() + maxage,
|
||||
hostname, portno, npnToken);
|
||||
gHttpHandler->UpdateAltServiceMapping(mapping, proxyInfo, callbacks, caps);
|
||||
}
|
||||
}
|
||||
|
||||
AltSvcMapping::AltSvcMapping(const nsACString &originScheme,
|
||||
const nsACString &originHost,
|
||||
int32_t originPort,
|
||||
|
@ -7,7 +7,7 @@
|
||||
/*
|
||||
Alt-Svc allows separation of transport routing from the origin host without
|
||||
using a proxy. See https://httpwg.github.io/http-extensions/alt-svc.html and
|
||||
https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-04
|
||||
https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-06
|
||||
|
||||
Nice To Have Future Enhancements::
|
||||
* flush on network change event when we have an indicator
|
||||
@ -49,6 +49,12 @@ public:
|
||||
int32_t alternatePort,
|
||||
const nsACString &npnToken);
|
||||
|
||||
static void ProcessHeader(const nsCString &buf, const nsCString &originScheme,
|
||||
const nsCString &originHost, int32_t originPort,
|
||||
const nsACString &username, bool privateBrowsing,
|
||||
nsIInterfaceRequestor *callbacks, nsProxyInfo *proxyInfo,
|
||||
uint32_t caps);
|
||||
|
||||
const nsCString &AlternateHost() const { return mAlternateHost; }
|
||||
const nsCString &OriginHost() const { return mOriginHost; }
|
||||
const nsCString &HashKey() const { return mHashKey; }
|
||||
|
@ -2023,15 +2023,11 @@ Http2Session::RecvContinuation(Http2Session *self)
|
||||
class UpdateAltSvcEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
UpdateAltSvcEvent(const nsCString &host, const uint16_t port,
|
||||
const nsCString &npnToken, const uint32_t expires,
|
||||
const nsCString &aOrigin,
|
||||
nsHttpConnectionInfo *aCI,
|
||||
nsIInterfaceRequestor *callbacks)
|
||||
: mHost(host)
|
||||
, mPort(port)
|
||||
, mNPNToken(npnToken)
|
||||
, mExpires(expires)
|
||||
UpdateAltSvcEvent(const nsCString &header,
|
||||
const nsCString &aOrigin,
|
||||
nsHttpConnectionInfo *aCI,
|
||||
nsIInterfaceRequestor *callbacks)
|
||||
: mHeader(header)
|
||||
, mOrigin(aOrigin)
|
||||
, mCI(aCI)
|
||||
, mCallbacks(callbacks)
|
||||
@ -2056,36 +2052,22 @@ public:
|
||||
uri->GetHost(originHost);
|
||||
uri->GetPort(&originPort);
|
||||
|
||||
const char *username = mCI->Username();
|
||||
const bool privateBrowsing = mCI->GetPrivate();
|
||||
|
||||
LOG(("UpdateAltSvcEvent location=%s:%u protocol=%s expires=%u "
|
||||
"origin=%s://%s:%u user=%s private=%d", mHost.get(), mPort,
|
||||
mNPNToken.get(), mExpires, originScheme.get(), originHost.get(),
|
||||
originPort, username, privateBrowsing));
|
||||
nsRefPtr<AltSvcMapping> mapping = new AltSvcMapping(
|
||||
nsDependentCString(originScheme.get()),
|
||||
nsDependentCString(originHost.get()),
|
||||
originPort, nsDependentCString(username), privateBrowsing, mExpires,
|
||||
mHost, mPort, mNPNToken);
|
||||
|
||||
nsProxyInfo *proxyInfo = mCI->ProxyInfo();
|
||||
gHttpHandler->UpdateAltServiceMapping(mapping, proxyInfo, mCallbacks, 0);
|
||||
AltSvcMapping::ProcessHeader(mHeader, originScheme, originHost, originPort,
|
||||
mCI->GetUsername(), mCI->GetPrivate(), mCallbacks,
|
||||
mCI->ProxyInfo(), 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCString mHost;
|
||||
uint16_t mPort;
|
||||
nsCString mNPNToken;
|
||||
uint32_t mExpires;
|
||||
nsCString mHeader;
|
||||
nsCString mOrigin;
|
||||
nsRefPtr<nsHttpConnectionInfo> mCI;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
};
|
||||
|
||||
// defined as an http2 extension - alt-svc
|
||||
// defines receipt of frame type 0x0A.. See AlternateSevices.h
|
||||
// defines receipt of frame type 0x0A.. See AlternateSevices.h at least draft -06 sec 4
|
||||
// as this is an extension, never generate protocol error - just ignore problems
|
||||
nsresult
|
||||
Http2Session::RecvAltSvc(Http2Session *self)
|
||||
{
|
||||
@ -2093,40 +2075,85 @@ Http2Session::RecvAltSvc(Http2Session *self)
|
||||
LOG3(("Http2Session::RecvAltSvc %p Flags 0x%X id 0x%X\n", self,
|
||||
self->mInputFrameFlags, self->mInputFrameID));
|
||||
|
||||
if (self->mInputFrameDataSize < 8) {
|
||||
if (self->mInputFrameDataSize < 2) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p frame too small", self));
|
||||
RETURN_SESSION_ERROR(self, FRAME_SIZE_ERROR);
|
||||
}
|
||||
|
||||
uint32_t maxAge =
|
||||
PR_ntohl(*reinterpret_cast<uint32_t *>(self->mInputFrameBuffer.get() + kFrameHeaderBytes));
|
||||
uint16_t portRoute =
|
||||
PR_ntohs(*reinterpret_cast<uint16_t *>(self->mInputFrameBuffer.get() + kFrameHeaderBytes + 4));
|
||||
uint8_t protoLen = self->mInputFrameBuffer.get()[kFrameHeaderBytes + 6];
|
||||
LOG3(("Http2Session::RecvAltSvc %p maxAge=%d port=%d protoLen=%d", self,
|
||||
maxAge, portRoute, protoLen));
|
||||
|
||||
if (self->mInputFrameDataSize < (8U + protoLen)) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p frame too small for protocol", self));
|
||||
RETURN_SESSION_ERROR(self, FRAME_SIZE_ERROR);
|
||||
}
|
||||
nsAutoCString protocol;
|
||||
protocol.Assign(self->mInputFrameBuffer.get() + kFrameHeaderBytes + 7, protoLen);
|
||||
|
||||
uint32_t spdyIndex;
|
||||
SpdyInformation *spdyInfo = gHttpHandler->SpdyInfo();
|
||||
if (!(NS_SUCCEEDED(spdyInfo->GetNPNIndex(protocol, &spdyIndex)) &&
|
||||
spdyInfo->ProtocolEnabled(spdyIndex))) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p unknown protocol %s, ignoring", self,
|
||||
protocol.BeginReading()));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint8_t hostLen = self->mInputFrameBuffer.get()[kFrameHeaderBytes + 7 + protoLen];
|
||||
if (self->mInputFrameDataSize < (8U + protoLen + hostLen)) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p frame too small for host", self));
|
||||
RETURN_SESSION_ERROR(self, FRAME_SIZE_ERROR);
|
||||
uint16_t originLen =
|
||||
PR_ntohs(*reinterpret_cast<uint16_t *>(self->mInputFrameBuffer.get() + kFrameHeaderBytes));
|
||||
if (originLen + 2U > self->mInputFrameDataSize) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p origin len too big for frame", self));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!gHttpHandler->AllowAltSvc()) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p frame alt service pref'd off", self));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint16_t altSvcFieldValueLen = static_cast<uint16_t>(self->mInputFrameDataSize) - 2U - originLen;
|
||||
LOG3(("Http2Session::RecvAltSvc %p frame originLen=%u altSvcFieldValueLen=%u\n",
|
||||
self, originLen, altSvcFieldValueLen));
|
||||
|
||||
if (self->mInputFrameDataSize > 2000) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p frame too large to parse sensibly", self));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString origin;
|
||||
bool impliedOrigin = true;
|
||||
if (originLen) {
|
||||
origin.Assign(self->mInputFrameBuffer.get() + kFrameHeaderBytes + 2, originLen);
|
||||
impliedOrigin = false;
|
||||
}
|
||||
|
||||
nsAutoCString altSvcFieldValue;
|
||||
if (altSvcFieldValueLen) {
|
||||
altSvcFieldValue.Assign(self->mInputFrameBuffer.get() + kFrameHeaderBytes + 2 + originLen,
|
||||
altSvcFieldValueLen);
|
||||
}
|
||||
|
||||
if (altSvcFieldValue.IsEmpty() || !nsHttp::IsReasonableHeaderValue(altSvcFieldValue)) {
|
||||
LOG(("Http2Session %p Alt-Svc Response Header seems unreasonable - skipping\n", self));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (self->mInputFrameID & 1) {
|
||||
// pulled streams apply to the origin of the pulled stream.
|
||||
// If the origin field is filled in the frame, the frame should be ignored
|
||||
if (!origin.IsEmpty()) {
|
||||
LOG(("Http2Session %p Alt-Svc pulled stream has non empty origin\n", self));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (NS_FAILED(self->SetInputFrameDataStream(self->mInputFrameID)) ||
|
||||
!self->mInputFrameDataStream->Transaction() ||
|
||||
!self->mInputFrameDataStream->Transaction()->RequestHead()) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p got frame w/o origin on invalid stream", self));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
origin.Assign(self->mInputFrameDataStream->Transaction()->RequestHead()->Origin());
|
||||
} else if (!self->mInputFrameID) {
|
||||
// ID 0 streams must supply their own origin
|
||||
if (origin.IsEmpty()) {
|
||||
LOG(("Http2Session %p Alt-Svc Stream 0 has empty origin\n", self));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
// handling of push streams is not defined. Let's ignore it
|
||||
LOG(("Http2Session %p Alt-Svc Stream 0 has empty origin\n", self));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsHttpConnectionInfo> ci(self->ConnectionInfo());
|
||||
@ -2137,21 +2164,7 @@ Http2Session::RecvAltSvc(Http2Session *self)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString hostRoute;
|
||||
hostRoute.Assign(self->mInputFrameBuffer.get() + kFrameHeaderBytes + 8 + protoLen, hostLen);
|
||||
|
||||
uint32_t originLen = self->mInputFrameDataSize - 8 - protoLen - hostLen;
|
||||
nsAutoCString specifiedOrigin;
|
||||
if (originLen) {
|
||||
if (self->mInputFrameID) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p got frame w/origin on non zero stream", self));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
specifiedOrigin.Assign(
|
||||
self->mInputFrameBuffer.get() + kFrameHeaderBytes + 8 + protoLen + hostLen,
|
||||
originLen);
|
||||
|
||||
if (!impliedOrigin) {
|
||||
bool okToReroute = true;
|
||||
nsCOMPtr<nsISupports> securityInfo;
|
||||
self->mConnection->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
@ -2163,17 +2176,15 @@ Http2Session::RecvAltSvc(Http2Session *self)
|
||||
// a little off main thread origin parser. This is a non critical function because
|
||||
// any alternate route created has to be verified anyhow
|
||||
nsAutoCString specifiedOriginHost;
|
||||
if (specifiedOrigin.EqualsIgnoreCase("https://", 8)) {
|
||||
specifiedOriginHost.Assign(specifiedOrigin.get() + 8,
|
||||
specifiedOrigin.Length() - 8);
|
||||
if (origin.EqualsIgnoreCase("https://", 8)) {
|
||||
specifiedOriginHost.Assign(origin.get() + 8, origin.Length() - 8);
|
||||
if (ci->GetRelaxed()) {
|
||||
// technically this is ok because it will still be confirmed before being used
|
||||
// but let's not support it.
|
||||
okToReroute = false;
|
||||
}
|
||||
} else if (specifiedOrigin.EqualsIgnoreCase("http://", 7)) {
|
||||
specifiedOriginHost.Assign(specifiedOrigin.get() + 7,
|
||||
specifiedOrigin.Length() - 7);
|
||||
} else if (origin.EqualsIgnoreCase("http://", 7)) {
|
||||
specifiedOriginHost.Assign(origin.get() + 7, origin.Length() - 7);
|
||||
}
|
||||
|
||||
int32_t colonOffset = specifiedOriginHost.FindCharInSet(":", 0);
|
||||
@ -2184,40 +2195,22 @@ Http2Session::RecvAltSvc(Http2Session *self)
|
||||
if (okToReroute) {
|
||||
ssl->IsAcceptableForHost(specifiedOriginHost, &okToReroute);
|
||||
}
|
||||
|
||||
if (!okToReroute) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p can't reroute non-authoritative origin %s",
|
||||
self, specifiedOrigin.BeginReading()));
|
||||
self, origin.BeginReading()));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
// no origin specified in frame. We need to have an active pull stream to match
|
||||
// this up to as if it were a response header.
|
||||
if (!(self->mInputFrameID & 0x1) ||
|
||||
NS_FAILED(self->SetInputFrameDataStream(self->mInputFrameID)) ||
|
||||
!self->mInputFrameDataStream->Transaction() ||
|
||||
!self->mInputFrameDataStream->Transaction()->RequestHead()) {
|
||||
LOG3(("Http2Session::RecvAltSvc %p got frame w/o origin on invalid stream", self));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
specifiedOrigin.Assign(
|
||||
self->mInputFrameDataStream->Transaction()->RequestHead()->Origin());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> callbacks;
|
||||
self->mConnection->GetSecurityInfo(getter_AddRefs(callbacks));
|
||||
nsCOMPtr<nsIInterfaceRequestor> irCallbacks = do_QueryInterface(callbacks);
|
||||
|
||||
nsRefPtr<UpdateAltSvcEvent> event = new UpdateAltSvcEvent(
|
||||
hostRoute, portRoute, protocol, NowInSeconds() + maxAge,
|
||||
specifiedOrigin, ci, irCallbacks);
|
||||
nsRefPtr<UpdateAltSvcEvent> event =
|
||||
new UpdateAltSvcEvent(altSvcFieldValue, origin, ci, irCallbacks);
|
||||
NS_DispatchToMainThread(event);
|
||||
|
||||
LOG3(("Http2Session::RecvAltSvc %p processed location=%s:%u protocol=%s "
|
||||
"maxAge=%u origin=%s", self, hostRoute.get(), portRoute,
|
||||
protocol.get(), maxAge, specifiedOrigin.get()));
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1278,104 +1278,35 @@ nsHttpChannel::ProcessAltService()
|
||||
return;
|
||||
}
|
||||
|
||||
if (isHttp && !gHttpHandler->AllowAltSvcOE()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *altSvc;
|
||||
if (!(altSvc = mResponseHead->PeekHeader(nsHttp::Alternate_Service))) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(("nsHttpChannel %p Alt-Svc Response Header %s\n", this, altSvc));
|
||||
|
||||
nsCString buf(altSvc);
|
||||
if (!nsHttp::IsReasonableHeaderValue(buf)) {
|
||||
LOG(("Alt-Svc Response Header seems unreasonable - skipping\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
ParsedHeaderValueListList parsedAltSvc(buf);
|
||||
nsRefPtr<AltSvcMapping> mapping;
|
||||
|
||||
nsAutoCString originHost;
|
||||
int32_t originPort = 80;
|
||||
mURI->GetPort(&originPort);
|
||||
if (NS_FAILED(mURI->GetHost(originHost))) {
|
||||
return;
|
||||
}
|
||||
uint32_t now = NowInSeconds(), currentAge = 0;
|
||||
mResponseHead->ComputeCurrentAge(now, mRequestTime, ¤tAge);
|
||||
|
||||
for (uint32_t index = 0; index < parsedAltSvc.mValues.Length(); ++index) {
|
||||
uint32_t maxage = 86400; // default
|
||||
nsAutoCString hostname; // Always empty in the header form
|
||||
nsAutoCString npnToken;
|
||||
int32_t portno = originPort;
|
||||
|
||||
for (uint32_t pairIndex = 0;
|
||||
pairIndex < parsedAltSvc.mValues[index].mValues.Length();
|
||||
++pairIndex) {
|
||||
nsDependentCSubstring ¤tName =
|
||||
parsedAltSvc.mValues[index].mValues[pairIndex].mName;
|
||||
nsDependentCSubstring ¤tValue =
|
||||
parsedAltSvc.mValues[index].mValues[pairIndex].mValue;
|
||||
|
||||
if (!pairIndex) {
|
||||
// h2=:443
|
||||
npnToken = currentName;
|
||||
int32_t colonIndex = currentValue.FindChar(':');
|
||||
if (colonIndex >= 0) {
|
||||
portno =
|
||||
atoi(PromiseFlatCString(currentValue).get() + colonIndex + 1);
|
||||
} else {
|
||||
colonIndex = 0;
|
||||
}
|
||||
hostname.Assign(currentValue.BeginReading(), colonIndex);
|
||||
} else if (currentName.Equals(NS_LITERAL_CSTRING("ma"))) {
|
||||
maxage = atoi(PromiseFlatCString(currentValue).get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// unescape modifies a c string in place, so afterwards
|
||||
// update nsCString length
|
||||
nsUnescape(npnToken.BeginWriting());
|
||||
npnToken.SetLength(strlen(npnToken.BeginReading()));
|
||||
|
||||
uint32_t spdyIndex;
|
||||
SpdyInformation *spdyInfo = gHttpHandler->SpdyInfo();
|
||||
if (!(NS_SUCCEEDED(spdyInfo->GetNPNIndex(npnToken, &spdyIndex)) &&
|
||||
spdyInfo->ProtocolEnabled(spdyIndex))) {
|
||||
LOG(("Alt Svc %p unknown protocol %s, ignoring", this, npnToken.get()));
|
||||
continue;
|
||||
}
|
||||
|
||||
mapping = new AltSvcMapping(scheme,
|
||||
originHost, originPort,
|
||||
mUsername, mPrivateBrowsing,
|
||||
NowInSeconds() + maxage,
|
||||
hostname, portno, npnToken);
|
||||
if (!mapping) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||
NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
|
||||
getter_AddRefs(callbacks));
|
||||
if (!callbacks) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsProxyInfo> proxyInfo;
|
||||
if (mProxyInfo) {
|
||||
proxyInfo = do_QueryInterface(mProxyInfo);
|
||||
}
|
||||
|
||||
gHttpHandler->
|
||||
UpdateAltServiceMapping(mapping, proxyInfo, callbacks,
|
||||
mCaps & NS_HTTP_DISALLOW_SPDY);
|
||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||
nsCOMPtr<nsProxyInfo> proxyInfo;
|
||||
NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
|
||||
getter_AddRefs(callbacks));
|
||||
if (mProxyInfo) {
|
||||
proxyInfo = do_QueryInterface(mProxyInfo);
|
||||
}
|
||||
|
||||
AltSvcMapping::ProcessHeader(buf, scheme, originHost, originPort,
|
||||
mUsername, mPrivateBrowsing, callbacks, proxyInfo,
|
||||
mCaps & NS_HTTP_DISALLOW_SPDY);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -4854,7 +4785,17 @@ nsHttpChannel::BeginConnect()
|
||||
LOG(("nsHttpChannel %p Alt Service Mapping Found %s://%s:%d\n", this,
|
||||
scheme.get(), mapping->AlternateHost().get(),
|
||||
mapping->AlternatePort()));
|
||||
mRequestHead.SetHeader(nsHttp::Alternate_Service_Used, NS_LITERAL_CSTRING("1"));
|
||||
|
||||
if (!(mLoadFlags & LOAD_ANONYMOUS) && !mPrivateBrowsing) {
|
||||
nsAutoCString altUsedLine(mapping->AlternateHost());
|
||||
bool defaultPort = mapping->AlternatePort() ==
|
||||
(isHttps ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT);
|
||||
if (!defaultPort) {
|
||||
altUsedLine.AppendLiteral(":");
|
||||
altUsedLine.AppendInt(mapping->AlternatePort());
|
||||
}
|
||||
mRequestHead.SetHeader(nsHttp::Alternate_Service_Used, altUsedLine);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIConsoleService> consoleService =
|
||||
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
|
||||
|
@ -102,6 +102,7 @@ public:
|
||||
|
||||
const nsCString &GetHost() { return mHost; }
|
||||
const nsCString &GetNPNToken() { return mNPNToken; }
|
||||
const nsCString &GetUsername() { return mUsername; }
|
||||
|
||||
// Returns true for any kind of proxy (http, socks, https, etc..)
|
||||
bool UsingProxy();
|
||||
|
@ -264,6 +264,9 @@ nsHttpResponseHead::AssignDefaultStatusText()
|
||||
case 417:
|
||||
mStatusText.AssignLiteral("Expectation Failed");
|
||||
break;
|
||||
case 421:
|
||||
mStatusText.AssignLiteral("Misdirected Request");
|
||||
break;
|
||||
case 501:
|
||||
mStatusText.AssignLiteral("Not Implemented");
|
||||
break;
|
||||
|
@ -1482,7 +1482,7 @@ nsHttpTransaction::HandleContentStart()
|
||||
break;
|
||||
case 421:
|
||||
if (!mConnInfo->GetAuthenticationHost().IsEmpty()) {
|
||||
LOG(("Not Authoritative.\n"));
|
||||
LOG(("Misdirected Request.\n"));
|
||||
gHttpHandler->ConnMgr()->
|
||||
ClearHostMapping(mConnInfo->GetHost(), mConnInfo->Port());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user