2008-05-08 Sam Weinig <sam@webkit.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 "EventTarget.h"
24 #include "ResourceResponse.h"
25 #include "SubresourceLoaderClient.h"
26
27 namespace WebCore {
28
29 class Document;
30 class TextResourceDecoder;
31
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)..
39 };
40
41 class XMLHttpRequest : public RefCounted<XMLHttpRequest>, public EventTarget, private SubresourceLoaderClient {
42 public:
43     static PassRefPtr<XMLHttpRequest> create(Document *document) { return adoptRef(new XMLHttpRequest(document)); }
44     ~XMLHttpRequest();
45
46     virtual XMLHttpRequest* toXMLHttpRequest() { return this; }
47
48     static void detachRequests(Document*);
49     static void cancelRequests(Document*);
50
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&);
58     void abort();
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;
65
66     void setOnReadyStateChangeListener(EventListener*);
67     EventListener* onReadyStateChangeListener() const;
68     void setOnLoadListener(EventListener*);
69     EventListener* onLoadListener() const;
70     void setOnProgressListener(EventListener*);
71     EventListener* onProgressListener() const;
72
73     typedef Vector<RefPtr<EventListener> > ListenerVector;
74     typedef HashMap<AtomicStringImpl*, ListenerVector> EventListenersMap;
75
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; }
81
82     void dispatchProgressEvent(long long expectedLength);
83
84     Document* document() const { return m_doc; }
85
86     using RefCounted<XMLHttpRequest>::ref;
87     using RefCounted<XMLHttpRequest>::deref;
88
89 private:
90     XMLHttpRequest(Document*);
91     
92     virtual void refEventTarget() { ref(); }
93     virtual void derefEventTarget() { deref(); }
94
95     bool urlMatchesDocumentDomain(const KURL&) const;
96
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&);
103
104     void processSyncLoadResults(const Vector<char>& data, const ResourceResponse&);
105     void updateAndDispatchOnProgress(unsigned int len);
106
107     String responseMIMEType() const;
108     bool responseIsXML() const;
109
110     String getRequestHeader(const String& name) const;
111
112     void changeState(XMLHttpRequestState newState);
113     void callReadyStateChangeListener();
114     void dropProtection();
115     void internalAbort();
116
117     Document* m_doc;
118
119     RefPtr<EventListener> m_onReadyStateChangeListener;
120     RefPtr<EventListener> m_onLoadListener;
121     RefPtr<EventListener> m_onProgressListener;
122     EventListenersMap m_eventListeners;
123
124     KURL m_url;
125     String m_method;
126     HTTPHeaderMap m_requestHeaders;
127     String m_mimeTypeOverride;
128     bool m_async;
129
130     RefPtr<SubresourceLoader> m_loader;
131     XMLHttpRequestState m_state;
132
133     ResourceResponse m_response;
134     String m_responseEncoding;
135
136     RefPtr<TextResourceDecoder> m_decoder;
137     unsigned long m_identifier;
138
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;
148
149     bool m_aborted;
150
151     // Used for onprogress tracking
152     long long m_receivedLength;
153 };
154
155 } // namespace WebCore
156
157 #endif // XMLHttpRequest_h