// -*- c-basic-offset: 2 -*- /* * This file is part of the KDE libraries * Copyright (C) 2003, 2006 Apple Computer, Inc. * Copyright (C) 2005, 2006 Alexey Proskuryakov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef XMLHttpRequest_h #define XMLHttpRequest_h #include "EventTarget.h" #include "HTTPHeaderMap.h" #include "KURL.h" #include "PlatformString.h" #include "ResourceResponse.h" #include "StringHash.h" #include "SubresourceLoaderClient.h" #include #include #include namespace WebCore { class TextResourceDecoder; class Document; class Event; class EventListener; class String; typedef int ExceptionCode; const int XMLHttpRequestExceptionOffset = 500; const int XMLHttpRequestExceptionMax = 699; enum XMLHttpRequestExceptionCode { PERMISSION_DENIED = XMLHttpRequestExceptionOffset, // Use SECURITY_ERR when that's in DOM Core, http://bugs.webkit.org/show_bug.cgi?id=12182 NETWORK_ERR = XMLHttpRequestExceptionOffset + 101 }; // these exact numeric values are important because JS expects them enum XMLHttpRequestState { Uninitialized = 0, // The initial value. Open = 1, // The open() method has been successfully called. Sent = 2, // The user agent successfully completed the request, but no data has yet been received. Receiving = 3, // Immediately before receiving the message body (if any). All HTTP headers have been received. Loaded = 4 // The data transfer has been completed. }; class XMLHttpRequest : public RefCounted, public EventTarget, private SubresourceLoaderClient { public: XMLHttpRequest(Document*); ~XMLHttpRequest(); virtual XMLHttpRequest* toXMLHttpRequest() { return this; } static void detachRequests(Document*); static void cancelRequests(Document*); String getStatusText(ExceptionCode&) const; int getStatus(ExceptionCode&) const; XMLHttpRequestState getReadyState() const; void open(const String& method, const KURL&, bool async, ExceptionCode&); void open(const String& method, const KURL&, bool async, const String& user, ExceptionCode&); void open(const String& method, const KURL&, bool async, const String& user, const String& password, ExceptionCode&); void send(const String& body, ExceptionCode&); void abort(); void setRequestHeader(const String& name, const String& value, ExceptionCode&); void overrideMIMEType(const String& override); String getAllResponseHeaders(ExceptionCode&) const; String getResponseHeader(const String& name, ExceptionCode&) const; const KJS::UString& getResponseText(ExceptionCode&) const; Document* getResponseXML(ExceptionCode&) const; void setOnReadyStateChangeListener(EventListener*); EventListener* onReadyStateChangeListener() const; void setOnLoadListener(EventListener*); EventListener* onLoadListener() const; typedef Vector > ListenerVector; typedef HashMap EventListenersMap; // useCapture is not used, even for add/remove pairing (for Firefox compatibility). virtual void addEventListener(const AtomicString& eventType, PassRefPtr, bool useCapture); virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); virtual bool dispatchEvent(PassRefPtr, ExceptionCode&, bool tempEvent = false); EventListenersMap& eventListeners() { return m_eventListeners; } Document* document() const { return m_doc; } using RefCounted::ref; using RefCounted::deref; private: virtual void refEventTarget() { ref(); } virtual void derefEventTarget() { deref(); } bool urlMatchesDocumentDomain(const KURL&) const; virtual void willSendRequest(SubresourceLoader*, ResourceRequest& request, const ResourceResponse& redirectResponse); virtual void didReceiveResponse(SubresourceLoader*, const ResourceResponse&); virtual void didReceiveData(SubresourceLoader*, const char* data, int size); virtual void didFail(SubresourceLoader*, const ResourceError&); virtual void didFinishLoading(SubresourceLoader*); virtual void receivedCancellation(SubresourceLoader*, const AuthenticationChallenge&); void processSyncLoadResults(const Vector& data, const ResourceResponse&); String responseMIMEType() const; bool responseIsXML() const; String getRequestHeader(const String& name) const; void changeState(XMLHttpRequestState newState); void callReadyStateChangeListener(); void dropProtection(); Document* m_doc; RefPtr m_onReadyStateChangeListener; RefPtr m_onLoadListener; EventListenersMap m_eventListeners; KURL m_url; DeprecatedString m_method; HTTPHeaderMap m_requestHeaders; String m_mimeTypeOverride; bool m_async; RefPtr m_loader; XMLHttpRequestState m_state; ResourceResponse m_response; String m_encoding; RefPtr m_decoder; // Unlike most strings in the DOM, we keep this as a KJS::UString, not a WebCore::String. // That's because these strings can easily get huge (they are filled from the network with // no parsing) and because JS can easily observe many intermediate states, so it's very useful // to be able to share the buffer with JavaScript versions of the whole or partial string. // In contrast, this string doesn't interact much with the rest of the engine so it's not that // big a cost that it isn't a String. KJS::UString m_responseText; mutable bool m_createdDocument; mutable RefPtr m_responseXML; bool m_aborted; }; } // namespace WebCore #endif // XMLHttpRequest_h