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 | #pragma once |
23 | |
24 | #include "ActiveDOMObject.h" |
25 | #include "ExceptionOr.h" |
26 | #include "FormData.h" |
27 | #include "ResourceResponse.h" |
28 | #include "ThreadableLoaderClient.h" |
29 | #include "UserGestureIndicator.h" |
30 | #include <wtf/URL.h> |
31 | #include "XMLHttpRequestEventTarget.h" |
32 | #include "XMLHttpRequestProgressEventThrottle.h" |
33 | #include <wtf/Variant.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 SecurityOrigin; |
47 | class SharedBuffer; |
48 | class TextResourceDecoder; |
49 | class ThreadableLoader; |
50 | class XMLHttpRequestUpload; |
51 | struct OwnedString; |
52 | |
53 | class XMLHttpRequest final : public ActiveDOMObject, public RefCounted<XMLHttpRequest>, private ThreadableLoaderClient, public XMLHttpRequestEventTarget { |
54 | WTF_MAKE_ISO_ALLOCATED(XMLHttpRequest); |
55 | public: |
56 | static Ref<XMLHttpRequest> create(ScriptExecutionContext&); |
57 | WEBCORE_EXPORT ~XMLHttpRequest(); |
58 | |
59 | // Keep it in 3bits. |
60 | enum State : uint8_t { |
61 | UNSENT = 0, |
62 | OPENED = 1, |
63 | = 2, |
64 | LOADING = 3, |
65 | DONE = 4 |
66 | }; |
67 | |
68 | virtual void didReachTimeout(); |
69 | |
70 | EventTargetInterface eventTargetInterface() const override { return XMLHttpRequestEventTargetInterfaceType; } |
71 | ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); } |
72 | |
73 | using SendTypes = Variant<RefPtr<Document>, RefPtr<Blob>, RefPtr<JSC::ArrayBufferView>, RefPtr<JSC::ArrayBuffer>, RefPtr<DOMFormData>, String>; |
74 | |
75 | const URL& url() const { return m_url; } |
76 | String statusText() const; |
77 | int status() const; |
78 | State readyState() const; |
79 | bool withCredentials() const { return m_includeCredentials; } |
80 | ExceptionOr<void> setWithCredentials(bool); |
81 | ExceptionOr<void> open(const String& method, const String& url); |
82 | ExceptionOr<void> open(const String& method, const URL&, bool async); |
83 | ExceptionOr<void> open(const String& method, const String&, bool async, const String& user, const String& password); |
84 | ExceptionOr<void> send(Optional<SendTypes>&&); |
85 | void abort(); |
86 | ExceptionOr<void> (const String& name, const String& value); |
87 | ExceptionOr<void> overrideMimeType(const String& override); |
88 | bool doneWithoutErrors() const { return !m_error && readyState() == DONE; } |
89 | String () const; |
90 | String (const String& name) const; |
91 | ExceptionOr<OwnedString> responseText(); |
92 | String responseTextIgnoringResponseType() const { return m_responseBuilder.toStringPreserveCapacity(); } |
93 | String responseMIMEType() const; |
94 | |
95 | Document* optionalResponseXML() const { return m_responseDocument.get(); } |
96 | ExceptionOr<Document*> responseXML(); |
97 | |
98 | Ref<Blob> createResponseBlob(); |
99 | RefPtr<JSC::ArrayBuffer> createResponseArrayBuffer(); |
100 | |
101 | unsigned timeout() const { return m_timeoutMilliseconds; } |
102 | ExceptionOr<void> setTimeout(unsigned); |
103 | |
104 | bool responseCacheIsValid() const { return m_responseCacheIsValid; } |
105 | void didCacheResponse(); |
106 | |
107 | // Keep it in 3bits. |
108 | enum class ResponseType : uint8_t { |
109 | EmptyString = 0, |
110 | Arraybuffer = 1, |
111 | Blob = 2, |
112 | Document = 3, |
113 | Json = 4, |
114 | Text = 5, |
115 | }; |
116 | ExceptionOr<void> setResponseType(ResponseType); |
117 | ResponseType responseType() const; |
118 | |
119 | String responseURL() const; |
120 | |
121 | XMLHttpRequestUpload& upload(); |
122 | XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); } |
123 | |
124 | const ResourceResponse& resourceResponse() const { return m_response; } |
125 | |
126 | using RefCounted<XMLHttpRequest>::ref; |
127 | using RefCounted<XMLHttpRequest>::deref; |
128 | |
129 | size_t memoryCost() const; |
130 | |
131 | WEBCORE_EXPORT void setMaximumIntervalForUserGestureForwarding(double); |
132 | |
133 | private: |
134 | explicit XMLHttpRequest(ScriptExecutionContext&); |
135 | |
136 | TextEncoding finalResponseCharset() const; |
137 | |
138 | // ActiveDOMObject |
139 | void contextDestroyed() override; |
140 | bool canSuspendForDocumentSuspension() const override; |
141 | void suspend(ReasonForSuspension) override; |
142 | void resume() override; |
143 | void stop() override; |
144 | const char* activeDOMObjectName() const override; |
145 | |
146 | void refEventTarget() override { ref(); } |
147 | void derefEventTarget() override { deref(); } |
148 | |
149 | Document* document() const; |
150 | SecurityOrigin* securityOrigin() const; |
151 | |
152 | #if ENABLE(DASHBOARD_SUPPORT) |
153 | bool usesDashboardBackwardCompatibilityMode() const; |
154 | #endif |
155 | |
156 | // ThreadableLoaderClient |
157 | void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override; |
158 | void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override; |
159 | void didReceiveData(const char* data, int dataLength) override; |
160 | void didFinishLoading(unsigned long identifier) override; |
161 | void didFail(const ResourceError&) override; |
162 | |
163 | bool responseIsXML() const; |
164 | |
165 | Optional<ExceptionOr<void>> prepareToSend(); |
166 | ExceptionOr<void> send(Document&); |
167 | ExceptionOr<void> send(const String& = { }); |
168 | ExceptionOr<void> send(Blob&); |
169 | ExceptionOr<void> send(DOMFormData&); |
170 | ExceptionOr<void> send(JSC::ArrayBuffer&); |
171 | ExceptionOr<void> send(JSC::ArrayBufferView&); |
172 | ExceptionOr<void> sendBytesData(const void*, size_t); |
173 | |
174 | void changeState(State); |
175 | void callReadyStateChangeListener(); |
176 | |
177 | // Returns false when cancelling the loader within internalAbort() triggers an event whose callback creates a new loader. |
178 | // In that case, the function calling internalAbort should exit. |
179 | bool internalAbort(); |
180 | |
181 | void clearResponse(); |
182 | void clearResponseBuffers(); |
183 | void clearRequest(); |
184 | |
185 | ExceptionOr<void> createRequest(); |
186 | |
187 | void genericError(); |
188 | void networkError(); |
189 | void abortError(); |
190 | |
191 | void dispatchErrorEvents(const AtomicString&); |
192 | |
193 | using EventTarget::dispatchEvent; |
194 | void dispatchEvent(Event&) override; |
195 | |
196 | void resumeTimerFired(); |
197 | Ref<TextResourceDecoder> createDecoder() const; |
198 | |
199 | void networkErrorTimerFired(); |
200 | |
201 | unsigned m_async : 1; |
202 | unsigned m_includeCredentials : 1; |
203 | unsigned m_sendFlag : 1; |
204 | unsigned m_createdDocument : 1; |
205 | unsigned m_error : 1; |
206 | unsigned m_uploadListenerFlag : 1; |
207 | unsigned m_uploadComplete : 1; |
208 | unsigned m_wasAbortedByClient : 1; |
209 | unsigned m_responseCacheIsValid : 1; |
210 | unsigned m_dispatchErrorOnResuming : 1; |
211 | unsigned m_readyState : 3; // State |
212 | unsigned m_responseType : 3; // ResponseType |
213 | |
214 | unsigned m_timeoutMilliseconds { 0 }; |
215 | |
216 | std::unique_ptr<XMLHttpRequestUpload> m_upload; |
217 | |
218 | URL m_url; |
219 | String m_method; |
220 | HTTPHeaderMap ; |
221 | RefPtr<FormData> m_requestEntityBody; |
222 | String m_mimeTypeOverride; |
223 | |
224 | RefPtr<ThreadableLoader> m_loader; |
225 | |
226 | String m_responseEncoding; |
227 | |
228 | ResourceResponse m_response; |
229 | |
230 | RefPtr<TextResourceDecoder> m_decoder; |
231 | |
232 | RefPtr<Document> m_responseDocument; |
233 | |
234 | RefPtr<SharedBuffer> m_binaryResponseBuilder; |
235 | |
236 | StringBuilder m_responseBuilder; |
237 | |
238 | // Used for progress event tracking. |
239 | long long m_receivedLength { 0 }; |
240 | |
241 | XMLHttpRequestProgressEventThrottle m_progressEventThrottle; |
242 | |
243 | mutable String ; |
244 | |
245 | Timer m_resumeTimer; |
246 | Timer m_networkErrorTimer; |
247 | Timer m_timeoutTimer; |
248 | |
249 | MonotonicTime m_sendingTime; |
250 | |
251 | Optional<ExceptionCode> m_exceptionCode; |
252 | RefPtr<UserGestureToken> m_userGestureToken; |
253 | Seconds m_maximumIntervalForUserGestureForwarding; |
254 | }; |
255 | |
256 | inline auto XMLHttpRequest::responseType() const -> ResponseType |
257 | { |
258 | return static_cast<ResponseType>(m_responseType); |
259 | } |
260 | |
261 | inline auto XMLHttpRequest::readyState() const -> State |
262 | { |
263 | return static_cast<State>(m_readyState); |
264 | } |
265 | |
266 | } // namespace WebCore |
267 | |