Chromium Code Reviews| 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..01d30b2685b040189b1ae0e531dda818d20ab923 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 bool serialize(ResourceRequest&, int, int&) = 0; | 
| virtual unsigned long long size() const = 0; | 
| + virtual const AtomicString getContentType() const = 0; | 
| 
 
tyoshino (SeeGerritForStatus)
2016/07/28 07:21:57
BeaconString returns the type including the charse
 
sof
2016/07/28 08:28:19
getContentType() implements what https://fetch.spe
 
 | 
| }; | 
| class BeaconString final : public Beacon { | 
| public: | 
| - BeaconString(const String& data) | 
| + explicit BeaconString(const String& data) | 
| : m_data(data) | 
| { | 
| } | 
| @@ -45,21 +48,23 @@ public: | 
| return m_data.sizeInBytes(); | 
| } | 
| - bool serialize(ResourceRequest& request, int, int&) const override | 
| + bool serialize(ResourceRequest& request, int, int&) override | 
| { | 
| 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) | 
| { | 
| } | 
| @@ -69,7 +74,7 @@ public: | 
| return m_data->size(); | 
| } | 
| - bool serialize(ResourceRequest& request, int, int&) const override | 
| + bool serialize(ResourceRequest& request, int, int&) override | 
| { | 
| ASSERT(m_data); | 
| RefPtr<EncodedFormData> entityBody = EncodedFormData::create(); | 
| @@ -81,19 +86,24 @@ public: | 
| request.setHTTPBody(entityBody.release()); | 
| const String& blobType = m_data->type(); | 
| - if (!blobType.isEmpty() && isValidContentType(blobType)) | 
| - request.setHTTPContentType(AtomicString(blobType)); | 
| + if (!blobType.isEmpty() && isValidContentType(blobType)) { | 
| + m_contentType = AtomicString(blobType); | 
| + request.setHTTPContentType(m_contentType); | 
| + } | 
| 
 
tyoshino (SeeGerritForStatus)
2016/07/28 07:21:57
do the extraction in the constructor and use it sa
 
sof
2016/07/28 08:28:20
Good idea, much better; done.
 
 | 
| 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) | 
| { | 
| } | 
| @@ -103,7 +113,7 @@ public: | 
| return m_data->byteLength(); | 
| } | 
| - bool serialize(ResourceRequest& request, int, int&) const override | 
| + bool serialize(ResourceRequest& request, int, int&) override | 
| { | 
| ASSERT(m_data); | 
| RefPtr<EncodedFormData> entityBody = EncodedFormData::create(m_data->baseAddress(), m_data->byteLength()); | 
| @@ -116,13 +126,15 @@ public: | 
| return true; | 
| } | 
| + const AtomicString getContentType() const { return nullAtom; } | 
| 
 
tyoshino (SeeGerritForStatus)
2016/07/28 07:21:57
be consistent with L123-124?
 
sof
2016/07/28 08:28:19
No, that would make ArrayBuffer-backed follow CORS
 
tyoshino (SeeGerritForStatus)
2016/07/28 12:03:20
OK
 
 | 
| + | 
| 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) | 
| { | 
| } | 
| @@ -133,7 +145,7 @@ public: | 
| return 0; | 
| } | 
| - bool serialize(ResourceRequest& request, int allowance, int& payloadLength) const override | 
| + bool serialize(ResourceRequest& request, int allowance, int& payloadLength) override | 
| { | 
| ASSERT(m_data); | 
| RefPtr<EncodedFormData> entityBody = m_data->encodeMultiPartFormData(); | 
| @@ -149,15 +161,17 @@ public: | 
| return true; | 
| } | 
| + const AtomicString getContentType() const { return AtomicString("multipart/form-data"); } | 
| + | 
| private: | 
| - const Persistent<FormData> m_data; | 
| + const Member<FormData> m_data; | 
| }; | 
| } // namespace | 
| class BeaconLoader::Sender { | 
| public: | 
| - static bool send(LocalFrame* frame, int allowance, const KURL& beaconURL, const Beacon& beacon, int& payloadLength) | 
| + static bool send(LocalFrame* frame, int allowance, const KURL& beaconURL, Beacon& beacon, int& payloadLength) | 
| { | 
| if (!frame->document()) | 
| return false; | 
| @@ -181,11 +195,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 +234,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 +263,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(); | 
| 
 
tyoshino (SeeGerritForStatus)
2016/07/28 07:21:57
This is ok but I wonder if you had to add this to
 
sof
2016/07/28 08:28:20
It won't work without it (a longer-standing bug.)
 
 | 
| return; | 
| } | 
| // FIXME: http://crbug.com/427429 is needed to correctly propagate |