Home | History | Annotate | Download | only in xml
      1 /*
      2  *  Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
      3  *  Copyright (C) 2005, 2006 Alexey Proskuryakov <ap (at) 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 "AtomicStringHash.h"
     25 #include "EventListener.h"
     26 #include "EventNames.h"
     27 #include "EventTarget.h"
     28 #include "FormData.h"
     29 #include "ResourceResponse.h"
     30 #include "ScriptString.h"
     31 #include "ThreadableLoaderClient.h"
     32 #include <wtf/OwnPtr.h>
     33 
     34 namespace WebCore {
     35 
     36 class Blob;
     37 class Document;
     38 class ResourceRequest;
     39 class TextResourceDecoder;
     40 class ThreadableLoader;
     41 
     42 class XMLHttpRequest : public RefCounted<XMLHttpRequest>, public EventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
     43 public:
     44     static PassRefPtr<XMLHttpRequest> create(ScriptExecutionContext* context) { return adoptRef(new XMLHttpRequest(context)); }
     45     ~XMLHttpRequest();
     46 
     47     // These exact numeric values are important because JS expects them.
     48     enum State {
     49         UNSENT = 0,
     50         OPENED = 1,
     51         HEADERS_RECEIVED = 2,
     52         LOADING = 3,
     53         DONE = 4
     54     };
     55 
     56     virtual XMLHttpRequest* toXMLHttpRequest() { return this; }
     57 
     58     virtual void contextDestroyed();
     59     virtual bool canSuspend() const;
     60     virtual void stop();
     61 
     62     virtual ScriptExecutionContext* scriptExecutionContext() const;
     63 
     64     String statusText(ExceptionCode&) const;
     65     int status(ExceptionCode&) const;
     66     State readyState() const;
     67     bool withCredentials() const { return m_includeCredentials; }
     68     void setWithCredentials(bool, ExceptionCode&);
     69     void open(const String& method, const KURL&, bool async, ExceptionCode&);
     70     void open(const String& method, const KURL&, bool async, const String& user, ExceptionCode&);
     71     void open(const String& method, const KURL&, bool async, const String& user, const String& password, ExceptionCode&);
     72     void send(ExceptionCode&);
     73     void send(Document*, ExceptionCode&);
     74     void send(const String&, ExceptionCode&);
     75     void send(Blob*, ExceptionCode&);
     76     void abort();
     77     void setRequestHeader(const AtomicString& name, const String& value, ExceptionCode&);
     78     void overrideMimeType(const String& override);
     79     String getAllResponseHeaders(ExceptionCode&) const;
     80     String getResponseHeader(const AtomicString& name, ExceptionCode&) const;
     81     const ScriptString& responseText() const;
     82     Document* responseXML() const;
     83     void setLastSendLineNumber(unsigned lineNumber) { m_lastSendLineNumber = lineNumber; }
     84     void setLastSendURL(const String& url) { m_lastSendURL = url; }
     85 
     86     XMLHttpRequestUpload* upload();
     87     XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); }
     88 
     89     DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
     90     DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
     91     DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
     92     DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
     93     DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
     94     DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
     95 
     96     using RefCounted<XMLHttpRequest>::ref;
     97     using RefCounted<XMLHttpRequest>::deref;
     98 
     99 private:
    100     XMLHttpRequest(ScriptExecutionContext*);
    101 
    102     virtual void refEventTarget() { ref(); }
    103     virtual void derefEventTarget() { deref(); }
    104     virtual EventTargetData* eventTargetData();
    105     virtual EventTargetData* ensureEventTargetData();
    106 
    107     Document* document() const;
    108 
    109 #if ENABLE(DASHBOARD_SUPPORT)
    110     bool usesDashboardBackwardCompatibilityMode() const;
    111 #endif
    112 
    113     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
    114     virtual void didReceiveResponse(const ResourceResponse&);
    115     virtual void didReceiveData(const char* data, int lengthReceived);
    116     virtual void didFinishLoading(unsigned long identifier);
    117     virtual void didFail(const ResourceError&);
    118     virtual void didFailRedirectCheck();
    119     virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
    120 
    121     String responseMIMEType() const;
    122     bool responseIsXML() const;
    123 
    124     bool initSend(ExceptionCode&);
    125 
    126     String getRequestHeader(const AtomicString& name) const;
    127     void setRequestHeaderInternal(const AtomicString& name, const String& value);
    128     bool isSafeRequestHeader(const String&) const;
    129 
    130     void changeState(State newState);
    131     void callReadyStateChangeListener();
    132     void dropProtection();
    133     void internalAbort();
    134     void clearResponse();
    135     void clearRequest();
    136 
    137     void createRequest(ExceptionCode&);
    138 
    139     void genericError();
    140     void networkError();
    141     void abortError();
    142 
    143     RefPtr<XMLHttpRequestUpload> m_upload;
    144 
    145     KURL m_url;
    146     String m_method;
    147     HTTPHeaderMap m_requestHeaders;
    148     RefPtr<FormData> m_requestEntityBody;
    149     String m_mimeTypeOverride;
    150     bool m_async;
    151     bool m_includeCredentials;
    152 
    153     RefPtr<ThreadableLoader> m_loader;
    154     State m_state;
    155 
    156     ResourceResponse m_response;
    157     String m_responseEncoding;
    158 
    159     RefPtr<TextResourceDecoder> m_decoder;
    160 
    161     // Unlike most strings in the DOM, we keep this as a ScriptString, not a WebCore::String.
    162     // That's because these strings can easily get huge (they are filled from the network with
    163     // no parsing) and because JS can easily observe many intermediate states, so it's very useful
    164     // to be able to share the buffer with JavaScript versions of the whole or partial string.
    165     // In contrast, this string doesn't interact much with the rest of the engine so it's not that
    166     // big a cost that it isn't a String.
    167     ScriptString m_responseText;
    168     mutable bool m_createdDocument;
    169     mutable RefPtr<Document> m_responseXML;
    170 
    171     bool m_error;
    172 
    173     bool m_uploadEventsAllowed;
    174     bool m_uploadComplete;
    175 
    176     bool m_sameOriginRequest;
    177     bool m_didTellLoaderAboutRequest;
    178 
    179     // Used for onprogress tracking
    180     long long m_receivedLength;
    181 
    182     unsigned m_lastSendLineNumber;
    183     String m_lastSendURL;
    184     ExceptionCode m_exceptionCode;
    185 
    186     EventTargetData m_eventTargetData;
    187 };
    188 
    189 } // namespace WebCore
    190 
    191 #endif // XMLHttpRequest_h
    192