1/*
2 *  Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
3 *  Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@nypop.com>
4 *  Copyright (C) 2011 Google Inc. All rights reserved.
5 *  Copyright (C) 2012 Intel Corporation
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22#ifndef XMLHttpRequest_h
23#define XMLHttpRequest_h
24
25#include "bindings/core/v8/ScriptString.h"
26#include "core/dom/ActiveDOMObject.h"
27#include "core/dom/DocumentParserClient.h"
28#include "core/events/EventListener.h"
29#include "core/loader/ThreadableLoaderClient.h"
30#include "core/streams/ReadableStreamImpl.h"
31#include "core/xml/XMLHttpRequestEventTarget.h"
32#include "core/xml/XMLHttpRequestProgressEventThrottle.h"
33#include "platform/heap/Handle.h"
34#include "platform/network/FormData.h"
35#include "platform/network/ResourceResponse.h"
36#include "platform/weborigin/SecurityOrigin.h"
37#include "wtf/OwnPtr.h"
38#include "wtf/text/AtomicStringHash.h"
39#include "wtf/text/StringBuilder.h"
40
41namespace blink {
42
43class Blob;
44class DOMFormData;
45class Document;
46class DocumentParser;
47class ExceptionState;
48class ResourceRequest;
49class SecurityOrigin;
50class SharedBuffer;
51class Stream;
52class TextResourceDecoder;
53class ThreadableLoader;
54class UnderlyingSource;
55
56typedef int ExceptionCode;
57
58class XMLHttpRequest FINAL
59    : public RefCountedWillBeGarbageCollectedFinalized<XMLHttpRequest>
60    , public XMLHttpRequestEventTarget
61    , private ThreadableLoaderClient
62    , public DocumentParserClient
63    , public ActiveDOMObject {
64    DEFINE_WRAPPERTYPEINFO();
65    REFCOUNTED_EVENT_TARGET(XMLHttpRequest);
66    WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(XMLHttpRequest);
67    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
68public:
69    static PassRefPtrWillBeRawPtr<XMLHttpRequest> create(ExecutionContext*, PassRefPtr<SecurityOrigin> = nullptr);
70    virtual ~XMLHttpRequest();
71
72    // These exact numeric values are important because JS expects them.
73    enum State {
74        UNSENT = 0,
75        OPENED = 1,
76        HEADERS_RECEIVED = 2,
77        LOADING = 3,
78        DONE = 4
79    };
80
81    enum ResponseTypeCode {
82        ResponseTypeDefault,
83        ResponseTypeText,
84        ResponseTypeJSON,
85        ResponseTypeDocument,
86        ResponseTypeBlob,
87        ResponseTypeArrayBuffer,
88        ResponseTypeLegacyStream,
89        ResponseTypeStream,
90    };
91
92    virtual void contextDestroyed() OVERRIDE;
93    virtual void suspend() OVERRIDE;
94    virtual void resume() OVERRIDE;
95    virtual void stop() OVERRIDE;
96    virtual bool hasPendingActivity() const OVERRIDE;
97
98    virtual const AtomicString& interfaceName() const OVERRIDE;
99    virtual ExecutionContext* executionContext() const OVERRIDE;
100
101    const KURL& url() const { return m_url; }
102    String statusText() const;
103    int status() const;
104    State readyState() const;
105    bool withCredentials() const { return m_includeCredentials; }
106    void setWithCredentials(bool, ExceptionState&);
107    void open(const AtomicString& method, const KURL&, ExceptionState&);
108    void open(const AtomicString& method, const KURL&, bool async, ExceptionState&);
109    void open(const AtomicString& method, const KURL&, bool async, const String& user, ExceptionState&);
110    void open(const AtomicString& method, const KURL&, bool async, const String& user, const String& password, ExceptionState&);
111    void send(ExceptionState&);
112    void send(Document*, ExceptionState&);
113    void send(const String&, ExceptionState&);
114    void send(Blob*, ExceptionState&);
115    void send(DOMFormData*, ExceptionState&);
116    void send(ArrayBuffer*, ExceptionState&);
117    void send(ArrayBufferView*, ExceptionState&);
118    void abort();
119    void setRequestHeader(const AtomicString& name, const AtomicString& value, ExceptionState&);
120    void overrideMimeType(const AtomicString& override, ExceptionState&);
121    String getAllResponseHeaders() const;
122    const AtomicString& getResponseHeader(const AtomicString&) const;
123    ScriptString responseText(ExceptionState&);
124    ScriptString responseJSONSource();
125    Document* responseXML(ExceptionState&);
126    Blob* responseBlob();
127    Stream* responseLegacyStream();
128    ReadableStream* responseStream();
129    unsigned long timeout() const { return m_timeoutMilliseconds; }
130    void setTimeout(unsigned long timeout, ExceptionState&);
131
132    void sendForInspectorXHRReplay(PassRefPtr<FormData>, ExceptionState&);
133
134    // Expose HTTP validation methods for other untrusted requests.
135    static AtomicString uppercaseKnownHTTPMethod(const AtomicString&);
136
137    void setResponseType(const String&, ExceptionState&);
138    String responseType();
139    ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; }
140
141    String responseURL();
142
143    // response attribute has custom getter.
144    ArrayBuffer* responseArrayBuffer();
145
146    void setLastSendLineNumber(unsigned lineNumber) { m_lastSendLineNumber = lineNumber; }
147    void setLastSendURL(const String& url) { m_lastSendURL = url; }
148
149    XMLHttpRequestUpload* upload();
150
151    DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
152
153    virtual void trace(Visitor*) OVERRIDE;
154
155private:
156    XMLHttpRequest(ExecutionContext*, PassRefPtr<SecurityOrigin>);
157
158    Document* document() const;
159    SecurityOrigin* securityOrigin() const;
160
161    virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
162    virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) OVERRIDE;
163    virtual void didReceiveData(const char* data, int dataLength) OVERRIDE;
164    // When responseType is set to "blob", didDownloadData() is called instead
165    // of didReceiveData().
166    virtual void didDownloadData(int dataLength) OVERRIDE;
167    virtual void didFinishLoading(unsigned long identifier, double finishTime) OVERRIDE;
168    virtual void didFail(const ResourceError&) OVERRIDE;
169    virtual void didFailRedirectCheck() OVERRIDE;
170
171    // DocumentParserClient
172    virtual void notifyParserStopped() OVERRIDE;
173
174    void endLoading();
175
176    // Returns the MIME type part of m_mimeTypeOverride if present and
177    // successfully parsed, or returns one of the "Content-Type" header value
178    // of the received response.
179    //
180    // This method is named after the term "final MIME type" defined in the
181    // spec but doesn't convert the result to ASCII lowercase as specified in
182    // the spec. Must be lowered later or compared using case insensitive
183    // comparison functions if required.
184    AtomicString finalResponseMIMEType() const;
185    // The same as finalResponseMIMEType() but fallbacks to "text/xml" if
186    // finalResponseMIMEType() returns an empty string.
187    AtomicString finalResponseMIMETypeWithFallback() const;
188    bool responseIsXML() const;
189    bool responseIsHTML() const;
190
191    PassOwnPtr<TextResourceDecoder> createDecoder() const;
192
193    void initResponseDocument();
194    void parseDocumentChunk(const char* data, int dataLength);
195
196    bool areMethodAndURLValidForSend();
197
198    bool initSend(ExceptionState&);
199    void sendBytesData(const void*, size_t, ExceptionState&);
200
201    const AtomicString& getRequestHeader(const AtomicString& name) const;
202    void setRequestHeaderInternal(const AtomicString& name, const AtomicString& value);
203
204    void trackProgress(int dataLength);
205    // Changes m_state and dispatches a readyStateChange event if new m_state
206    // value is different from last one.
207    void changeState(State newState);
208    void dispatchReadyStateChangeEvent();
209
210    // Clears variables used only while the resource is being loaded.
211    void clearVariablesForLoading();
212    // Returns false iff reentry happened and a new load is started.
213    bool internalAbort();
214    // Clears variables holding response header and body data.
215    void clearResponse();
216    void clearRequest();
217
218    void createRequest(PassRefPtr<FormData>, ExceptionState&);
219
220    // Dispatches a response ProgressEvent.
221    void dispatchProgressEvent(const AtomicString&, long long, long long);
222    // Dispatches a response ProgressEvent using values sampled from
223    // m_receivedLength and m_response.
224    void dispatchProgressEventFromSnapshot(const AtomicString&);
225
226    // Handles didFail() call not caused by cancellation or timeout.
227    void handleNetworkError();
228    // Handles didFail() call for cancellations. For example, the
229    // ResourceLoader handling the load notifies m_loader of an error
230    // cancellation when the frame containing the XHR navigates away.
231    void handleDidCancel();
232    // Handles didFail() call for timeout.
233    void handleDidTimeout();
234
235    void handleRequestError(ExceptionCode, const AtomicString&, long long, long long);
236
237    OwnPtrWillBeMember<XMLHttpRequestUpload> m_upload;
238
239    KURL m_url;
240    AtomicString m_method;
241    HTTPHeaderMap m_requestHeaders;
242    // Not converted to ASCII lowercase. Must be lowered later or compared
243    // using case insensitive comparison functions if needed.
244    AtomicString m_mimeTypeOverride;
245    unsigned long m_timeoutMilliseconds;
246    RefPtrWillBeMember<Blob> m_responseBlob;
247    RefPtrWillBeMember<Stream> m_responseLegacyStream;
248    PersistentWillBeMember<ReadableStreamImpl<ReadableStreamChunkTypeTraits<ArrayBuffer> > > m_responseStream;
249    PersistentWillBeMember<UnderlyingSource> m_streamSource;
250
251    RefPtr<ThreadableLoader> m_loader;
252    unsigned long m_loaderIdentifier;
253    State m_state;
254
255    ResourceResponse m_response;
256    String m_finalResponseCharset;
257
258    OwnPtr<TextResourceDecoder> m_decoder;
259
260    ScriptString m_responseText;
261    RefPtrWillBeMember<Document> m_responseDocument;
262    RefPtrWillBeMember<DocumentParser> m_responseDocumentParser;
263
264    RefPtr<SharedBuffer> m_binaryResponseBuilder;
265    long long m_lengthDownloadedToFile;
266
267    RefPtr<ArrayBuffer> m_responseArrayBuffer;
268
269    // Used for onprogress tracking
270    long long m_receivedLength;
271
272    unsigned m_lastSendLineNumber;
273    String m_lastSendURL;
274    // An exception to throw in synchronous mode. It's set when failure
275    // notification is received from m_loader and thrown at the end of send() if
276    // any.
277    ExceptionCode m_exceptionCode;
278
279    XMLHttpRequestProgressEventThrottle m_progressEventThrottle;
280
281    // An enum corresponding to the allowed string values for the responseType attribute.
282    ResponseTypeCode m_responseTypeCode;
283    RefPtr<SecurityOrigin> m_securityOrigin;
284
285    bool m_async;
286    bool m_includeCredentials;
287    // Used to skip m_responseDocument creation if it's done previously. We need
288    // this separate flag since m_responseDocument can be 0 for some cases.
289    bool m_parsedResponse;
290    bool m_error;
291    bool m_uploadEventsAllowed;
292    bool m_uploadComplete;
293    bool m_sameOriginRequest;
294    // True iff the ongoing resource loading is using the downloadToFile
295    // option.
296    bool m_downloadingToFile;
297};
298
299} // namespace blink
300
301#endif // XMLHttpRequest_h
302