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 Uninitialized = 0, // The initial value.
35 Open = 1, // The open() method has been successfully called.
36 Sent = 2, // The user agent successfully completed the request, but no data has yet been received.
37 Receiving = 3, // Immediately before receiving the message body (if any). All HTTP headers have been received.
38 Loaded = 4 // The data transfer has been completed.
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