Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(528)

Unified Diff: third_party/WebKit/Source/core/loader/BeaconLoader.cpp

Issue 2177383006: Update and fix sendBeacon() redirect behavior. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: improve content type initialization Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/loader/BeaconLoader.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/loader/BeaconLoader.cpp
diff --git a/third_party/WebKit/Source/core/loader/BeaconLoader.cpp b/third_party/WebKit/Source/core/loader/BeaconLoader.cpp
index c2c137dc796bc61e6714af88876ae81f8ff663ee..ced714ce3c2d573219b01d976fb5898d5822c6f1 100644
--- a/third_party/WebKit/Source/core/loader/BeaconLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/BeaconLoader.cpp
@@ -9,6 +9,7 @@
#include "core/fetch/CrossOriginAccessControl.h"
#include "core/fetch/FetchContext.h"
#include "core/fetch/FetchInitiatorTypeNames.h"
+#include "core/fetch/FetchUtils.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/fileapi/File.h"
#include "core/frame/LocalFrame.h"
@@ -28,14 +29,16 @@ namespace blink {
namespace {
class Beacon {
+ STACK_ALLOCATED();
public:
virtual bool serialize(ResourceRequest&, int, int&) const = 0;
virtual unsigned long long size() const = 0;
+ virtual const AtomicString getContentType() const = 0;
};
class BeaconString final : public Beacon {
public:
- BeaconString(const String& data)
+ explicit BeaconString(const String& data)
: m_data(data)
{
}
@@ -49,19 +52,24 @@ public:
{
RefPtr<EncodedFormData> entityBody = EncodedFormData::create(m_data.utf8());
request.setHTTPBody(entityBody);
- request.setHTTPContentType("text/plain;charset=UTF-8");
+ request.setHTTPContentType(getContentType());
return true;
}
+ const AtomicString getContentType() const { return AtomicString("text/plain;charset=UTF-8"); }
+
private:
const String m_data;
};
class BeaconBlob final : public Beacon {
public:
- BeaconBlob(Blob* data)
+ explicit BeaconBlob(Blob* data)
: m_data(data)
{
+ const String& blobType = m_data->type();
+ if (!blobType.isEmpty() && isValidContentType(blobType))
+ m_contentType = AtomicString(blobType);
}
unsigned long long size() const override
@@ -80,20 +88,22 @@ public:
request.setHTTPBody(entityBody.release());
- const String& blobType = m_data->type();
- if (!blobType.isEmpty() && isValidContentType(blobType))
- request.setHTTPContentType(AtomicString(blobType));
+ if (!m_contentType.isEmpty())
+ request.setHTTPContentType(m_contentType);
return true;
}
+ const AtomicString getContentType() const { return m_contentType; }
+
private:
- const Persistent<Blob> m_data;
+ const Member<Blob> m_data;
+ AtomicString m_contentType;
};
class BeaconDOMArrayBufferView final : public Beacon {
public:
- BeaconDOMArrayBufferView(DOMArrayBufferView* data)
+ explicit BeaconDOMArrayBufferView(DOMArrayBufferView* data)
: m_data(data)
{
}
@@ -116,15 +126,19 @@ public:
return true;
}
+ const AtomicString getContentType() const { return nullAtom; }
+
private:
- const Persistent<DOMArrayBufferView> m_data;
+ const Member<DOMArrayBufferView> m_data;
};
class BeaconFormData final : public Beacon {
public:
- BeaconFormData(FormData* data)
+ explicit BeaconFormData(FormData* data)
: m_data(data)
+ , m_entityBody(m_data->encodeMultiPartFormData())
{
+ m_contentType = AtomicString("multipart/form-data; boundary=") + m_entityBody->boundary().data();
}
unsigned long long size() const override
@@ -135,22 +149,23 @@ public:
bool serialize(ResourceRequest& request, int allowance, int& payloadLength) const override
{
- ASSERT(m_data);
- RefPtr<EncodedFormData> entityBody = m_data->encodeMultiPartFormData();
- unsigned long long entitySize = entityBody->sizeInBytes();
+ unsigned long long entitySize = m_entityBody->sizeInBytes();
if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
return false;
- AtomicString contentType = AtomicString("multipart/form-data; boundary=") + entityBody->boundary().data();
- request.setHTTPBody(entityBody.release());
- request.setHTTPContentType(contentType);
+ request.setHTTPBody(m_entityBody.get());
+ request.setHTTPContentType(m_contentType);
payloadLength = entitySize;
return true;
}
+ const AtomicString getContentType() const { return m_contentType; }
+
private:
- const Persistent<FormData> m_data;
+ const Member<FormData> m_data;
+ RefPtr<EncodedFormData> m_entityBody;
+ AtomicString m_contentType;
};
} // namespace
@@ -181,11 +196,16 @@ public:
if (!beacon.serialize(request, allowance, payloadLength))
return false;
+ const AtomicString contentType = beacon.getContentType();
+ CORSEnabled corsEnabled = IsCORSEnabled;
+ if (!contentType.isNull() && FetchUtils::isSimpleHeader(AtomicString("content-type"), contentType))
+ corsEnabled = NotCORSEnabled;
+
FetchInitiatorInfo initiatorInfo;
initiatorInfo.name = FetchInitiatorTypeNames::beacon;
// The loader keeps itself alive until it receives a response and disposes itself.
- BeaconLoader* loader = new BeaconLoader(frame, request, initiatorInfo, AllowStoredCredentials);
+ BeaconLoader* loader = new BeaconLoader(frame, request, initiatorInfo, AllowStoredCredentials, corsEnabled);
ASSERT_UNUSED(loader, loader);
return true;
}
@@ -215,15 +235,19 @@ bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac
return Sender::send(frame, allowance, beaconURL, beacon, payloadLength);
}
-BeaconLoader::BeaconLoader(LocalFrame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed)
+BeaconLoader::BeaconLoader(LocalFrame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed, CORSEnabled corsMode)
: PingLoader(frame, request, initiatorInfo, credentialsAllowed)
, m_beaconOrigin(frame->document()->getSecurityOrigin())
+ , m_redirectsFollowCORS(corsMode == IsCORSEnabled)
{
}
void BeaconLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewRequest, const WebURLResponse& passedRedirectResponse, int64_t encodedDataLength)
{
passedNewRequest.setAllowStoredCredentials(true);
+ if (!m_redirectsFollowCORS)
+ return;
+
ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest());
const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceResponse());
@@ -240,6 +264,8 @@ void BeaconLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewReq
}
// Cancel the load and self destruct.
dispose();
+ // Signal WebURLLoader that the redirect musn't be followed.
+ passedNewRequest = WebURLRequest();
return;
}
// FIXME: http://crbug.com/427429 is needed to correctly propagate
« no previous file with comments | « third_party/WebKit/Source/core/loader/BeaconLoader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698