2 * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@nypop.com>
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.
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.
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
20 #ifndef XMLHttpRequest_h
21 #define XMLHttpRequest_h
23 #include "EventTarget.h"
24 #include "ResourceResponse.h"
25 #include "SubresourceLoaderClient.h"
30 class TextResourceDecoder;
32 // these exact numeric values are important because JS expects them
33 enum XMLHttpRequestState {
34 UNSENT = 0, // The object has been constructed.
35 OPENED = 1, // The open() method has been successfully invoked. During this state request headers can be set using setRequestHeader() and the request can be made using the send() method.
36 HEADERS_RECEIVED = 2, // All HTTP headers have been received. Several response members of the object are now available.
37 LOADING = 3, // The response entity body is being received.
38 DONE = 4 // The data transfer has been completed or something went wrong during the transfer (such as infinite redirects)..
41 class XMLHttpRequest : public RefCounted<XMLHttpRequest>, public EventTarget, private SubresourceLoaderClient {
43 static PassRefPtr<XMLHttpRequest> create(Document *document) { return adoptRef(new XMLHttpRequest(document)); }
46 virtual XMLHttpRequest* toXMLHttpRequest() { return this; }
48 static void detachRequests(Document*);
49 static void cancelRequests(Document*);
51 String statusText(ExceptionCode&) const;
52 int status(ExceptionCode&) const;
53 XMLHttpRequestState readyState() const;
54 void open(const String& method, const KURL&, bool async, ExceptionCode&);
55 void open(const String& method, const KURL&, bool async, const String& user, ExceptionCode&);
56 void open(const String& method, const KURL&, bool async, const String& user, const String& password, ExceptionCode&);
57 void send(const String& body, ExceptionCode&);
59 void setRequestHeader(const String& name, const String& value, ExceptionCode&);
60 void overrideMimeType(const String& override);
61 String getAllResponseHeaders(ExceptionCode&) const;
62 String getResponseHeader(const String& name, ExceptionCode&) const;
63 const KJS::UString& responseText() const;
64 Document* responseXML() const;
66 void setOnReadyStateChangeListener(EventListener*);
67 EventListener* onReadyStateChangeListener() const;
68 void setOnLoadListener(EventListener*);
69 EventListener* onLoadListener() const;
70 void setOnProgressListener(EventListener*);
71 EventListener* onProgressListener() const;
73 typedef Vector<RefPtr<EventListener> > ListenerVector;
74 typedef HashMap<AtomicStringImpl*, ListenerVector> EventListenersMap;
76 // useCapture is not used, even for add/remove pairing (for Firefox compatibility).
77 virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
78 virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
79 virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&, bool tempEvent = false);
80 EventListenersMap& eventListeners() { return m_eventListeners; }
82 void dispatchProgressEvent(long long expectedLength);
84 Document* document() const { return m_doc; }
86 using RefCounted<XMLHttpRequest>::ref;
87 using RefCounted<XMLHttpRequest>::deref;
90 XMLHttpRequest(Document*);
92 virtual void refEventTarget() { ref(); }
93 virtual void derefEventTarget() { deref(); }
95 bool urlMatchesDocumentDomain(const KURL&) const;
97 virtual void willSendRequest(SubresourceLoader*, ResourceRequest& request, const ResourceResponse& redirectResponse);
98 virtual void didReceiveResponse(SubresourceLoader*, const ResourceResponse&);
99 virtual void didReceiveData(SubresourceLoader*, const char* data, int size);
100 virtual void didFail(SubresourceLoader*, const ResourceError&);
101 virtual void didFinishLoading(SubresourceLoader*);
102 virtual void receivedCancellation(SubresourceLoader*, const AuthenticationChallenge&);
104 void processSyncLoadResults(const Vector<char>& data, const ResourceResponse&);
105 void updateAndDispatchOnProgress(unsigned int len);
107 String responseMIMEType() const;
108 bool responseIsXML() const;
110 String getRequestHeader(const String& name) const;
112 void changeState(XMLHttpRequestState newState);
113 void callReadyStateChangeListener();
114 void dropProtection();
115 void internalAbort();
119 RefPtr<EventListener> m_onReadyStateChangeListener;
120 RefPtr<EventListener> m_onLoadListener;
121 RefPtr<EventListener> m_onProgressListener;
122 EventListenersMap m_eventListeners;
126 HTTPHeaderMap m_requestHeaders;
127 String m_mimeTypeOverride;
130 RefPtr<SubresourceLoader> m_loader;
131 XMLHttpRequestState m_state;
133 ResourceResponse m_response;
134 String m_responseEncoding;
136 RefPtr<TextResourceDecoder> m_decoder;
137 unsigned long m_identifier;
139 // Unlike most strings in the DOM, we keep this as a KJS::UString, not a WebCore::String.
140 // That's because these strings can easily get huge (they are filled from the network with
141 // no parsing) and because JS can easily observe many intermediate states, so it's very useful
142 // to be able to share the buffer with JavaScript versions of the whole or partial string.
143 // In contrast, this string doesn't interact much with the rest of the engine so it's not that
144 // big a cost that it isn't a String.
145 KJS::UString m_responseText;
146 mutable bool m_createdDocument;
147 mutable RefPtr<Document> m_responseXML;
151 // Used for onprogress tracking
152 long long m_receivedLength;
155 } // namespace WebCore
157 #endif // XMLHttpRequest_h