|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "nsDNSPrefetch.h" |
|
7 #include "nsCOMPtr.h" |
|
8 #include "nsString.h" |
|
9 #include "nsThreadUtils.h" |
|
10 |
|
11 #include "nsIDNSListener.h" |
|
12 #include "nsIDNSService.h" |
|
13 #include "nsICancelable.h" |
|
14 #include "nsIURI.h" |
|
15 |
|
16 static nsIDNSService *sDNSService = nullptr; |
|
17 |
|
18 nsresult |
|
19 nsDNSPrefetch::Initialize(nsIDNSService *aDNSService) |
|
20 { |
|
21 NS_IF_RELEASE(sDNSService); |
|
22 sDNSService = aDNSService; |
|
23 NS_IF_ADDREF(sDNSService); |
|
24 return NS_OK; |
|
25 } |
|
26 |
|
27 nsresult |
|
28 nsDNSPrefetch::Shutdown() |
|
29 { |
|
30 NS_IF_RELEASE(sDNSService); |
|
31 return NS_OK; |
|
32 } |
|
33 |
|
34 nsDNSPrefetch::nsDNSPrefetch(nsIURI *aURI, |
|
35 nsIDNSListener *aListener, |
|
36 bool storeTiming) |
|
37 : mStoreTiming(storeTiming) |
|
38 , mListener(do_GetWeakReference(aListener)) |
|
39 { |
|
40 aURI->GetAsciiHost(mHostname); |
|
41 } |
|
42 |
|
43 nsresult |
|
44 nsDNSPrefetch::Prefetch(uint16_t flags) |
|
45 { |
|
46 if (mHostname.IsEmpty()) |
|
47 return NS_ERROR_NOT_AVAILABLE; |
|
48 |
|
49 if (!sDNSService) |
|
50 return NS_ERROR_NOT_AVAILABLE; |
|
51 |
|
52 nsCOMPtr<nsICancelable> tmpOutstanding; |
|
53 |
|
54 if (mStoreTiming) |
|
55 mStartTimestamp = mozilla::TimeStamp::Now(); |
|
56 // If AsyncResolve fails, for example because prefetching is disabled, |
|
57 // then our timing will be useless. However, in such a case, |
|
58 // mEndTimestamp will be a null timestamp and callers should check |
|
59 // TimingsValid() before using the timing. |
|
60 nsCOMPtr<nsIThread> mainThread = do_GetMainThread(); |
|
61 return sDNSService->AsyncResolve(mHostname, |
|
62 flags | nsIDNSService::RESOLVE_SPECULATE, |
|
63 this, mainThread, |
|
64 getter_AddRefs(tmpOutstanding)); |
|
65 } |
|
66 |
|
67 nsresult |
|
68 nsDNSPrefetch::PrefetchLow(bool refreshDNS) |
|
69 { |
|
70 return Prefetch(nsIDNSService::RESOLVE_PRIORITY_LOW | |
|
71 (refreshDNS ? nsIDNSService::RESOLVE_BYPASS_CACHE : 0)); |
|
72 } |
|
73 |
|
74 nsresult |
|
75 nsDNSPrefetch::PrefetchMedium(bool refreshDNS) |
|
76 { |
|
77 return Prefetch(nsIDNSService::RESOLVE_PRIORITY_MEDIUM | |
|
78 (refreshDNS ? nsIDNSService::RESOLVE_BYPASS_CACHE : 0)); |
|
79 } |
|
80 |
|
81 nsresult |
|
82 nsDNSPrefetch::PrefetchHigh(bool refreshDNS) |
|
83 { |
|
84 return Prefetch(refreshDNS ? |
|
85 nsIDNSService::RESOLVE_BYPASS_CACHE : 0); |
|
86 } |
|
87 |
|
88 |
|
89 NS_IMPL_ISUPPORTS(nsDNSPrefetch, nsIDNSListener) |
|
90 |
|
91 NS_IMETHODIMP |
|
92 nsDNSPrefetch::OnLookupComplete(nsICancelable *request, |
|
93 nsIDNSRecord *rec, |
|
94 nsresult status) |
|
95 { |
|
96 MOZ_ASSERT(NS_IsMainThread(), "Expecting DNS callback on main thread."); |
|
97 |
|
98 if (mStoreTiming) { |
|
99 mEndTimestamp = mozilla::TimeStamp::Now(); |
|
100 } |
|
101 nsCOMPtr<nsIDNSListener> listener = do_QueryReferent(mListener); |
|
102 if (listener) { |
|
103 listener->OnLookupComplete(request, rec, status); |
|
104 } |
|
105 return NS_OK; |
|
106 } |