Commit d3ac1c7a authored by sunjian's avatar sunjian Committed by Commit bot

nav timing 2 redirect allow opt-in

BUG=665160

Review-Url: https://codereview.chromium.org/2550883003
Cr-Commit-Position: refs/heads/master@{#438052}
parent 196ee3b6
......@@ -50,6 +50,16 @@
namespace blink {
namespace {
SecurityOrigin* getSecurityOrigin(ExecutionContext* context) {
if (context)
return context->getSecurityOrigin();
return nullptr;
}
} // namespace
using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>;
static const size_t defaultResourceTimingBufferSize = 150;
......@@ -225,7 +235,7 @@ void PerformanceBase::setFrameTimingBufferSize(unsigned size) {
dispatchEvent(Event::create(EventTypeNames::frametimingbufferfull));
}
static bool passesTimingAllowCheck(
bool PerformanceBase::passesTimingAllowCheck(
const ResourceResponse& response,
const SecurityOrigin& initiatorSecurityOrigin,
const AtomicString& originalTimingAllowOrigin,
......@@ -263,10 +273,11 @@ static bool passesTimingAllowCheck(
return false;
}
static bool allowsTimingRedirect(const Vector<ResourceResponse>& redirectChain,
const ResourceResponse& finalResponse,
const SecurityOrigin& initiatorSecurityOrigin,
ExecutionContext* context) {
bool PerformanceBase::allowsTimingRedirect(
const Vector<ResourceResponse>& redirectChain,
const ResourceResponse& finalResponse,
const SecurityOrigin& initiatorSecurityOrigin,
ExecutionContext* context) {
if (!passesTimingAllowCheck(finalResponse, initiatorSecurityOrigin,
AtomicString(), context))
return false;
......@@ -284,10 +295,8 @@ void PerformanceBase::addResourceTiming(const ResourceTimingInfo& info) {
if (isResourceTimingBufferFull() &&
!hasObserverFor(PerformanceEntry::Resource))
return;
SecurityOrigin* securityOrigin = nullptr;
ExecutionContext* context = getExecutionContext();
if (context)
securityOrigin = context->getSecurityOrigin();
SecurityOrigin* securityOrigin = getSecurityOrigin(context);
if (!securityOrigin)
return;
......@@ -357,6 +366,15 @@ void PerformanceBase::addNavigationTiming(LocalFrame* frame) {
double lastRedirectEndTime = documentLoadTiming.redirectEnd();
double finishTime = documentLoadTiming.loadEventEnd();
ExecutionContext* context = getExecutionContext();
SecurityOrigin* securityOrigin = getSecurityOrigin(context);
if (!securityOrigin)
return;
bool allowRedirectDetails =
allowsTimingRedirect(navigationTimingInfo->redirectChain(), finalResponse,
*securityOrigin, context);
unsigned long long transferSize = navigationTimingInfo->transferSize();
unsigned long long encodedBodyLength = finalResponse.encodedBodyLength();
unsigned long long decodedBodyLength = finalResponse.decodedBodyLength();
......@@ -374,7 +392,7 @@ void PerformanceBase::addNavigationTiming(LocalFrame* frame) {
documentTiming ? documentTiming->domComplete() : 0, type,
documentLoadTiming.redirectStart(), documentLoadTiming.redirectEnd(),
documentLoadTiming.fetchStart(), documentLoadTiming.responseEnd(),
documentLoadTiming.hasCrossOriginRedirect(),
allowRedirectDetails,
documentLoadTiming.hasSameOriginAsPreviousDocument(), resourceLoadTiming,
lastRedirectEndTime, finishTime, transferSize, encodedBodyLength,
decodedBodyLength, didReuseConnection);
......
......@@ -132,6 +132,16 @@ class CORE_EXPORT PerformanceBase : public EventTargetWithInlineData {
NavigationType,
const Document*);
static bool allowsTimingRedirect(const Vector<ResourceResponse>&,
const ResourceResponse&,
const SecurityOrigin&,
ExecutionContext*);
static bool passesTimingAllowCheck(const ResourceResponse&,
const SecurityOrigin&,
const AtomicString&,
ExecutionContext*);
protected:
explicit PerformanceBase(double timeOrigin);
......
......@@ -7,10 +7,12 @@
#include "bindings/core/v8/PerformanceObserverCallback.h"
#include "bindings/core/v8/V8BindingForTesting.h"
#include "core/testing/DummyPageHolder.h"
#include "core/testing/NullExecutionContext.h"
#include "core/timing/PerformanceBase.h"
#include "core/timing/PerformanceLongTaskTiming.h"
#include "core/timing/PerformanceObserver.h"
#include "core/timing/PerformanceObserverInit.h"
#include "platform/network/ResourceResponse.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
......@@ -46,8 +48,11 @@ class PerformanceBaseTest : public ::testing::Test {
void SetUp() override {
m_pageHolder = DummyPageHolder::create(IntSize(800, 600));
m_executionContext = new NullExecutionContext();
}
ExecutionContext* getExecutionContext() { return m_executionContext.get(); }
int numPerformanceEntriesInObserver() {
return m_observer->m_performanceEntries.size();
}
......@@ -58,7 +63,17 @@ class PerformanceBaseTest : public ::testing::Test {
return PerformanceBase::getNavigationType(type, document);
}
static bool allowsTimingRedirect(
const Vector<ResourceResponse>& redirectChain,
const ResourceResponse& finalResponse,
const SecurityOrigin& initiatorSecurityOrigin,
ExecutionContext* context) {
return PerformanceBase::allowsTimingRedirect(
redirectChain, finalResponse, initiatorSecurityOrigin, context);
}
Persistent<TestPerformanceBase> m_base;
Persistent<ExecutionContext> m_executionContext;
Persistent<PerformanceObserver> m_observer;
std::unique_ptr<DummyPageHolder> m_pageHolder;
Persistent<PerformanceObserverCallback> m_cb;
......@@ -144,4 +159,40 @@ TEST_F(PerformanceBaseTest, GetNavigationType) {
EXPECT_EQ(returnedType,
PerformanceNavigationTiming::NavigationType::Navigate);
}
TEST_F(PerformanceBaseTest, AllowsTimingRedirect) {
// When there are no cross-origin redirects.
AtomicString originDomain = "http://127.0.0.1:8000";
Vector<ResourceResponse> redirectChain;
KURL url(ParsedURLString, originDomain + "/foo.html");
ResourceResponse finalResponse;
finalResponse.setURL(url);
ResourceResponse redirectResponse1;
redirectResponse1.setURL(url);
ResourceResponse redirectResponse2;
redirectResponse2.setURL(url);
redirectChain.append(redirectResponse1);
redirectChain.append(redirectResponse2);
RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::create(url);
EXPECT_TRUE(allowsTimingRedirect(redirectChain, finalResponse,
*securityOrigin.get(),
getExecutionContext()));
// When there exist cross-origin redirects.
AtomicString crossOriginDomain = "http://126.0.0.1:8000";
KURL redirectUrl(ParsedURLString, crossOriginDomain + "/bar.html");
ResourceResponse redirectResponse3;
redirectResponse3.setURL(redirectUrl);
redirectChain.append(redirectResponse3);
EXPECT_FALSE(allowsTimingRedirect(redirectChain, finalResponse,
*securityOrigin.get(),
getExecutionContext()));
// When cross-origin redirect opts in.
redirectChain.back().setHTTPHeaderField(HTTPNames::Timing_Allow_Origin,
originDomain);
EXPECT_TRUE(allowsTimingRedirect(redirectChain, finalResponse,
*securityOrigin.get(),
getExecutionContext()));
}
} // namespace blink
......@@ -36,7 +36,7 @@ PerformanceNavigationTiming::PerformanceNavigationTiming(
double redirectEnd,
double fetchStart,
double responseEnd,
bool hasCrossOriginRedirect,
bool allowRedirectDetails,
bool hasSameOriginAsPreviousDocument,
ResourceLoadTiming* timing,
double lastRedirectEndTime,
......@@ -57,7 +57,7 @@ PerformanceNavigationTiming::PerformanceNavigationTiming(
true /*allowTimingDetails*/, // TODO(sunjian):
// Create an enum
// for this.
!hasCrossOriginRedirect,
allowRedirectDetails,
"document",
"navigation",
timeOrigin),
......@@ -76,19 +76,19 @@ PerformanceNavigationTiming::PerformanceNavigationTiming(
m_redirectEnd(redirectEnd),
m_fetchStart(fetchStart),
m_responseEnd(responseEnd),
m_hasCrossOriginRedirect(hasCrossOriginRedirect),
m_allowRedirectDetails(allowRedirectDetails),
m_hasSameOriginAsPreviousDocument(hasSameOriginAsPreviousDocument) {}
PerformanceNavigationTiming::~PerformanceNavigationTiming() {}
double PerformanceNavigationTiming::unloadEventStart() const {
if (m_hasCrossOriginRedirect || !m_hasSameOriginAsPreviousDocument)
if (!m_allowRedirectDetails || !m_hasSameOriginAsPreviousDocument)
return 0;
return monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, m_unloadEventStart);
}
double PerformanceNavigationTiming::unloadEventEnd() const {
if (m_hasCrossOriginRedirect || !m_hasSameOriginAsPreviousDocument)
if (!m_allowRedirectDetails || !m_hasSameOriginAsPreviousDocument)
return 0;
return monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, m_unloadEventEnd);
......@@ -136,8 +136,7 @@ AtomicString PerformanceNavigationTiming::type() const {
}
unsigned short PerformanceNavigationTiming::redirectCount() const {
// TODO(sunjian): Also check response headers to allow opt-in crbugs/665160
if (m_hasCrossOriginRedirect)
if (!m_allowRedirectDetails)
return 0;
return m_redirectCount;
}
......@@ -147,13 +146,13 @@ double PerformanceNavigationTiming::fetchStart() const {
}
double PerformanceNavigationTiming::redirectStart() const {
if (m_hasCrossOriginRedirect)
if (!m_allowRedirectDetails)
return 0;
return monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, m_redirectStart);
}
double PerformanceNavigationTiming::redirectEnd() const {
if (m_hasCrossOriginRedirect)
if (!m_allowRedirectDetails)
return 0;
return monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, m_redirectEnd);
}
......
......@@ -32,7 +32,7 @@ class CORE_EXPORT PerformanceNavigationTiming final
double redirectEnd,
double fetchStart,
double responseEnd,
bool hasCrossOriginRedirect,
bool allowRedirectDetails,
bool hasSameOriginAsPreviousDocument,
ResourceLoadTiming*,
double lastRedirectEndTime,
......@@ -80,7 +80,7 @@ class CORE_EXPORT PerformanceNavigationTiming final
double m_redirectEnd;
double m_fetchStart;
double m_responseEnd;
bool m_hasCrossOriginRedirect;
bool m_allowRedirectDetails;
bool m_hasSameOriginAsPreviousDocument;
};
} // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment