зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1686828 - Use https OriginAttributes to fetch HTTPS RR r=necko-reviewers,timhuang,dragana
Differential Revision: https://phabricator.services.mozilla.com/D102234
This commit is contained in:
Родитель
a14601368c
Коммит
27daadc420
|
@ -41,7 +41,16 @@ nsDNSPrefetch::nsDNSPrefetch(nsIURI* aURI,
|
|||
mTRRMode(aTRRMode),
|
||||
mListener(do_GetWeakReference(aListener)) {
|
||||
aURI->GetAsciiHost(mHostname);
|
||||
mIsHttps = aURI->SchemeIs("https");
|
||||
}
|
||||
|
||||
nsDNSPrefetch::nsDNSPrefetch(nsIURI* aURI,
|
||||
mozilla::OriginAttributes& aOriginAttributes,
|
||||
nsIRequest::TRRMode aTRRMode)
|
||||
: mOriginAttributes(aOriginAttributes),
|
||||
mStoreTiming(false),
|
||||
mTRRMode(aTRRMode),
|
||||
mListener(nullptr) {
|
||||
aURI->GetAsciiHost(mHostname);
|
||||
}
|
||||
|
||||
nsresult nsDNSPrefetch::Prefetch(uint32_t flags) {
|
||||
|
@ -114,17 +123,20 @@ HTTPSRRListener::OnLookupComplete(nsICancelable* aRequest, nsIDNSRecord* aRec,
|
|||
}; // namespace
|
||||
|
||||
nsresult nsDNSPrefetch::FetchHTTPSSVC(
|
||||
bool aRefreshDNS, std::function<void(nsIDNSHTTPSSVCRecord*)>&& aCallback) {
|
||||
bool aRefreshDNS, bool aPrefetch,
|
||||
std::function<void(nsIDNSHTTPSSVCRecord*)>&& aCallback) {
|
||||
if (!sDNSService) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target = mozilla::GetCurrentEventTarget();
|
||||
uint32_t flags = nsIDNSService::GetFlagsFromTRRMode(mTRRMode) |
|
||||
nsIDNSService::RESOLVE_SPECULATE;
|
||||
uint32_t flags = nsIDNSService::GetFlagsFromTRRMode(mTRRMode);
|
||||
if (aRefreshDNS) {
|
||||
flags |= nsIDNSService::RESOLVE_BYPASS_CACHE;
|
||||
}
|
||||
if (aPrefetch) {
|
||||
flags |= nsIDNSService::RESOLVE_SPECULATE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICancelable> tmpOutstanding;
|
||||
nsCOMPtr<nsIDNSListener> listener = new HTTPSRRListener(std::move(aCallback));
|
||||
|
|
|
@ -31,6 +31,9 @@ class nsDNSPrefetch final : public nsIDNSListener {
|
|||
nsDNSPrefetch(nsIURI* aURI, mozilla::OriginAttributes& aOriginAttributes,
|
||||
nsIRequest::TRRMode aTRRMode, nsIDNSListener* aListener,
|
||||
bool storeTiming);
|
||||
// For fetching HTTPS RR.
|
||||
nsDNSPrefetch(nsIURI* aURI, mozilla::OriginAttributes& aOriginAttributes,
|
||||
nsIRequest::TRRMode aTRRMode);
|
||||
bool TimingsValid() const {
|
||||
return !mStartTimestamp.IsNull() && !mEndTimestamp.IsNull();
|
||||
}
|
||||
|
@ -47,11 +50,11 @@ class nsDNSPrefetch final : public nsIDNSListener {
|
|||
nsresult PrefetchLow(bool refreshDNS = false);
|
||||
|
||||
nsresult FetchHTTPSSVC(
|
||||
bool aRefreshDNS, std::function<void(nsIDNSHTTPSSVCRecord*)>&& aCallback);
|
||||
bool aRefreshDNS, bool aPrefetch,
|
||||
std::function<void(nsIDNSHTTPSSVCRecord*)>&& aCallback);
|
||||
|
||||
private:
|
||||
nsCString mHostname;
|
||||
bool mIsHttps;
|
||||
mozilla::OriginAttributes mOriginAttributes;
|
||||
bool mStoreTiming;
|
||||
nsIRequest::TRRMode mTRRMode;
|
||||
|
|
|
@ -6829,12 +6829,20 @@ nsresult nsHttpChannel::MaybeStartDNSPrefetch() {
|
|||
mDNSBlockingThenable = mDNSBlockingPromise.Ensure(__func__);
|
||||
}
|
||||
|
||||
// When LoadUseHTTPSSVC() is true, we should really "fetch" the HTTPS RR,
|
||||
// not "prefetch", since DNS prefetch can be disabled by the pref.
|
||||
if (LoadUseHTTPSSVC() ||
|
||||
gHttpHandler->UseHTTPSRRForSpeculativeConnection()) {
|
||||
OriginAttributes originAttributes;
|
||||
StoragePrincipalHelper::GetOriginAttributesForHTTPSRR(this,
|
||||
originAttributes);
|
||||
|
||||
RefPtr<nsDNSPrefetch> resolver =
|
||||
new nsDNSPrefetch(mURI, originAttributes, nsIRequest::GetTRRMode());
|
||||
nsWeakPtr weakPtrThis(
|
||||
do_GetWeakReference(static_cast<nsIHttpChannel*>(this)));
|
||||
rv = mDNSPrefetch->FetchHTTPSSVC(
|
||||
mCaps & NS_HTTP_REFRESH_DNS,
|
||||
nsresult rv = resolver->FetchHTTPSSVC(
|
||||
mCaps & NS_HTTP_REFRESH_DNS, !LoadUseHTTPSSVC(),
|
||||
[weakPtrThis](nsIDNSHTTPSSVCRecord* aRecord) {
|
||||
nsCOMPtr<nsIHttpChannel> channel = do_QueryReferent(weakPtrThis);
|
||||
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(channel);
|
||||
|
|
|
@ -236,6 +236,7 @@ function makeChan(url) {
|
|||
let chan = NetUtil.newChannel({
|
||||
uri: url,
|
||||
loadUsingSystemPrincipal: true,
|
||||
contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
return chan;
|
||||
}
|
||||
|
@ -285,8 +286,13 @@ add_task(async function testConnectionWithIPHint() {
|
|||
);
|
||||
|
||||
// The connection should be succeeded since the IP hint is 127.0.0.1.
|
||||
let chan = makeChan(`https://test.iphint.com:8080/`);
|
||||
let chan = makeChan(`http://test.iphint.com:8080/`);
|
||||
// Note that the partitionKey stored in DNS cache would be
|
||||
// "%28https%2Ciphint.com%29". The http request to test.iphint.com will be
|
||||
// upgraded to https and the ip hint address will be used by the https
|
||||
// request in the end.
|
||||
let [req] = await channelOpenPromise(chan);
|
||||
req.QueryInterface(Ci.nsIHttpChannel);
|
||||
Assert.equal(req.getResponseHeader("x-connection-http2"), "yes");
|
||||
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
||||
|
|
|
@ -328,10 +328,14 @@ void StoragePrincipalHelper::UpdateOriginAttributesForNetworkState(
|
|||
aAttributes.SetPartitionKey(aFirstPartyURI);
|
||||
}
|
||||
|
||||
// static
|
||||
bool StoragePrincipalHelper::GetOriginAttributesForHSTS(
|
||||
nsIChannel* aChannel, OriginAttributes& aAttributes) {
|
||||
if (!GetOriginAttributesForNetworkState(aChannel, aAttributes)) {
|
||||
enum SupportedScheme { HTTP, HTTPS };
|
||||
|
||||
static bool GetOriginAttributesWithScheme(nsIChannel* aChannel,
|
||||
OriginAttributes& aAttributes,
|
||||
SupportedScheme aScheme) {
|
||||
const nsString targetScheme = aScheme == HTTP ? u"http"_ns : u"https"_ns;
|
||||
if (!StoragePrincipalHelper::GetOriginAttributesForNetworkState(
|
||||
aChannel, aAttributes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -358,16 +362,29 @@ bool StoragePrincipalHelper::GetOriginAttributesForHSTS(
|
|||
nsAutoString scheme;
|
||||
scheme.Assign(Substring(start, iter));
|
||||
|
||||
if (!scheme.EqualsLiteral("https")) {
|
||||
if (scheme.Equals(targetScheme)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsAutoString key;
|
||||
key.AssignLiteral("(http");
|
||||
key += u"("_ns;
|
||||
key += targetScheme;
|
||||
key.Append(Substring(iter, end));
|
||||
aAttributes.SetPartitionKey(key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool StoragePrincipalHelper::GetOriginAttributesForHSTS(
|
||||
nsIChannel* aChannel, OriginAttributes& aAttributes) {
|
||||
return GetOriginAttributesWithScheme(aChannel, aAttributes, HTTP);
|
||||
}
|
||||
|
||||
// static
|
||||
bool StoragePrincipalHelper::GetOriginAttributesForHTTPSRR(
|
||||
nsIChannel* aChannel, OriginAttributes& aAttributes) {
|
||||
return GetOriginAttributesWithScheme(aChannel, aAttributes, HTTPS);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -275,6 +275,14 @@ class StoragePrincipalHelper final {
|
|||
// For HSTS we want to force 'HTTP' in the partition key.
|
||||
static bool GetOriginAttributesForHSTS(nsIChannel* aChannel,
|
||||
OriginAttributes& aAttributes);
|
||||
|
||||
// Like the function above, this function forces `HTTPS` in the partition key.
|
||||
// The OA created by this function is mainly used in DNS cache. The spec
|
||||
// specifies that the presence of HTTPS RR for an origin also indicates that
|
||||
// all HTTP resources are available over HTTPS, so we use this function to
|
||||
// ensure that all HTTPS RRs in DNS cache are accessed by HTTPS requests only.
|
||||
static bool GetOriginAttributesForHTTPSRR(nsIChannel* aChannel,
|
||||
OriginAttributes& aAttributes);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
Загрузка…
Ссылка в новой задаче