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

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

Issue 562563003: [XHR] Accept data on didReceiveData call even if responseType is set to Blob (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Addressed #4 Created 6 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
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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 xmlHttpRequest->suspendIfNeeded(); 139 xmlHttpRequest->suspendIfNeeded();
140 140
141 return xmlHttpRequest.release(); 141 return xmlHttpRequest.release();
142 } 142 }
143 143
144 XMLHttpRequest::XMLHttpRequest(ExecutionContext* context, PassRefPtr<SecurityOri gin> securityOrigin) 144 XMLHttpRequest::XMLHttpRequest(ExecutionContext* context, PassRefPtr<SecurityOri gin> securityOrigin)
145 : ActiveDOMObject(context) 145 : ActiveDOMObject(context)
146 , m_timeoutMilliseconds(0) 146 , m_timeoutMilliseconds(0)
147 , m_loaderIdentifier(0) 147 , m_loaderIdentifier(0)
148 , m_state(UNSENT) 148 , m_state(UNSENT)
149 , m_downloadedBlobLength(0) 149 , m_downloadingToFile(false)
150 , m_lengthDownloadedToFile(0)
150 , m_receivedLength(0) 151 , m_receivedLength(0)
151 , m_lastSendLineNumber(0) 152 , m_lastSendLineNumber(0)
152 , m_exceptionCode(0) 153 , m_exceptionCode(0)
153 , m_progressEventThrottle(this) 154 , m_progressEventThrottle(this)
154 , m_responseTypeCode(ResponseTypeDefault) 155 , m_responseTypeCode(ResponseTypeDefault)
155 , m_securityOrigin(securityOrigin) 156 , m_securityOrigin(securityOrigin)
156 , m_async(true) 157 , m_async(true)
157 , m_includeCredentials(false) 158 , m_includeCredentials(false)
158 , m_parsedResponse(false) 159 , m_parsedResponse(false)
159 , m_error(false) 160 , m_error(false)
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 255
255 m_parsedResponse = true; 256 m_parsedResponse = true;
256 } 257 }
257 258
258 return m_responseDocument.get(); 259 return m_responseDocument.get();
259 } 260 }
260 261
261 Blob* XMLHttpRequest::responseBlob() 262 Blob* XMLHttpRequest::responseBlob()
262 { 263 {
263 ASSERT(m_responseTypeCode == ResponseTypeBlob); 264 ASSERT(m_responseTypeCode == ResponseTypeBlob);
264 ASSERT(!m_binaryResponseBuilder.get());
265 265
266 // We always return null before DONE. 266 // We always return null before DONE.
267 if (m_error || m_state != DONE) 267 if (m_error || m_state != DONE)
268 return 0; 268 return 0;
269 269
270 if (!m_responseBlob) { 270 if (!m_responseBlob) {
271 // When responseType is set to "blob", we redirect the downloaded data
272 // to a file-handle directly in the browser process. We get the
273 // file-path from the ResourceResponse directly instead of copying the
274 // bytes between the browser and the renderer.
275 OwnPtr<BlobData> blobData = BlobData::create(); 271 OwnPtr<BlobData> blobData = BlobData::create();
276 String filePath = m_response.downloadedFilePath(); 272 if (m_downloadingToFile) {
277 // If we errored out or got no data, we still return a blob, just an 273 ASSERT(!m_binaryResponseBuilder.get());
278 // empty one. 274
279 if (!filePath.isEmpty() && m_downloadedBlobLength) { 275 // When responseType is set to "blob", we redirect the downloaded
280 blobData->appendFile(filePath); 276 // data to a file-handle directly in the browser process. We get
281 // FIXME: finalResponseMIMETypeWithFallback() defaults to text/xml 277 // the file-path from the ResourceResponse directly instead of
282 // which may be incorrect. Replace it with finalResponseMIMEType() 278 // copying the bytes between the browser and the renderer.
283 // after compatibility investigation. 279 String filePath = m_response.downloadedFilePath();
284 blobData->setContentType(finalResponseMIMETypeWithFallback()); 280 // If we errored out or got no data, we still return a blob, just
281 // an empty one.
282 if (!filePath.isEmpty() && m_lengthDownloadedToFile) {
283 blobData->appendFile(filePath);
284 // FIXME: finalResponseMIMETypeWithFallback() defaults to
285 // text/xml which may be incorrect. Replace it with
286 // finalResponseMIMEType() after compatibility investigation.
287 blobData->setContentType(finalResponseMIMETypeWithFallback());
288 }
289 m_responseBlob = Blob::create(BlobDataHandle::create(blobData.releas e(), m_lengthDownloadedToFile));
290 } else {
291 size_t size = 0;
292 if (m_binaryResponseBuilder.get() && m_binaryResponseBuilder->size() > 0) {
sof 2014/09/10 14:21:39 Can be shortened to if (m_binaryResponseBuilde
tyoshino (SeeGerritForStatus) 2014/09/11 04:30:57 Done.
293 RefPtr<RawData> rawData = RawData::create();
294 size = m_binaryResponseBuilder->size();
sof 2014/09/10 14:21:39 What happens if size_t is signed and MSB of the re
sof 2014/09/10 20:24:10 Please disregard, a non-issue. But couldn't this b
tyoshino (SeeGerritForStatus) 2014/09/11 04:30:57 Sounds good. I'll do it
295 rawData->mutableData()->append(m_binaryResponseBuilder->data(), size);
296 blobData->appendData(rawData, 0, BlobDataItem::toEndOfFile);
297 blobData->setContentType(finalResponseMIMETypeWithFallback());
298 m_binaryResponseBuilder.clear();
299 }
300 m_responseBlob = Blob::create(BlobDataHandle::create(blobData.releas e(), size));
285 } 301 }
286 m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), m_downloadedBlobLength));
287 } 302 }
288 303
289 return m_responseBlob.get(); 304 return m_responseBlob.get();
290 } 305 }
291 306
292 ArrayBuffer* XMLHttpRequest::responseArrayBuffer() 307 ArrayBuffer* XMLHttpRequest::responseArrayBuffer()
293 { 308 {
294 ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer); 309 ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer);
295 310
296 if (m_error || m_state != DONE) 311 if (m_error || m_state != DONE)
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 862
848 ResourceLoaderOptions resourceLoaderOptions; 863 ResourceLoaderOptions resourceLoaderOptions;
849 resourceLoaderOptions.allowCredentials = (m_sameOriginRequest || m_includeCr edentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials; 864 resourceLoaderOptions.allowCredentials = (m_sameOriginRequest || m_includeCr edentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
850 resourceLoaderOptions.credentialsRequested = m_includeCredentials ? ClientRe questedCredentials : ClientDidNotRequestCredentials; 865 resourceLoaderOptions.credentialsRequested = m_includeCredentials ? ClientRe questedCredentials : ClientDidNotRequestCredentials;
851 resourceLoaderOptions.securityOrigin = securityOrigin(); 866 resourceLoaderOptions.securityOrigin = securityOrigin();
852 resourceLoaderOptions.mixedContentBlockingTreatment = RuntimeEnabledFeatures ::laxMixedContentCheckingEnabled() ? TreatAsPassiveContent : TreatAsActiveConten t; 867 resourceLoaderOptions.mixedContentBlockingTreatment = RuntimeEnabledFeatures ::laxMixedContentCheckingEnabled() ? TreatAsPassiveContent : TreatAsActiveConten t;
853 868
854 // When responseType is set to "blob", we redirect the downloaded data to a 869 // When responseType is set to "blob", we redirect the downloaded data to a
855 // file-handle directly. 870 // file-handle directly.
856 if (responseTypeCode() == ResponseTypeBlob) { 871 if (responseTypeCode() == ResponseTypeBlob) {
872 m_downloadingToFile = true;
sof 2014/09/10 14:21:39 Move out of "if" as, m_downloadingToFile = resp
tyoshino (SeeGerritForStatus) 2014/09/11 04:30:57 Nice! Done
857 request.setDownloadToFile(true); 873 request.setDownloadToFile(true);
858 resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData; 874 resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData;
875 } else {
876 m_downloadingToFile = false;
859 } 877 }
860 878
861 m_exceptionCode = 0; 879 m_exceptionCode = 0;
862 m_error = false; 880 m_error = false;
863 881
864 if (m_async) { 882 if (m_async) {
865 if (m_upload) 883 if (m_upload)
866 request.setReportUploadProgress(true); 884 request.setReportUploadProgress(true);
867 885
868 // ThreadableLoader::create can return null here, for example if we're n o longer attached to a page. 886 // ThreadableLoader::create can return null here, for example if we're n o longer attached to a page.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 m_receivedLength = 0; 993 m_receivedLength = 0;
976 994
977 m_response = ResourceResponse(); 995 m_response = ResourceResponse();
978 996
979 m_responseText.clear(); 997 m_responseText.clear();
980 998
981 m_parsedResponse = false; 999 m_parsedResponse = false;
982 m_responseDocument = nullptr; 1000 m_responseDocument = nullptr;
983 1001
984 m_responseBlob = nullptr; 1002 m_responseBlob = nullptr;
985 m_downloadedBlobLength = 0; 1003
1004 m_downloadingToFile = false;
1005 m_lengthDownloadedToFile = 0;
986 1006
987 m_responseLegacyStream = nullptr; 1007 m_responseLegacyStream = nullptr;
988 m_responseStream = nullptr; 1008 m_responseStream = nullptr;
989 1009
990 // These variables may referred by the response accessors. So, we can clear 1010 // These variables may referred by the response accessors. So, we can clear
991 // this only when we clear the response holder variables above. 1011 // this only when we clear the response holder variables above.
992 m_binaryResponseBuilder.clear(); 1012 m_binaryResponseBuilder.clear();
993 m_responseArrayBuffer.clear(); 1013 m_responseArrayBuffer.clear();
994 } 1014 }
995 1015
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 } 1432 }
1413 1433
1414 if (responseIsHTML()) 1434 if (responseIsHTML())
1415 return TextResourceDecoder::create("text/html", "UTF-8"); 1435 return TextResourceDecoder::create("text/html", "UTF-8");
1416 1436
1417 return TextResourceDecoder::create("text/plain", "UTF-8"); 1437 return TextResourceDecoder::create("text/plain", "UTF-8");
1418 } 1438 }
1419 1439
1420 void XMLHttpRequest::didReceiveData(const char* data, int len) 1440 void XMLHttpRequest::didReceiveData(const char* data, int len)
1421 { 1441 {
1422 ASSERT(m_responseTypeCode != ResponseTypeBlob); 1442 ASSERT(!m_downloadingToFile);
1423 1443
1424 if (m_error) 1444 if (m_error)
1425 return; 1445 return;
1426 1446
1427 if (m_state < HEADERS_RECEIVED) 1447 if (m_state < HEADERS_RECEIVED)
1428 changeState(HEADERS_RECEIVED); 1448 changeState(HEADERS_RECEIVED);
1429 1449
1430 if (!len) 1450 if (!len)
1431 return; 1451 return;
1432 1452
1433 if (len == -1) 1453 if (len == -1)
1434 len = strlen(data); 1454 len = strlen(data);
1435 1455
1436 if (m_responseTypeCode == ResponseTypeDocument && responseIsHTML()) { 1456 if (m_responseTypeCode == ResponseTypeDocument && responseIsHTML()) {
1437 parseDocumentChunk(data, len); 1457 parseDocumentChunk(data, len);
1438 } else if (m_responseTypeCode == ResponseTypeDefault || m_responseTypeCode = = ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_responseTypeCo de == ResponseTypeDocument) { 1458 } else if (m_responseTypeCode == ResponseTypeDefault || m_responseTypeCode = = ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_responseTypeCo de == ResponseTypeDocument) {
1439 if (!m_decoder) 1459 if (!m_decoder)
1440 m_decoder = createDecoder(); 1460 m_decoder = createDecoder();
1441 1461
1442 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); 1462 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len));
1443 } else if (m_responseTypeCode == ResponseTypeArrayBuffer) { 1463 } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCo de == ResponseTypeBlob) {
1444 // Buffer binary data. 1464 // Buffer binary data.
1445 if (!m_binaryResponseBuilder) 1465 if (!m_binaryResponseBuilder)
1446 m_binaryResponseBuilder = SharedBuffer::create(); 1466 m_binaryResponseBuilder = SharedBuffer::create();
1447 m_binaryResponseBuilder->append(data, len); 1467 m_binaryResponseBuilder->append(data, len);
1448 } else if (m_responseTypeCode == ResponseTypeLegacyStream) { 1468 } else if (m_responseTypeCode == ResponseTypeLegacyStream) {
1449 if (!m_responseLegacyStream) 1469 if (!m_responseLegacyStream)
1450 m_responseLegacyStream = Stream::create(executionContext(), response Type()); 1470 m_responseLegacyStream = Stream::create(executionContext(), response Type());
1451 m_responseLegacyStream->addData(data, len); 1471 m_responseLegacyStream->addData(data, len);
1452 } else if (m_responseTypeCode == ResponseTypeStream) { 1472 } else if (m_responseTypeCode == ResponseTypeStream) {
1453 if (!m_responseStream) { 1473 if (!m_responseStream) {
1454 m_responseStream = new ReadableStreamImpl<ReadableStreamChunkTypeTra its<ArrayBuffer> >(executionContext(), new ReadableStreamSource(this)); 1474 m_responseStream = new ReadableStreamImpl<ReadableStreamChunkTypeTra its<ArrayBuffer> >(executionContext(), new ReadableStreamSource(this));
1455 m_responseStream->didSourceStart(); 1475 m_responseStream->didSourceStart();
1456 } 1476 }
1457 m_responseStream->enqueue(ArrayBuffer::create(data, len)); 1477 m_responseStream->enqueue(ArrayBuffer::create(data, len));
1458 } 1478 }
1459 1479
1460 if (m_error) 1480 if (m_error)
1461 return; 1481 return;
1462 1482
1463 trackProgress(len); 1483 trackProgress(len);
1464 } 1484 }
1465 1485
1466 void XMLHttpRequest::didDownloadData(int dataLength) 1486 void XMLHttpRequest::didDownloadData(int dataLength)
1467 { 1487 {
1468 ASSERT(m_responseTypeCode == ResponseTypeBlob);
1469
1470 if (m_error) 1488 if (m_error)
1471 return; 1489 return;
1472 1490
1491 ASSERT(m_downloadingToFile);
1492
1473 if (m_state < HEADERS_RECEIVED) 1493 if (m_state < HEADERS_RECEIVED)
1474 changeState(HEADERS_RECEIVED); 1494 changeState(HEADERS_RECEIVED);
1475 1495
1476 if (!dataLength) 1496 if (!dataLength)
1477 return; 1497 return;
1478 1498
1479 // readystatechange event handler may do something to put this XHR in error 1499 // readystatechange event handler may do something to put this XHR in error
1480 // state. We need to check m_error again here. 1500 // state. We need to check m_error again here.
1481 if (m_error) 1501 if (m_error)
1482 return; 1502 return;
1483 1503
1484 m_downloadedBlobLength += dataLength; 1504 m_lengthDownloadedToFile += dataLength;
1485 1505
1486 trackProgress(dataLength); 1506 trackProgress(dataLength);
1487 } 1507 }
1488 1508
1489 void XMLHttpRequest::handleDidTimeout() 1509 void XMLHttpRequest::handleDidTimeout()
1490 { 1510 {
1491 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); 1511 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
1492 1512
1493 // Response is cleared next, save needed progress event data. 1513 // Response is cleared next, save needed progress event data.
1494 long long expectedLength = m_response.expectedContentLength(); 1514 long long expectedLength = m_response.expectedContentLength();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1547 visitor->trace(m_responseStream); 1567 visitor->trace(m_responseStream);
1548 visitor->trace(m_streamSource); 1568 visitor->trace(m_streamSource);
1549 visitor->trace(m_responseDocument); 1569 visitor->trace(m_responseDocument);
1550 visitor->trace(m_responseDocumentParser); 1570 visitor->trace(m_responseDocumentParser);
1551 visitor->trace(m_progressEventThrottle); 1571 visitor->trace(m_progressEventThrottle);
1552 visitor->trace(m_upload); 1572 visitor->trace(m_upload);
1553 XMLHttpRequestEventTarget::trace(visitor); 1573 XMLHttpRequestEventTarget::trace(visitor);
1554 } 1574 }
1555 1575
1556 } // namespace blink 1576 } // namespace blink
OLDNEW
« Source/core/xml/XMLHttpRequest.h ('K') | « Source/core/xml/XMLHttpRequest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698