XMLHttpRequests should not prevent a page from entering PageCache
[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 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 #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     // Expose HTTP validation methods for other untrusted requests.
125     static bool isAllowedHTTPMethod(const String&);
126     static String uppercaseKnownHTTPMethod(const String&);
127     static bool isAllowedHTTPHeader(const String&);
128
129     void setResponseType(const String&, ExceptionCode&);
130     String responseType();
131     ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; }
132
133     String responseURL() const;
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     const ResourceResponse& resourceResponse() const { return m_response; }
146
147     using RefCounted<XMLHttpRequest>::ref;
148     using RefCounted<XMLHttpRequest>::deref;
149
150 private:
151     explicit XMLHttpRequest(ScriptExecutionContext&);
152
153     // ActiveDOMObject
154     void contextDestroyed() override;
155     bool canSuspend() const override;
156     void suspend(ReasonForSuspension) override;
157     void resume() override;
158     void stop() override;
159     const char* activeDOMObjectName() const override;
160
161     virtual void refEventTarget() override { ref(); }
162     virtual void derefEventTarget() override { deref(); }
163
164     Document* document() const;
165     SecurityOrigin* securityOrigin() const;
166
167 #if ENABLE(DASHBOARD_SUPPORT)
168     bool usesDashboardBackwardCompatibilityMode() const;
169 #endif
170
171     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
172     virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override;
173     virtual void didReceiveData(const char* data, int dataLength) override;
174     virtual void didFinishLoading(unsigned long identifier, double finishTime) override;
175     virtual void didFail(const ResourceError&) override;
176     virtual void didFailRedirectCheck() override;
177
178     bool responseIsXML() const;
179
180     bool initSend(ExceptionCode&);
181     void sendBytesData(const void*, size_t, ExceptionCode&);
182
183     String getRequestHeader(const String& name) const;
184     void setRequestHeaderInternal(const String& name, const String& value);
185
186     void changeState(State newState);
187     void callReadyStateChangeListener();
188     void dropProtection();
189
190     // Returns false when cancelling the loader within internalAbort() triggers an event whose callback creates a new loader. 
191     // In that case, the function calling internalAbort should exit.
192     bool internalAbort();
193
194     void clearResponse();
195     void clearResponseBuffers();
196     void clearRequest();
197
198     void createRequest(ExceptionCode&);
199
200     void genericError();
201     void networkError();
202     void abortError();
203
204     bool shouldDecodeResponse() const { return m_responseTypeCode < FirstBinaryResponseType; }
205
206     void dispatchErrorEvents(const AtomicString&);
207
208     void resumeTimerFired();
209
210     std::unique_ptr<XMLHttpRequestUpload> m_upload;
211
212     URL m_url;
213     String m_method;
214     HTTPHeaderMap m_requestHeaders;
215     RefPtr<FormData> m_requestEntityBody;
216     String m_mimeTypeOverride;
217     bool m_async;
218     bool m_includeCredentials;
219 #if ENABLE(XHR_TIMEOUT)
220     unsigned long m_timeoutMilliseconds;
221 #endif
222     RefPtr<Blob> m_responseBlob;
223
224     RefPtr<ThreadableLoader> m_loader;
225     State m_state;
226
227     ResourceResponse m_response;
228     String m_responseEncoding;
229
230     RefPtr<TextResourceDecoder> m_decoder;
231
232     StringBuilder m_responseBuilder;
233     bool m_createdDocument;
234     RefPtr<Document> m_responseDocument;
235     
236     RefPtr<SharedBuffer> m_binaryResponseBuilder;
237     RefPtr<JSC::ArrayBuffer> m_responseArrayBuffer;
238
239     bool m_error;
240
241     bool m_uploadEventsAllowed;
242     bool m_uploadComplete;
243
244     bool m_sameOriginRequest;
245
246     // Used for onprogress tracking
247     long long m_receivedLength;
248
249     unsigned m_lastSendLineNumber;
250     unsigned m_lastSendColumnNumber;
251     String m_lastSendURL;
252     ExceptionCode m_exceptionCode;
253
254     XMLHttpRequestProgressEventThrottle m_progressEventThrottle;
255
256     // An enum corresponding to the allowed string values for the responseType attribute.
257     ResponseTypeCode m_responseTypeCode;
258     bool m_responseCacheIsValid;
259
260     Timer m_resumeTimer;
261     bool m_dispatchErrorOnResuming;
262 };
263
264 } // namespace WebCore
265
266 #endif // XMLHttpRequest_h