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