[WTF] Import std::optional reference implementation as WTF::Optional
[WebKit-https.git] / Source / WebCore / xml / XMLHttpRequest.h
index ae50b48..04abc09 100644 (file)
@@ -2,6 +2,7 @@
  *  Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
  *  Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@nypop.com>
  *  Copyright (C) 2011 Google Inc. All rights reserved.
  *  Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
  *  Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@nypop.com>
  *  Copyright (C) 2011 Google Inc. All rights reserved.
+ *  Copyright (C) 2012 Intel Corporation
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef XMLHttpRequest_h
-#define XMLHttpRequest_h
+#pragma once
 
 #include "ActiveDOMObject.h"
 
 #include "ActiveDOMObject.h"
-#include "EventListener.h"
-#include "EventNames.h"
-#include "EventTarget.h"
+#include "ExceptionOr.h"
 #include "FormData.h"
 #include "ResourceResponse.h"
 #include "ThreadableLoaderClient.h"
 #include "FormData.h"
 #include "ResourceResponse.h"
 #include "ThreadableLoaderClient.h"
+#include "XMLHttpRequestEventTarget.h"
 #include "XMLHttpRequestProgressEventThrottle.h"
 #include "XMLHttpRequestProgressEventThrottle.h"
-#include <wtf/OwnPtr.h>
-#include <wtf/text/AtomicStringHash.h>
 #include <wtf/text/StringBuilder.h>
 
 #include <wtf/text/StringBuilder.h>
 
+namespace JSC {
+class ArrayBuffer;
+class ArrayBufferView;
+}
+
 namespace WebCore {
 
 namespace WebCore {
 
-class ArrayBuffer;
 class Blob;
 class Document;
 class DOMFormData;
 class Blob;
 class Document;
 class DOMFormData;
-class ResourceRequest;
 class SecurityOrigin;
 class SharedBuffer;
 class TextResourceDecoder;
 class ThreadableLoader;
 class SecurityOrigin;
 class SharedBuffer;
 class TextResourceDecoder;
 class ThreadableLoader;
+class XMLHttpRequestUpload;
 
 
-class XMLHttpRequest : public RefCounted<XMLHttpRequest>, public EventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
+class XMLHttpRequest final : public RefCounted<XMLHttpRequest>, public XMLHttpRequestEventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassRefPtr<XMLHttpRequest> create(ScriptExecutionContext*, PassRefPtr<SecurityOrigin> = 0);
-    ~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,
     enum State {
         UNSENT = 0,
         OPENED = 1,
@@ -59,94 +59,84 @@ public:
         LOADING = 3,
         DONE = 4
     };
         LOADING = 3,
         DONE = 4
     };
-    
-    enum ResponseTypeCode {
-        ResponseTypeDefault,
-        ResponseTypeText, 
-        ResponseTypeDocument,
-        ResponseTypeBlob,
-        ResponseTypeArrayBuffer
-    };
 
 
-    virtual XMLHttpRequest* toXMLHttpRequest() { return this; }
+    virtual void didReachTimeout();
 
 
-    virtual void contextDestroyed();
-    virtual bool canSuspend() const;
-    virtual void suspend(ReasonForSuspension);
-    virtual void resume();
-    virtual void stop();
+    EventTargetInterface eventTargetInterface() const override { return XMLHttpRequestEventTargetInterfaceType; }
+    ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); }
 
 
-    virtual ScriptExecutionContext* scriptExecutionContext() const;
-
-    const KURL& url() const { return m_url; }
-    String statusText(ExceptionCode&) const;
-    int status(ExceptionCode&) const;
+    const URL& url() const { return m_url; }
+    String statusText() const;
+    int status() const;
     State readyState() const;
     bool withCredentials() const { return m_includeCredentials; }
     State readyState() const;
     bool withCredentials() const { return m_includeCredentials; }
-    void setWithCredentials(bool, ExceptionCode&);
-#if ENABLE(XHR_RESPONSE_BLOB)
-    bool asBlob() const { return responseTypeCode() == ResponseTypeBlob; }
-    void setAsBlob(bool, ExceptionCode&);
-#endif
-    void open(const String& method, const KURL&, ExceptionCode&);
-    void open(const String& method, const KURL&, bool async, ExceptionCode&);
-    void open(const String& method, const KURL&, bool async, const String& user, ExceptionCode&);
-    void open(const String& method, const KURL&, 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(ArrayBuffer*, 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(Document&);
+    ExceptionOr<void> send(const String& = { });
+    ExceptionOr<void> send(Blob&);
+    ExceptionOr<void> send(DOMFormData&);
+    ExceptionOr<void> send(JSC::ArrayBuffer&);
+    ExceptionOr<void> send(JSC::ArrayBufferView&);
     void abort();
     void abort();
-    void setRequestHeader(const AtomicString& name, const String& value, ExceptionCode&);
-    void overrideMimeType(const String& override);
-    String getAllResponseHeaders(ExceptionCode&) const;
-    String getResponseHeader(const AtomicString& name, ExceptionCode&) const;
-    String responseText(ExceptionCode&);
-    Document* responseXML(ExceptionCode&);
-    Document* optionalResponseXML() const { return m_responseXML.get(); }
-#if ENABLE(XHR_RESPONSE_BLOB)
-    Blob* responseBlob(ExceptionCode&) const;
-    Blob* optionalResponseBlob() const { return m_responseBlob.get(); }
-#endif
+    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 String& name) const;
+    ExceptionOr<String> responseText();
+    String responseTextIgnoringResponseType() const { return m_responseBuilder.toStringPreserveCapacity(); }
+    String responseMIMEType() const;
+
+    Document* optionalResponseXML() const { return m_responseDocument.get(); }
+    ExceptionOr<Document*> responseXML();
+
+    Ref<Blob> createResponseBlob();
+    RefPtr<JSC::ArrayBuffer> createResponseArrayBuffer();
+
+    unsigned timeout() const { return m_timeoutMilliseconds; }
+    ExceptionOr<void> setTimeout(unsigned);
+
+    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&);
 
 
     // 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; }
-    
-    // response attribute has custom getter.
-    ArrayBuffer* responseArrayBuffer(ExceptionCode&);
-    ArrayBuffer* optionalResponseArrayBuffer() const { return m_responseArrayBuffer.get(); }
+    enum class ResponseType { EmptyString, Arraybuffer, Blob, Document, Json, Text };
+    ExceptionOr<void> setResponseType(ResponseType);
+    ResponseType responseType() const;
+
+    String responseURL() const;
 
 
-    void setLastSendLineNumber(unsigned lineNumber) { m_lastSendLineNumber = lineNumber; }
+    void setLastSendLineAndColumnNumber(unsigned lineNumber, unsigned columnNumber);
     void setLastSendURL(const String& url) { m_lastSendURL = url; }
 
     XMLHttpRequestUpload* upload();
     XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); }
 
     void setLastSendURL(const String& url) { m_lastSendURL = url; }
 
     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(loadstart);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
+    const ResourceResponse& resourceResponse() const { return m_response; }
 
     using RefCounted<XMLHttpRequest>::ref;
     using RefCounted<XMLHttpRequest>::deref;
 
 private:
 
     using RefCounted<XMLHttpRequest>::ref;
     using RefCounted<XMLHttpRequest>::deref;
 
 private:
-    XMLHttpRequest(ScriptExecutionContext*, PassRefPtr<SecurityOrigin>);
+    explicit XMLHttpRequest(ScriptExecutionContext&);
+
+    // ActiveDOMObject
+    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() { ref(); }
-    virtual void derefEventTarget() { deref(); }
-    virtual EventTargetData* eventTargetData();
-    virtual EventTargetData* ensureEventTargetData();
+    void refEventTarget() override { ref(); }
+    void derefEventTarget() override { deref(); }
 
     Document* document() const;
     SecurityOrigin* securityOrigin() const;
 
     Document* document() const;
     SecurityOrigin* securityOrigin() const;
@@ -155,50 +145,52 @@ private:
     bool usesDashboardBackwardCompatibilityMode() const;
 #endif
 
     bool usesDashboardBackwardCompatibilityMode() const;
 #endif
 
-    virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
-    virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&);
-    virtual void didReceiveData(const char* data, int dataLength);
-    virtual void didFinishLoading(unsigned long identifier, double finishTime);
-    virtual void didFail(const ResourceError&);
-    virtual void didFailRedirectCheck();
+    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 responseIsXML() const;
 
-    bool initSend(ExceptionCode&);
-
-    String getRequestHeader(const AtomicString& name) const;
-    void setRequestHeaderInternal(const AtomicString& name, const String& value);
+    std::optional<ExceptionOr<void>> prepareToSend();
+    ExceptionOr<void> sendBytesData(const void*, size_t);
 
 
-    void changeState(State newState);
+    void changeState(State);
     void callReadyStateChangeListener();
     void dropProtection();
     void callReadyStateChangeListener();
     void dropProtection();
-    void internalAbort();
+
+    // Returns false when cancelling the loader within internalAbort() triggers an event whose callback creates a new loader. 
+    // In that case, the function calling internalAbort should exit.
+    bool internalAbort();
+
     void clearResponse();
     void clearResponseBuffers();
     void clearRequest();
 
     void clearResponse();
     void clearResponseBuffers();
     void clearRequest();
 
-    void createRequest(ExceptionCode&);
+    ExceptionOr<void> createRequest();
 
     void genericError();
     void networkError();
     void abortError();
 
 
     void genericError();
     void networkError();
     void abortError();
 
-    OwnPtr<XMLHttpRequestUpload> m_upload;
+    void dispatchErrorEvents(const AtomicString&);
 
 
-    KURL m_url;
+    void resumeTimerFired();
+
+    std::unique_ptr<XMLHttpRequestUpload> m_upload;
+
+    URL m_url;
     String m_method;
     HTTPHeaderMap m_requestHeaders;
     RefPtr<FormData> m_requestEntityBody;
     String m_mimeTypeOverride;
     String m_method;
     HTTPHeaderMap m_requestHeaders;
     RefPtr<FormData> m_requestEntityBody;
     String m_mimeTypeOverride;
-    bool m_async;
-    bool m_includeCredentials;
-#if ENABLE(XHR_RESPONSE_BLOB)
-    RefPtr<Blob> m_responseBlob;
-#endif
+    bool m_async { true };
+    bool m_includeCredentials { false };
 
     RefPtr<ThreadableLoader> m_loader;
 
     RefPtr<ThreadableLoader> m_loader;
-    State m_state;
+    State m_state { UNSENT };
+    bool m_sendFlag { false };
 
     ResourceResponse m_response;
     String m_responseEncoding;
 
     ResourceResponse m_response;
     String m_responseEncoding;
@@ -206,36 +198,45 @@ private:
     RefPtr<TextResourceDecoder> m_decoder;
 
     StringBuilder m_responseBuilder;
     RefPtr<TextResourceDecoder> m_decoder;
 
     StringBuilder m_responseBuilder;
-    mutable bool m_createdDocument;
-    mutable RefPtr<Document> m_responseXML;
-    
+    bool m_createdDocument { false };
+    RefPtr<Document> m_responseDocument;
+
     RefPtr<SharedBuffer> m_binaryResponseBuilder;
     RefPtr<SharedBuffer> m_binaryResponseBuilder;
-    mutable RefPtr<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_lastSendLineNumber { 0 };
+    unsigned m_lastSendColumnNumber { 0 };
     String m_lastSendURL;
     String m_lastSendURL;
-    ExceptionCode m_exceptionCode;
-
-    EventTargetData m_eventTargetData;
+    ExceptionCode m_exceptionCode { 0 };
 
     XMLHttpRequestProgressEventThrottle m_progressEventThrottle;
 
 
     XMLHttpRequestProgressEventThrottle m_progressEventThrottle;
 
-    // An enum corresponding to the allowed string values for the responseType attribute.
-    ResponseTypeCode m_responseTypeCode;
+    ResponseType m_responseType { ResponseType::EmptyString };
+    bool m_responseCacheIsValid { false };
+
+    Timer m_resumeTimer;
+    bool m_dispatchErrorOnResuming { false };
 
 
-    RefPtr<SecurityOrigin> m_securityOrigin;
+    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