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

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

Issue 311593002: Reenable optimization on XMLHttpRequest's receive-as-blob functionality (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 6 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') | no next file » | 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
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 return xmlHttpRequest.release(); 164 return xmlHttpRequest.release();
165 } 165 }
166 166
167 XMLHttpRequest::XMLHttpRequest(ExecutionContext* context, PassRefPtr<SecurityOri gin> securityOrigin) 167 XMLHttpRequest::XMLHttpRequest(ExecutionContext* context, PassRefPtr<SecurityOri gin> securityOrigin)
168 : ActiveDOMObject(context) 168 : ActiveDOMObject(context)
169 , m_async(true) 169 , m_async(true)
170 , m_includeCredentials(false) 170 , m_includeCredentials(false)
171 , m_timeoutMilliseconds(0) 171 , m_timeoutMilliseconds(0)
172 , m_state(UNSENT) 172 , m_state(UNSENT)
173 , m_createdDocument(false) 173 , m_createdDocument(false)
174 , m_downloadedBlobLength(0)
174 , m_error(false) 175 , m_error(false)
175 , m_uploadEventsAllowed(true) 176 , m_uploadEventsAllowed(true)
176 , m_uploadComplete(false) 177 , m_uploadComplete(false)
177 , m_sameOriginRequest(true) 178 , m_sameOriginRequest(true)
178 , m_receivedLength(0) 179 , m_receivedLength(0)
179 , m_lastSendLineNumber(0) 180 , m_lastSendLineNumber(0)
180 , m_exceptionCode(0) 181 , m_exceptionCode(0)
181 , m_progressEventThrottle(this) 182 , m_progressEventThrottle(this)
182 , m_responseTypeCode(ResponseTypeDefault) 183 , m_responseTypeCode(ResponseTypeDefault)
183 , m_dropProtectionRunner(this, &XMLHttpRequest::dropProtection) 184 , m_dropProtectionRunner(this, &XMLHttpRequest::dropProtection)
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 } 270 }
270 m_createdDocument = true; 271 m_createdDocument = true;
271 } 272 }
272 273
273 return m_responseDocument.get(); 274 return m_responseDocument.get();
274 } 275 }
275 276
276 Blob* XMLHttpRequest::responseBlob() 277 Blob* XMLHttpRequest::responseBlob()
277 { 278 {
278 ASSERT(m_responseTypeCode == ResponseTypeBlob); 279 ASSERT(m_responseTypeCode == ResponseTypeBlob);
280 ASSERT(!m_binaryResponseBuilder.get());
279 281
280 // We always return null before DONE. 282 // We always return null before DONE.
281 if (m_error || m_state != DONE) 283 if (m_error || m_state != DONE)
282 return 0; 284 return 0;
283 285
284 if (!m_responseBlob) { 286 if (!m_responseBlob) {
285 // FIXME: Once RedirectToFileResourceHandler is fixed in Chromium, 287 // When responseType is set to "blob", we redirect the downloaded data
286 // re-enable download-to-file optimization introduced by Blink revision 288 // to a file-handle directly in the browser process. We get the
287 // 163141. 289 // file-path from the ResourceResponse directly instead of copying the
290 // bytes between the browser and the renderer.
288 OwnPtr<BlobData> blobData = BlobData::create(); 291 OwnPtr<BlobData> blobData = BlobData::create();
289 size_t size = 0; 292 String filePath = m_response.downloadedFilePath();
290 if (m_binaryResponseBuilder.get() && m_binaryResponseBuilder->size() > 0 ) { 293 // If we errored out or got no data, we still return a blob, just an
291 RefPtr<RawData> rawData = RawData::create(); 294 // empty one.
292 size = m_binaryResponseBuilder->size(); 295 if (!filePath.isEmpty() && m_downloadedBlobLength) {
293 rawData->mutableData()->append(m_binaryResponseBuilder->data(), size ); 296 blobData->appendFile(filePath);
294 blobData->appendData(rawData, 0, BlobDataItem::toEndOfFile);
295 blobData->setContentType(responseMIMEType()); // responseMIMEType de faults to text/xml which may be incorrect. 297 blobData->setContentType(responseMIMEType()); // responseMIMEType de faults to text/xml which may be incorrect.
296 m_binaryResponseBuilder.clear();
297 } 298 }
298 m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), size)); 299 m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), m_downloadedBlobLength));
299 } 300 }
300 301
301 return m_responseBlob.get(); 302 return m_responseBlob.get();
302 } 303 }
303 304
304 ArrayBuffer* XMLHttpRequest::responseArrayBuffer() 305 ArrayBuffer* XMLHttpRequest::responseArrayBuffer()
305 { 306 {
306 ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer); 307 ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer);
307 308
308 if (m_error || m_state != DONE) 309 if (m_error || m_state != DONE)
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 // added after the request is started. 818 // added after the request is started.
818 m_uploadEventsAllowed = m_sameOriginRequest || uploadEvents || !isSimpleCros sOriginAccessRequest(m_method, m_requestHeaders); 819 m_uploadEventsAllowed = m_sameOriginRequest || uploadEvents || !isSimpleCros sOriginAccessRequest(m_method, m_requestHeaders);
819 820
820 ASSERT(executionContext()); 821 ASSERT(executionContext());
821 ExecutionContext& executionContext = *this->executionContext(); 822 ExecutionContext& executionContext = *this->executionContext();
822 823
823 ResourceRequest request(m_url); 824 ResourceRequest request(m_url);
824 request.setHTTPMethod(m_method); 825 request.setHTTPMethod(m_method);
825 request.setTargetType(ResourceRequest::TargetIsXHR); 826 request.setTargetType(ResourceRequest::TargetIsXHR);
826 827
828 // When responseType is set to "blob", we redirect the downloaded data to a
829 // file-handle directly.
830 if (responseTypeCode() == ResponseTypeBlob)
831 request.setDownloadToFile(true);
832
827 InspectorInstrumentation::willLoadXHR(&executionContext, this, this, m_metho d, m_url, m_async, m_requestEntityBody ? m_requestEntityBody->deepCopy() : nullp tr, m_requestHeaders, m_includeCredentials); 833 InspectorInstrumentation::willLoadXHR(&executionContext, this, this, m_metho d, m_url, m_async, m_requestEntityBody ? m_requestEntityBody->deepCopy() : nullp tr, m_requestHeaders, m_includeCredentials);
828 834
829 if (m_requestEntityBody) { 835 if (m_requestEntityBody) {
830 ASSERT(m_method != "GET"); 836 ASSERT(m_method != "GET");
831 ASSERT(m_method != "HEAD"); 837 ASSERT(m_method != "HEAD");
832 request.setHTTPBody(m_requestEntityBody.release()); 838 request.setHTTPBody(m_requestEntityBody.release());
833 } 839 }
834 840
835 if (m_requestHeaders.size() > 0) 841 if (m_requestHeaders.size() > 0)
836 request.addHTTPHeaderFields(m_requestHeaders); 842 request.addHTTPHeaderFields(m_requestHeaders);
837 843
838 ThreadableLoaderOptions options; 844 ThreadableLoaderOptions options;
839 options.sniffContent = DoNotSniffContent; 845 options.sniffContent = DoNotSniffContent;
840 options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight; 846 options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight;
841 options.allowCredentials = (m_sameOriginRequest || m_includeCredentials) ? A llowStoredCredentials : DoNotAllowStoredCredentials; 847 options.allowCredentials = (m_sameOriginRequest || m_includeCredentials) ? A llowStoredCredentials : DoNotAllowStoredCredentials;
842 options.credentialsRequested = m_includeCredentials ? ClientRequestedCredent ials : ClientDidNotRequestCredentials; 848 options.credentialsRequested = m_includeCredentials ? ClientRequestedCredent ials : ClientDidNotRequestCredentials;
843 options.crossOriginRequestPolicy = UseAccessControl; 849 options.crossOriginRequestPolicy = UseAccessControl;
844 options.securityOrigin = securityOrigin(); 850 options.securityOrigin = securityOrigin();
845 options.initiator = FetchInitiatorTypeNames::xmlhttprequest; 851 options.initiator = FetchInitiatorTypeNames::xmlhttprequest;
846 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa ssMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceConn ectSrcDirective; 852 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa ssMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceConn ectSrcDirective;
847 // TODO(tsepez): Specify TreatAsActiveContent per http://crbug.com/305303. 853 // TODO(tsepez): Specify TreatAsActiveContent per http://crbug.com/305303.
848 options.mixedContentBlockingTreatment = TreatAsPassiveContent; 854 options.mixedContentBlockingTreatment = TreatAsPassiveContent;
849 options.timeoutMilliseconds = m_timeoutMilliseconds; 855 options.timeoutMilliseconds = m_timeoutMilliseconds;
850 856
857 // When responseType is set to "blob", we redirect the downloaded data to a
858 // file-handle directly. So, buffering is not needed.
859 if (responseTypeCode() == ResponseTypeBlob)
Nate Chapin 2014/06/02 16:59:51 Can we combine the two blob cases in this function
tyoshino (SeeGerritForStatus) 2014/06/04 04:39:50 Done.
860 options.dataBufferingPolicy = DoNotBufferData;
861
851 m_exceptionCode = 0; 862 m_exceptionCode = 0;
852 m_error = false; 863 m_error = false;
853 864
854 if (m_async) { 865 if (m_async) {
855 if (m_upload) 866 if (m_upload)
856 request.setReportUploadProgress(true); 867 request.setReportUploadProgress(true);
857 868
858 // ThreadableLoader::create can return null here, for example if we're n o longer attached to a page. 869 // ThreadableLoader::create can return null here, for example if we're n o longer attached to a page.
859 // This is true while running onunload handlers. 870 // This is true while running onunload handlers.
860 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload , <http://bugs.webkit.org/show_bug.cgi?id=10904>. 871 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload , <http://bugs.webkit.org/show_bug.cgi?id=10904>.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 m_receivedLength = 0; 975 m_receivedLength = 0;
965 976
966 m_response = ResourceResponse(); 977 m_response = ResourceResponse();
967 978
968 m_responseText.clear(); 979 m_responseText.clear();
969 980
970 m_createdDocument = false; 981 m_createdDocument = false;
971 m_responseDocument = nullptr; 982 m_responseDocument = nullptr;
972 983
973 m_responseBlob = nullptr; 984 m_responseBlob = nullptr;
985 m_downloadedBlobLength = 0;
974 986
975 m_responseStream = nullptr; 987 m_responseStream = nullptr;
976 988
977 // These variables may referred by the response accessors. So, we can clear 989 // These variables may referred by the response accessors. So, we can clear
978 // this only when we clear the response holder variables above. 990 // this only when we clear the response holder variables above.
979 m_binaryResponseBuilder.clear(); 991 m_binaryResponseBuilder.clear();
980 m_responseArrayBuffer.clear(); 992 m_responseArrayBuffer.clear();
981 } 993 }
982 994
983 void XMLHttpRequest::clearRequest() 995 void XMLHttpRequest::clearRequest()
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); 1313 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride);
1302 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride); 1314 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride);
1303 } 1315 }
1304 1316
1305 if (m_responseEncoding.isEmpty()) 1317 if (m_responseEncoding.isEmpty())
1306 m_responseEncoding = response.textEncodingName(); 1318 m_responseEncoding = response.textEncodingName();
1307 } 1319 }
1308 1320
1309 void XMLHttpRequest::didReceiveData(const char* data, int len) 1321 void XMLHttpRequest::didReceiveData(const char* data, int len)
1310 { 1322 {
1323 ASSERT(m_responseTypeCode != ResponseTypeBlob);
1324
1311 if (m_error) 1325 if (m_error)
1312 return; 1326 return;
1313 1327
1314 if (m_state < HEADERS_RECEIVED) 1328 if (m_state < HEADERS_RECEIVED)
1315 changeState(HEADERS_RECEIVED); 1329 changeState(HEADERS_RECEIVED);
1316 1330
1317 bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTyp eCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_respons eTypeCode == ResponseTypeDocument; 1331 bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTyp eCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_respons eTypeCode == ResponseTypeDocument;
1318 1332
1319 if (useDecoder && !m_decoder) { 1333 if (useDecoder && !m_decoder) {
1320 if (m_responseTypeCode == ResponseTypeJSON) 1334 if (m_responseTypeCode == ResponseTypeJSON)
(...skipping 12 matching lines...) Expand all
1333 } 1347 }
1334 1348
1335 if (!len) 1349 if (!len)
1336 return; 1350 return;
1337 1351
1338 if (len == -1) 1352 if (len == -1)
1339 len = strlen(data); 1353 len = strlen(data);
1340 1354
1341 if (useDecoder) { 1355 if (useDecoder) {
1342 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); 1356 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len));
1343 } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCo de == ResponseTypeBlob) { 1357 } else if (m_responseTypeCode == ResponseTypeArrayBuffer) {
1344 // Buffer binary data. 1358 // Buffer binary data.
1345 if (!m_binaryResponseBuilder) 1359 if (!m_binaryResponseBuilder)
1346 m_binaryResponseBuilder = SharedBuffer::create(); 1360 m_binaryResponseBuilder = SharedBuffer::create();
1347 m_binaryResponseBuilder->append(data, len); 1361 m_binaryResponseBuilder->append(data, len);
1348 } else if (m_responseTypeCode == ResponseTypeStream) { 1362 } else if (m_responseTypeCode == ResponseTypeStream) {
1349 if (!m_responseStream) 1363 if (!m_responseStream)
1350 m_responseStream = Stream::create(executionContext(), responseMIMETy pe()); 1364 m_responseStream = Stream::create(executionContext(), responseMIMETy pe());
1351 m_responseStream->addData(data, len); 1365 m_responseStream->addData(data, len);
1352 } 1366 }
1353 1367
1354 if (m_error) 1368 if (m_error)
1355 return; 1369 return;
1356 1370
1357 trackProgress(len); 1371 trackProgress(len);
1358 } 1372 }
1359 1373
1374 void XMLHttpRequest::didDownloadData(int dataLength)
1375 {
1376 ASSERT(m_responseTypeCode == ResponseTypeBlob);
1377
1378 if (m_error)
1379 return;
1380
1381 if (m_state < HEADERS_RECEIVED)
1382 changeState(HEADERS_RECEIVED);
1383
1384 if (!dataLength)
1385 return;
1386
1387 if (m_error)
Nate Chapin 2014/06/02 16:59:51 This looks redundant. Can changeState cancel the X
tyoshino (SeeGerritForStatus) 2014/06/04 04:39:50 Yes. We need this. changeState() calls readystatec
1388 return;
1389
1390 m_downloadedBlobLength += dataLength;
1391
1392 trackProgress(dataLength);
1393 }
1394
1360 void XMLHttpRequest::handleDidTimeout() 1395 void XMLHttpRequest::handleDidTimeout()
1361 { 1396 {
1362 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); 1397 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
1363 1398
1364 // internalAbort() calls dropProtection(), which may release the last refere nce. 1399 // internalAbort() calls dropProtection(), which may release the last refere nce.
1365 RefPtrWillBeRawPtr<XMLHttpRequest> protect(this); 1400 RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
1366 1401
1367 // Response is cleared next, save needed progress event data. 1402 // Response is cleared next, save needed progress event data.
1368 long long expectedLength = m_response.expectedContentLength(); 1403 long long expectedLength = m_response.expectedContentLength();
1369 long long receivedLength = m_receivedLength; 1404 long long receivedLength = m_receivedLength;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 { 1445 {
1411 visitor->trace(m_responseBlob); 1446 visitor->trace(m_responseBlob);
1412 visitor->trace(m_responseStream); 1447 visitor->trace(m_responseStream);
1413 visitor->trace(m_responseDocument); 1448 visitor->trace(m_responseDocument);
1414 visitor->trace(m_progressEventThrottle); 1449 visitor->trace(m_progressEventThrottle);
1415 visitor->trace(m_upload); 1450 visitor->trace(m_upload);
1416 XMLHttpRequestEventTarget::trace(visitor); 1451 XMLHttpRequestEventTarget::trace(visitor);
1417 } 1452 }
1418 1453
1419 } // namespace WebCore 1454 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698