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