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, 20 * MA 02110-1301 USA 21 */ 22 23 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_XMLHTTPREQUEST_XML_HTTP_REQUEST_H_ 24 #define THIRD_PARTY_BLINK_RENDERER_CORE_XMLHTTPREQUEST_XML_HTTP_REQUEST_H_ 25 26 #include <memory> 27 28 #include "base/memory/scoped_refptr.h" 29 #include "mojo/public/cpp/bindings/pending_remote.h" 30 #include "services/network/public/mojom/trust_tokens.mojom-blink.h" 31 #include "services/network/public/mojom/url_loader_factory.mojom-blink.h" 32 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" 33 #include "third_party/blink/renderer/core/dom/document_parser_client.h" 34 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" 35 #include "third_party/blink/renderer/core/fetch/trust_token.h" 36 #include "third_party/blink/renderer/core/loader/threadable_loader_client.h" 37 #include "third_party/blink/renderer/core/probe/async_task_id.h" 38 #include "third_party/blink/renderer/core/xmlhttprequest/xml_http_request_event_target.h" 39 #include "third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.h" 40 #include "third_party/blink/renderer/platform/bindings/exception_code.h" 41 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" 42 #include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h" 43 #include "third_party/blink/renderer/platform/heap/handle.h" 44 #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" 45 #include "third_party/blink/renderer/platform/network/encoded_form_data.h" 46 #include "third_party/blink/renderer/platform/network/http_header_map.h" 47 #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" 48 #include "third_party/blink/renderer/platform/weborigin/kurl.h" 49 #include "third_party/blink/renderer/platform/weborigin/security_origin.h" 50 #include "third_party/blink/renderer/platform/wtf/forward.h" 51 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" 52 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" 53 54 namespace blink { 55 56 class 57 ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringOrFormDataOrURLSearchParams; 58 class Blob; 59 class BlobDataHandle; 60 class DOMArrayBuffer; 61 class DOMArrayBufferView; 62 class Document; 63 class DocumentParser; 64 class ExceptionState; 65 class ExecutionContext; 66 class FormData; 67 class ScriptState; 68 class TextResourceDecoder; 69 class ThreadableLoader; 70 class URLSearchParams; 71 class XMLHttpRequestUpload; 72 73 class XMLHttpRequest final : public XMLHttpRequestEventTarget, 74 public ThreadableLoaderClient, 75 public DocumentParserClient, 76 public ActiveScriptWrappable<XMLHttpRequest>, 77 public ExecutionContextLifecycleObserver { 78 DEFINE_WRAPPERTYPEINFO(); 79 USING_GARBAGE_COLLECTED_MIXIN(XMLHttpRequest); 80 81 public: 82 static XMLHttpRequest* Create(ScriptState*); 83 static XMLHttpRequest* Create(ExecutionContext*); 84 85 XMLHttpRequest(ExecutionContext*, 86 v8::Isolate*, 87 bool is_isolated_world, 88 scoped_refptr<SecurityOrigin>); 89 ~XMLHttpRequest() override; 90 91 // These exact numeric values are important because JS expects them. 92 enum State { 93 kUnsent = 0, 94 kOpened = 1, 95 kHeadersReceived = 2, 96 kLoading = 3, 97 kDone = 4 98 }; 99 100 enum ResponseTypeCode { 101 kResponseTypeDefault, 102 kResponseTypeText, 103 kResponseTypeJSON, 104 kResponseTypeDocument, 105 kResponseTypeBlob, 106 kResponseTypeArrayBuffer, 107 }; 108 109 // ExecutionContextLifecycleObserver 110 void ContextDestroyed() override; 111 ExecutionContext* GetExecutionContext() const override; 112 113 // ScriptWrappable 114 bool HasPendingActivity() const final; 115 116 // XMLHttpRequestEventTarget 117 const AtomicString& InterfaceName() const override; 118 119 // JavaScript attributes and methods Url()120 const KURL& Url() const { return url_; } 121 String statusText() const; 122 int status() const; 123 State readyState() const; withCredentials()124 bool withCredentials() const { return with_credentials_; } 125 void setWithCredentials(bool, ExceptionState&); 126 void open(const AtomicString& method, const String& url, ExceptionState&); 127 void open(const AtomicString& method, 128 const String& url, 129 bool async, 130 const String& username, 131 const String& password, 132 ExceptionState&); 133 void open(const AtomicString& method, 134 const KURL&, 135 bool async, 136 ExceptionState&); 137 void send( 138 const ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringOrFormDataOrURLSearchParams&, 139 ExceptionState&); 140 void abort(); 141 void Dispose(); 142 void setRequestHeader(const AtomicString& name, 143 const AtomicString& value, 144 ExceptionState&); 145 void setTrustToken(const TrustToken*, ExceptionState&); 146 void overrideMimeType(const AtomicString& override, ExceptionState&); 147 String getAllResponseHeaders() const; 148 const AtomicString& getResponseHeader(const AtomicString&) const; 149 v8::Local<v8::String> responseText(ExceptionState&); 150 v8::Local<v8::String> ResponseJSONSource(); 151 Document* responseXML(ExceptionState&); 152 Blob* ResponseBlob(); 153 DOMArrayBuffer* ResponseArrayBuffer(); timeout()154 unsigned timeout() const { 155 return static_cast<unsigned>(timeout_.InMilliseconds()); 156 } 157 void setTimeout(unsigned timeout, ExceptionState&); GetResponseTypeCode()158 ResponseTypeCode GetResponseTypeCode() const { return response_type_code_; } 159 String responseType(); 160 void setResponseType(const String&, ExceptionState&); 161 String responseURL(); 162 163 // For Inspector. 164 void SendForInspectorXHRReplay(scoped_refptr<EncodedFormData>, 165 ExceptionState&); 166 167 XMLHttpRequestUpload* upload(); IsAsync()168 bool IsAsync() { return async_; } 169 async_task_id()170 probe::AsyncTaskId* async_task_id() { return &async_task_id_; } 171 172 DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange, kReadystatechange) 173 174 void Trace(Visitor*) override; NameInHeapSnapshot()175 const char* NameInHeapSnapshot() const override { return "XMLHttpRequest"; } 176 177 private: 178 class BlobLoader; 179 180 Document* GetDocument() const; 181 182 void DidSendData(uint64_t bytes_sent, 183 uint64_t total_bytes_to_be_sent) override; 184 void DidReceiveResponse(uint64_t identifier, 185 const ResourceResponse&) override; 186 void DidReceiveData(const char* data, unsigned data_length) override; 187 // When responseType is set to "blob", didDownloadData() is called instead 188 // of didReceiveData(). 189 void DidDownloadData(uint64_t data_length) override; 190 void DidDownloadToBlob(scoped_refptr<BlobDataHandle>) override; 191 void DidFinishLoading(uint64_t identifier) override; 192 void DidFail(const ResourceError&) override; 193 void DidFailRedirectCheck() override; 194 195 // BlobLoader notifications. 196 void DidFinishLoadingInternal(); 197 void DidFinishLoadingFromBlob(); 198 void DidFailLoadingFromBlob(); 199 200 // DocumentParserClient 201 void NotifyParserStopped() override; 202 203 void EndLoading(); 204 205 // Returns the MIME type part of mime_type_override_ if present and 206 // successfully parsed, or returns one of the "Content-Type" header value 207 // of the received response. 208 // 209 // This method is named after the term "final MIME type" defined in the 210 // spec but doesn't convert the result to ASCII lowercase as specified in 211 // the spec. Must be lowered later or compared using case insensitive 212 // comparison functions if required. 213 AtomicString FinalResponseMIMEType() const; 214 // The same as finalResponseMIMEType() but fallbacks to "text/xml" if 215 // finalResponseMIMEType() returns an empty string. 216 AtomicString FinalResponseMIMETypeWithFallback() const; 217 // Returns the "final charset" defined in 218 // https://xhr.spec.whatwg.org/#final-charset. 219 WTF::TextEncoding FinalResponseCharset() const; 220 bool ResponseIsXML() const; 221 bool ResponseIsHTML() const; 222 223 std::unique_ptr<TextResourceDecoder> CreateDecoder() const; 224 225 void InitResponseDocument(); 226 void ParseDocumentChunk(const char* data, unsigned data_length); 227 228 bool AreMethodAndURLValidForSend(); 229 230 void ThrowForLoadFailureIfNeeded(ExceptionState&, const String&); 231 232 bool InitSend(ExceptionState&); 233 void SendBytesData(const void*, size_t, ExceptionState&); 234 void send(Document*, ExceptionState&); 235 void send(const String&, ExceptionState&); 236 void send(Blob*, ExceptionState&); 237 void send(FormData*, ExceptionState&); 238 void send(URLSearchParams*, ExceptionState&); 239 void send(DOMArrayBuffer*, ExceptionState&); 240 void send(DOMArrayBufferView*, ExceptionState&); 241 242 bool HasContentTypeRequestHeader() const; 243 void SetRequestHeaderInternal(const AtomicString& name, 244 const AtomicString& value); 245 246 void TrackProgress(uint64_t data_length); 247 // Changes m_state and dispatches a readyStateChange event if new m_state 248 // value is different from last one. 249 void ChangeState(State new_state); 250 void DispatchReadyStateChangeEvent(); 251 252 // Clears variables used only while the resource is being loaded. 253 void ClearVariablesForLoading(); 254 // Clears state and cancels loader. 255 void InternalAbort(); 256 // Clears variables holding response header and body data. 257 void ClearResponse(); 258 void ClearRequest(); 259 260 void CreateRequest(scoped_refptr<EncodedFormData>, ExceptionState&); 261 262 // Dispatches a response ProgressEvent. 263 void DispatchProgressEvent(const AtomicString&, int64_t, int64_t); 264 // Dispatches a response ProgressEvent using values sampled from 265 // m_receivedLength and m_response. 266 void DispatchProgressEventFromSnapshot(const AtomicString&); 267 268 // Handles didFail() call not caused by cancellation or timeout. 269 void HandleNetworkError(); 270 // Handles didFail() call for cancellations. For example, the 271 // ResourceLoader handling the load notifies m_loader of an error 272 // cancellation when the frame containing the XHR navigates away. 273 void HandleDidCancel(); 274 // Handles didFail() call for timeout. 275 void HandleDidTimeout(); 276 277 void HandleRequestError(DOMExceptionCode, 278 const AtomicString&, 279 int64_t, 280 int64_t); 281 282 void UpdateContentTypeAndCharset(const AtomicString& content_type, 283 const String& charset); 284 285 XMLHttpRequestProgressEventThrottle& ProgressEventThrottle(); 286 287 // Report the memory usage associated with this object to V8 so that V8 can 288 // schedule GC accordingly. This function should be called whenever the 289 // internal memory usage changes except for the following members. 290 // - response_text_ of type TraceWrapperV8String 291 // ScriptString internally creates and holds a v8::String, so V8 is aware of 292 // its memory usage. 293 // - response_array_buffer_ of type DOMArrayBuffer 294 // DOMArrayBuffer supports the memory usage reporting system on their own, 295 // so there is no need. 296 void ReportMemoryUsageToV8(); 297 298 Member<XMLHttpRequestUpload> upload_; 299 300 KURL url_; 301 mojo::PendingRemote<network::mojom::blink::URLLoaderFactory> 302 blob_url_loader_factory_; 303 AtomicString method_; 304 HTTPHeaderMap request_headers_; 305 network::mojom::blink::TrustTokenParamsPtr trust_token_params_; 306 // Not converted to ASCII lowercase. Must be lowered later or compared 307 // using case insensitive comparison functions if needed. 308 AtomicString mime_type_override_; 309 base::TimeDelta timeout_; 310 Member<Blob> response_blob_; 311 312 TaskHandle pending_abort_event_; 313 314 Member<ThreadableLoader> loader_; 315 State state_ = kUnsent; 316 317 ResourceResponse response_; 318 319 std::unique_ptr<TextResourceDecoder> decoder_; 320 321 // Avoid using a flat WTF::String here and rather use a traced v8::String 322 // which internally builds a string rope. 323 GC_PLUGIN_IGNORE("crbug.com/841830") TraceWrapperV8String response_text_; 324 Member<Document> response_document_; 325 Member<DocumentParser> response_document_parser_; 326 327 scoped_refptr<SharedBuffer> binary_response_builder_; 328 size_t binary_response_builder_last_reported_size_ = 0; 329 int64_t length_downloaded_to_blob_ = 0; 330 int64_t length_downloaded_to_blob_last_reported_ = 0; 331 332 Member<DOMArrayBuffer> response_array_buffer_; 333 334 // Used for onprogress tracking 335 int64_t received_length_ = 0; 336 337 // An exception to throw in synchronous mode. It's set when failure 338 // notification is received from m_loader and thrown at the end of send() if 339 // any. 340 DOMExceptionCode exception_code_ = DOMExceptionCode::kNoError; 341 342 Member<XMLHttpRequestProgressEventThrottle> progress_event_throttle_; 343 344 // An enum corresponding to the allowed string values for the responseType 345 // attribute. 346 ResponseTypeCode response_type_code_ = kResponseTypeDefault; 347 348 v8::Isolate* const isolate_; 349 // Set to true if the XMLHttpRequest was created in an isolated world. 350 bool is_isolated_world_; 351 // Stores the SecurityOrigin associated with the isolated world if any. 352 scoped_refptr<SecurityOrigin> isolated_world_security_origin_; 353 354 // This blob loader will be used if |m_downloadingToFile| is true and 355 // |m_responseTypeCode| is NOT ResponseTypeBlob. 356 Member<BlobLoader> blob_loader_; 357 358 // Positive if we are dispatching events. 359 // This is an integer specifying the recursion level rather than a boolean 360 // because in some cases we have recursive dispatching. 361 int event_dispatch_recursion_level_ = 0; 362 363 bool async_ = true; 364 365 bool with_credentials_ = false; 366 367 // Used to skip m_responseDocument creation if it's done previously. We need 368 // this separate flag since m_responseDocument can be 0 for some cases. 369 bool parsed_response_ = false; 370 bool error_ = false; 371 bool upload_events_allowed_ = true; 372 bool upload_complete_ = false; 373 // True iff the ongoing resource loading is using the downloadToBlob 374 // option. 375 bool downloading_to_blob_ = false; 376 bool response_text_overflow_ = false; 377 bool send_flag_ = false; 378 bool response_array_buffer_failure_ = false; 379 380 probe::AsyncTaskId async_task_id_; 381 }; 382 383 std::ostream& operator<<(std::ostream&, const XMLHttpRequest*); 384 385 } // namespace blink 386 387 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_XMLHTTPREQUEST_XML_HTTP_REQUEST_H_ 388