diff options
Diffstat (limited to 'Source/WebCore/xml/XMLHttpRequest.h')
-rw-r--r-- | Source/WebCore/xml/XMLHttpRequest.h | 219 |
1 files changed, 99 insertions, 120 deletions
diff --git a/Source/WebCore/xml/XMLHttpRequest.h b/Source/WebCore/xml/XMLHttpRequest.h index 51cd5aa1d..0c61fdbee 100644 --- a/Source/WebCore/xml/XMLHttpRequest.h +++ b/Source/WebCore/xml/XMLHttpRequest.h @@ -19,24 +19,23 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef XMLHttpRequest_h -#define XMLHttpRequest_h +#pragma once #include "ActiveDOMObject.h" -#include "EventListener.h" -#include "EventNames.h" -#include "EventTarget.h" +#include "ExceptionOr.h" #include "FormData.h" #include "ResourceResponse.h" -#include "ScriptWrappable.h" #include "ThreadableLoaderClient.h" +#include "URL.h" +#include "XMLHttpRequestEventTarget.h" #include "XMLHttpRequestProgressEventThrottle.h" -#include <wtf/text/AtomicStringHash.h> +#include <wtf/Variant.h> #include <wtf/text/StringBuilder.h> namespace JSC { class ArrayBuffer; class ArrayBufferView; +class ExecState; } namespace WebCore { @@ -44,19 +43,18 @@ namespace WebCore { class Blob; class Document; class DOMFormData; -class ResourceRequest; class SecurityOrigin; class SharedBuffer; class TextResourceDecoder; class ThreadableLoader; +class XMLHttpRequestUpload; -class XMLHttpRequest final : public ScriptWrappable, public RefCounted<XMLHttpRequest>, public EventTargetWithInlineData, private ThreadableLoaderClient, public ActiveDOMObject { +class XMLHttpRequest final : public RefCounted<XMLHttpRequest>, public XMLHttpRequestEventTarget, private ThreadableLoaderClient, public ActiveDOMObject { WTF_MAKE_FAST_ALLOCATED; public: - static PassRefPtr<XMLHttpRequest> create(ScriptExecutionContext&); - ~XMLHttpRequest(); + static Ref<XMLHttpRequest> create(ScriptExecutionContext&); + WEBCORE_EXPORT ~XMLHttpRequest(); - // These exact numeric values are important because JS expects them. enum State { UNSENT = 0, OPENED = 1, @@ -64,77 +62,56 @@ public: LOADING = 3, DONE = 4 }; - - enum ResponseTypeCode { - ResponseTypeDefault, - ResponseTypeText, - ResponseTypeJSON, - ResponseTypeDocument, - - // Binary format - ResponseTypeBlob, - ResponseTypeArrayBuffer - }; - static const ResponseTypeCode FirstBinaryResponseType = ResponseTypeBlob; -#if ENABLE(XHR_TIMEOUT) - virtual void didTimeout(); -#endif + virtual void didReachTimeout(); + + EventTargetInterface eventTargetInterface() const override { return XMLHttpRequestEventTargetInterfaceType; } + ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); } - virtual EventTargetInterface eventTargetInterface() const override { return XMLHttpRequestEventTargetInterfaceType; } - virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); } + using SendTypes = Variant<RefPtr<Document>, RefPtr<Blob>, RefPtr<JSC::ArrayBufferView>, RefPtr<JSC::ArrayBuffer>, RefPtr<DOMFormData>, String>; const URL& url() const { return m_url; } - String statusText(ExceptionCode&) const; - int status(ExceptionCode&) const; + String statusText() const; + int status() const; State readyState() const; bool withCredentials() const { return m_includeCredentials; } - void setWithCredentials(bool, ExceptionCode&); - void open(const String& method, const URL&, ExceptionCode&); - void open(const String& method, const URL&, bool async, ExceptionCode&); - void open(const String& method, const URL&, bool async, const String& user, ExceptionCode&); - void open(const String& method, const URL&, bool async, const String& user, const String& password, ExceptionCode&); - void send(ExceptionCode&); - void send(Document*, ExceptionCode&); - void send(const String&, ExceptionCode&); - void send(Blob*, ExceptionCode&); - void send(DOMFormData*, ExceptionCode&); - void send(JSC::ArrayBuffer*, ExceptionCode&); - void send(JSC::ArrayBufferView*, ExceptionCode&); + ExceptionOr<void> setWithCredentials(bool); + ExceptionOr<void> open(const String& method, const String& url); + ExceptionOr<void> open(const String& method, const URL&, bool async); + ExceptionOr<void> open(const String& method, const String&, bool async, const String& user, const String& password); + ExceptionOr<void> send(JSC::ExecState&, std::optional<SendTypes>&&); void abort(); - void setRequestHeader(const AtomicString& name, const String& value, ExceptionCode&); - void overrideMimeType(const String& override); + ExceptionOr<void> setRequestHeader(const String& name, const String& value); + ExceptionOr<void> overrideMimeType(const String& override); bool doneWithoutErrors() const { return !m_error && m_state == DONE; } String getAllResponseHeaders() const; - String getResponseHeader(const AtomicString& name) const; - String responseText(ExceptionCode&); + String getResponseHeader(const String& name) const; + ExceptionOr<String> responseText(); String responseTextIgnoringResponseType() const { return m_responseBuilder.toStringPreserveCapacity(); } - Document* responseXML(ExceptionCode&); + String responseMIMEType() const; + Document* optionalResponseXML() const { return m_responseDocument.get(); } - Blob* responseBlob(); - Blob* optionalResponseBlob() const { return m_responseBlob.get(); } -#if ENABLE(XHR_TIMEOUT) - unsigned long timeout() const { return m_timeoutMilliseconds; } - void setTimeout(unsigned long timeout, ExceptionCode&); -#endif + ExceptionOr<Document*> responseXML(); - bool responseCacheIsValid() const { return m_responseCacheIsValid; } - void didCacheResponseJSON(); + Ref<Blob> createResponseBlob(); + RefPtr<JSC::ArrayBuffer> createResponseArrayBuffer(); + + unsigned timeout() const { return m_timeoutMilliseconds; } + ExceptionOr<void> setTimeout(unsigned); - void sendFromInspector(PassRefPtr<FormData>, ExceptionCode&); + bool responseCacheIsValid() const { return m_responseCacheIsValid; } + void didCacheResponse(); // Expose HTTP validation methods for other untrusted requests. static bool isAllowedHTTPMethod(const String&); static String uppercaseKnownHTTPMethod(const String&); static bool isAllowedHTTPHeader(const String&); - void setResponseType(const String&, ExceptionCode&); - String responseType(); - ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; } + enum class ResponseType { EmptyString, Arraybuffer, Blob, Document, Json, Text }; + ExceptionOr<void> setResponseType(ResponseType); + ResponseType responseType() const; - // response attribute has custom getter. - JSC::ArrayBuffer* responseArrayBuffer(); - JSC::ArrayBuffer* optionalResponseArrayBuffer() const { return m_responseArrayBuffer.get(); } + String responseURL() const; void setLastSendLineAndColumnNumber(unsigned lineNumber, unsigned columnNumber); void setLastSendURL(const String& url) { m_lastSendURL = url; } @@ -142,16 +119,7 @@ public: XMLHttpRequestUpload* upload(); XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); } - DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange); - DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); - DEFINE_ATTRIBUTE_EVENT_LISTENER(error); - DEFINE_ATTRIBUTE_EVENT_LISTENER(load); - DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend); - DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart); - DEFINE_ATTRIBUTE_EVENT_LISTENER(progress); -#if ENABLE(XHR_TIMEOUT) - DEFINE_ATTRIBUTE_EVENT_LISTENER(timeout); -#endif + const ResourceResponse& resourceResponse() const { return m_response; } using RefCounted<XMLHttpRequest>::ref; using RefCounted<XMLHttpRequest>::deref; @@ -160,14 +128,15 @@ private: explicit XMLHttpRequest(ScriptExecutionContext&); // ActiveDOMObject - virtual void contextDestroyed() override; - virtual bool canSuspend() const override; - virtual void suspend(ReasonForSuspension) override; - virtual void resume() override; - virtual void stop() override; + void contextDestroyed() override; + bool canSuspendForDocumentSuspension() const override; + void suspend(ReasonForSuspension) override; + void resume() override; + void stop() override; + const char* activeDOMObjectName() const override; - virtual void refEventTarget() override { ref(); } - virtual void derefEventTarget() override { deref(); } + void refEventTarget() override { ref(); } + void derefEventTarget() override { deref(); } Document* document() const; SecurityOrigin* securityOrigin() const; @@ -176,23 +145,25 @@ private: bool usesDashboardBackwardCompatibilityMode() const; #endif - virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override; - virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override; - virtual void didReceiveData(const char* data, int dataLength) override; - virtual void didFinishLoading(unsigned long identifier, double finishTime) override; - virtual void didFail(const ResourceError&) override; - virtual void didFailRedirectCheck() override; + // ThreadableLoaderClient + void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override; + void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override; + void didReceiveData(const char* data, int dataLength) override; + void didFinishLoading(unsigned long identifier, double finishTime) override; + void didFail(const ResourceError&) override; - String responseMIMEType() const; bool responseIsXML() const; - bool initSend(ExceptionCode&); - void sendBytesData(const void*, size_t, ExceptionCode&); + std::optional<ExceptionOr<void>> prepareToSend(); + ExceptionOr<void> send(Document&); + ExceptionOr<void> send(const String& = { }); + ExceptionOr<void> send(Blob&); + ExceptionOr<void> send(DOMFormData&); + ExceptionOr<void> send(JSC::ArrayBuffer&); + ExceptionOr<void> send(JSC::ArrayBufferView&); + ExceptionOr<void> sendBytesData(const void*, size_t); - String getRequestHeader(const AtomicString& name) const; - void setRequestHeaderInternal(const AtomicString& name, const String& value); - - void changeState(State newState); + void changeState(State); void callReadyStateChangeListener(); void dropProtection(); @@ -204,16 +175,16 @@ private: void clearResponseBuffers(); void clearRequest(); - void createRequest(ExceptionCode&); + ExceptionOr<void> createRequest(); void genericError(); void networkError(); void abortError(); - bool shouldDecodeResponse() const { return m_responseTypeCode < FirstBinaryResponseType; } - void dispatchErrorEvents(const AtomicString&); + void resumeTimerFired(); + std::unique_ptr<XMLHttpRequestUpload> m_upload; URL m_url; @@ -221,15 +192,12 @@ private: HTTPHeaderMap m_requestHeaders; RefPtr<FormData> m_requestEntityBody; String m_mimeTypeOverride; - bool m_async; - bool m_includeCredentials; -#if ENABLE(XHR_TIMEOUT) - unsigned long m_timeoutMilliseconds; -#endif - RefPtr<Blob> m_responseBlob; + bool m_async { true }; + bool m_includeCredentials { false }; RefPtr<ThreadableLoader> m_loader; - State m_state; + State m_state { UNSENT }; + bool m_sendFlag { false }; ResourceResponse m_response; String m_responseEncoding; @@ -237,34 +205,45 @@ private: RefPtr<TextResourceDecoder> m_decoder; StringBuilder m_responseBuilder; - bool m_createdDocument; + bool m_createdDocument { false }; RefPtr<Document> m_responseDocument; - + RefPtr<SharedBuffer> m_binaryResponseBuilder; - RefPtr<JSC::ArrayBuffer> m_responseArrayBuffer; - bool m_error; + bool m_error { false }; - bool m_uploadEventsAllowed; - bool m_uploadComplete; + bool m_uploadEventsAllowed { true }; + bool m_uploadComplete { false }; - bool m_sameOriginRequest; + bool m_sameOriginRequest { true }; - // Used for onprogress tracking - long long m_receivedLength; + // Used for progress event tracking. + long long m_receivedLength { 0 }; - unsigned m_lastSendLineNumber; - unsigned m_lastSendColumnNumber; + unsigned m_lastSendLineNumber { 0 }; + unsigned m_lastSendColumnNumber { 0 }; String m_lastSendURL; - ExceptionCode m_exceptionCode; + ExceptionCode m_exceptionCode { 0 }; XMLHttpRequestProgressEventThrottle m_progressEventThrottle; - // An enum corresponding to the allowed string values for the responseType attribute. - ResponseTypeCode m_responseTypeCode; - bool m_responseCacheIsValid; + ResponseType m_responseType { ResponseType::EmptyString }; + bool m_responseCacheIsValid { false }; + + Timer m_resumeTimer; + bool m_dispatchErrorOnResuming { false }; + + Timer m_networkErrorTimer; + void networkErrorTimerFired(); + + unsigned m_timeoutMilliseconds { 0 }; + std::chrono::steady_clock::time_point m_sendingTime; + Timer m_timeoutTimer; }; -} // namespace WebCore +inline auto XMLHttpRequest::responseType() const -> ResponseType +{ + return m_responseType; +} -#endif // XMLHttpRequest_h +} // namespace WebCore |