Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(726)

Side by Side Diff: Source/core/xml/XMLHttpRequest.cpp

Issue 18883002: Add Streams API support to XMLHttpRequest (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: kinuko's comment Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | Source/core/xml/XMLHttpRequest.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org> 3 * Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org>
4 * Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org> 4 * Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org>
5 * Copyright (C) 2008, 2011 Google Inc. All rights reserved. 5 * Copyright (C) 2008, 2011 Google Inc. All rights reserved.
6 * Copyright (C) 2012 Intel Corporation 6 * Copyright (C) 2012 Intel Corporation
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public 9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version. 11 * version 2 of the License, or (at your option) any later version.
12 * 12 *
13 * This library is distributed in the hope that it will be useful, 13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details. 16 * Lesser General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU Lesser General Public 18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software 19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 U SA 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 U SA
21 */ 21 */
22 22
23 #include "config.h" 23 #include "config.h"
24 #include "core/xml/XMLHttpRequest.h" 24 #include "core/xml/XMLHttpRequest.h"
25 25
26 #include "FetchInitiatorTypeNames.h" 26 #include "FetchInitiatorTypeNames.h"
27 #include "RuntimeEnabledFeatures.h"
27 #include "bindings/v8/ExceptionMessages.h" 28 #include "bindings/v8/ExceptionMessages.h"
28 #include "bindings/v8/ExceptionState.h" 29 #include "bindings/v8/ExceptionState.h"
29 #include "core/dom/ContextFeatures.h" 30 #include "core/dom/ContextFeatures.h"
30 #include "core/dom/DOMImplementation.h" 31 #include "core/dom/DOMImplementation.h"
31 #include "core/dom/Event.h" 32 #include "core/dom/Event.h"
32 #include "core/dom/EventListener.h" 33 #include "core/dom/EventListener.h"
33 #include "core/dom/EventNames.h" 34 #include "core/dom/EventNames.h"
34 #include "core/dom/ExceptionCode.h" 35 #include "core/dom/ExceptionCode.h"
35 #include "core/editing/markup.h" 36 #include "core/editing/markup.h"
36 #include "core/fetch/TextResourceDecoder.h" 37 #include "core/fetch/TextResourceDecoder.h"
37 #include "core/fileapi/Blob.h" 38 #include "core/fileapi/Blob.h"
38 #include "core/fileapi/File.h" 39 #include "core/fileapi/File.h"
40 #include "core/fileapi/Stream.h"
39 #include "core/html/DOMFormData.h" 41 #include "core/html/DOMFormData.h"
40 #include "core/html/HTMLDocument.h" 42 #include "core/html/HTMLDocument.h"
41 #include "core/inspector/InspectorInstrumentation.h" 43 #include "core/inspector/InspectorInstrumentation.h"
42 #include "core/loader/CrossOriginAccessControl.h" 44 #include "core/loader/CrossOriginAccessControl.h"
43 #include "core/loader/ThreadableLoader.h" 45 #include "core/loader/ThreadableLoader.h"
44 #include "core/page/ContentSecurityPolicy.h" 46 #include "core/page/ContentSecurityPolicy.h"
45 #include "core/page/Settings.h" 47 #include "core/page/Settings.h"
46 #include "core/platform/HistogramSupport.h" 48 #include "core/platform/HistogramSupport.h"
47 #include "core/platform/SharedBuffer.h" 49 #include "core/platform/SharedBuffer.h"
48 #include "core/platform/network/BlobData.h" 50 #include "core/platform/network/BlobData.h"
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 return 0; 313 return 0;
312 314
313 if (!m_responseArrayBuffer.get() && m_binaryResponseBuilder.get() && m_binar yResponseBuilder->size() > 0) { 315 if (!m_responseArrayBuffer.get() && m_binaryResponseBuilder.get() && m_binar yResponseBuilder->size() > 0) {
314 m_responseArrayBuffer = m_binaryResponseBuilder->getAsArrayBuffer(); 316 m_responseArrayBuffer = m_binaryResponseBuilder->getAsArrayBuffer();
315 m_binaryResponseBuilder.clear(); 317 m_binaryResponseBuilder.clear();
316 } 318 }
317 319
318 return m_responseArrayBuffer.get(); 320 return m_responseArrayBuffer.get();
319 } 321 }
320 322
323 Stream* XMLHttpRequest::responseStream()
324 {
325 ASSERT(m_responseTypeCode == ResponseTypeStream);
326
327 if (m_error || (m_state != LOADING && m_state != DONE))
328 return 0;
329
330 return m_responseStream.get();
331 }
332
321 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionState& es) 333 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionState& es)
322 { 334 {
323 // FIXME: Need to trigger or update the timeout Timer here, if needed. http: //webkit.org/b/98156 335 // FIXME: Need to trigger or update the timeout Timer here, if needed. http: //webkit.org/b/98156
324 // XHR2 spec, 4.7.3. "This implies that the timeout attribute can be set whi le fetching is in progress. If that occurs it will still be measured relative to the start of fetching." 336 // XHR2 spec, 4.7.3. "This implies that the timeout attribute can be set whi le fetching is in progress. If that occurs it will still be measured relative to the start of fetching."
325 if (scriptExecutionContext()->isDocument() && !m_async) { 337 if (scriptExecutionContext()->isDocument() && !m_async) {
326 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToSet( "timeout", "XMLHttpRequest", "timeouts cannot be set for synchronous requests ma de from a document.")); 338 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToSet( "timeout", "XMLHttpRequest", "timeouts cannot be set for synchronous requests ma de from a document."));
327 return; 339 return;
328 } 340 }
329 m_timeoutMilliseconds = timeout; 341 m_timeoutMilliseconds = timeout;
330 } 342 }
331 343
332 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState& es) 344 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState& es)
333 { 345 {
334 if (m_state >= LOADING) { 346 if (m_state >= LOADING) {
335 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToSet(" responseType", "XMLHttpRequest", "the response type cannot be set if the object' s state is LOADING or DONE.")); 347 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToSet(" responseType", "XMLHttpRequest", "the response type cannot be set if the object' s state is LOADING or DONE."));
336 return; 348 return;
337 } 349 }
338 350
339 // Newer functionality is not available to synchronous requests in window co ntexts, as a spec-mandated 351 // Newer functionality is not available to synchronous requests in window co ntexts, as a spec-mandated
340 // attempt to discourage synchronous XHR use. responseType is one such piece of functionality. 352 // attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
341 // We'll only disable this functionality for HTTP(S) requests since sync req uests for local protocols 353 // We'll only disable this functionality for HTTP(S) requests since sync req uests for local protocols
342 // such as file: and data: still make sense to allow. 354 // such as file: and data: still make sense to allow.
343 if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsIn HTTPFamily()) { 355 if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsIn HTTPFamily()) {
344 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToSet( "responseType", "XMLHttpRequest", "the response type can only be changed for asy nchronous HTTP requests made from a document.")); 356 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToSet( "responseType", "XMLHttpRequest", "the response type can only be changed for asy nchronous HTTP requests made from a document."));
345 return; 357 return;
346 } 358 }
347 359
348 if (responseType == "") 360 if (responseType == "") {
349 m_responseTypeCode = ResponseTypeDefault; 361 m_responseTypeCode = ResponseTypeDefault;
350 else if (responseType == "text") 362 } else if (responseType == "text") {
351 m_responseTypeCode = ResponseTypeText; 363 m_responseTypeCode = ResponseTypeText;
352 else if (responseType == "json") 364 } else if (responseType == "json") {
353 m_responseTypeCode = ResponseTypeJSON; 365 m_responseTypeCode = ResponseTypeJSON;
354 else if (responseType == "document") 366 } else if (responseType == "document") {
355 m_responseTypeCode = ResponseTypeDocument; 367 m_responseTypeCode = ResponseTypeDocument;
356 else if (responseType == "blob") 368 } else if (responseType == "blob") {
357 m_responseTypeCode = ResponseTypeBlob; 369 m_responseTypeCode = ResponseTypeBlob;
358 else if (responseType == "arraybuffer") 370 } else if (responseType == "arraybuffer") {
359 m_responseTypeCode = ResponseTypeArrayBuffer; 371 m_responseTypeCode = ResponseTypeArrayBuffer;
360 else 372 } else if (responseType == "stream") {
373 if (RuntimeEnabledFeatures::streamEnabled())
374 m_responseTypeCode = ResponseTypeStream;
375 else
376 return;
377 } else {
361 ASSERT_NOT_REACHED(); 378 ASSERT_NOT_REACHED();
379 }
362 } 380 }
363 381
364 String XMLHttpRequest::responseType() 382 String XMLHttpRequest::responseType()
365 { 383 {
366 switch (m_responseTypeCode) { 384 switch (m_responseTypeCode) {
367 case ResponseTypeDefault: 385 case ResponseTypeDefault:
368 return ""; 386 return "";
369 case ResponseTypeText: 387 case ResponseTypeText:
370 return "text"; 388 return "text";
371 case ResponseTypeJSON: 389 case ResponseTypeJSON:
372 return "json"; 390 return "json";
373 case ResponseTypeDocument: 391 case ResponseTypeDocument:
374 return "document"; 392 return "document";
375 case ResponseTypeBlob: 393 case ResponseTypeBlob:
376 return "blob"; 394 return "blob";
377 case ResponseTypeArrayBuffer: 395 case ResponseTypeArrayBuffer:
378 return "arraybuffer"; 396 return "arraybuffer";
397 case ResponseTypeStream:
398 return "stream";
379 } 399 }
380 return ""; 400 return "";
381 } 401 }
382 402
383 XMLHttpRequestUpload* XMLHttpRequest::upload() 403 XMLHttpRequestUpload* XMLHttpRequest::upload()
384 { 404 {
385 if (!m_upload) 405 if (!m_upload)
386 m_upload = XMLHttpRequestUpload::create(this); 406 m_upload = XMLHttpRequestUpload::create(this);
387 return m_upload.get(); 407 return m_upload.get();
388 } 408 }
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 void XMLHttpRequest::internalAbort(DropProtection async) 838 void XMLHttpRequest::internalAbort(DropProtection async)
819 { 839 {
820 m_error = true; 840 m_error = true;
821 841
822 // FIXME: when we add the support for multi-part XHR, we will have to think be careful with this initialization. 842 // FIXME: when we add the support for multi-part XHR, we will have to think be careful with this initialization.
823 m_receivedLength = 0; 843 m_receivedLength = 0;
824 m_decoder = 0; 844 m_decoder = 0;
825 845
826 InspectorInstrumentation::didFailXHRLoading(scriptExecutionContext(), this); 846 InspectorInstrumentation::didFailXHRLoading(scriptExecutionContext(), this);
827 847
828 if (m_loader) { 848 if (m_responseStream && m_state != DONE)
829 m_loader->cancel(); 849 m_responseStream->abort();
830 m_loader = 0;
831 850
832 if (async == DropProtectionAsync) 851 if (!m_loader)
833 dropProtectionSoon(); 852 return;
834 else 853
835 dropProtection(); 854 m_loader->cancel();
836 } 855 m_loader = 0;
856
857 if (async == DropProtectionAsync)
858 dropProtectionSoon();
859 else
860 dropProtection();
837 } 861 }
838 862
839 void XMLHttpRequest::clearResponse() 863 void XMLHttpRequest::clearResponse()
840 { 864 {
841 m_response = ResourceResponse(); 865 m_response = ResourceResponse();
842 clearResponseBuffers(); 866 clearResponseBuffers();
843 } 867 }
844 868
845 void XMLHttpRequest::clearResponseBuffers() 869 void XMLHttpRequest::clearResponseBuffers()
846 { 870 {
847 m_responseText.clear(); 871 m_responseText.clear();
848 m_responseEncoding = String(); 872 m_responseEncoding = String();
849 m_createdDocument = false; 873 m_createdDocument = false;
850 m_responseDocument = 0; 874 m_responseDocument = 0;
851 m_responseBlob = 0; 875 m_responseBlob = 0;
876 m_responseStream = 0;
852 m_binaryResponseBuilder.clear(); 877 m_binaryResponseBuilder.clear();
853 m_responseArrayBuffer.clear(); 878 m_responseArrayBuffer.clear();
854 } 879 }
855 880
856 void XMLHttpRequest::clearRequest() 881 void XMLHttpRequest::clearRequest()
857 { 882 {
858 m_requestHeaders.clear(); 883 m_requestHeaders.clear();
859 m_requestEntityBody = 0; 884 m_requestEntityBody = 0;
860 } 885 }
861 886
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 { 1114 {
1090 if (m_error) 1115 if (m_error)
1091 return; 1116 return;
1092 1117
1093 if (m_state < HEADERS_RECEIVED) 1118 if (m_state < HEADERS_RECEIVED)
1094 changeState(HEADERS_RECEIVED); 1119 changeState(HEADERS_RECEIVED);
1095 1120
1096 if (m_decoder) 1121 if (m_decoder)
1097 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); 1122 m_responseText = m_responseText.concatenateWith(m_decoder->flush());
1098 1123
1124 if (m_responseStream)
1125 m_responseStream->finalize();
1126
1099 InspectorInstrumentation::didFinishXHRLoading(scriptExecutionContext(), this , identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); 1127 InspectorInstrumentation::didFinishXHRLoading(scriptExecutionContext(), this , identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber);
1100 1128
1101 // Prevent dropProtection releasing the last reference, and retain |this| un til the end of this method. 1129 // Prevent dropProtection releasing the last reference, and retain |this| un til the end of this method.
1102 RefPtr<XMLHttpRequest> protect(this); 1130 RefPtr<XMLHttpRequest> protect(this);
1103 1131
1104 if (m_loader) { 1132 if (m_loader) {
1105 m_loader = 0; 1133 m_loader = 0;
1106 dropProtection(); 1134 dropProtection();
1107 } 1135 }
1108 1136
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 else 1193 else
1166 m_decoder = TextResourceDecoder::create("text/plain", "UTF-8"); 1194 m_decoder = TextResourceDecoder::create("text/plain", "UTF-8");
1167 } 1195 }
1168 1196
1169 if (!len) 1197 if (!len)
1170 return; 1198 return;
1171 1199
1172 if (len == -1) 1200 if (len == -1)
1173 len = strlen(data); 1201 len = strlen(data);
1174 1202
1175 if (useDecoder) 1203 if (useDecoder) {
1176 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); 1204 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len));
1177 else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCode == ResponseTypeBlob) { 1205 } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCo de == ResponseTypeBlob) {
1178 // Buffer binary data. 1206 // Buffer binary data.
1179 if (!m_binaryResponseBuilder) 1207 if (!m_binaryResponseBuilder)
1180 m_binaryResponseBuilder = SharedBuffer::create(); 1208 m_binaryResponseBuilder = SharedBuffer::create();
1181 m_binaryResponseBuilder->append(data, len); 1209 m_binaryResponseBuilder->append(data, len);
1210 } else if (m_responseTypeCode == ResponseTypeStream) {
1211 if (!m_responseStream)
1212 m_responseStream = Stream::create(responseMIMEType());
1213 m_responseStream->addData(data, len);
1182 } 1214 }
1183 1215
1184 if (!m_error) { 1216 if (!m_error) {
1185 long long expectedLength = m_response.expectedContentLength(); 1217 long long expectedLength = m_response.expectedContentLength();
1186 m_receivedLength += len; 1218 m_receivedLength += len;
1187 1219
1188 if (m_async) { 1220 if (m_async) {
1189 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex pectedLength; 1221 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex pectedLength;
1190 unsigned long long total = lengthComputable ? expectedLength : 0; 1222 unsigned long long total = lengthComputable ? expectedLength : 0;
1191 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re ceivedLength, total); 1223 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re ceivedLength, total);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 { 1289 {
1258 return eventNames().interfaceForXMLHttpRequest; 1290 return eventNames().interfaceForXMLHttpRequest;
1259 } 1291 }
1260 1292
1261 ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const 1293 ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const
1262 { 1294 {
1263 return ActiveDOMObject::scriptExecutionContext(); 1295 return ActiveDOMObject::scriptExecutionContext();
1264 } 1296 }
1265 1297
1266 } // namespace WebCore 1298 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | Source/core/xml/XMLHttpRequest.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698