зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1615335 - Use SimpleHttpChannel to fetch TRR data r=valentin
Differential Revision: https://phabricator.services.mozilla.com/D63646 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
e2b5968015
Коммит
6fce0d130b
|
@ -7366,25 +7366,25 @@
|
|||
|
||||
# Single TRR request timeout, in milliseconds
|
||||
- name: network.trr.request_timeout_ms
|
||||
type: uint32_t
|
||||
type: RelaxedAtomicUint32
|
||||
value: 1500
|
||||
mirror: always
|
||||
|
||||
# Single TRR request timeout, in milliseconds for mode 3
|
||||
- name: network.trr.request_timeout_mode_trronly_ms
|
||||
type: uint32_t
|
||||
type: RelaxedAtomicUint32
|
||||
value: 30000
|
||||
mirror: always
|
||||
|
||||
# Whether to send the Accept-Language header for TRR requests
|
||||
- name: network.trr.send_accept-language_headers
|
||||
type: bool
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# Whether to send the User-Agent header for TRR requests
|
||||
- name: network.trr.send_user-agent_headers
|
||||
type: bool
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
|
@ -7408,6 +7408,12 @@
|
|||
value: false
|
||||
mirror: always
|
||||
|
||||
# This pref controls whether to use SimpleHttpChannel off main thread.
|
||||
- name: network.trr.fetch_off_main_thread
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# Allow the network changed event to get sent when a network topology or setup
|
||||
# change is noticed while running.
|
||||
- name: network.notify.changed
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsHostResolver.h"
|
||||
#include "nsHttpHandler.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIIOService.h"
|
||||
|
@ -28,6 +29,7 @@
|
|||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Tokenizer.h"
|
||||
|
@ -156,7 +158,12 @@ nsresult TRR::DohEncode(nsCString& aBody, bool aDisableECS) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
TRR::Run() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT_IF(gTRRService && StaticPrefs::network_trr_fetch_off_main_thread(),
|
||||
gTRRService->IsOnTRRThread());
|
||||
MOZ_ASSERT_IF(
|
||||
gTRRService && !StaticPrefs::network_trr_fetch_off_main_thread(),
|
||||
NS_IsMainThread());
|
||||
|
||||
if ((gTRRService == nullptr) || NS_FAILED(SendHTTPRequest())) {
|
||||
FailData(NS_ERROR_FAILURE);
|
||||
// The dtor will now be run
|
||||
|
@ -164,9 +171,63 @@ TRR::Run() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static void InitHttpHandler() {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> ios = do_GetIOService(&rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIProtocolHandler> handler;
|
||||
rv = ios->GetProtocolHandler("http", getter_AddRefs(handler));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult TRR::CreateChannelHelper(nsIURI* aUri, nsIChannel** aResult) {
|
||||
*aResult = nullptr;
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_NewChannel(aResult, aUri, nsContentUtils::GetSystemPrincipal(),
|
||||
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
nsIContentPolicy::TYPE_OTHER,
|
||||
nullptr, // nsICookieJarSettings
|
||||
nullptr, // PerformanceStorage
|
||||
nullptr, // aLoadGroup
|
||||
nullptr, // aCallbacks
|
||||
nsIRequest::LOAD_NORMAL, ios);
|
||||
}
|
||||
|
||||
// Unfortunately, we can only initialize gHttpHandler on main thread.
|
||||
if (!gHttpHandler) {
|
||||
nsCOMPtr<nsIEventTarget> main = GetMainThreadEventTarget();
|
||||
if (main) {
|
||||
// Forward to the main thread synchronously.
|
||||
SyncRunnable::DispatchToThread(
|
||||
main, new SyncRunnable(NS_NewRunnableFunction(
|
||||
"InitHttpHandler", []() { InitHttpHandler(); })));
|
||||
}
|
||||
}
|
||||
|
||||
if (!gHttpHandler) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return gHttpHandler->CreateSimpleHttpChannel(aUri,
|
||||
nullptr, // givenProxyInfo
|
||||
0, // proxyResolveFlags
|
||||
nullptr, // proxyURI
|
||||
nullptr, // aLoadInfo
|
||||
aResult);
|
||||
}
|
||||
|
||||
nsresult TRR::SendHTTPRequest() {
|
||||
// This is essentially the "run" method - created from nsHostResolver
|
||||
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
|
||||
|
||||
if ((mType != TRRTYPE_A) && (mType != TRRTYPE_AAAA) &&
|
||||
(mType != TRRTYPE_NS) && (mType != TRRTYPE_TXT)) {
|
||||
|
@ -196,14 +257,11 @@ nsresult TRR::SendHTTPRequest() {
|
|||
}
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool useGet = gTRRService->UseGET();
|
||||
nsAutoCString body;
|
||||
nsCOMPtr<nsIURI> dnsURI;
|
||||
bool disableECS = gTRRService->DisableECS();
|
||||
nsresult rv;
|
||||
|
||||
LOG(("TRR::SendHTTPRequest resolve %s type %u\n", mHost.get(), mType));
|
||||
|
||||
|
@ -246,23 +304,20 @@ nsresult TRR::SendHTTPRequest() {
|
|||
return rv;
|
||||
}
|
||||
|
||||
rv = NS_NewChannel(getter_AddRefs(mChannel), dnsURI,
|
||||
nsContentUtils::GetSystemPrincipal(),
|
||||
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
nsIContentPolicy::TYPE_OTHER,
|
||||
nullptr, // nsICookieJarSettings
|
||||
nullptr, // PerformanceStorage
|
||||
nullptr, // aLoadGroup
|
||||
this,
|
||||
nsIRequest::LOAD_ANONYMOUS | nsIRequest::INHIBIT_CACHING |
|
||||
nsIRequest::LOAD_BYPASS_CACHE |
|
||||
nsIChannel::LOAD_BYPASS_URL_CLASSIFIER,
|
||||
ios);
|
||||
rv = CreateChannelHelper(dnsURI, getter_AddRefs(mChannel));
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("TRR:SendHTTPRequest: NewChannel failed!\n"));
|
||||
return rv;
|
||||
}
|
||||
|
||||
mChannel->SetLoadFlags(
|
||||
nsIRequest::LOAD_ANONYMOUS | nsIRequest::INHIBIT_CACHING |
|
||||
nsIRequest::LOAD_BYPASS_CACHE | nsIChannel::LOAD_BYPASS_URL_CLASSIFIER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mChannel->SetNotificationCallbacks(this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
|
||||
if (!httpChannel) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -1019,7 +1074,10 @@ nsresult TRR::On200Response(nsIChannel* aChannel) {
|
|||
mCname.get(), mCnameLoop));
|
||||
RefPtr<TRR> trr =
|
||||
new TRR(mHostResolver, mRec, mCname, mType, mCnameLoop, mPB);
|
||||
rv = NS_DispatchToMainThread(trr);
|
||||
if (!gTRRService) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = gTRRService->DispatchTRRRequest(trr);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1188,10 +1246,22 @@ class ProxyCancel : public Runnable {
|
|||
};
|
||||
|
||||
void TRR::Cancel() {
|
||||
if (StaticPrefs::network_trr_fetch_off_main_thread()) {
|
||||
if (gTRRService) {
|
||||
nsCOMPtr<nsIThread> thread = gTRRService->TRRThread();
|
||||
if (thread && !thread->IsOnCurrentThread()) {
|
||||
nsCOMPtr<nsIRunnable> r = new ProxyCancel(this);
|
||||
thread->Dispatch(r.forget());
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!NS_IsMainThread()) {
|
||||
NS_DispatchToMainThread(new ProxyCancel(this));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mChannel) {
|
||||
LOG(("TRR: %p canceling Channel %p %s %d\n", this, mChannel.get(),
|
||||
mHost.get(), mType));
|
||||
|
|
|
@ -165,6 +165,8 @@ class TRR : public Runnable,
|
|||
|
||||
bool UseDefaultServer();
|
||||
|
||||
nsresult CreateChannelHelper(nsIURI* aUri, nsIChannel** aResult);
|
||||
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
enum TrrType mType;
|
||||
TimeStamp mStartTime;
|
||||
|
|
|
@ -34,6 +34,7 @@ extern mozilla::LazyLogModule gHostResolverLog;
|
|||
#define LOG(args) MOZ_LOG(gHostResolverLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
TRRService* gTRRService = nullptr;
|
||||
StaticRefPtr<nsIThread> sTRRBackgroundThread;
|
||||
|
||||
NS_IMPL_ISUPPORTS(TRRService, nsIObserver, nsISupportsWeakReference)
|
||||
|
||||
|
@ -75,6 +76,7 @@ nsresult TRRService::Init() {
|
|||
observerService->AddObserver(this, kPurge, true);
|
||||
observerService->AddObserver(this, NS_NETWORK_LINK_TOPIC, true);
|
||||
observerService->AddObserver(this, NS_DNS_SUFFIX_LIST_UPDATED_TOPIC, true);
|
||||
observerService->AddObserver(this, "xpcom-shutdown-threads", true);
|
||||
}
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
GetPrefBranch(getter_AddRefs(prefBranch));
|
||||
|
@ -106,6 +108,18 @@ nsresult TRRService::Init() {
|
|||
nsCOMPtr<nsINetworkLinkService> nls =
|
||||
do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID);
|
||||
RebuildSuffixList(nls);
|
||||
|
||||
if (StaticPrefs::network_trr_fetch_off_main_thread()) {
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
if (NS_FAILED(
|
||||
NS_NewNamedThread("TRR Background", getter_AddRefs(thread)))) {
|
||||
NS_WARNING("NS_NewNamedThread failed!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
sTRRBackgroundThread = thread;
|
||||
}
|
||||
|
||||
LOG(("Initialized TRRService\n"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -397,6 +411,49 @@ TRRService::~TRRService() {
|
|||
gTRRService = nullptr;
|
||||
}
|
||||
|
||||
nsresult TRRService::DispatchTRRRequest(TRR* aTrrRequest) {
|
||||
return DispatchTRRRequestInternal(aTrrRequest, true);
|
||||
}
|
||||
|
||||
nsresult TRRService::DispatchTRRRequestInternal(TRR* aTrrRequest,
|
||||
bool aWithLock) {
|
||||
NS_ENSURE_ARG_POINTER(aTrrRequest);
|
||||
if (!StaticPrefs::network_trr_fetch_off_main_thread()) {
|
||||
return NS_DispatchToMainThread(aTrrRequest);
|
||||
}
|
||||
|
||||
RefPtr<TRR> trr = aTrrRequest;
|
||||
nsCOMPtr<nsIThread> thread = aWithLock ? TRRThread() : TRRThread_locked();
|
||||
if (!thread) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return thread->Dispatch(trr.forget());
|
||||
}
|
||||
|
||||
already_AddRefed<nsIThread> TRRService::TRRThread() {
|
||||
MutexAutoLock lock(mLock);
|
||||
return TRRThread_locked();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIThread> TRRService::TRRThread_locked() {
|
||||
RefPtr<nsIThread> thread = sTRRBackgroundThread;
|
||||
return thread.forget();
|
||||
}
|
||||
|
||||
bool TRRService::IsOnTRRThread() {
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
thread = sTRRBackgroundThread;
|
||||
}
|
||||
if (!thread) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return thread->IsOnCurrentThread();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TRRService::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) {
|
||||
|
@ -462,6 +519,16 @@ TRRService::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
nsCOMPtr<nsINetworkLinkService> link = do_QueryInterface(aSubject);
|
||||
RebuildSuffixList(link);
|
||||
CheckPlatformDNSStatus(link);
|
||||
} else if (!strcmp(aTopic, "xpcom-shutdown-threads")) {
|
||||
if (sTRRBackgroundThread) {
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
thread = sTRRBackgroundThread.get();
|
||||
sTRRBackgroundThread = nullptr;
|
||||
}
|
||||
MOZ_ALWAYS_SUCCEEDS(thread->Shutdown());
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -526,7 +593,7 @@ void TRRService::MaybeConfirm_locked() {
|
|||
mConfirmationNS.get()));
|
||||
mConfirmer =
|
||||
new TRR(this, mConfirmationNS, TRRTYPE_NS, EmptyCString(), false);
|
||||
NS_DispatchToMainThread(mConfirmer);
|
||||
DispatchTRRRequestInternal(mConfirmer, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -563,9 +630,6 @@ bool TRRService::MaybeBootstrap(const nsACString& aPossible,
|
|||
bool TRRService::IsDomainBlacklisted(const nsACString& aHost,
|
||||
const nsACString& aOriginSuffix,
|
||||
bool aPrivateBrowsing) {
|
||||
// Only use the Storage API on the main thread
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread(), "wrong thread");
|
||||
|
||||
if (!Enabled(nsIRequest::TRR_DEFAULT_MODE)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -576,9 +640,16 @@ bool TRRService::IsDomainBlacklisted(const nsACString& aHost,
|
|||
// Calling the locking version of this method would cause us to grab
|
||||
// the mutex for every label of the hostname, which would be very
|
||||
// inefficient.
|
||||
if (NS_IsMainThread()) {
|
||||
if (IsExcludedFromTRR_unlocked(aHost)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(IsOnTRRThread());
|
||||
if (IsExcludedFromTRR(aHost)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mTRRBLStorage) {
|
||||
return false;
|
||||
|
@ -770,7 +841,7 @@ void TRRService::TRRBlacklist(const nsACString& aHost,
|
|||
// check if there's an NS entry for this name
|
||||
RefPtr<TRR> trr =
|
||||
new TRR(this, check, TRRTYPE_NS, aOriginSuffix, privateBrowsing);
|
||||
NS_DispatchToMainThread(trr);
|
||||
DispatchTRRRequest(trr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -792,7 +863,11 @@ TRRService::Notify(nsITimer* aTimer) {
|
|||
}
|
||||
|
||||
void TRRService::TRRIsOkay(enum TrrOkay aReason) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT_IF(StaticPrefs::network_trr_fetch_off_main_thread(),
|
||||
IsOnTRRThread());
|
||||
MOZ_ASSERT_IF(!StaticPrefs::network_trr_fetch_off_main_thread(),
|
||||
NS_IsMainThread());
|
||||
|
||||
Telemetry::AccumulateCategorical(
|
||||
aReason == OKAY_NORMAL ? Telemetry::LABELS_DNS_TRR_SUCCESS::Fine
|
||||
: (aReason == OKAY_TIMEOUT
|
||||
|
@ -819,7 +894,10 @@ AHostResolver::LookupStatus TRRService::CompleteLookup(
|
|||
const nsACString& aOriginSuffix) {
|
||||
// this is an NS check for the TRR blacklist or confirmationNS check
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT_IF(StaticPrefs::network_trr_fetch_off_main_thread(),
|
||||
IsOnTRRThread());
|
||||
MOZ_ASSERT_IF(!StaticPrefs::network_trr_fetch_off_main_thread(),
|
||||
NS_IsMainThread());
|
||||
MOZ_ASSERT(!rec);
|
||||
|
||||
RefPtr<AddrInfo> newRRSet(aNewRRSet);
|
||||
|
|
|
@ -67,6 +67,10 @@ class TRRService : public nsIObserver,
|
|||
void TRRIsOkay(enum TrrOkay aReason);
|
||||
bool ParentalControlEnabled() const { return mParentalControlEnabled; }
|
||||
|
||||
nsresult DispatchTRRRequest(TRR* aTrrRequest);
|
||||
already_AddRefed<nsIThread> TRRThread();
|
||||
bool IsOnTRRThread();
|
||||
|
||||
private:
|
||||
virtual ~TRRService();
|
||||
nsresult ReadPrefs(const char* name);
|
||||
|
@ -84,6 +88,9 @@ class TRRService : public nsIObserver,
|
|||
void RebuildSuffixList(nsINetworkLinkService* aLinkService);
|
||||
void CheckPlatformDNSStatus(nsINetworkLinkService* aLinkService);
|
||||
|
||||
nsresult DispatchTRRRequestInternal(TRR* aTrrRequest, bool aWithLock);
|
||||
already_AddRefed<nsIThread> TRRThread_locked();
|
||||
|
||||
bool mInitialized;
|
||||
Atomic<uint32_t, Relaxed> mMode;
|
||||
Atomic<uint32_t, Relaxed> mTRRBlacklistExpireTime;
|
||||
|
|
|
@ -82,6 +82,7 @@ GeneratedFile('etld_data.inc', script='prepare_tlds.py',
|
|||
# need to include etld_data.inc
|
||||
LOCAL_INCLUDES += [
|
||||
'/netwerk/base',
|
||||
'/netwerk/protocol/http',
|
||||
]
|
||||
|
||||
USE_LIBS += ['icu']
|
||||
|
|
|
@ -1272,7 +1272,7 @@ nsresult nsHostResolver::TrrLookup(nsHostRecord* aRec, TRR* pushedTRR) {
|
|||
RefPtr<TRR> trr;
|
||||
MutexAutoLock trrlock(addrRec->mTrrLock);
|
||||
trr = pushedTRR ? pushedTRR : new TRR(this, rec, rectype);
|
||||
if (pushedTRR || NS_SUCCEEDED(NS_DispatchToMainThread(trr))) {
|
||||
if (pushedTRR || NS_SUCCEEDED(gTRRService->DispatchTRRRequest(trr))) {
|
||||
addrRec->mResolving++;
|
||||
if (rectype == TRRTYPE_A) {
|
||||
MOZ_ASSERT(!addrRec->mTrrA);
|
||||
|
@ -1305,7 +1305,8 @@ nsresult nsHostResolver::TrrLookup(nsHostRecord* aRec, TRR* pushedTRR) {
|
|||
RefPtr<TRR> trr;
|
||||
MutexAutoLock trrlock(typeRec->mTrrLock);
|
||||
trr = pushedTRR ? pushedTRR : new TRR(this, rec, rectype);
|
||||
if (pushedTRR || NS_SUCCEEDED(NS_DispatchToMainThread(trr))) {
|
||||
RefPtr<TRR> trrRequest = trr;
|
||||
if (pushedTRR || NS_SUCCEEDED(gTRRService->DispatchTRRRequest(trr))) {
|
||||
typeRec->mResolving++;
|
||||
MOZ_ASSERT(!typeRec->mTrr);
|
||||
typeRec->mTrr = trr;
|
||||
|
|
Загрузка…
Ссылка в новой задаче