JavaScriptCore:
[WebKit-https.git] / WebCore / xml / XMLHttpRequest.h
1 // -*- c-basic-offset: 2 -*-
2 /*
3  *  This file is part of the KDE libraries
4  *  Copyright (C) 2003, 2006 Apple Computer, Inc.
5  *  Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@nypop.com>
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #ifndef XMLHttpRequest_h
23 #define XMLHttpRequest_h
24
25 #include "EventTarget.h"
26 #include "HTTPHeaderMap.h"
27 #include "KURL.h"
28 #include "PlatformString.h"
29 #include "ResourceResponse.h"
30 #include "StringHash.h"
31 #include "SubresourceLoaderClient.h"
32 #include <kjs/ustring.h>
33
34 #include <wtf/HashMap.h>
35 #include <wtf/Vector.h>
36
37 namespace WebCore {
38
39 class TextResourceDecoder;
40 class Document;
41 class Event;
42 class EventListener;
43 class String;
44
45 typedef int ExceptionCode;
46
47 const int XMLHttpRequestExceptionOffset = 500;
48 const int XMLHttpRequestExceptionMax = 699;
49 enum XMLHttpRequestExceptionCode {
50     PERMISSION_DENIED = XMLHttpRequestExceptionOffset, // Use SECURITY_ERR when that's in DOM Core, http://bugs.webkit.org/show_bug.cgi?id=12182
51     NETWORK_ERR = XMLHttpRequestExceptionOffset + 101
52 };
53
54 // these exact numeric values are important because JS expects them
55 enum XMLHttpRequestState {
56     Uninitialized = 0,  // The initial value.
57     Open = 1,           // The open() method has been successfully called.
58     Sent = 2,           // The user agent successfully completed the request, but no data has yet been received.
59     Receiving = 3,      // Immediately before receiving the message body (if any). All HTTP headers have been received.
60     Loaded = 4          // The data transfer has been completed.
61 };
62
63 class XMLHttpRequest : public Shared<XMLHttpRequest>, public EventTarget, private SubresourceLoaderClient {
64 public:
65     XMLHttpRequest(Document*);
66     ~XMLHttpRequest();
67
68     virtual XMLHttpRequest* toXMLHttpRequest() { return this; }
69
70     static void detachRequests(Document*);
71     static void cancelRequests(Document*);
72
73     String getStatusText(ExceptionCode&) const;
74     int getStatus(ExceptionCode&) const;
75     XMLHttpRequestState getReadyState() const;
76     void open(const String& method, const KURL&, bool async, ExceptionCode&);
77     void open(const String& method, const KURL&, bool async, const String& user, ExceptionCode&);
78     void open(const String& method, const KURL&, bool async, const String& user, const String& password, ExceptionCode&);
79     void send(const String& body, ExceptionCode&);
80     void abort();
81     void setRequestHeader(const String& name, const String& value, ExceptionCode&);
82     void overrideMIMEType(const String& override);
83     String getAllResponseHeaders() const;
84     String getResponseHeader(const String& name) const;
85     const KJS::UString& getResponseText() const;
86     Document* getResponseXML() const;
87
88     void setOnReadyStateChangeListener(EventListener*);
89     EventListener* onReadyStateChangeListener() const;
90     void setOnLoadListener(EventListener*);
91     EventListener* onLoadListener() const;
92
93     typedef Vector<RefPtr<EventListener> > ListenerVector;
94     typedef HashMap<AtomicStringImpl*, ListenerVector> EventListenersMap;
95
96     // useCapture is not used, even for add/remove pairing (for Firefox compatibility).
97     virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
98     virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
99     virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&, bool tempEvent = false);
100     EventListenersMap& eventListeners() { return m_eventListeners; }
101
102     using Shared<XMLHttpRequest>::ref;
103     using Shared<XMLHttpRequest>::deref;
104
105 private:
106     virtual void refEventTarget() { ref(); }
107     virtual void derefEventTarget() { deref(); }
108
109     bool urlMatchesDocumentDomain(const KURL&) const;
110
111     virtual void willSendRequest(SubresourceLoader*, ResourceRequest& request, const ResourceResponse& redirectResponse);
112     virtual void didReceiveResponse(SubresourceLoader*, const ResourceResponse&);
113     virtual void didReceiveData(SubresourceLoader*, const char* data, int size);
114     virtual void didFail(SubresourceLoader*, const ResourceError&);
115     virtual void didFinishLoading(SubresourceLoader*);
116
117     void processSyncLoadResults(const Vector<char>& data, const ResourceResponse&);
118
119     String responseMIMEType() const;
120     bool responseIsXML() const;
121
122     String getRequestHeader(const String& name) const;
123
124     void changeState(XMLHttpRequestState newState);
125     void callReadyStateChangeListener();
126     void dropProtection();
127
128     Document* m_doc;
129
130     RefPtr<EventListener> m_onReadyStateChangeListener;
131     RefPtr<EventListener> m_onLoadListener;
132     EventListenersMap m_eventListeners;
133
134     KURL m_url;
135     DeprecatedString m_method;
136     HTTPHeaderMap m_requestHeaders;
137     String m_mimeTypeOverride;
138     bool m_async;
139
140     RefPtr<SubresourceLoader> m_loader;
141     XMLHttpRequestState m_state;
142
143     ResourceResponse m_response;
144     String m_encoding;
145
146     RefPtr<TextResourceDecoder> m_decoder;
147
148     // Unlike most strings in the DOM, we keep this as a KJS::UString, not a WebCore::String.
149     // That's because these strings can easily get huge (they are filled from the network with
150     // no parsing) and because JS can easily observe many intermediate states, so it's very useful
151     // to be able to share the buffer with JavaScript versions of the whole or partial string.
152     // In contrast, this string doesn't interact much with the rest of the engine so it's not that
153     // big a cost that it isn't a String.
154     KJS::UString m_responseText;
155     mutable bool m_createdDocument;
156     mutable RefPtr<Document> m_responseXML;
157
158     bool m_aborted;
159 };
160
161 } // namespace WebCore
162
163 #endif // XMLHttpRequest_h