| Index: Source/core/loader/DocumentThreadableLoader.cpp
|
| diff --git a/Source/core/loader/DocumentThreadableLoader.cpp b/Source/core/loader/DocumentThreadableLoader.cpp
|
| index 2e13905e227776b707c16480c5983a66d2098570..c497a11efbbd8a6f6c5da97955cb00b4ac7fe57c 100644
|
| --- a/Source/core/loader/DocumentThreadableLoader.cpp
|
| +++ b/Source/core/loader/DocumentThreadableLoader.cpp
|
| @@ -49,14 +49,58 @@
|
| #include "core/loader/FrameLoaderClient.h"
|
| #include "core/loader/ThreadableLoaderClient.h"
|
| #include "platform/SharedBuffer.h"
|
| +#include "platform/Task.h"
|
| #include "platform/network/ResourceRequest.h"
|
| #include "platform/weborigin/SchemeRegistry.h"
|
| #include "platform/weborigin/SecurityOrigin.h"
|
| +#include "public/platform/Platform.h"
|
| #include "public/platform/WebURLRequest.h"
|
| #include "wtf/Assertions.h"
|
|
|
| namespace blink {
|
|
|
| +namespace {
|
| +
|
| +class EmptyDataHandle final : public WebDataConsumerHandle {
|
| +private:
|
| + class EmptyDataReader final : public WebDataConsumerHandle::Reader {
|
| + public:
|
| + explicit EmptyDataReader(WebDataConsumerHandle::Client* client) : m_factory(this)
|
| + {
|
| + Platform::current()->currentThread()->postTask(FROM_HERE, new Task(bind(&EmptyDataReader::notify, m_factory.createWeakPtr(), client)));
|
| + }
|
| + private:
|
| + Result read(void*, size_t, WebDataConsumerHandle::Flags, size_t *readSize) override
|
| + {
|
| + *readSize = 0;
|
| + return Done;
|
| + }
|
| + Result beginRead(const void** buffer, WebDataConsumerHandle::Flags, size_t *available) override
|
| + {
|
| + *available = 0;
|
| + *buffer = nullptr;
|
| + return Done;
|
| + }
|
| + Result endRead(size_t) override
|
| + {
|
| + return WebDataConsumerHandle::UnexpectedError;
|
| + }
|
| + void notify(WebDataConsumerHandle::Client* client)
|
| + {
|
| + client->didGetReadable();
|
| + }
|
| + WeakPtrFactory<EmptyDataReader> m_factory;
|
| + };
|
| +
|
| + Reader* obtainReaderInternal(Client* client) override
|
| + {
|
| + return new EmptyDataReader(client);
|
| + }
|
| + const char* debugName() const override { return "EmptyDataHandle"; }
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| // Max number of CORS redirects handled in DocumentThreadableLoader.
|
| // Same number as net/url_request/url_request.cc, and
|
| // same number as https://fetch.spec.whatwg.org/#concept-http-fetch, Step 4.
|
| @@ -94,6 +138,7 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl
|
| , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout)
|
| , m_requestStartedSeconds(0.0)
|
| , m_corsRedirectLimit(kMaxCORSRedirects)
|
| + , m_redirectMode(request.fetchRedirectMode())
|
| {
|
| ASSERT(client);
|
| // Setting an outgoing referer is only supported in the async code path.
|
| @@ -269,7 +314,25 @@ void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ
|
|
|
| RefPtr<DocumentThreadableLoader> protect(this);
|
|
|
| - if (!isAllowedByContentSecurityPolicy(request.url(), ContentSecurityPolicy::DidRedirect)) {
|
| + if (m_redirectMode == WebURLRequest::FetchRedirectModeManual) {
|
| + // We use |m_redirectMode| to check the original redirect mode.
|
| + // |request| is a new request for redirect. So we don't set the redirect
|
| + // mode of it in WebURLLoaderImpl::Context::OnReceivedRedirect().
|
| + ASSERT(request.useStreamOnResponse());
|
| + // There is no need to read the body of redirect response because there
|
| + // is no way to read the body of opaque-redirect filtered response's
|
| + // internal response.
|
| + // TODO(horo): If we support any API which expose the internal body, we
|
| + // will have to read the body. And also HTTPCache changes will be needed
|
| + // because it doesn't store the body of redirect responses.
|
| + responseReceived(resource, redirectResponse, adoptPtr(new EmptyDataHandle()));
|
| + notifyFinished(resource);
|
| + clearResource();
|
| + request = ResourceRequest();
|
| + return;
|
| + }
|
| +
|
| + if (m_redirectMode == WebURLRequest::FetchRedirectModeError || !isAllowedByContentSecurityPolicy(request.url(), ContentSecurityPolicy::DidRedirect)) {
|
| m_client->didFailRedirectCheck();
|
|
|
| clearResource();
|
|
|