1 /* 2 * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2005, 2006 Alexey Proskuryakov <ap (at) 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/v8/ScriptString.h" 26 #include "bindings/v8/ScriptWrappable.h" 27 #include "core/dom/ActiveDOMObject.h" 28 #include "core/events/EventListener.h" 29 #include "core/events/ThreadLocalEventNames.h" 30 #include "core/loader/ThreadableLoaderClient.h" 31 #include "core/xml/XMLHttpRequestEventTarget.h" 32 #include "core/xml/XMLHttpRequestProgressEventThrottle.h" 33 #include "platform/AsyncMethodRunner.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 41 namespace WebCore { 42 43 class Blob; 44 class DOMFormData; 45 class Document; 46 class ExceptionState; 47 class ResourceRequest; 48 class SecurityOrigin; 49 class SharedBuffer; 50 class Stream; 51 class TextResourceDecoder; 52 class ThreadableLoader; 53 54 typedef int ExceptionCode; 55 56 class XMLHttpRequest : public ScriptWrappable, public RefCounted<XMLHttpRequest>, public XMLHttpRequestEventTarget, private ThreadableLoaderClient, public ActiveDOMObject { 57 WTF_MAKE_FAST_ALLOCATED; 58 REFCOUNTED_EVENT_TARGET(XMLHttpRequest); 59 public: 60 static PassRefPtr<XMLHttpRequest> create(ExecutionContext*, PassRefPtr<SecurityOrigin> = 0); 61 ~XMLHttpRequest(); 62 63 // These exact numeric values are important because JS expects them. 64 enum State { 65 UNSENT = 0, 66 OPENED = 1, 67 HEADERS_RECEIVED = 2, 68 LOADING = 3, 69 DONE = 4 70 }; 71 72 enum ResponseTypeCode { 73 ResponseTypeDefault, 74 ResponseTypeText, 75 ResponseTypeJSON, 76 ResponseTypeDocument, 77 ResponseTypeBlob, 78 ResponseTypeArrayBuffer, 79 ResponseTypeStream 80 }; 81 82 enum DropProtection { 83 DropProtectionSync, 84 DropProtectionAsync, 85 }; 86 87 virtual void contextDestroyed(); 88 virtual void suspend(); 89 virtual void resume(); 90 virtual void stop(); 91 92 virtual const AtomicString& interfaceName() const OVERRIDE; 93 virtual ExecutionContext* executionContext() const OVERRIDE; 94 95 const KURL& url() const { return m_url; } 96 String statusText() const; 97 int status() const; 98 State readyState() const; 99 bool withCredentials() const { return m_includeCredentials; } 100 void setWithCredentials(bool, ExceptionState&); 101 void open(const AtomicString& method, const KURL&, ExceptionState&); 102 void open(const AtomicString& method, const KURL&, bool async, ExceptionState&); 103 void open(const AtomicString& method, const KURL&, bool async, const String& user, ExceptionState&); 104 void open(const AtomicString& method, const KURL&, bool async, const String& user, const String& password, ExceptionState&); 105 void send(ExceptionState&); 106 void send(Document*, ExceptionState&); 107 void send(const String&, ExceptionState&); 108 void send(Blob*, ExceptionState&); 109 void send(DOMFormData*, ExceptionState&); 110 void send(ArrayBuffer*, ExceptionState&); 111 void send(ArrayBufferView*, ExceptionState&); 112 void abort(); 113 void setRequestHeader(const AtomicString& name, const AtomicString& value, ExceptionState&); 114 void overrideMimeType(const AtomicString& override); 115 String getAllResponseHeaders() const; 116 const AtomicString& getResponseHeader(const AtomicString&) const; 117 ScriptString responseText(ExceptionState&); 118 ScriptString responseJSONSource(); 119 Document* responseXML(ExceptionState&); 120 Blob* responseBlob(); 121 Stream* responseStream(); 122 unsigned long timeout() const { return m_timeoutMilliseconds; } 123 void setTimeout(unsigned long timeout, ExceptionState&); 124 125 void sendForInspectorXHRReplay(PassRefPtr<FormData>, ExceptionState&); 126 127 // Expose HTTP validation methods for other untrusted requests. 128 static bool isAllowedHTTPMethod(const String&); 129 static AtomicString uppercaseKnownHTTPMethod(const AtomicString&); 130 static bool isAllowedHTTPHeader(const String&); 131 132 void setResponseType(const String&, ExceptionState&); 133 String responseType(); 134 ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; } 135 136 // response attribute has custom getter. 137 ArrayBuffer* responseArrayBuffer(); 138 139 void setLastSendLineNumber(unsigned lineNumber) { m_lastSendLineNumber = lineNumber; } 140 void setLastSendURL(const String& url) { m_lastSendURL = url; } 141 142 XMLHttpRequestUpload* upload(); 143 144 DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange); 145 146 private: 147 XMLHttpRequest(ExecutionContext*, PassRefPtr<SecurityOrigin>); 148 149 Document* document() const; 150 SecurityOrigin* securityOrigin() const; 151 152 virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent); 153 virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&); 154 virtual void didReceiveData(const char* data, int dataLength); 155 // When "blob" is specified as the responseType attribute, didDownloadData 156 // is called instead of didReceiveData. 157 virtual void didDownloadData(int dataLength); 158 virtual void didFinishLoading(unsigned long identifier, double finishTime); 159 virtual void didFail(const ResourceError&); 160 virtual void didFailRedirectCheck(); 161 162 AtomicString responseMIMEType() const; 163 bool responseIsXML() const; 164 165 bool areMethodAndURLValidForSend(); 166 167 bool initSend(ExceptionState&); 168 void sendBytesData(const void*, size_t, ExceptionState&); 169 170 const AtomicString& getRequestHeader(const AtomicString& name) const; 171 void setRequestHeaderInternal(const AtomicString& name, const AtomicString& value); 172 173 void trackProgress(int dataLength); 174 // Changes m_state and dispatches a readyStateChange event if new m_state 175 // value is different from last one. 176 void changeState(State newState); 177 void dispatchReadyStateChangeEvent(); 178 179 void dropProtectionSoon(); 180 void dropProtection(); 181 // Clears variables used only while the resource is being loaded. 182 void clearVariablesForLoading(); 183 // Returns false iff reentry happened and a new load is started. 184 bool internalAbort(DropProtection = DropProtectionSync); 185 // Clears variables holding response header and body data. 186 void clearResponse(); 187 void clearRequest(); 188 189 void createRequest(ExceptionState&); 190 191 // Dispatches an event of the specified type to m_progressEventThrottle. 192 void dispatchEventAndLoadEnd(const AtomicString&, long long, long long); 193 194 // Dispatches a response progress event to m_progressEventThrottle. 195 void dispatchThrottledProgressEvent(const AtomicString&, long long, long long); 196 197 // Dispatches a response progress event using values sampled from 198 // m_receivedLength and m_response. 199 void dispatchThrottledProgressEventSnapshot(const AtomicString&); 200 201 // Does clean up common for all kind of didFail() call. 202 void handleDidFailGeneric(); 203 // Handles didFail() call not caused by cancellation or timeout. 204 void handleNetworkError(); 205 // Handles didFail() call triggered by m_loader->cancel(). 206 void handleDidCancel(); 207 // Handles didFail() call for timeout. 208 void handleDidTimeout(); 209 210 void handleRequestError(ExceptionCode, const AtomicString&, long long, long long); 211 212 OwnPtr<XMLHttpRequestUpload> m_upload; 213 214 KURL m_url; 215 AtomicString m_method; 216 HTTPHeaderMap m_requestHeaders; 217 RefPtr<FormData> m_requestEntityBody; 218 AtomicString m_mimeTypeOverride; 219 bool m_async; 220 bool m_includeCredentials; 221 unsigned long m_timeoutMilliseconds; 222 RefPtr<Blob> m_responseBlob; 223 RefPtr<Stream> m_responseStream; 224 225 RefPtr<ThreadableLoader> m_loader; 226 State m_state; 227 228 ResourceResponse m_response; 229 String m_responseEncoding; 230 231 OwnPtr<TextResourceDecoder> m_decoder; 232 233 ScriptString m_responseText; 234 // Used to skip m_responseDocument creation if it's done previously. We need 235 // this separate flag since m_responseDocument can be 0 for some cases. 236 bool m_createdDocument; 237 RefPtr<Document> m_responseDocument; 238 239 RefPtr<SharedBuffer> m_binaryResponseBuilder; 240 long long m_downloadedBlobLength; 241 RefPtr<ArrayBuffer> m_responseArrayBuffer; 242 243 bool m_error; 244 245 bool m_uploadEventsAllowed; 246 bool m_uploadComplete; 247 248 bool m_sameOriginRequest; 249 250 // Used for onprogress tracking 251 long long m_receivedLength; 252 253 unsigned m_lastSendLineNumber; 254 String m_lastSendURL; 255 // An exception to throw in synchronous mode. It's set when failure 256 // notification is received from m_loader and thrown at the end of send() if 257 // any. 258 ExceptionCode m_exceptionCode; 259 260 XMLHttpRequestProgressEventThrottle m_progressEventThrottle; 261 262 // An enum corresponding to the allowed string values for the responseType attribute. 263 ResponseTypeCode m_responseTypeCode; 264 AsyncMethodRunner<XMLHttpRequest> m_dropProtectionRunner; 265 RefPtr<SecurityOrigin> m_securityOrigin; 266 }; 267 268 } // namespace WebCore 269 270 #endif // XMLHttpRequest_h 271