HTMLDNSPrefetch.h (4967B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_HTMLDNSPrefetch_h___ 8 #define mozilla_dom_HTMLDNSPrefetch_h___ 9 10 #include "nsCOMPtr.h" 11 #include "nsIDNSService.h" 12 #include "nsIRequest.h" 13 #include "nsString.h" 14 15 class nsITimer; 16 class nsIURI; 17 namespace mozilla { 18 19 class OriginAttributes; 20 21 namespace net { 22 class NeckoParent; 23 } // namespace net 24 25 namespace dom { 26 class Document; 27 class Element; 28 29 class SupportsDNSPrefetch; 30 31 class HTMLDNSPrefetch { 32 public: 33 // The required aDocument parameter is the context requesting the prefetch - 34 // under certain circumstances (e.g. headers, or security context) associated 35 // with the context the prefetch will not be performed. 36 static bool IsAllowed(Document* aDocument); 37 38 static nsresult Initialize(); 39 static nsresult Shutdown(); 40 41 // Call one of the Prefetch* methods to start the lookup. 42 // 43 // The URI versions will defer DNS lookup until pageload is 44 // complete, while the string versions submit the lookup to 45 // the DNS system immediately. The URI version is somewhat lighter 46 // weight, but its request is also more likely to be dropped due to a 47 // full queue and it may only be used from the main thread. 48 // 49 // If you are planning to use the methods with the OriginAttributes param, be 50 // sure that you pass a partitioned one. See StoragePrincipalHelper.h to know 51 // more. 52 53 enum class Priority { 54 Low, 55 Medium, 56 High, 57 }; 58 enum class PrefetchSource { 59 LinkDnsPrefetch, 60 AnchorSpeculativePrefetch, 61 }; 62 static nsresult DeferPrefetch(SupportsDNSPrefetch& aSupports, 63 Element& aElement, Priority aPriority); 64 static void SendRequest(Element& aElement, nsIDNSService::DNSFlags aFlags); 65 static nsresult Prefetch( 66 const nsAString& host, bool isHttps, 67 const OriginAttributes& aPartitionedPrincipalOriginAttributes, 68 nsIRequest::TRRMode aTRRMode, Priority); 69 static nsresult CancelPrefetch( 70 const nsAString& host, bool isHttps, 71 const OriginAttributes& aPartitionedPrincipalOriginAttributes, 72 nsIRequest::TRRMode aTRRMode, Priority, nsresult aReason); 73 static nsresult CancelPrefetch(SupportsDNSPrefetch&, Element&, Priority, 74 nsresult aReason); 75 static void ElementDestroyed(Element&, SupportsDNSPrefetch&); 76 77 static nsIDNSService::DNSFlags PriorityToDNSServiceFlags(Priority); 78 79 private: 80 static nsresult Prefetch( 81 const nsAString& host, bool isHttps, 82 const OriginAttributes& aPartitionedPrincipalOriginAttributes, 83 nsIDNSService::DNSFlags flags); 84 static nsresult CancelPrefetch( 85 const nsAString& hostname, bool isHttps, 86 const OriginAttributes& aPartitionedPrincipalOriginAttributes, 87 nsIDNSService::DNSFlags flags, nsresult aReason); 88 89 friend class net::NeckoParent; 90 }; 91 92 // Elements that support DNS prefetch are expected to subclass this. 93 class SupportsDNSPrefetch { 94 public: 95 bool IsInDNSPrefetch() { return mInDNSPrefetch; } 96 void SetIsInDNSPrefetch() { mInDNSPrefetch = true; } 97 void ClearIsInDNSPrefetch() { mInDNSPrefetch = false; } 98 99 void DNSPrefetchRequestStarted() { 100 mDNSPrefetchDeferred = false; 101 mDNSPrefetchRequested = true; 102 } 103 104 void DNSPrefetchRequestDeferred() { 105 mDNSPrefetchDeferred = true; 106 mDNSPrefetchRequested = false; 107 } 108 109 bool IsDNSPrefetchRequestDeferred() const { return mDNSPrefetchDeferred; } 110 111 // This could be a virtual function or something like that, but that would 112 // cause our subclasses to grow by two pointers, rather than just 1 byte at 113 // most. 114 nsIURI* GetURIForDNSPrefetch(Element& aOwner); 115 116 protected: 117 SupportsDNSPrefetch() 118 : mInDNSPrefetch(false), 119 mDNSPrefetchRequested(false), 120 mDNSPrefetchDeferred(false), 121 mDestroyedCalled(false) {} 122 123 void CancelDNSPrefetch(Element& aOwner); 124 void TryDNSPrefetch(Element& aOwner, HTMLDNSPrefetch::PrefetchSource aSource); 125 126 // This MUST be called on the destructor of the Element subclass. 127 // Our own destructor ensures that. 128 void Destroyed(Element& aOwner) { 129 MOZ_DIAGNOSTIC_ASSERT(!mDestroyedCalled, 130 "Multiple calls to SupportsDNSPrefetch::Destroyed?"); 131 mDestroyedCalled = true; 132 if (mInDNSPrefetch) { 133 HTMLDNSPrefetch::ElementDestroyed(aOwner, *this); 134 } 135 } 136 137 ~SupportsDNSPrefetch() { 138 MOZ_DIAGNOSTIC_ASSERT(mDestroyedCalled, 139 "Need to call SupportsDNSPrefetch::Destroyed " 140 "from the owner element"); 141 } 142 143 private: 144 bool mInDNSPrefetch : 1; 145 bool mDNSPrefetchRequested : 1; 146 bool mDNSPrefetchDeferred : 1; 147 bool mDestroyedCalled : 1; 148 }; 149 150 } // namespace dom 151 } // namespace mozilla 152 153 #endif