• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "AtomicStringHash.h"
25 #include "EventListener.h"
26 #include "EventTarget.h"
27 #include "FormData.h"
28 #include "ResourceResponse.h"
29 #include "ScriptString.h"
30 #include "ThreadableLoaderClient.h"
31 #include <wtf/OwnPtr.h>
32 
33 namespace WebCore {
34 
35 class Document;
36 class File;
37 struct ResourceRequest;
38 class TextResourceDecoder;
39 class ThreadableLoader;
40 
41 class XMLHttpRequest : public RefCounted<XMLHttpRequest>, public EventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
42 public:
create(ScriptExecutionContext * context)43     static PassRefPtr<XMLHttpRequest> create(ScriptExecutionContext* context) { return adoptRef(new XMLHttpRequest(context)); }
44     ~XMLHttpRequest();
45 
46     // These exact numeric values are important because JS expects them.
47     enum State {
48         UNSENT = 0,
49         OPENED = 1,
50         HEADERS_RECEIVED = 2,
51         LOADING = 3,
52         DONE = 4
53     };
54 
toXMLHttpRequest()55     virtual XMLHttpRequest* toXMLHttpRequest() { return this; }
56 
57     virtual void contextDestroyed();
58     virtual bool canSuspend() const;
59     virtual void stop();
60 
61     virtual ScriptExecutionContext* scriptExecutionContext() const;
62 
63     String statusText(ExceptionCode&) const;
64     int status(ExceptionCode&) const;
65     State readyState() const;
withCredentials()66     bool withCredentials() const { return m_includeCredentials; }
67     void setWithCredentials(bool, ExceptionCode&);
68     void open(const String& method, const KURL&, bool async, ExceptionCode&);
69     void open(const String& method, const KURL&, bool async, const String& user, ExceptionCode&);
70     void open(const String& method, const KURL&, bool async, const String& user, const String& password, ExceptionCode&);
71     void send(ExceptionCode&);
72     void send(Document*, ExceptionCode&);
73     void send(const String&, ExceptionCode&);
74     void send(File*, ExceptionCode&);
75     void abort();
76     void setRequestHeader(const AtomicString& name, const String& value, ExceptionCode&);
77     void overrideMimeType(const String& override);
78     String getAllResponseHeaders(ExceptionCode&) const;
79     String getResponseHeader(const AtomicString& name, ExceptionCode&) const;
80     const ScriptString& responseText() const;
81     Document* responseXML() const;
setLastSendLineNumber(unsigned lineNumber)82     void setLastSendLineNumber(unsigned lineNumber) { m_lastSendLineNumber = lineNumber; }
setLastSendURL(const String & url)83     void setLastSendURL(const String& url) { m_lastSendURL = url; }
84 
85     XMLHttpRequestUpload* upload();
optionalUpload()86     XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); }
87 
setOnreadystatechange(PassRefPtr<EventListener> eventListener)88     void setOnreadystatechange(PassRefPtr<EventListener> eventListener) { m_onReadyStateChangeListener = eventListener; }
onreadystatechange()89     EventListener* onreadystatechange() const { return m_onReadyStateChangeListener.get(); }
90 
setOnabort(PassRefPtr<EventListener> eventListener)91     void setOnabort(PassRefPtr<EventListener> eventListener) { m_onAbortListener = eventListener; }
onabort()92     EventListener* onabort() const { return m_onAbortListener.get(); }
93 
setOnerror(PassRefPtr<EventListener> eventListener)94     void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; }
onerror()95     EventListener* onerror() const { return m_onErrorListener.get(); }
96 
setOnload(PassRefPtr<EventListener> eventListener)97     void setOnload(PassRefPtr<EventListener> eventListener) { m_onLoadListener = eventListener; }
onload()98     EventListener* onload() const { return m_onLoadListener.get(); }
99 
setOnloadstart(PassRefPtr<EventListener> eventListener)100     void setOnloadstart(PassRefPtr<EventListener> eventListener) { m_onLoadStartListener = eventListener; }
onloadstart()101     EventListener* onloadstart() const { return m_onLoadStartListener.get(); }
102 
setOnprogress(PassRefPtr<EventListener> eventListener)103     void setOnprogress(PassRefPtr<EventListener> eventListener) { m_onProgressListener = eventListener; }
onprogress()104     EventListener* onprogress() const { return m_onProgressListener.get(); }
105 
106     typedef Vector<RefPtr<EventListener> > ListenerVector;
107     typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
108 
109     // useCapture is not used, even for add/remove pairing (for Firefox compatibility).
110     virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
111     virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
112     virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
eventListeners()113     EventListenersMap& eventListeners() { return m_eventListeners; }
114 
115     using RefCounted<XMLHttpRequest>::ref;
116     using RefCounted<XMLHttpRequest>::deref;
117 
118 private:
119     XMLHttpRequest(ScriptExecutionContext*);
120 
refEventTarget()121     virtual void refEventTarget() { ref(); }
derefEventTarget()122     virtual void derefEventTarget() { deref(); }
123 
124     Document* document() const;
125 
126 #if ENABLE(DASHBOARD_SUPPORT)
127     bool usesDashboardBackwardCompatibilityMode() const;
128 #endif
129 
130     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
131     virtual void didReceiveResponse(const ResourceResponse&);
132     virtual void didReceiveData(const char* data, int lengthReceived);
133     virtual void didFinishLoading(unsigned long identifier);
134     virtual void didFail(const ResourceError&);
135     virtual void didFailRedirectCheck();
136     virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
137 
138     // Special versions for the preflight
139     void didReceiveResponsePreflight(const ResourceResponse&);
140     void didFinishLoadingPreflight();
141 
142     void updateAndDispatchOnProgress(unsigned int len);
143 
144     String responseMIMEType() const;
145     bool responseIsXML() const;
146 
147     bool initSend(ExceptionCode&);
148 
149     String getRequestHeader(const AtomicString& name) const;
150     void setRequestHeaderInternal(const AtomicString& name, const String& value);
151     bool isSafeRequestHeader(const String&) const;
152 
153     void changeState(State newState);
154     void callReadyStateChangeListener();
155     void dropProtection();
156     void internalAbort();
157     void clearResponse();
158     void clearRequest();
159 
160     void createRequest(ExceptionCode&);
161 
162     void makeSameOriginRequest(ExceptionCode&);
163     void makeCrossOriginAccessRequest(ExceptionCode&);
164 
165     void makeSimpleCrossOriginAccessRequest(ExceptionCode&);
166     void makeCrossOriginAccessRequestWithPreflight(ExceptionCode&);
167     void handleAsynchronousPreflightResult();
168 
169     void loadRequestSynchronously(ResourceRequest&, ExceptionCode&);
170     void loadRequestAsynchronously(ResourceRequest&);
171 
172     void genericError();
173     void networkError();
174     void abortError();
175 
176     void dispatchReadyStateChangeEvent();
177     void dispatchXMLHttpRequestProgressEvent(EventListener* listener, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total);
178     void dispatchAbortEvent();
179     void dispatchErrorEvent();
180     void dispatchLoadEvent();
181     void dispatchLoadStartEvent();
182     void dispatchProgressEvent(long long expectedLength);
183 
184     RefPtr<EventListener> m_onReadyStateChangeListener;
185     RefPtr<EventListener> m_onAbortListener;
186     RefPtr<EventListener> m_onErrorListener;
187     RefPtr<EventListener> m_onLoadListener;
188     RefPtr<EventListener> m_onLoadStartListener;
189     RefPtr<EventListener> m_onProgressListener;
190     EventListenersMap m_eventListeners;
191 
192     RefPtr<XMLHttpRequestUpload> m_upload;
193 
194     KURL m_url;
195     String m_method;
196     HTTPHeaderMap m_requestHeaders;
197     RefPtr<FormData> m_requestEntityBody;
198     String m_mimeTypeOverride;
199     bool m_async;
200     bool m_includeCredentials;
201 
202     RefPtr<ThreadableLoader> m_loader;
203     State m_state;
204 
205     ResourceResponse m_response;
206     String m_responseEncoding;
207 
208     RefPtr<TextResourceDecoder> m_decoder;
209 
210     // Unlike most strings in the DOM, we keep this as a ScriptString, not a WebCore::String.
211     // That's because these strings can easily get huge (they are filled from the network with
212     // no parsing) and because JS can easily observe many intermediate states, so it's very useful
213     // to be able to share the buffer with JavaScript versions of the whole or partial string.
214     // In contrast, this string doesn't interact much with the rest of the engine so it's not that
215     // big a cost that it isn't a String.
216     ScriptString m_responseText;
217     mutable bool m_createdDocument;
218     mutable RefPtr<Document> m_responseXML;
219 
220     bool m_error;
221 
222     bool m_uploadEventsAllowed;
223     bool m_uploadComplete;
224 
225     bool m_sameOriginRequest;
226     bool m_allowAccess;
227     bool m_inPreflight;
228     bool m_didTellLoaderAboutRequest;
229 
230     // Used for onprogress tracking
231     long long m_receivedLength;
232 
233     unsigned m_lastSendLineNumber;
234     String m_lastSendURL;
235     ExceptionCode m_exceptionCode;
236 };
237 
238 } // namespace WebCore
239 
240 #endif // XMLHttpRequest_h
241