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 "AtomicStringHash.h" 25 #include "EventListener.h" 26 #include "EventTarget.h" 27 #include "FormData.h" 28 #include "ResourceResponse.h" 29 #include "ScriptString.h" 30 #include "ThreadableLoaderClient.h" 31 #include <wtf/OwnPtr.h> 32 33 namespace WebCore { 34 35 class Document; 36 class File; 37 struct ResourceRequest; 38 class TextResourceDecoder; 39 class ThreadableLoader; 40 41 class XMLHttpRequest : public RefCounted<XMLHttpRequest>, public EventTarget, private ThreadableLoaderClient, public ActiveDOMObject { 42 public: create(ScriptExecutionContext * context)43 static PassRefPtr<XMLHttpRequest> create(ScriptExecutionContext* context) { return adoptRef(new XMLHttpRequest(context)); } 44 ~XMLHttpRequest(); 45 46 // These exact numeric values are important because JS expects them. 47 enum State { 48 UNSENT = 0, 49 OPENED = 1, 50 HEADERS_RECEIVED = 2, 51 LOADING = 3, 52 DONE = 4 53 }; 54 toXMLHttpRequest()55 virtual XMLHttpRequest* toXMLHttpRequest() { return this; } 56 57 virtual void contextDestroyed(); 58 virtual bool canSuspend() const; 59 virtual void stop(); 60 61 virtual ScriptExecutionContext* scriptExecutionContext() const; 62 63 String statusText(ExceptionCode&) const; 64 int status(ExceptionCode&) const; 65 State readyState() const; withCredentials()66 bool withCredentials() const { return m_includeCredentials; } 67 void setWithCredentials(bool, ExceptionCode&); 68 void open(const String& method, const KURL&, bool async, ExceptionCode&); 69 void open(const String& method, const KURL&, bool async, const String& user, ExceptionCode&); 70 void open(const String& method, const KURL&, bool async, const String& user, const String& password, ExceptionCode&); 71 void send(ExceptionCode&); 72 void send(Document*, ExceptionCode&); 73 void send(const String&, ExceptionCode&); 74 void send(File*, ExceptionCode&); 75 void abort(); 76 void setRequestHeader(const AtomicString& name, const String& value, ExceptionCode&); 77 void overrideMimeType(const String& override); 78 String getAllResponseHeaders(ExceptionCode&) const; 79 String getResponseHeader(const AtomicString& name, ExceptionCode&) const; 80 const ScriptString& responseText() const; 81 Document* responseXML() const; setLastSendLineNumber(unsigned lineNumber)82 void setLastSendLineNumber(unsigned lineNumber) { m_lastSendLineNumber = lineNumber; } setLastSendURL(const String & url)83 void setLastSendURL(const String& url) { m_lastSendURL = url; } 84 85 XMLHttpRequestUpload* upload(); optionalUpload()86 XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); } 87 setOnreadystatechange(PassRefPtr<EventListener> eventListener)88 void setOnreadystatechange(PassRefPtr<EventListener> eventListener) { m_onReadyStateChangeListener = eventListener; } onreadystatechange()89 EventListener* onreadystatechange() const { return m_onReadyStateChangeListener.get(); } 90 setOnabort(PassRefPtr<EventListener> eventListener)91 void setOnabort(PassRefPtr<EventListener> eventListener) { m_onAbortListener = eventListener; } onabort()92 EventListener* onabort() const { return m_onAbortListener.get(); } 93 setOnerror(PassRefPtr<EventListener> eventListener)94 void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; } onerror()95 EventListener* onerror() const { return m_onErrorListener.get(); } 96 setOnload(PassRefPtr<EventListener> eventListener)97 void setOnload(PassRefPtr<EventListener> eventListener) { m_onLoadListener = eventListener; } onload()98 EventListener* onload() const { return m_onLoadListener.get(); } 99 setOnloadstart(PassRefPtr<EventListener> eventListener)100 void setOnloadstart(PassRefPtr<EventListener> eventListener) { m_onLoadStartListener = eventListener; } onloadstart()101 EventListener* onloadstart() const { return m_onLoadStartListener.get(); } 102 setOnprogress(PassRefPtr<EventListener> eventListener)103 void setOnprogress(PassRefPtr<EventListener> eventListener) { m_onProgressListener = eventListener; } onprogress()104 EventListener* onprogress() const { return m_onProgressListener.get(); } 105 106 typedef Vector<RefPtr<EventListener> > ListenerVector; 107 typedef HashMap<AtomicString, ListenerVector> EventListenersMap; 108 109 // useCapture is not used, even for add/remove pairing (for Firefox compatibility). 110 virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); 111 virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); 112 virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); eventListeners()113 EventListenersMap& eventListeners() { return m_eventListeners; } 114 115 using RefCounted<XMLHttpRequest>::ref; 116 using RefCounted<XMLHttpRequest>::deref; 117 118 private: 119 XMLHttpRequest(ScriptExecutionContext*); 120 refEventTarget()121 virtual void refEventTarget() { ref(); } derefEventTarget()122 virtual void derefEventTarget() { deref(); } 123 124 Document* document() const; 125 126 #if ENABLE(DASHBOARD_SUPPORT) 127 bool usesDashboardBackwardCompatibilityMode() const; 128 #endif 129 130 virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent); 131 virtual void didReceiveResponse(const ResourceResponse&); 132 virtual void didReceiveData(const char* data, int lengthReceived); 133 virtual void didFinishLoading(unsigned long identifier); 134 virtual void didFail(const ResourceError&); 135 virtual void didFailRedirectCheck(); 136 virtual void didReceiveAuthenticationCancellation(const ResourceResponse&); 137 138 // Special versions for the preflight 139 void didReceiveResponsePreflight(const ResourceResponse&); 140 void didFinishLoadingPreflight(); 141 142 void updateAndDispatchOnProgress(unsigned int len); 143 144 String responseMIMEType() const; 145 bool responseIsXML() const; 146 147 bool initSend(ExceptionCode&); 148 149 String getRequestHeader(const AtomicString& name) const; 150 void setRequestHeaderInternal(const AtomicString& name, const String& value); 151 bool isSafeRequestHeader(const String&) const; 152 153 void changeState(State newState); 154 void callReadyStateChangeListener(); 155 void dropProtection(); 156 void internalAbort(); 157 void clearResponse(); 158 void clearRequest(); 159 160 void createRequest(ExceptionCode&); 161 162 void makeSameOriginRequest(ExceptionCode&); 163 void makeCrossOriginAccessRequest(ExceptionCode&); 164 165 void makeSimpleCrossOriginAccessRequest(ExceptionCode&); 166 void makeCrossOriginAccessRequestWithPreflight(ExceptionCode&); 167 void handleAsynchronousPreflightResult(); 168 169 void loadRequestSynchronously(ResourceRequest&, ExceptionCode&); 170 void loadRequestAsynchronously(ResourceRequest&); 171 172 void genericError(); 173 void networkError(); 174 void abortError(); 175 176 void dispatchReadyStateChangeEvent(); 177 void dispatchXMLHttpRequestProgressEvent(EventListener* listener, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total); 178 void dispatchAbortEvent(); 179 void dispatchErrorEvent(); 180 void dispatchLoadEvent(); 181 void dispatchLoadStartEvent(); 182 void dispatchProgressEvent(long long expectedLength); 183 184 RefPtr<EventListener> m_onReadyStateChangeListener; 185 RefPtr<EventListener> m_onAbortListener; 186 RefPtr<EventListener> m_onErrorListener; 187 RefPtr<EventListener> m_onLoadListener; 188 RefPtr<EventListener> m_onLoadStartListener; 189 RefPtr<EventListener> m_onProgressListener; 190 EventListenersMap m_eventListeners; 191 192 RefPtr<XMLHttpRequestUpload> m_upload; 193 194 KURL m_url; 195 String m_method; 196 HTTPHeaderMap m_requestHeaders; 197 RefPtr<FormData> m_requestEntityBody; 198 String m_mimeTypeOverride; 199 bool m_async; 200 bool m_includeCredentials; 201 202 RefPtr<ThreadableLoader> m_loader; 203 State m_state; 204 205 ResourceResponse m_response; 206 String m_responseEncoding; 207 208 RefPtr<TextResourceDecoder> m_decoder; 209 210 // Unlike most strings in the DOM, we keep this as a ScriptString, not a WebCore::String. 211 // That's because these strings can easily get huge (they are filled from the network with 212 // no parsing) and because JS can easily observe many intermediate states, so it's very useful 213 // to be able to share the buffer with JavaScript versions of the whole or partial string. 214 // In contrast, this string doesn't interact much with the rest of the engine so it's not that 215 // big a cost that it isn't a String. 216 ScriptString m_responseText; 217 mutable bool m_createdDocument; 218 mutable RefPtr<Document> m_responseXML; 219 220 bool m_error; 221 222 bool m_uploadEventsAllowed; 223 bool m_uploadComplete; 224 225 bool m_sameOriginRequest; 226 bool m_allowAccess; 227 bool m_inPreflight; 228 bool m_didTellLoaderAboutRequest; 229 230 // Used for onprogress tracking 231 long long m_receivedLength; 232 233 unsigned m_lastSendLineNumber; 234 String m_lastSendURL; 235 ExceptionCode m_exceptionCode; 236 }; 237 238 } // namespace WebCore 239 240 #endif // XMLHttpRequest_h 241