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 "EventListener.h"
25#include "EventNames.h"
26#include "EventTarget.h"
27#include "FormData.h"
28#include "ResourceResponse.h"
29#include "ThreadableLoaderClient.h"
30#include "XMLHttpRequestProgressEventThrottle.h"
31#include <wtf/OwnPtr.h>
32#include <wtf/text/AtomicStringHash.h>
33#include <wtf/text/StringBuilder.h>
34
35namespace WebCore {
36
37class ArrayBuffer;
38class Blob;
39class Document;
40class DOMFormData;
41class ResourceRequest;
42class SharedBuffer;
43class TextResourceDecoder;
44class ThreadableLoader;
45
46class XMLHttpRequest : public RefCounted<XMLHttpRequest>, public EventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
47    WTF_MAKE_FAST_ALLOCATED;
48public:
49    static PassRefPtr<XMLHttpRequest> create(ScriptExecutionContext* context) { return adoptRef(new XMLHttpRequest(context)); }
50    ~XMLHttpRequest();
51
52    // These exact numeric values are important because JS expects them.
53    enum State {
54        UNSENT = 0,
55        OPENED = 1,
56        HEADERS_RECEIVED = 2,
57        LOADING = 3,
58        DONE = 4
59    };
60
61    enum ResponseTypeCode {
62        ResponseTypeDefault,
63        ResponseTypeText,
64        ResponseTypeDocument,
65        ResponseTypeBlob,
66        ResponseTypeArrayBuffer
67    };
68
69    virtual XMLHttpRequest* toXMLHttpRequest() { return this; }
70
71    virtual void contextDestroyed();
72    virtual bool canSuspend() const;
73    virtual void suspend(ReasonForSuspension);
74    virtual void resume();
75    virtual void stop();
76
77    virtual ScriptExecutionContext* scriptExecutionContext() const;
78
79    const KURL& url() const { return m_url; }
80    String statusText(ExceptionCode&) const;
81    int status(ExceptionCode&) const;
82    State readyState() const;
83    bool withCredentials() const { return m_includeCredentials; }
84    void setWithCredentials(bool, ExceptionCode&);
85#if ENABLE(XHR_RESPONSE_BLOB)
86    bool asBlob() const { return responseTypeCode() == ResponseTypeBlob; }
87    void setAsBlob(bool, ExceptionCode&);
88#endif
89    void open(const String& method, const KURL&, ExceptionCode&);
90    void open(const String& method, const KURL&, bool async, ExceptionCode&);
91    void open(const String& method, const KURL&, bool async, const String& user, ExceptionCode&);
92    void open(const String& method, const KURL&, bool async, const String& user, const String& password, ExceptionCode&);
93    void send(ExceptionCode&);
94    void send(Document*, ExceptionCode&);
95    void send(const String&, ExceptionCode&);
96    void send(Blob*, ExceptionCode&);
97    void send(DOMFormData*, ExceptionCode&);
98    void send(ArrayBuffer*, ExceptionCode&);
99    void abort();
100    void setRequestHeader(const AtomicString& name, const String& value, ExceptionCode&);
101    void overrideMimeType(const String& override);
102    String getAllResponseHeaders(ExceptionCode&) const;
103    String getResponseHeader(const AtomicString& name, ExceptionCode&) const;
104    String responseText(ExceptionCode&);
105    Document* responseXML(ExceptionCode&);
106    Document* optionalResponseXML() const { return m_responseXML.get(); }
107#if ENABLE(XHR_RESPONSE_BLOB)
108    Blob* responseBlob(ExceptionCode&) const;
109    Blob* optionalResponseBlob() const { return m_responseBlob.get(); }
110#endif
111
112    void setResponseType(const String&, ExceptionCode&);
113    String responseType();
114    ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; }
115
116    // response attribute has custom getter.
117    ArrayBuffer* responseArrayBuffer(ExceptionCode&);
118    ArrayBuffer* optionalResponseArrayBuffer() const { return m_responseArrayBuffer.get(); }
119
120    void setLastSendLineNumber(unsigned lineNumber) { m_lastSendLineNumber = lineNumber; }
121    void setLastSendURL(const String& url) { m_lastSendURL = url; }
122
123    XMLHttpRequestUpload* upload();
124    XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); }
125
126    DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
127    DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
128    DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
129    DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
130    DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
131    DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
132
133    using RefCounted<XMLHttpRequest>::ref;
134    using RefCounted<XMLHttpRequest>::deref;
135
136private:
137    XMLHttpRequest(ScriptExecutionContext*);
138
139    virtual void refEventTarget() { ref(); }
140    virtual void derefEventTarget() { deref(); }
141    virtual EventTargetData* eventTargetData();
142    virtual EventTargetData* ensureEventTargetData();
143
144    Document* document() const;
145
146#if ENABLE(DASHBOARD_SUPPORT)
147    bool usesDashboardBackwardCompatibilityMode() const;
148#endif
149
150    virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
151    virtual void didReceiveResponse(const ResourceResponse&);
152    virtual void didReceiveData(const char* data, int dataLength);
153    virtual void didFinishLoading(unsigned long identifier, double finishTime);
154    virtual void didFail(const ResourceError&);
155    virtual void didFailRedirectCheck();
156    virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
157
158    String responseMIMEType() const;
159    bool responseIsXML() const;
160
161    bool initSend(ExceptionCode&);
162
163    String getRequestHeader(const AtomicString& name) const;
164    void setRequestHeaderInternal(const AtomicString& name, const String& value);
165    bool isSafeRequestHeader(const String&) const;
166
167    void changeState(State newState);
168    void callReadyStateChangeListener();
169    void dropProtection();
170    void internalAbort();
171    void clearResponse();
172    void clearResponseBuffers();
173    void clearRequest();
174
175    void createRequest(ExceptionCode&);
176
177    void genericError();
178    void networkError();
179    void abortError();
180
181    RefPtr<XMLHttpRequestUpload> m_upload;
182
183    KURL m_url;
184    String m_method;
185    HTTPHeaderMap m_requestHeaders;
186    RefPtr<FormData> m_requestEntityBody;
187    String m_mimeTypeOverride;
188    bool m_async;
189    bool m_includeCredentials;
190#if ENABLE(XHR_RESPONSE_BLOB)
191    RefPtr<Blob> m_responseBlob;
192#endif
193
194    RefPtr<ThreadableLoader> m_loader;
195    State m_state;
196
197    ResourceResponse m_response;
198    String m_responseEncoding;
199
200    RefPtr<TextResourceDecoder> m_decoder;
201
202    StringBuilder m_responseBuilder;
203    mutable bool m_createdDocument;
204    mutable RefPtr<Document> m_responseXML;
205
206    RefPtr<SharedBuffer> m_binaryResponseBuilder;
207    mutable RefPtr<ArrayBuffer> m_responseArrayBuffer;
208
209    bool m_error;
210
211    bool m_uploadEventsAllowed;
212    bool m_uploadComplete;
213
214    bool m_sameOriginRequest;
215
216    // Used for onprogress tracking
217    long long m_receivedLength;
218
219    unsigned m_lastSendLineNumber;
220    String m_lastSendURL;
221    ExceptionCode m_exceptionCode;
222
223    EventTargetData m_eventTargetData;
224
225    XMLHttpRequestProgressEventThrottle m_progressEventThrottle;
226
227    // An enum corresponding to the allowed string values for the responseType attribute.
228    ResponseTypeCode m_responseTypeCode;
229};
230
231} // namespace WebCore
232
233#endif // XMLHttpRequest_h
234