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

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: abarth's comments Created 7 years, 5 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 <wtf/ArrayBuffer.h> 26 #include "RuntimeEnabledFeatures.h"
27 #include <wtf/ArrayBufferView.h>
28 #include <wtf/RefCountedLeakCounter.h>
29 #include <wtf/StdLibExtras.h>
30 #include <wtf/text/CString.h>
31 #include <wtf/UnusedParam.h>
32 #include "core/dom/ContextFeatures.h" 27 #include "core/dom/ContextFeatures.h"
33 #include "core/dom/DOMImplementation.h" 28 #include "core/dom/DOMImplementation.h"
34 #include "core/dom/Event.h" 29 #include "core/dom/Event.h"
35 #include "core/dom/EventListener.h" 30 #include "core/dom/EventListener.h"
36 #include "core/dom/EventNames.h" 31 #include "core/dom/EventNames.h"
37 #include "core/dom/ExceptionCode.h" 32 #include "core/dom/ExceptionCode.h"
38 #include "core/dom/WebCoreMemoryInstrumentation.h" 33 #include "core/dom/WebCoreMemoryInstrumentation.h"
39 #include "core/editing/markup.h" 34 #include "core/editing/markup.h"
40 #include "core/fileapi/Blob.h" 35 #include "core/fileapi/Blob.h"
41 #include "core/fileapi/File.h" 36 #include "core/fileapi/File.h"
37 #include "core/fileapi/Stream.h"
42 #include "core/html/DOMFormData.h" 38 #include "core/html/DOMFormData.h"
43 #include "core/html/HTMLDocument.h" 39 #include "core/html/HTMLDocument.h"
44 #include "core/inspector/InspectorInstrumentation.h" 40 #include "core/inspector/InspectorInstrumentation.h"
45 #include "core/loader/CrossOriginAccessControl.h" 41 #include "core/loader/CrossOriginAccessControl.h"
46 #include "core/loader/TextResourceDecoder.h" 42 #include "core/loader/TextResourceDecoder.h"
47 #include "core/loader/ThreadableLoader.h" 43 #include "core/loader/ThreadableLoader.h"
48 #include "core/loader/cache/CachedResourceRequestInitiators.h" 44 #include "core/loader/cache/CachedResourceRequestInitiators.h"
49 #include "core/page/ContentSecurityPolicy.h" 45 #include "core/page/ContentSecurityPolicy.h"
50 #include "core/page/Settings.h" 46 #include "core/page/Settings.h"
51 #include "core/platform/HistogramSupport.h" 47 #include "core/platform/HistogramSupport.h"
52 #include "core/platform/SharedBuffer.h" 48 #include "core/platform/SharedBuffer.h"
53 #include "core/platform/network/BlobData.h" 49 #include "core/platform/network/BlobData.h"
54 #include "core/platform/network/HTTPParsers.h" 50 #include "core/platform/network/HTTPParsers.h"
55 #include "core/platform/network/ParsedContentType.h" 51 #include "core/platform/network/ParsedContentType.h"
56 #include "core/platform/network/ResourceError.h" 52 #include "core/platform/network/ResourceError.h"
57 #include "core/platform/network/ResourceRequest.h" 53 #include "core/platform/network/ResourceRequest.h"
58 #include "core/xml/XMLHttpRequestProgressEvent.h" 54 #include "core/xml/XMLHttpRequestProgressEvent.h"
59 #include "core/xml/XMLHttpRequestUpload.h" 55 #include "core/xml/XMLHttpRequestUpload.h"
60 #include "weborigin/SecurityOrigin.h" 56 #include "weborigin/SecurityOrigin.h"
57 #include "wtf/ArrayBuffer.h"
58 #include "wtf/ArrayBufferView.h"
59 #include "wtf/RefCountedLeakCounter.h"
60 #include "wtf/StdLibExtras.h"
61 #include "wtf/UnusedParam.h"
62 #include "wtf/text/CString.h"
61 63
62 namespace WebCore { 64 namespace WebCore {
63 65
64 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, xmlHttpRequestCounter, ("XM LHttpRequest")); 66 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, xmlHttpRequestCounter, ("XM LHttpRequest"));
65 67
66 // Histogram enum to see when we can deprecate xhr.send(ArrayBuffer). 68 // Histogram enum to see when we can deprecate xhr.send(ArrayBuffer).
67 enum XMLHttpRequestSendArrayBufferOrView { 69 enum XMLHttpRequestSendArrayBufferOrView {
68 XMLHttpRequestSendArrayBuffer, 70 XMLHttpRequestSendArrayBuffer,
69 XMLHttpRequestSendArrayBufferView, 71 XMLHttpRequestSendArrayBufferView,
70 XMLHttpRequestSendArrayBufferOrViewMax, 72 XMLHttpRequestSendArrayBufferOrViewMax,
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 return 0; 308 return 0;
307 309
308 if (!m_responseArrayBuffer.get() && m_binaryResponseBuilder.get() && m_binar yResponseBuilder->size() > 0) { 310 if (!m_responseArrayBuffer.get() && m_binaryResponseBuilder.get() && m_binar yResponseBuilder->size() > 0) {
309 m_responseArrayBuffer = m_binaryResponseBuilder->getAsArrayBuffer(); 311 m_responseArrayBuffer = m_binaryResponseBuilder->getAsArrayBuffer();
310 m_binaryResponseBuilder.clear(); 312 m_binaryResponseBuilder.clear();
311 } 313 }
312 314
313 return m_responseArrayBuffer.get(); 315 return m_responseArrayBuffer.get();
314 } 316 }
315 317
318 Stream* XMLHttpRequest::responseStream(ExceptionCode& ec)
319 {
320 if (m_responseTypeCode != ResponseTypeStream) {
321 ec = InvalidStateError;
322 return 0;
323 }
324
325 if (m_error || (m_state != LOADING && m_state != DONE))
326 return 0;
327
328 return m_responseStream.get();
329 }
330
316 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionCode& ec) 331 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionCode& ec)
317 { 332 {
318 // FIXME: Need to trigger or update the timeout Timer here, if needed. http: //webkit.org/b/98156 333 // FIXME: Need to trigger or update the timeout Timer here, if needed. http: //webkit.org/b/98156
319 // 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." 334 // 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."
320 if (scriptExecutionContext()->isDocument() && !m_async) { 335 if (scriptExecutionContext()->isDocument() && !m_async) {
321 logConsoleError(scriptExecutionContext(), "XMLHttpRequest.timeout cannot be set for synchronous HTTP(S) requests made from the window context."); 336 logConsoleError(scriptExecutionContext(), "XMLHttpRequest.timeout cannot be set for synchronous HTTP(S) requests made from the window context.");
322 ec = InvalidAccessError; 337 ec = InvalidAccessError;
323 return; 338 return;
324 } 339 }
325 m_timeoutMilliseconds = timeout; 340 m_timeoutMilliseconds = timeout;
326 } 341 }
327 342
328 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionCode& ec) 343 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionCode& ec)
329 { 344 {
330 if (m_state >= LOADING) { 345 if (m_state >= LOADING) {
331 ec = InvalidStateError; 346 ec = InvalidStateError;
332 return; 347 return;
333 } 348 }
334 349
335 // Newer functionality is not available to synchronous requests in window co ntexts, as a spec-mandated 350 // Newer functionality is not available to synchronous requests in window co ntexts, as a spec-mandated
336 // attempt to discourage synchronous XHR use. responseType is one such piece of functionality. 351 // attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
337 // We'll only disable this functionality for HTTP(S) requests since sync req uests for local protocols 352 // We'll only disable this functionality for HTTP(S) requests since sync req uests for local protocols
338 // such as file: and data: still make sense to allow. 353 // such as file: and data: still make sense to allow.
339 if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsIn HTTPFamily()) { 354 if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsIn HTTPFamily()) {
340 logConsoleError(scriptExecutionContext(), "XMLHttpRequest.responseType c annot be changed for synchronous HTTP(S) requests made from the window context." ); 355 logConsoleError(scriptExecutionContext(), "XMLHttpRequest.responseType c annot be changed for synchronous HTTP(S) requests made from the window context." );
341 ec = InvalidAccessError; 356 ec = InvalidAccessError;
342 return; 357 return;
343 } 358 }
344 359
345 if (responseType == "") 360 if (responseType == "") {
346 m_responseTypeCode = ResponseTypeDefault; 361 m_responseTypeCode = ResponseTypeDefault;
347 else if (responseType == "text") 362 } else if (responseType == "text") {
348 m_responseTypeCode = ResponseTypeText; 363 m_responseTypeCode = ResponseTypeText;
349 else if (responseType == "document") 364 } else if (responseType == "document") {
350 m_responseTypeCode = ResponseTypeDocument; 365 m_responseTypeCode = ResponseTypeDocument;
351 else if (responseType == "blob") 366 } else if (responseType == "blob") {
352 m_responseTypeCode = ResponseTypeBlob; 367 m_responseTypeCode = ResponseTypeBlob;
353 else if (responseType == "arraybuffer") 368 } else if (responseType == "arraybuffer") {
354 m_responseTypeCode = ResponseTypeArrayBuffer; 369 m_responseTypeCode = ResponseTypeArrayBuffer;
355 else 370 } else if (responseType == "stream") {
371 if (RuntimeEnabledFeatures::streamEnabled())
372 m_responseTypeCode = ResponseTypeStream;
373 else
374 return;
375 } else {
356 ASSERT_NOT_REACHED(); 376 ASSERT_NOT_REACHED();
377 }
357 } 378 }
358 379
359 String XMLHttpRequest::responseType() 380 String XMLHttpRequest::responseType()
360 { 381 {
361 switch (m_responseTypeCode) { 382 switch (m_responseTypeCode) {
362 case ResponseTypeDefault: 383 case ResponseTypeDefault:
363 return ""; 384 return ASCIILiteral("");
364 case ResponseTypeText: 385 case ResponseTypeText:
365 return "text"; 386 return ASCIILiteral("text");
366 case ResponseTypeDocument: 387 case ResponseTypeDocument:
367 return "document"; 388 return ASCIILiteral("document");
368 case ResponseTypeBlob: 389 case ResponseTypeBlob:
369 return "blob"; 390 return ASCIILiteral("blob");
370 case ResponseTypeArrayBuffer: 391 case ResponseTypeArrayBuffer:
371 return "arraybuffer"; 392 return ASCIILiteral("arraybuffer");
393 case ResponseTypeStream:
394 return ASCIILiteral("stream");
372 } 395 }
373 return ""; 396 return ASCIILiteral("");
374 } 397 }
375 398
376 XMLHttpRequestUpload* XMLHttpRequest::upload() 399 XMLHttpRequestUpload* XMLHttpRequest::upload()
377 { 400 {
378 if (!m_upload) 401 if (!m_upload)
379 m_upload = XMLHttpRequestUpload::create(this); 402 m_upload = XMLHttpRequestUpload::create(this);
380 return m_upload.get(); 403 return m_upload.get();
381 } 404 }
382 405
383 void XMLHttpRequest::changeState(State newState) 406 void XMLHttpRequest::changeState(State newState)
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 954
932 String XMLHttpRequest::getRequestHeader(const AtomicString& name) const 955 String XMLHttpRequest::getRequestHeader(const AtomicString& name) const
933 { 956 {
934 return m_requestHeaders.get(name); 957 return m_requestHeaders.get(name);
935 } 958 }
936 959
937 String XMLHttpRequest::getAllResponseHeaders(ExceptionCode& ec) const 960 String XMLHttpRequest::getAllResponseHeaders(ExceptionCode& ec) const
938 { 961 {
939 if (m_state < HEADERS_RECEIVED) { 962 if (m_state < HEADERS_RECEIVED) {
940 ec = InvalidStateError; 963 ec = InvalidStateError;
941 return ""; 964 return ASCIILiteral("");
942 } 965 }
943 966
944 StringBuilder stringBuilder; 967 StringBuilder stringBuilder;
945 968
946 HTTPHeaderSet accessControlExposeHeaderSet; 969 HTTPHeaderSet accessControlExposeHeaderSet;
947 parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access- Control-Expose-Headers"), accessControlExposeHeaderSet); 970 parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access- Control-Expose-Headers"), accessControlExposeHeaderSet);
948 HTTPHeaderMap::const_iterator end = m_response.httpHeaderFields().end(); 971 HTTPHeaderMap::const_iterator end = m_response.httpHeaderFields().end();
949 for (HTTPHeaderMap::const_iterator it = m_response.httpHeaderFields().begin( ); it!= end; ++it) { 972 for (HTTPHeaderMap::const_iterator it = m_response.httpHeaderFields().begin( ); it!= end; ++it) {
950 // Hide Set-Cookie header fields from the XMLHttpRequest client for thes e reasons: 973 // Hide Set-Cookie header fields from the XMLHttpRequest client for thes e reasons:
951 // 1) If the client did have access to the fields, then it could rea d HTTP-only 974 // 1) If the client did have access to the fields, then it could rea d HTTP-only
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 return; 1102 return;
1080 1103
1081 if (m_state < HEADERS_RECEIVED) 1104 if (m_state < HEADERS_RECEIVED)
1082 changeState(HEADERS_RECEIVED); 1105 changeState(HEADERS_RECEIVED);
1083 1106
1084 if (m_decoder) 1107 if (m_decoder)
1085 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); 1108 m_responseText = m_responseText.concatenateWith(m_decoder->flush());
1086 1109
1087 InspectorInstrumentation::didFinishXHRLoading(scriptExecutionContext(), this , identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); 1110 InspectorInstrumentation::didFinishXHRLoading(scriptExecutionContext(), this , identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber);
1088 1111
1112 if (m_responseStream)
1113 m_responseStream->finalize();
1114
1089 bool hadLoader = m_loader; 1115 bool hadLoader = m_loader;
1090 m_loader = 0; 1116 m_loader = 0;
1091 1117
1092 changeState(DONE); 1118 changeState(DONE);
1093 m_decoder = 0; 1119 m_decoder = 0;
1094 1120
1095 if (hadLoader) 1121 if (hadLoader)
1096 dropProtection(); 1122 dropProtection();
1097 } 1123 }
1098 1124
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 if (len == -1) 1181 if (len == -1)
1156 len = strlen(data); 1182 len = strlen(data);
1157 1183
1158 if (useDecoder) 1184 if (useDecoder)
1159 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); 1185 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len));
1160 else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCode == ResponseTypeBlob) { 1186 else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCode == ResponseTypeBlob) {
1161 // Buffer binary data. 1187 // Buffer binary data.
1162 if (!m_binaryResponseBuilder) 1188 if (!m_binaryResponseBuilder)
1163 m_binaryResponseBuilder = SharedBuffer::create(); 1189 m_binaryResponseBuilder = SharedBuffer::create();
1164 m_binaryResponseBuilder->append(data, len); 1190 m_binaryResponseBuilder->append(data, len);
1191 } else if (m_responseTypeCode == ResponseTypeStream) {
1192 if (!m_responseStream)
1193 m_responseStream = Stream::create(responseMIMEType());
1194 m_responseStream->addData(data, len);
michaeln 2013/07/24 03:57:22 Also, it it a desired characteristic of this imple
1165 } 1195 }
1166 1196
1167 if (!m_error) { 1197 if (!m_error) {
1168 long long expectedLength = m_response.expectedContentLength(); 1198 long long expectedLength = m_response.expectedContentLength();
1169 m_receivedLength += len; 1199 m_receivedLength += len;
1170 1200
1171 if (m_async) { 1201 if (m_async) {
1172 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex pectedLength; 1202 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex pectedLength;
1173 unsigned long long total = lengthComputable ? expectedLength : 0; 1203 unsigned long long total = lengthComputable ? expectedLength : 0;
1174 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re ceivedLength, total); 1204 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re ceivedLength, total);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 info.addMember(m_responseDocument, "responseDocument"); 1306 info.addMember(m_responseDocument, "responseDocument");
1277 info.addMember(m_binaryResponseBuilder, "binaryResponseBuilder"); 1307 info.addMember(m_binaryResponseBuilder, "binaryResponseBuilder");
1278 info.addMember(m_responseArrayBuffer, "responseArrayBuffer"); 1308 info.addMember(m_responseArrayBuffer, "responseArrayBuffer");
1279 info.addMember(m_lastSendURL, "lastSendURL"); 1309 info.addMember(m_lastSendURL, "lastSendURL");
1280 info.addMember(m_eventTargetData, "eventTargetData"); 1310 info.addMember(m_eventTargetData, "eventTargetData");
1281 info.addMember(m_progressEventThrottle, "progressEventThrottle"); 1311 info.addMember(m_progressEventThrottle, "progressEventThrottle");
1282 info.addMember(m_securityOrigin, "securityOrigin"); 1312 info.addMember(m_securityOrigin, "securityOrigin");
1283 } 1313 }
1284 1314
1285 } // namespace WebCore 1315 } // 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