[XHR] Abort method execution when m_loader->cancel() in internalAbort() caused reentry
[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 "EventTarget.h"
28 #include "FormData.h"
29 #include "ResourceResponse.h"
30 #include "ScriptWrappable.h"
31 #include "ThreadableLoaderClient.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 ScriptWrappable, public RefCounted<XMLHttpRequest>, public EventTargetWithInlineData, private ThreadableLoaderClient, public ActiveDOMObject {
53     WTF_MAKE_FAST_ALLOCATED;
54 public:
55     static PassRefPtr<XMLHttpRequest> create(ScriptExecutionContext&);
56     ~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 #if ENABLE(XHR_TIMEOUT)
80     virtual void didTimeout();
81 #endif
82
83     virtual EventTargetInterface eventTargetInterface() const override { return XMLHttpRequestEventTargetInterfaceType; }
84     virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); }
85
86     const URL& url() const { return m_url; }
87     String statusText() const;
88     int status() const;
89     State readyState() const;
90     bool withCredentials() const { return m_includeCredentials; }
91     void setWithCredentials(bool, ExceptionCode&);
92     void open(const String& method, const URL&, ExceptionCode&);
93     void open(const String& method, const URL&, bool async, ExceptionCode&);
94     void open(const String& method, const URL&, bool async, const String& user, ExceptionCode&);
95     void open(const String& method, const URL&, bool async, const String& user, const String& password, ExceptionCode&);
96     void send(ExceptionCode&);
97     void send(Document*, ExceptionCode&);
98     void send(const String&, ExceptionCode&);
99     void send(Blob*, ExceptionCode&);
100     void send(DOMFormData*, ExceptionCode&);
101     void send(JSC::ArrayBuffer*, ExceptionCode&);
102     void send(JSC::ArrayBufferView*, ExceptionCode&);
103     void abort();
104     void setRequestHeader(const String& name, const String& value, ExceptionCode&);
105     void overrideMimeType(const String& override, ExceptionCode&);
106     bool doneWithoutErrors() const { return !m_error && m_state == DONE; }
107     String getAllResponseHeaders() const;
108     String getResponseHeader(const String& name) const;
109     String responseText(ExceptionCode&);
110     String responseTextIgnoringResponseType() const { return m_responseBuilder.toStringPreserveCapacity(); }
111     String responseMIMEType() const;
112     Document* responseXML(ExceptionCode&);
113     Document* optionalResponseXML() const { return m_responseDocument.get(); }
114     Blob* responseBlob();
115     Blob* optionalResponseBlob() const { return m_responseBlob.get(); }
116 #if ENABLE(XHR_TIMEOUT)
117     unsigned long timeout() const { return m_timeoutMilliseconds; }
118     void setTimeout(unsigned long timeout, ExceptionCode&);
119 #endif
120
121     bool responseCacheIsValid() const { return m_responseCacheIsValid; }
122     void didCacheResponseJSON();
123
124     void sendForInspectorXHRReplay(PassRefPtr<FormData>, ExceptionCode&);
125
126     // Expose HTTP validation methods for other untrusted requests.
127     static bool isAllowedHTTPMethod(const String&);
128     static String uppercaseKnownHTTPMethod(const String&);
129     static bool isAllowedHTTPHeader(const String&);
130
131     void setResponseType(const String&, ExceptionCode&);
132     String responseType();
133     ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; }
134
135     // response attribute has custom getter.
136     JSC::ArrayBuffer* responseArrayBuffer();
137     JSC::ArrayBuffer* optionalResponseArrayBuffer() const { return m_responseArrayBuffer.get(); }
138
139     void setLastSendLineAndColumnNumber(unsigned lineNumber, unsigned columnNumber);
140     void setLastSendURL(const String& url) { m_lastSendURL = url; }
141
142     XMLHttpRequestUpload* upload();
143     XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); }
144
145     DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
146     DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
147     DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
148     DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
149     DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend);
150     DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
151     DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
152 #if ENABLE(XHR_TIMEOUT)
153     DEFINE_ATTRIBUTE_EVENT_LISTENER(timeout);
154 #endif
155
156     using RefCounted<XMLHttpRequest>::ref;
157     using RefCounted<XMLHttpRequest>::deref;
158
159 private:
160     explicit XMLHttpRequest(ScriptExecutionContext&);
161
162     // ActiveDOMObject
163     virtual void contextDestroyed() override;
164     virtual bool canSuspend() const override;
165     virtual void suspend(ReasonForSuspension) override;
166     virtual void resume() override;
167     virtual void stop() override;
168
169     virtual void refEventTarget() override { ref(); }
170     virtual void derefEventTarget() override { deref(); }
171
172     Document* document() const;
173     SecurityOrigin* securityOrigin() const;
174
175 #if ENABLE(DASHBOARD_SUPPORT)
176     bool usesDashboardBackwardCompatibilityMode() const;
177 #endif
178
179     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
180     virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override;
181     virtual void didReceiveData(const char* data, int dataLength) override;
182     virtual void didFinishLoading(unsigned long identifier, double finishTime) override;
183     virtual void didFail(const ResourceError&) override;
184     virtual void didFailRedirectCheck() override;
185
186     bool responseIsXML() const;
187
188     bool initSend(ExceptionCode&);
189     void sendBytesData(const void*, size_t, ExceptionCode&);
190
191     String getRequestHeader(const String& name) const;
192     void setRequestHeaderInternal(const String& name, const String& value);
193
194     void changeState(State newState);
195     void callReadyStateChangeListener();
196     void dropProtection();
197
198     // Returns false when cancelling the loader within internalAbort() triggers an event whose callback creates a new loader. 
199     // In that case, the function calling internalAbort should exit.
200     bool internalAbort();
201
202     void clearResponse();
203     void clearResponseBuffers();
204     void clearRequest();
205
206     void createRequest(ExceptionCode&);
207
208     void genericError();
209     void networkError();
210     void abortError();
211
212     bool shouldDecodeResponse() const { return m_responseTypeCode < FirstBinaryResponseType; }
213
214     void dispatchErrorEvents(const AtomicString&);
215
216     std::unique_ptr<XMLHttpRequestUpload> m_upload;
217
218     URL m_url;
219     String m_method;
220     HTTPHeaderMap m_requestHeaders;
221     RefPtr<FormData> m_requestEntityBody;
222     String m_mimeTypeOverride;
223     bool m_async;
224     bool m_includeCredentials;
225 #if ENABLE(XHR_TIMEOUT)
226     unsigned long m_timeoutMilliseconds;
227 #endif
228     RefPtr<Blob> m_responseBlob;
229
230     RefPtr<ThreadableLoader> m_loader;
231     State m_state;
232
233     ResourceResponse m_response;
234     String m_responseEncoding;
235
236     RefPtr<TextResourceDecoder> m_decoder;
237
238     StringBuilder m_responseBuilder;
239     bool m_createdDocument;
240     RefPtr<Document> m_responseDocument;
241     
242     RefPtr<SharedBuffer> m_binaryResponseBuilder;
243     RefPtr<JSC::ArrayBuffer> m_responseArrayBuffer;
244
245     bool m_error;
246
247     bool m_uploadEventsAllowed;
248     bool m_uploadComplete;
249
250     bool m_sameOriginRequest;
251
252     // Used for onprogress tracking
253     long long m_receivedLength;
254
255     unsigned m_lastSendLineNumber;
256     unsigned m_lastSendColumnNumber;
257     String m_lastSendURL;
258     ExceptionCode m_exceptionCode;
259
260     XMLHttpRequestProgressEventThrottle m_progressEventThrottle;
261
262     // An enum corresponding to the allowed string values for the responseType attribute.
263     ResponseTypeCode m_responseTypeCode;
264     bool m_responseCacheIsValid;
265 };
266
267 } // namespace WebCore
268
269 #endif // XMLHttpRequest_h