зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1596935 - Separate rel=dns-prefetch behaviour from html anchor dns prefetch r=dom-core,necko-reviewers,sefeng
Split the rel=dns-prefetch behaviour from the Dom's speculative DNS prefetch for all anchor elements. This will allow us to independently enable rel=dns-prefetch for https document without prefetching DNS for anchors. This patch does not change the behaviour for either source of DNS prefetch. Differential Revision: https://phabricator.services.mozilla.com/D205630
This commit is contained in:
Родитель
735c8471c7
Коммит
1312eb3dff
|
@ -68,10 +68,7 @@ nsresult HTMLAnchorElement::BindToTree(BindContext& aContext,
|
|||
Link::BindToTree(aContext);
|
||||
|
||||
// Prefetch links
|
||||
if (IsInComposedDoc()) {
|
||||
TryDNSPrefetch(*this);
|
||||
}
|
||||
|
||||
MaybeTryDNSPrefetch();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -194,8 +191,8 @@ void HTMLAnchorElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
|||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::href) {
|
||||
Link::ResetLinkState(aNotify, !!aValue);
|
||||
if (aValue && IsInComposedDoc()) {
|
||||
TryDNSPrefetch(*this);
|
||||
if (aValue) {
|
||||
MaybeTryDNSPrefetch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,4 +207,22 @@ void HTMLAnchorElement::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
|
|||
*aNodeSize += Link::SizeOfExcludingThis(aSizes.mState);
|
||||
}
|
||||
|
||||
void HTMLAnchorElement::MaybeTryDNSPrefetch() {
|
||||
if (IsInComposedDoc()) {
|
||||
nsIURI* docURI = OwnerDoc()->GetDocumentURI();
|
||||
if (!docURI) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool docIsHttps = docURI->SchemeIs("https");
|
||||
if ((docIsHttps &&
|
||||
StaticPrefs::dom_prefetch_dns_for_anchor_https_document()) ||
|
||||
(!docIsHttps &&
|
||||
StaticPrefs::dom_prefetch_dns_for_anchor_http_document())) {
|
||||
TryDNSPrefetch(
|
||||
*this, HTMLDNSPrefetch::PrefetchSource::AnchorSpeculativePrefetch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -189,6 +189,8 @@ class HTMLAnchorElement final : public nsGenericHTMLElement,
|
|||
protected:
|
||||
virtual ~HTMLAnchorElement();
|
||||
|
||||
void MaybeTryDNSPrefetch();
|
||||
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
RefPtr<nsDOMTokenList> mRelList;
|
||||
};
|
||||
|
|
|
@ -105,7 +105,7 @@ class DeferredDNSPrefetches final : public nsIWebProgressListener,
|
|||
void Flush();
|
||||
|
||||
void SubmitQueue();
|
||||
void SubmitQueueEntry(Element&, nsIDNSService::DNSFlags aFlags);
|
||||
void SubmitQueueEntry(Element& aElement, nsIDNSService::DNSFlags aFlags);
|
||||
|
||||
uint16_t mHead;
|
||||
uint16_t mTail;
|
||||
|
@ -206,8 +206,8 @@ nsIDNSService::DNSFlags HTMLDNSPrefetch::PriorityToDNSServiceFlags(
|
|||
return nsIDNSService::RESOLVE_DEFAULT_FLAGS;
|
||||
}
|
||||
|
||||
nsresult HTMLDNSPrefetch::Prefetch(SupportsDNSPrefetch& aSupports,
|
||||
Element& aElement, Priority aPriority) {
|
||||
nsresult HTMLDNSPrefetch::DeferPrefetch(SupportsDNSPrefetch& aSupports,
|
||||
Element& aElement, Priority aPriority) {
|
||||
MOZ_ASSERT(&ToSupportsDNSPrefetch(aElement) == &aSupports);
|
||||
if (!(sInitialized && sPrefetches && sDNSListener) || !EnsureDNSService()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
@ -362,10 +362,84 @@ void HTMLDNSPrefetch::ElementDestroyed(Element& aElement,
|
|||
}
|
||||
}
|
||||
|
||||
void SupportsDNSPrefetch::TryDNSPrefetch(Element& aOwner) {
|
||||
void HTMLDNSPrefetch::SendRequest(Element& aElement,
|
||||
nsIDNSService::DNSFlags aFlags) {
|
||||
auto& supports = ToSupportsDNSPrefetch(aElement);
|
||||
|
||||
nsIURI* uri = supports.GetURIForDNSPrefetch(aElement);
|
||||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString hostName;
|
||||
uri->GetAsciiHost(hostName);
|
||||
if (hostName.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isLocalResource = false;
|
||||
nsresult rv = NS_URIChainHasFlags(
|
||||
uri, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE, &isLocalResource);
|
||||
if (NS_FAILED(rv) || isLocalResource) {
|
||||
return;
|
||||
}
|
||||
|
||||
OriginAttributes oa;
|
||||
StoragePrincipalHelper::GetOriginAttributesForNetworkState(
|
||||
aElement.OwnerDoc(), oa);
|
||||
|
||||
bool isHttps = uri->SchemeIs("https");
|
||||
|
||||
if (IsNeckoChild()) {
|
||||
// during shutdown gNeckoChild might be null
|
||||
if (gNeckoChild) {
|
||||
gNeckoChild->SendHTMLDNSPrefetch(NS_ConvertUTF8toUTF16(hostName), isHttps,
|
||||
oa, aFlags);
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsICancelable> tmpOutstanding;
|
||||
|
||||
rv = sDNSService->AsyncResolveNative(
|
||||
hostName, nsIDNSService::RESOLVE_TYPE_DEFAULT,
|
||||
aFlags | nsIDNSService::RESOLVE_SPECULATE, nullptr, sDNSListener,
|
||||
nullptr, oa, getter_AddRefs(tmpOutstanding));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch HTTPS RR if needed.
|
||||
if (StaticPrefs::network_dns_upgrade_with_https_rr() ||
|
||||
StaticPrefs::network_dns_use_https_rr_as_altsvc()) {
|
||||
sDNSService->AsyncResolveNative(
|
||||
hostName, nsIDNSService::RESOLVE_TYPE_HTTPSSVC,
|
||||
aFlags | nsIDNSService::RESOLVE_SPECULATE, nullptr, sDNSListener,
|
||||
nullptr, oa, getter_AddRefs(tmpOutstanding));
|
||||
}
|
||||
}
|
||||
|
||||
// Tell element that deferred prefetch was requested.
|
||||
supports.DNSPrefetchRequestStarted();
|
||||
}
|
||||
|
||||
void SupportsDNSPrefetch::TryDNSPrefetch(
|
||||
Element& aOwner, HTMLDNSPrefetch::PrefetchSource aSource) {
|
||||
MOZ_ASSERT(aOwner.IsInComposedDoc());
|
||||
if (HTMLDNSPrefetch::IsAllowed(aOwner.OwnerDoc())) {
|
||||
HTMLDNSPrefetch::Prefetch(*this, aOwner, HTMLDNSPrefetch::Priority::Low);
|
||||
if (!(sInitialized && sDNSListener) || !EnsureDNSService()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aSource == HTMLDNSPrefetch::PrefetchSource::AnchorSpeculativePrefetch) {
|
||||
HTMLDNSPrefetch::DeferPrefetch(*this, aOwner,
|
||||
HTMLDNSPrefetch::Priority::Low);
|
||||
} else if (aSource == HTMLDNSPrefetch::PrefetchSource::LinkDnsPrefetch) {
|
||||
HTMLDNSPrefetch::SendRequest(
|
||||
aOwner, GetDNSFlagsFromElement(aOwner) |
|
||||
HTMLDNSPrefetch::PriorityToDNSServiceFlags(
|
||||
HTMLDNSPrefetch::Priority::High));
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown DNS prefetch type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -470,59 +544,7 @@ void DeferredDNSPrefetches::SubmitQueueEntry(Element& aElement,
|
|||
return;
|
||||
}
|
||||
|
||||
nsIURI* uri = supports.GetURIForDNSPrefetch(aElement);
|
||||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString hostName;
|
||||
uri->GetAsciiHost(hostName);
|
||||
if (hostName.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isLocalResource = false;
|
||||
nsresult rv = NS_URIChainHasFlags(
|
||||
uri, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE, &isLocalResource);
|
||||
if (NS_FAILED(rv) || isLocalResource) {
|
||||
return;
|
||||
}
|
||||
|
||||
OriginAttributes oa;
|
||||
StoragePrincipalHelper::GetOriginAttributesForNetworkState(
|
||||
aElement.OwnerDoc(), oa);
|
||||
|
||||
bool isHttps = uri->SchemeIs("https");
|
||||
|
||||
if (IsNeckoChild()) {
|
||||
// during shutdown gNeckoChild might be null
|
||||
if (gNeckoChild) {
|
||||
gNeckoChild->SendHTMLDNSPrefetch(NS_ConvertUTF8toUTF16(hostName), isHttps,
|
||||
oa, mEntries[mTail].mFlags);
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsICancelable> tmpOutstanding;
|
||||
|
||||
rv = sDNSService->AsyncResolveNative(
|
||||
hostName, nsIDNSService::RESOLVE_TYPE_DEFAULT,
|
||||
mEntries[mTail].mFlags | nsIDNSService::RESOLVE_SPECULATE, nullptr,
|
||||
sDNSListener, nullptr, oa, getter_AddRefs(tmpOutstanding));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch HTTPS RR if needed.
|
||||
if (StaticPrefs::network_dns_upgrade_with_https_rr() ||
|
||||
StaticPrefs::network_dns_use_https_rr_as_altsvc()) {
|
||||
sDNSService->AsyncResolveNative(
|
||||
hostName, nsIDNSService::RESOLVE_TYPE_HTTPSSVC,
|
||||
mEntries[mTail].mFlags | nsIDNSService::RESOLVE_SPECULATE, nullptr,
|
||||
sDNSListener, nullptr, oa, getter_AddRefs(tmpOutstanding));
|
||||
}
|
||||
}
|
||||
|
||||
// Tell element that deferred prefetch was requested.
|
||||
supports.DNSPrefetchRequestStarted();
|
||||
HTMLDNSPrefetch::SendRequest(aElement, aFlags);
|
||||
}
|
||||
|
||||
void DeferredDNSPrefetches::Activate() {
|
||||
|
|
|
@ -55,7 +55,13 @@ class HTMLDNSPrefetch {
|
|||
Medium,
|
||||
High,
|
||||
};
|
||||
static nsresult Prefetch(SupportsDNSPrefetch&, Element&, Priority);
|
||||
enum class PrefetchSource {
|
||||
LinkDnsPrefetch,
|
||||
AnchorSpeculativePrefetch,
|
||||
};
|
||||
static nsresult DeferPrefetch(SupportsDNSPrefetch& aSupports,
|
||||
Element& aElement, Priority aPriority);
|
||||
static void SendRequest(Element& aElement, nsIDNSService::DNSFlags aFlags);
|
||||
static nsresult Prefetch(
|
||||
const nsAString& host, bool isHttps,
|
||||
const OriginAttributes& aPartitionedPrincipalOriginAttributes,
|
||||
|
@ -68,9 +74,9 @@ class HTMLDNSPrefetch {
|
|||
nsresult aReason);
|
||||
static void ElementDestroyed(Element&, SupportsDNSPrefetch&);
|
||||
|
||||
private:
|
||||
static nsIDNSService::DNSFlags PriorityToDNSServiceFlags(Priority);
|
||||
|
||||
private:
|
||||
static nsresult Prefetch(
|
||||
const nsAString& host, bool isHttps,
|
||||
const OriginAttributes& aPartitionedPrincipalOriginAttributes,
|
||||
|
@ -114,8 +120,8 @@ class SupportsDNSPrefetch {
|
|||
mDNSPrefetchDeferred(false),
|
||||
mDestroyedCalled(false) {}
|
||||
|
||||
void CancelDNSPrefetch(Element&);
|
||||
void TryDNSPrefetch(Element&);
|
||||
void CancelDNSPrefetch(Element& aOwner);
|
||||
void TryDNSPrefetch(Element& aOwner, HTMLDNSPrefetch::PrefetchSource aSource);
|
||||
|
||||
// This MUST be called on the destructor of the Element subclass.
|
||||
// Our own destructor ensures that.
|
||||
|
|
|
@ -555,7 +555,7 @@ void HTMLLinkElement::
|
|||
}
|
||||
|
||||
if (linkTypes & eDNS_PREFETCH) {
|
||||
TryDNSPrefetch(*this);
|
||||
TryDNSPrefetch(*this, HTMLDNSPrefetch::PrefetchSource::LinkDnsPrefetch);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3295,6 +3295,18 @@
|
|||
value: false
|
||||
mirror: always
|
||||
|
||||
# Should we speculatively prefetch dns for anchor elements on http documents
|
||||
- name: dom.prefetch_dns_for_anchor_http_document
|
||||
type: bool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Should we speculatively prefetch dns for anchor elements on https documents
|
||||
- name: dom.prefetch_dns_for_anchor_https_document
|
||||
type: bool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# This currently only affects XHTML. For XUL the cache is always allowed.
|
||||
- name: dom.prototype_document_cache.enabled
|
||||
type: bool
|
||||
|
|
Загрузка…
Ссылка в новой задаче