1/*
2 *  Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
3 *  Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@nypop.com>
4 *  Copyright (C) 2011 Google Inc. All rights reserved.
5 *  Copyright (C) 2012 Intel Corporation
6 *
7 *  This library is free software; you can redistribute it and/or
8 *  modify it under the terms of the GNU Lesser General Public
9 *  License as published by the Free Software Foundation; either
10 *  version 2 of the License, or (at your option) any later version.
11 *
12 *  This library is distributed in the hope that it will be useful,
13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 *  Lesser General Public License for more details.
16 *
17 *  You should have received a copy of the GNU Lesser General Public
18 *  License along with this library; if not, write to the Free Software
19 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22#ifndef XMLHttpRequest_h
23#define XMLHttpRequest_h
24
25#include "ActiveDOMObject.h"
26#include "EventListener.h"
27#include "EventNames.h"
28#include "EventTarget.h"
29#include "FormData.h"
30#include "ResourceResponse.h"
31#include "ScriptWrappable.h"
32#include "ThreadableLoaderClient.h"
33#include "XMLHttpRequestProgressEventThrottle.h"
34#include <wtf/text/AtomicStringHash.h>
35#include <wtf/text/StringBuilder.h>
36
37namespace JSC {
38class ArrayBuffer;
39class ArrayBufferView;
40}
41
42namespace WebCore {
43
44class Blob;
45class Document;
46class DOMFormData;
47class ResourceRequest;
48class SecurityOrigin;
49class SharedBuffer;
50class TextResourceDecoder;
51class ThreadableLoader;
52
53class XMLHttpRequest final : public ScriptWrappable, public RefCounted<XMLHttpRequest>, public EventTargetWithInlineData, private ThreadableLoaderClient, public ActiveDOMObject {
54    WTF_MAKE_FAST_ALLOCATED;
55public:
56    static PassRefPtr<XMLHttpRequest> create(ScriptExecutionContext&);
57    ~XMLHttpRequest();
58
59    // These exact numeric values are important because JS expects them.
60    enum State {
61        UNSENT = 0,
62        OPENED = 1,
63        HEADERS_RECEIVED = 2,
64        LOADING = 3,
65        DONE = 4
66    };
67
68    enum ResponseTypeCode {
69        ResponseTypeDefault,
70        ResponseTypeText,
71        ResponseTypeJSON,
72        ResponseTypeDocument,
73
74        // Binary format
75        ResponseTypeBlob,
76        ResponseTypeArrayBuffer
77    };
78    static const ResponseTypeCode FirstBinaryResponseType = ResponseTypeBlob;
79
80#if ENABLE(XHR_TIMEOUT)
81    virtual void didTimeout();
82#endif
83
84    virtual EventTargetInterface eventTargetInterface() const override { return XMLHttpRequestEventTargetInterfaceType; }
85    virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); }
86
87    const URL& url() const { return m_url; }
88    String statusText() const;
89    int status() const;
90    State readyState() const;
91    bool withCredentials() const { return m_includeCredentials; }
92    void setWithCredentials(bool, ExceptionCode&);
93    void open(const String& method, const URL&, ExceptionCode&);
94    void open(const String& method, const URL&, bool async, ExceptionCode&);
95    void open(const String& method, const URL&, bool async, const String& user, ExceptionCode&);
96    void open(const String& method, const URL&, bool async, const String& user, const String& password, ExceptionCode&);
97    void send(ExceptionCode&);
98    void send(Document*, ExceptionCode&);
99    void send(const String&, ExceptionCode&);
100    void send(Blob*, ExceptionCode&);
101    void send(DOMFormData*, ExceptionCode&);
102    void send(JSC::ArrayBuffer*, ExceptionCode&);
103    void send(JSC::ArrayBufferView*, ExceptionCode&);
104    void abort();
105    void setRequestHeader(const String& name, const String& value, ExceptionCode&);
106    void overrideMimeType(const String& override);
107    bool doneWithoutErrors() const { return !m_error && m_state == DONE; }
108    String getAllResponseHeaders() const;
109    String getResponseHeader(const String& name) const;
110    String responseText(ExceptionCode&);
111    String responseTextIgnoringResponseType() const { return m_responseBuilder.toStringPreserveCapacity(); }
112    String responseMIMEType() const;
113    Document* responseXML(ExceptionCode&);
114    Document* optionalResponseXML() const { return m_responseDocument.get(); }
115    Blob* responseBlob();
116    Blob* optionalResponseBlob() const { return m_responseBlob.get(); }
117#if ENABLE(XHR_TIMEOUT)
118    unsigned long timeout() const { return m_timeoutMilliseconds; }
119    void setTimeout(unsigned long timeout, ExceptionCode&);
120#endif
121
122    bool responseCacheIsValid() const { return m_responseCacheIsValid; }
123    void didCacheResponseJSON();
124
125    void sendForInspectorXHRReplay(PassRefPtr<FormData>, ExceptionCode&);
126
127    // Expose HTTP validation methods for other untrusted requests.
128    static bool isAllowedHTTPMethod(const String&);
129    static String uppercaseKnownHTTPMethod(const String&);
130    static bool isAllowedHTTPHeader(const String&);
131
132    void setResponseType(const String&, ExceptionCode&);
133    String responseType();
134    ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; }
135
136    // response attribute has custom getter.
137    JSC::ArrayBuffer* responseArrayBuffer();
138    JSC::ArrayBuffer* optionalResponseArrayBuffer() const { return m_responseArrayBuffer.get(); }
139
140    void setLastSendLineAndColumnNumber(unsigned lineNumber, unsigned columnNumber);
141    void setLastSendURL(const String& url) { m_lastSendURL = url; }
142
143    XMLHttpRequestUpload* upload();
144    XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); }
145
146    DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
147    DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
148    DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
149    DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
150    DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend);
151    DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
152    DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
153#if ENABLE(XHR_TIMEOUT)
154    DEFINE_ATTRIBUTE_EVENT_LISTENER(timeout);
155#endif
156
157    using RefCounted<XMLHttpRequest>::ref;
158    using RefCounted<XMLHttpRequest>::deref;
159
160private:
161    explicit XMLHttpRequest(ScriptExecutionContext&);
162
163    // ActiveDOMObject
164    virtual void contextDestroyed() override;
165    virtual bool canSuspend() const override;
166    virtual void suspend(ReasonForSuspension) override;
167    virtual void resume() override;
168    virtual void stop() override;
169
170    virtual void refEventTarget() override { ref(); }
171    virtual void derefEventTarget() override { deref(); }
172
173    Document* document() const;
174    SecurityOrigin* securityOrigin() const;
175
176#if ENABLE(DASHBOARD_SUPPORT)
177    bool usesDashboardBackwardCompatibilityMode() const;
178#endif
179
180    virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
181    virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override;
182    virtual void didReceiveData(const char* data, int dataLength) override;
183    virtual void didFinishLoading(unsigned long identifier, double finishTime) override;
184    virtual void didFail(const ResourceError&) override;
185    virtual void didFailRedirectCheck() override;
186
187    bool responseIsXML() const;
188
189    bool initSend(ExceptionCode&);
190    void sendBytesData(const void*, size_t, ExceptionCode&);
191
192    String getRequestHeader(const String& name) const;
193    void setRequestHeaderInternal(const String& name, const String& value);
194
195    void changeState(State newState);
196    void callReadyStateChangeListener();
197    void dropProtection();
198    void internalAbort();
199    void clearResponse();
200    void clearResponseBuffers();
201    void clearRequest();
202
203    void createRequest(ExceptionCode&);
204
205    void genericError();
206    void networkError();
207    void abortError();
208
209    bool shouldDecodeResponse() const { return m_responseTypeCode < FirstBinaryResponseType; }
210
211    void dispatchErrorEvents(const AtomicString&);
212
213    std::unique_ptr<XMLHttpRequestUpload> m_upload;
214
215    URL m_url;
216    String m_method;
217    HTTPHeaderMap m_requestHeaders;
218    RefPtr<FormData> m_requestEntityBody;
219    String m_mimeTypeOverride;
220    bool m_async;
221    bool m_includeCredentials;
222#if ENABLE(XHR_TIMEOUT)
223    unsigned long m_timeoutMilliseconds;
224#endif
225    RefPtr<Blob> m_responseBlob;
226
227    RefPtr<ThreadableLoader> m_loader;
228    State m_state;
229
230    ResourceResponse m_response;
231    String m_responseEncoding;
232
233    RefPtr<TextResourceDecoder> m_decoder;
234
235    StringBuilder m_responseBuilder;
236    bool m_createdDocument;
237    RefPtr<Document> m_responseDocument;
238
239    RefPtr<SharedBuffer> m_binaryResponseBuilder;
240    RefPtr<JSC::ArrayBuffer> m_responseArrayBuffer;
241
242    bool m_error;
243
244    bool m_uploadEventsAllowed;
245    bool m_uploadComplete;
246
247    bool m_sameOriginRequest;
248
249    // Used for onprogress tracking
250    long long m_receivedLength;
251
252    unsigned m_lastSendLineNumber;
253    unsigned m_lastSendColumnNumber;
254    String m_lastSendURL;
255    ExceptionCode m_exceptionCode;
256
257    XMLHttpRequestProgressEventThrottle m_progressEventThrottle;
258
259    // An enum corresponding to the allowed string values for the responseType attribute.
260    ResponseTypeCode m_responseTypeCode;
261    bool m_responseCacheIsValid;
262};
263
264} // namespace WebCore
265
266#endif // XMLHttpRequest_h
267