XMLHttpRequest / XMLHttpRequestUpload should inherit XMLHttpRequestEventTarget
[WebKit-https.git] / Source / WebCore / xml / XMLHttpRequest.h
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 "FormData.h"
28 #include "ResourceResponse.h"
29 #include "ScriptWrappable.h"
30 #include "ThreadableLoaderClient.h"
31 #include "XMLHttpRequestEventTarget.h"
32 #include "XMLHttpRequestProgressEventThrottle.h"
33 #include <wtf/text/AtomicStringHash.h>
34 #include <wtf/text/StringBuilder.h>
35
36 namespace JSC {
37 class ArrayBuffer;
38 class ArrayBufferView;
39 }
40
41 namespace WebCore {
42
43 class Blob;
44 class Document;
45 class DOMFormData;
46 class ResourceRequest;
47 class SecurityOrigin;
48 class SharedBuffer;
49 class TextResourceDecoder;
50 class ThreadableLoader;
51
52 class XMLHttpRequest final : public RefCounted<XMLHttpRequest>, public XMLHttpRequestEventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
53     WTF_MAKE_FAST_ALLOCATED;
54 public:
55     static Ref<XMLHttpRequest> create(ScriptExecutionContext&);
56     WEBCORE_EXPORT ~XMLHttpRequest();
57
58     // These exact numeric values are important because JS expects them.
59     enum State {
60         UNSENT = 0,
61         OPENED = 1,
62         HEADERS_RECEIVED = 2,
63         LOADING = 3,
64         DONE = 4
65     };
66     
67     enum ResponseTypeCode {
68         ResponseTypeDefault,
69         ResponseTypeText,
70         ResponseTypeJSON,
71         ResponseTypeDocument,
72
73         // Binary format
74         ResponseTypeBlob,
75         ResponseTypeArrayBuffer
76     };
77     static const ResponseTypeCode FirstBinaryResponseType = ResponseTypeBlob;
78
79     virtual void didReachTimeout();
80
81     virtual EventTargetInterface eventTargetInterface() const override { return XMLHttpRequestEventTargetInterfaceType; }
82     virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); }
83
84     const URL& url() const { return m_url; }
85     String statusText() const;
86     int status() const;
87     State readyState() const;
88     bool withCredentials() const { return m_includeCredentials; }
89     void setWithCredentials(bool, ExceptionCode&);
90     void open(const String& method, const URL&, ExceptionCode&);
91     void open(const String& method, const URL&, bool async, ExceptionCode&);
92     void open(const String& method, const URL&, bool async, const String& user, ExceptionCode&);
93     void open(const String& method, const URL&, bool async, const String& user, const String& password, ExceptionCode&);
94     void send(ExceptionCode&);
95     void send(Document*, ExceptionCode&);
96     void send(const String&, ExceptionCode&);
97     void send(Blob*, ExceptionCode&);
98     void send(DOMFormData*, ExceptionCode&);
99     void send(JSC::ArrayBuffer*, ExceptionCode&);
100     void send(JSC::ArrayBufferView*, ExceptionCode&);
101     void abort();
102     void setRequestHeader(const String& name, const String& value, ExceptionCode&);
103     void overrideMimeType(const String& override, ExceptionCode&);
104     bool doneWithoutErrors() const { return !m_error && m_state == DONE; }
105     String getAllResponseHeaders() const;
106     String getResponseHeader(const String& name) const;
107     String responseText(ExceptionCode&);
108     String responseTextIgnoringResponseType() const { return m_responseBuilder.toStringPreserveCapacity(); }
109     String responseMIMEType() const;
110     Document* responseXML(ExceptionCode&);
111     Document* optionalResponseXML() const { return m_responseDocument.get(); }
112     Blob* responseBlob();
113     Blob* optionalResponseBlob() const { return m_responseBlob.get(); }
114     unsigned timeout() const { return m_timeoutMilliseconds; }
115     void setTimeout(unsigned timeout, ExceptionCode&);
116
117     bool responseCacheIsValid() const { return m_responseCacheIsValid; }
118     void didCacheResponseJSON();
119
120     // Expose HTTP validation methods for other untrusted requests.
121     static bool isAllowedHTTPMethod(const String&);
122     static String uppercaseKnownHTTPMethod(const String&);
123     static bool isAllowedHTTPHeader(const String&);
124
125     void setResponseType(const String&, ExceptionCode&);
126     String responseType();
127     ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; }
128
129     String responseURL() const;
130
131     // response attribute has custom getter.
132     JSC::ArrayBuffer* responseArrayBuffer();
133     JSC::ArrayBuffer* optionalResponseArrayBuffer() const { return m_responseArrayBuffer.get(); }
134
135     void setLastSendLineAndColumnNumber(unsigned lineNumber, unsigned columnNumber);
136     void setLastSendURL(const String& url) { m_lastSendURL = url; }
137
138     XMLHttpRequestUpload* upload();
139     XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); }
140
141     const ResourceResponse& resourceResponse() const { return m_response; }
142
143     using RefCounted<XMLHttpRequest>::ref;
144     using RefCounted<XMLHttpRequest>::deref;
145
146 private:
147     explicit XMLHttpRequest(ScriptExecutionContext&);
148
149     // ActiveDOMObject
150     void contextDestroyed() override;
151     bool canSuspendForDocumentSuspension() const override;
152     void suspend(ReasonForSuspension) override;
153     void resume() override;
154     void stop() override;
155     const char* activeDOMObjectName() const override;
156
157     virtual void refEventTarget() override { ref(); }
158     virtual void derefEventTarget() override { deref(); }
159
160     Document* document() const;
161     SecurityOrigin* securityOrigin() const;
162
163 #if ENABLE(DASHBOARD_SUPPORT)
164     bool usesDashboardBackwardCompatibilityMode() const;
165 #endif
166
167     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
168     virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override;
169     virtual void didReceiveData(const char* data, int dataLength) override;
170     virtual void didFinishLoading(unsigned long identifier, double finishTime) override;
171     virtual void didFail(const ResourceError&) override;
172     virtual void didFailRedirectCheck() override;
173
174     bool responseIsXML() const;
175
176     bool initSend(ExceptionCode&);
177     void sendBytesData(const void*, size_t, ExceptionCode&);
178
179     void changeState(State newState);
180     void callReadyStateChangeListener();
181     void dropProtection();
182
183     // Returns false when cancelling the loader within internalAbort() triggers an event whose callback creates a new loader. 
184     // In that case, the function calling internalAbort should exit.
185     bool internalAbort();
186
187     void clearResponse();
188     void clearResponseBuffers();
189     void clearRequest();
190
191     void createRequest(ExceptionCode&);
192
193     void genericError();
194     void networkError();
195     void abortError();
196
197     bool shouldDecodeResponse() const { return m_responseTypeCode < FirstBinaryResponseType; }
198
199     void dispatchErrorEvents(const AtomicString&);
200
201     void resumeTimerFired();
202
203     std::unique_ptr<XMLHttpRequestUpload> m_upload;
204
205     URL m_url;
206     String m_method;
207     HTTPHeaderMap m_requestHeaders;
208     RefPtr<FormData> m_requestEntityBody;
209     String m_mimeTypeOverride;
210     bool m_async;
211     bool m_includeCredentials;
212     RefPtr<Blob> m_responseBlob;
213
214     RefPtr<ThreadableLoader> m_loader;
215     State m_state;
216     bool m_sendFlag { false };
217
218     ResourceResponse m_response;
219     String m_responseEncoding;
220
221     RefPtr<TextResourceDecoder> m_decoder;
222
223     StringBuilder m_responseBuilder;
224     bool m_createdDocument;
225     RefPtr<Document> m_responseDocument;
226     
227     RefPtr<SharedBuffer> m_binaryResponseBuilder;
228     RefPtr<JSC::ArrayBuffer> m_responseArrayBuffer;
229
230     bool m_error;
231
232     bool m_uploadEventsAllowed;
233     bool m_uploadComplete;
234
235     bool m_sameOriginRequest;
236
237     // Used for onprogress tracking
238     long long m_receivedLength;
239
240     unsigned m_lastSendLineNumber;
241     unsigned m_lastSendColumnNumber;
242     String m_lastSendURL;
243     ExceptionCode m_exceptionCode;
244
245     XMLHttpRequestProgressEventThrottle m_progressEventThrottle;
246
247     // An enum corresponding to the allowed string values for the responseType attribute.
248     ResponseTypeCode m_responseTypeCode;
249     bool m_responseCacheIsValid;
250
251     Timer m_resumeTimer;
252     bool m_dispatchErrorOnResuming;
253
254     Timer m_networkErrorTimer;
255     void networkErrorTimerFired();
256
257     unsigned m_timeoutMilliseconds { 0 };
258     std::chrono::steady_clock::time_point m_sendingTime;
259     Timer m_timeoutTimer;
260 };
261
262 } // namespace WebCore
263
264 #endif // XMLHttpRequest_h