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 "ActiveDOMObject.h" 26#include "EventListener.h" 27#include "EventNames.h" 28#include "EventTarget.h" 29#include "FormData.h" 30#include "ResourceResponse.h" 31#include "ScriptWrappable.h" 32#include "ThreadableLoaderClient.h" 33#include "XMLHttpRequestProgressEventThrottle.h" 34#include <wtf/text/AtomicStringHash.h> 35#include <wtf/text/StringBuilder.h> 36 37namespace JSC { 38class ArrayBuffer; 39class ArrayBufferView; 40} 41 42namespace WebCore { 43 44class Blob; 45class Document; 46class DOMFormData; 47class ResourceRequest; 48class SecurityOrigin; 49class SharedBuffer; 50class TextResourceDecoder; 51class ThreadableLoader; 52 53class XMLHttpRequest final : public ScriptWrappable, public RefCounted<XMLHttpRequest>, public EventTargetWithInlineData, private ThreadableLoaderClient, public ActiveDOMObject { 54 WTF_MAKE_FAST_ALLOCATED; 55public: 56 static PassRefPtr<XMLHttpRequest> create(ScriptExecutionContext&); 57 ~XMLHttpRequest(); 58 59 // These exact numeric values are important because JS expects them. 60 enum State { 61 UNSENT = 0, 62 OPENED = 1, 63 HEADERS_RECEIVED = 2, 64 LOADING = 3, 65 DONE = 4 66 }; 67 68 enum ResponseTypeCode { 69 ResponseTypeDefault, 70 ResponseTypeText, 71 ResponseTypeJSON, 72 ResponseTypeDocument, 73 74 // Binary format 75 ResponseTypeBlob, 76 ResponseTypeArrayBuffer 77 }; 78 static const ResponseTypeCode FirstBinaryResponseType = ResponseTypeBlob; 79 80#if ENABLE(XHR_TIMEOUT) 81 virtual void didTimeout(); 82#endif 83 84 virtual EventTargetInterface eventTargetInterface() const override { return XMLHttpRequestEventTargetInterfaceType; } 85 virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); } 86 87 const URL& url() const { return m_url; } 88 String statusText() const; 89 int status() const; 90 State readyState() const; 91 bool withCredentials() const { return m_includeCredentials; } 92 void setWithCredentials(bool, ExceptionCode&); 93 void open(const String& method, const URL&, ExceptionCode&); 94 void open(const String& method, const URL&, bool async, ExceptionCode&); 95 void open(const String& method, const URL&, bool async, const String& user, ExceptionCode&); 96 void open(const String& method, const URL&, bool async, const String& user, const String& password, ExceptionCode&); 97 void send(ExceptionCode&); 98 void send(Document*, ExceptionCode&); 99 void send(const String&, ExceptionCode&); 100 void send(Blob*, ExceptionCode&); 101 void send(DOMFormData*, ExceptionCode&); 102 void send(JSC::ArrayBuffer*, ExceptionCode&); 103 void send(JSC::ArrayBufferView*, ExceptionCode&); 104 void abort(); 105 void setRequestHeader(const String& name, const String& value, ExceptionCode&); 106 void overrideMimeType(const String& override); 107 bool doneWithoutErrors() const { return !m_error && m_state == DONE; } 108 String getAllResponseHeaders() const; 109 String getResponseHeader(const String& name) const; 110 String responseText(ExceptionCode&); 111 String responseTextIgnoringResponseType() const { return m_responseBuilder.toStringPreserveCapacity(); } 112 String responseMIMEType() const; 113 Document* responseXML(ExceptionCode&); 114 Document* optionalResponseXML() const { return m_responseDocument.get(); } 115 Blob* responseBlob(); 116 Blob* optionalResponseBlob() const { return m_responseBlob.get(); } 117#if ENABLE(XHR_TIMEOUT) 118 unsigned long timeout() const { return m_timeoutMilliseconds; } 119 void setTimeout(unsigned long timeout, ExceptionCode&); 120#endif 121 122 bool responseCacheIsValid() const { return m_responseCacheIsValid; } 123 void didCacheResponseJSON(); 124 125 void sendForInspectorXHRReplay(PassRefPtr<FormData>, ExceptionCode&); 126 127 // Expose HTTP validation methods for other untrusted requests. 128 static bool isAllowedHTTPMethod(const String&); 129 static String uppercaseKnownHTTPMethod(const String&); 130 static bool isAllowedHTTPHeader(const String&); 131 132 void setResponseType(const String&, ExceptionCode&); 133 String responseType(); 134 ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; } 135 136 // response attribute has custom getter. 137 JSC::ArrayBuffer* responseArrayBuffer(); 138 JSC::ArrayBuffer* optionalResponseArrayBuffer() const { return m_responseArrayBuffer.get(); } 139 140 void setLastSendLineAndColumnNumber(unsigned lineNumber, unsigned columnNumber); 141 void setLastSendURL(const String& url) { m_lastSendURL = url; } 142 143 XMLHttpRequestUpload* upload(); 144 XMLHttpRequestUpload* optionalUpload() const { return m_upload.get(); } 145 146 DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange); 147 DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); 148 DEFINE_ATTRIBUTE_EVENT_LISTENER(error); 149 DEFINE_ATTRIBUTE_EVENT_LISTENER(load); 150 DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend); 151 DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart); 152 DEFINE_ATTRIBUTE_EVENT_LISTENER(progress); 153#if ENABLE(XHR_TIMEOUT) 154 DEFINE_ATTRIBUTE_EVENT_LISTENER(timeout); 155#endif 156 157 using RefCounted<XMLHttpRequest>::ref; 158 using RefCounted<XMLHttpRequest>::deref; 159 160private: 161 explicit XMLHttpRequest(ScriptExecutionContext&); 162 163 // ActiveDOMObject 164 virtual void contextDestroyed() override; 165 virtual bool canSuspend() const override; 166 virtual void suspend(ReasonForSuspension) override; 167 virtual void resume() override; 168 virtual void stop() override; 169 170 virtual void refEventTarget() override { ref(); } 171 virtual void derefEventTarget() override { deref(); } 172 173 Document* document() const; 174 SecurityOrigin* securityOrigin() const; 175 176#if ENABLE(DASHBOARD_SUPPORT) 177 bool usesDashboardBackwardCompatibilityMode() const; 178#endif 179 180 virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override; 181 virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override; 182 virtual void didReceiveData(const char* data, int dataLength) override; 183 virtual void didFinishLoading(unsigned long identifier, double finishTime) override; 184 virtual void didFail(const ResourceError&) override; 185 virtual void didFailRedirectCheck() override; 186 187 bool responseIsXML() const; 188 189 bool initSend(ExceptionCode&); 190 void sendBytesData(const void*, size_t, ExceptionCode&); 191 192 String getRequestHeader(const String& name) const; 193 void setRequestHeaderInternal(const String& name, const String& value); 194 195 void changeState(State newState); 196 void callReadyStateChangeListener(); 197 void dropProtection(); 198 void internalAbort(); 199 void clearResponse(); 200 void clearResponseBuffers(); 201 void clearRequest(); 202 203 void createRequest(ExceptionCode&); 204 205 void genericError(); 206 void networkError(); 207 void abortError(); 208 209 bool shouldDecodeResponse() const { return m_responseTypeCode < FirstBinaryResponseType; } 210 211 void dispatchErrorEvents(const AtomicString&); 212 213 std::unique_ptr<XMLHttpRequestUpload> m_upload; 214 215 URL m_url; 216 String m_method; 217 HTTPHeaderMap m_requestHeaders; 218 RefPtr<FormData> m_requestEntityBody; 219 String m_mimeTypeOverride; 220 bool m_async; 221 bool m_includeCredentials; 222#if ENABLE(XHR_TIMEOUT) 223 unsigned long m_timeoutMilliseconds; 224#endif 225 RefPtr<Blob> m_responseBlob; 226 227 RefPtr<ThreadableLoader> m_loader; 228 State m_state; 229 230 ResourceResponse m_response; 231 String m_responseEncoding; 232 233 RefPtr<TextResourceDecoder> m_decoder; 234 235 StringBuilder m_responseBuilder; 236 bool m_createdDocument; 237 RefPtr<Document> m_responseDocument; 238 239 RefPtr<SharedBuffer> m_binaryResponseBuilder; 240 RefPtr<JSC::ArrayBuffer> m_responseArrayBuffer; 241 242 bool m_error; 243 244 bool m_uploadEventsAllowed; 245 bool m_uploadComplete; 246 247 bool m_sameOriginRequest; 248 249 // Used for onprogress tracking 250 long long m_receivedLength; 251 252 unsigned m_lastSendLineNumber; 253 unsigned m_lastSendColumnNumber; 254 String m_lastSendURL; 255 ExceptionCode m_exceptionCode; 256 257 XMLHttpRequestProgressEventThrottle m_progressEventThrottle; 258 259 // An enum corresponding to the allowed string values for the responseType attribute. 260 ResponseTypeCode m_responseTypeCode; 261 bool m_responseCacheIsValid; 262}; 263 264} // namespace WebCore 265 266#endif // XMLHttpRequest_h 267