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

Unified Diff: Source/core/xml/XMLHttpRequest.cpp

Issue 455303002: Add 'stream' to XMLHttpRequest response type. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@stream-promise-property-reset
Patch Set: Created 6 years, 4 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 | « Source/core/xml/XMLHttpRequest.h ('k') | Source/core/xml/XMLHttpRequest.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/xml/XMLHttpRequest.cpp
diff --git a/Source/core/xml/XMLHttpRequest.cpp b/Source/core/xml/XMLHttpRequest.cpp
index 30c501640c68d1f1d7c453ae08f7ca615b3f6e22..d263355af8508105b4306388040d991fe8ea86b1 100644
--- a/Source/core/xml/XMLHttpRequest.cpp
+++ b/Source/core/xml/XMLHttpRequest.cpp
@@ -26,6 +26,7 @@
#include "bindings/core/v8/ExceptionState.h"
#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/ContextFeatures.h"
+#include "core/dom/DOMException.h"
#include "core/dom/DOMImplementation.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/XMLDocument.h"
@@ -44,7 +45,10 @@
#include "core/inspector/InspectorInstrumentation.h"
#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/ThreadableLoader.h"
+#include "core/streams/ReadableStream.h"
+#include "core/streams/ReadableStreamImpl.h"
#include "core/streams/Stream.h"
+#include "core/streams/UnderlyingSource.h"
#include "core/xml/XMLHttpRequestProgressEvent.h"
#include "core/xml/XMLHttpRequestUpload.h"
#include "platform/Logging.h"
@@ -111,6 +115,34 @@ static void logConsoleError(ExecutionContext* context, const String& message)
context->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message));
}
+namespace {
+
+class ReadableStreamSource : public GarbageCollectedFinalized<ReadableStreamSource>, public UnderlyingSource {
+ USING_GARBAGE_COLLECTED_MIXIN(ReadableStreamSource);
+public:
+ ReadableStreamSource(XMLHttpRequest* owner) : m_owner(owner) { }
+ virtual ~ReadableStreamSource() { }
+ virtual void pullSource() OVERRIDE { }
+ virtual ScriptPromise cancelSource(ScriptState* scriptState, ScriptValue reason) OVERRIDE
+ {
+ m_owner->abort();
+ return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate()));
+ }
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_owner);
+ UnderlyingSource::trace(visitor);
+ }
+
+private:
+ // This is RawPtr in non-oilpan build to avoid the reference cycle. To
+ // avoid use-after free, the associated ReadableStream must be closed
+ // or errored when m_owner is gone.
+ RawPtrWillBeMember<XMLHttpRequest> m_owner;
+};
+
+} // namespace
+
PassRefPtrWillBeRawPtr<XMLHttpRequest> XMLHttpRequest::create(ExecutionContext* context, PassRefPtr<SecurityOrigin> securityOrigin)
{
RefPtrWillBeRawPtr<XMLHttpRequest> xmlHttpRequest = adoptRefWillBeRefCountedGarbageCollected(new XMLHttpRequest(context, securityOrigin));
@@ -295,14 +327,23 @@ ArrayBuffer* XMLHttpRequest::responseArrayBuffer()
return m_responseArrayBuffer.get();
}
-Stream* XMLHttpRequest::responseStream()
+Stream* XMLHttpRequest::responseLegacyStream()
{
ASSERT(m_responseTypeCode == ResponseTypeLegacyStream);
if (m_error || (m_state != LOADING && m_state != DONE))
return 0;
- return m_responseStream.get();
+ return m_responseLegacyStream.get();
+}
+
+ReadableStream* XMLHttpRequest::responseStream()
+{
+ ASSERT(m_responseTypeCode == ResponseTypeStream);
+ if (m_error || (m_state != LOADING && m_state != DONE))
+ return 0;
+
+ return m_responseStream;
}
void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionState& exceptionState)
@@ -356,6 +397,11 @@ void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState&
m_responseTypeCode = ResponseTypeLegacyStream;
else
return;
+ } else if (responseType == "stream") {
+ if (RuntimeEnabledFeatures::streamEnabled())
+ m_responseTypeCode = ResponseTypeStream;
+ else
+ return;
} else {
ASSERT_NOT_REACHED();
}
@@ -378,6 +424,8 @@ String XMLHttpRequest::responseType()
return "arraybuffer";
case ResponseTypeLegacyStream:
return "legacystream";
+ case ResponseTypeStream:
+ return "stream";
}
return "";
}
@@ -893,8 +941,15 @@ bool XMLHttpRequest::internalAbort()
InspectorInstrumentation::didFailXHRLoading(executionContext(), this, this);
- if (m_responseStream && m_state != DONE)
- m_responseStream->abort();
+ if (m_responseLegacyStream && m_state != DONE)
+ m_responseLegacyStream->abort();
+
+ if (m_responseStream) {
+ // When the stream is already closed (including canceled from the
+ // user), |error| does nothing.
+ // FIXME: Create a more specific error.
+ m_responseStream->error(DOMException::create(!m_async && m_exceptionCode ? m_exceptionCode : AbortError, "XMLHttpRequest::abort"));
+ }
if (!m_loader)
return true;
@@ -936,6 +991,7 @@ void XMLHttpRequest::clearResponse()
m_responseBlob = nullptr;
m_downloadedBlobLength = 0;
+ m_responseLegacyStream = nullptr;
m_responseStream = nullptr;
// These variables may referred by the response accessors. So, we can clear
@@ -1229,8 +1285,11 @@ void XMLHttpRequest::didFinishLoading(unsigned long identifier, double)
if (m_decoder)
m_responseText = m_responseText.concatenateWith(m_decoder->flush());
+ if (m_responseLegacyStream)
+ m_responseLegacyStream->finalize();
+
if (m_responseStream)
- m_responseStream->finalize();
+ m_responseStream->close();
clearVariablesForLoading();
@@ -1326,9 +1385,15 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
m_binaryResponseBuilder = SharedBuffer::create();
m_binaryResponseBuilder->append(data, len);
} else if (m_responseTypeCode == ResponseTypeLegacyStream) {
- if (!m_responseStream)
- m_responseStream = Stream::create(executionContext(), finalResponseMIMEType());
- m_responseStream->addData(data, len);
+ if (!m_responseLegacyStream)
+ m_responseLegacyStream = Stream::create(executionContext(), responseType());
+ m_responseLegacyStream->addData(data, len);
+ } else if (m_responseTypeCode == ResponseTypeStream) {
+ if (!m_responseStream) {
+ m_responseStream = new ReadableStreamImpl<ReadableStreamChunkTypeTraits<ArrayBuffer> >(executionContext(), new ReadableStreamSource(this));
+ m_responseStream->didSourceStart();
+ }
+ m_responseStream->enqueue(ArrayBuffer::create(data, len));
}
if (m_error)
@@ -1417,7 +1482,9 @@ ExecutionContext* XMLHttpRequest::executionContext() const
void XMLHttpRequest::trace(Visitor* visitor)
{
visitor->trace(m_responseBlob);
+ visitor->trace(m_responseLegacyStream);
visitor->trace(m_responseStream);
+ visitor->trace(m_streamSource);
visitor->trace(m_responseDocument);
visitor->trace(m_progressEventThrottle);
visitor->trace(m_upload);
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | Source/core/xml/XMLHttpRequest.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698