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