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 |