Commit 04d7a90e authored by japhet@chromium.org's avatar japhet@chromium.org

Make generateReferrerHeader() return a Referrer instead of a String

Rename it to generateReferrer() to better match its return type.

Also, make setHTTPReferrer() remove the header if the value parameter is empty. There shouldn't ever be a reason to send an empty referrer header (rather than not sending a referrer header at all), so this enables us to enforce this property in one place, rather than several.

BUG=

Review URL: https://codereview.chromium.org/650023003

git-svn-id: svn://svn.chromium.org/blink/trunk@183838 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 27e8bbdf
......@@ -32,8 +32,7 @@ void RemoteFrame::navigate(Document& originDocument, const KURL& url, bool lockB
// The process where this frame actually lives won't have sufficient information to determine
// correct referrer, since it won't have access to the originDocument. Set it now.
ResourceRequest request(url);
Referrer referrer(SecurityPolicy::generateReferrerHeader(originDocument.referrerPolicy(), url, originDocument.outgoingReferrer()), originDocument.referrerPolicy());
request.setHTTPReferrer(referrer);
request.setHTTPReferrer(SecurityPolicy::generateReferrer(originDocument.referrerPolicy(), url, originDocument.outgoingReferrer()));
remoteFrameClient()->navigate(request, lockBackForwardList);
}
......
......@@ -73,12 +73,7 @@ void FrameFetchContext::addAdditionalRequestHeaders(Document* document, Resource
outgoingOrigin = SecurityOrigin::createFromString(outgoingReferrer)->toString();
}
outgoingReferrer = SecurityPolicy::generateReferrerHeader(referrerPolicy, request.url(), outgoingReferrer);
if (outgoingReferrer.isEmpty())
request.clearHTTPReferrer();
else
request.setHTTPReferrer(Referrer(outgoingReferrer, referrerPolicy));
request.setHTTPReferrer(SecurityPolicy::generateReferrer(referrerPolicy, request.url(), outgoingReferrer));
request.addHTTPOriginIfNeeded(AtomicString(outgoingOrigin));
}
......
......@@ -630,12 +630,12 @@ void FrameLoader::setReferrerForFrameRequest(ResourceRequest& request, ShouldSen
return;
// Always use the initiating document to generate the referrer.
// We need to generateReferrerHeader(), because we haven't enforced ReferrerPolicy or https->http
// We need to generateReferrer(), because we haven't enforced ReferrerPolicy or https->http
// referrer suppression yet.
String referrer = SecurityPolicy::generateReferrerHeader(originDocument->referrerPolicy(), request.url(), originDocument->outgoingReferrer());
Referrer referrer = SecurityPolicy::generateReferrer(originDocument->referrerPolicy(), request.url(), originDocument->outgoingReferrer());
request.setHTTPReferrer(Referrer(referrer, originDocument->referrerPolicy()));
RefPtr<SecurityOrigin> referrerOrigin = SecurityOrigin::createFromString(referrer);
request.setHTTPReferrer(referrer);
RefPtr<SecurityOrigin> referrerOrigin = SecurityOrigin::createFromString(referrer.referrer);
request.addHTTPOriginIfNeeded(referrerOrigin->toAtomicString());
}
......
......@@ -46,14 +46,10 @@ PassOwnPtr<PrerenderHandle> PrerenderHandle::create(Document& document, Prerende
{
// Prerenders are unlike requests in most ways (for instance, they pass down fragments, and they don't return data),
// but they do have referrers.
const ReferrerPolicy referrerPolicy = document.referrerPolicy();
if (!document.frame())
return PassOwnPtr<PrerenderHandle>();
const String referrer = SecurityPolicy::generateReferrerHeader(referrerPolicy, url, document.outgoingReferrer());
RefPtr<Prerender> prerender = Prerender::create(client, url, prerenderRelTypes, referrer, referrerPolicy);
RefPtr<Prerender> prerender = Prerender::create(client, url, prerenderRelTypes, SecurityPolicy::generateReferrer(document.referrerPolicy(), url, document.outgoingReferrer()));
PrerendererClient* prerendererClient = PrerendererClient::from(document.page());
if (prerendererClient)
......
......@@ -133,10 +133,9 @@ LocalFrame* createWindow(const String& urlString, const AtomicString& frameName,
// Normally, FrameLoader would take care of setting the referrer for a navigation that is
// triggered from javascript. However, creating a window goes through sufficient processing
// that it eventually enters FrameLoader as an embedder-initiated navigation. FrameLoader
// assumes no responsibility for generating an embedder-initiated navigation's referrer,
// assumes no responsibility for generating an embedder-initiated navigation's referrer,
// so we need to ensure the proper referrer is set now.
Referrer referrer(SecurityPolicy::generateReferrerHeader(activeFrame->document()->referrerPolicy(), completedURL, activeFrame->document()->outgoingReferrer()), activeFrame->document()->referrerPolicy());
frameRequest.resourceRequest().setHTTPReferrer(referrer);
frameRequest.resourceRequest().setHTTPReferrer(SecurityPolicy::generateReferrer(activeFrame->document()->referrerPolicy(), completedURL, activeFrame->document()->outgoingReferrer()));
// We pass the opener frame for the lookupFrame in case the active frame is different from
// the opener frame, and the name references a frame relative to the opener frame.
......
......@@ -38,17 +38,16 @@
namespace blink {
PassRefPtr<Prerender> Prerender::create(PrerenderClient* client, const KURL& url, unsigned relTypes, const String& referrer, ReferrerPolicy policy)
PassRefPtr<Prerender> Prerender::create(PrerenderClient* client, const KURL& url, unsigned relTypes, const Referrer& referrer)
{
return adoptRef(new Prerender(client, url, relTypes, referrer, policy));
return adoptRef(new Prerender(client, url, relTypes, referrer));
}
Prerender::Prerender(PrerenderClient* client, const KURL& url, const unsigned relTypes, const String& referrer, ReferrerPolicy policy)
Prerender::Prerender(PrerenderClient* client, const KURL& url, const unsigned relTypes, const Referrer& referrer)
: m_client(client)
, m_url(url)
, m_relTypes(relTypes)
, m_referrer(referrer)
, m_referrerPolicy(policy)
{
}
......
......@@ -34,7 +34,7 @@
#include "platform/PlatformExport.h"
#include "platform/weborigin/KURL.h"
#include "platform/weborigin/ReferrerPolicy.h"
#include "platform/weborigin/Referrer.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
......@@ -54,7 +54,7 @@ public:
virtual ~ExtraData() { }
};
static PassRefPtr<Prerender> create(PrerenderClient*, const KURL&, unsigned relTypes, const String& referrer, ReferrerPolicy);
static PassRefPtr<Prerender> create(PrerenderClient*, const KURL&, unsigned relTypes, const Referrer&);
~Prerender();
void removeClient();
......@@ -65,8 +65,8 @@ public:
const KURL& url() const { return m_url; }
unsigned relTypes() const { return m_relTypes; }
const String& referrer() const { return m_referrer; }
ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
const String& referrer() const { return m_referrer.referrer; }
ReferrerPolicy referrerPolicy() const { return m_referrer.referrerPolicy; }
void setExtraData(PassRefPtr<ExtraData> extraData) { m_extraData = extraData; }
ExtraData* extraData() { return m_extraData.get(); }
......@@ -77,14 +77,13 @@ public:
void didSendDOMContentLoadedForPrerender();
private:
Prerender(PrerenderClient*, const KURL&, unsigned relTypes, const String& referrer, ReferrerPolicy);
Prerender(PrerenderClient*, const KURL&, unsigned relTypes, const Referrer&);
PrerenderClient* m_client;
const KURL m_url;
const unsigned m_relTypes;
const String m_referrer;
const ReferrerPolicy m_referrerPolicy;
const Referrer m_referrer;
RefPtr<ExtraData> m_extraData;
};
......
......@@ -169,10 +169,7 @@ void WebURLRequest::setHTTPHeaderField(const WebString& name, const WebString& v
void WebURLRequest::setHTTPReferrer(const WebString& referrer, WebReferrerPolicy referrerPolicy)
{
if (referrer.isEmpty())
m_private->m_resourceRequest->clearHTTPReferrer();
else
m_private->m_resourceRequest->setHTTPReferrer(Referrer(referrer, static_cast<ReferrerPolicy>(referrerPolicy)));
m_private->m_resourceRequest->setHTTPReferrer(Referrer(referrer, static_cast<ReferrerPolicy>(referrerPolicy)));
}
void WebURLRequest::addHTTPHeaderField(const WebString& name, const WebString& value)
......
......@@ -186,6 +186,15 @@ void ResourceRequest::setHTTPHeaderField(const char* name, const AtomicString& v
setHTTPHeaderField(AtomicString(name), value);
}
void ResourceRequest::setHTTPReferrer(const Referrer& referrer)
{
if (referrer.referrer.isEmpty())
m_httpHeaderFields.remove("Referer");
else
setHTTPHeaderField("Referer", referrer.referrer);
m_referrerPolicy = referrer.referrerPolicy;
}
void ResourceRequest::clearHTTPAuthorization()
{
m_httpHeaderFields.remove("Authorization");
......
......@@ -113,7 +113,7 @@ public:
const AtomicString& httpReferrer() const { return httpHeaderField("Referer"); }
ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
void setHTTPReferrer(const Referrer& httpReferrer) { setHTTPHeaderField("Referer", httpReferrer.referrer); m_referrerPolicy = httpReferrer.referrerPolicy; }
void setHTTPReferrer(const Referrer&);
void clearHTTPReferrer();
const AtomicString& httpOrigin() const { return httpHeaderField("Origin"); }
......
......@@ -65,32 +65,32 @@ bool SecurityPolicy::shouldHideReferrer(const KURL& url, const String& referrer)
return !URLIsSecureURL;
}
String SecurityPolicy::generateReferrerHeader(ReferrerPolicy referrerPolicy, const KURL& url, const String& referrer)
Referrer SecurityPolicy::generateReferrer(ReferrerPolicy referrerPolicy, const KURL& url, const String& referrer)
{
if (referrer.isEmpty())
return String();
return Referrer(String(), referrerPolicy);
if (!(protocolIs(referrer, "https") || protocolIs(referrer, "http")))
return String();
return Referrer(String(), referrerPolicy);
switch (referrerPolicy) {
case ReferrerPolicyNever:
return String();
return Referrer(String(), referrerPolicy);
case ReferrerPolicyAlways:
return referrer;
return Referrer(referrer, referrerPolicy);
case ReferrerPolicyOrigin: {
String origin = SecurityOrigin::createFromString(referrer)->toString();
if (origin == "null")
return String();
return Referrer(String(), referrerPolicy);
// A security origin is not a canonical URL as it lacks a path. Add /
// to turn it into a canonical URL we can use as referrer.
return origin + "/";
return Referrer(origin + "/", referrerPolicy);
}
case ReferrerPolicyDefault:
break;
}
return shouldHideReferrer(url, referrer) ? String() : referrer;
return Referrer(shouldHideReferrer(url, referrer) ? String() : referrer, referrerPolicy);
}
bool SecurityPolicy::isAccessWhiteListed(const SecurityOrigin* activeOrigin, const SecurityOrigin* targetOrigin)
......
......@@ -30,6 +30,7 @@
#define SecurityPolicy_h
#include "platform/PlatformExport.h"
#include "platform/weborigin/Referrer.h"
#include "platform/weborigin/ReferrerPolicy.h"
#include "wtf/text/WTFString.h"
......@@ -48,7 +49,7 @@ public:
// Returns the referrer modified according to the referrer policy for a
// navigation to a given URL. If the referrer returned is empty, the
// referrer header should be omitted.
static String generateReferrerHeader(ReferrerPolicy, const KURL&, const String& referrer);
static Referrer generateReferrer(ReferrerPolicy, const KURL&, const String& referrer);
static void addOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomain, bool allowDestinationSubdomains);
static void removeOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomain, bool allowDestinationSubdomains);
......
......@@ -41,7 +41,7 @@ namespace {
TEST(SecurityPolicyTest, ReferrerIsAlwaysAWebURL)
{
EXPECT_TRUE(String() == SecurityPolicy::generateReferrerHeader(blink::ReferrerPolicyAlways, KURL(blink::ParsedURLString, "http://example.com/"), String::fromUTF8("chrome://somepage/")));
EXPECT_TRUE(String() == SecurityPolicy::generateReferrer(blink::ReferrerPolicyAlways, KURL(blink::ParsedURLString, "http://example.com/"), String::fromUTF8("chrome://somepage/")).referrer);
}
} // namespace
......
......@@ -924,10 +924,7 @@ bool WebLocalFrameImpl::isViewSourceModeEnabled() const
void WebLocalFrameImpl::setReferrerForRequest(WebURLRequest& request, const WebURL& referrerURL)
{
String referrer = referrerURL.isEmpty() ? frame()->document()->outgoingReferrer() : String(referrerURL.spec().utf16());
referrer = SecurityPolicy::generateReferrerHeader(frame()->document()->referrerPolicy(), request.url(), referrer);
if (referrer.isEmpty())
return;
request.setHTTPReferrer(referrer, static_cast<WebReferrerPolicy>(frame()->document()->referrerPolicy()));
request.toMutableResourceRequest().setHTTPReferrer(SecurityPolicy::generateReferrer(frame()->document()->referrerPolicy(), request.url(), referrer));
}
void WebLocalFrameImpl::dispatchWillSendRequest(WebURLRequest& request)
......
......@@ -104,7 +104,7 @@ void WebSecurityPolicy::resetOriginAccessWhitelists()
WebString WebSecurityPolicy::generateReferrerHeader(WebReferrerPolicy referrerPolicy, const WebURL& url, const WebString& referrer)
{
return SecurityPolicy::generateReferrerHeader(static_cast<ReferrerPolicy>(referrerPolicy), url, referrer);
return SecurityPolicy::generateReferrer(static_cast<ReferrerPolicy>(referrerPolicy), url, referrer).referrer;
}
void WebSecurityPolicy::registerURLSchemeAsNotAllowingJavascriptURLs(const WebString& scheme)
......
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