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

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: 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
« 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 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_lengthDownloadedToFile(0)
150 , m_receivedLength(0) 150 , m_receivedLength(0)
151 , m_lastSendLineNumber(0) 151 , m_lastSendLineNumber(0)
152 , m_exceptionCode(0) 152 , m_exceptionCode(0)
153 , m_progressEventThrottle(this) 153 , m_progressEventThrottle(this)
154 , m_responseTypeCode(ResponseTypeDefault) 154 , m_responseTypeCode(ResponseTypeDefault)
155 , m_securityOrigin(securityOrigin) 155 , m_securityOrigin(securityOrigin)
156 , m_async(true) 156 , m_async(true)
157 , m_includeCredentials(false) 157 , m_includeCredentials(false)
158 , m_parsedResponse(false) 158 , m_parsedResponse(false)
159 , m_error(false) 159 , m_error(false)
160 , m_uploadEventsAllowed(true) 160 , m_uploadEventsAllowed(true)
161 , m_uploadComplete(false) 161 , m_uploadComplete(false)
162 , m_sameOriginRequest(true) 162 , m_sameOriginRequest(true)
163 , m_downloadingToFile(false)
163 { 164 {
164 #ifndef NDEBUG 165 #ifndef NDEBUG
165 xmlHttpRequestCounter.increment(); 166 xmlHttpRequestCounter.increment();
166 #endif 167 #endif
167 } 168 }
168 169
169 XMLHttpRequest::~XMLHttpRequest() 170 XMLHttpRequest::~XMLHttpRequest()
170 { 171 {
171 #ifndef NDEBUG 172 #ifndef NDEBUG
172 xmlHttpRequestCounter.decrement(); 173 xmlHttpRequestCounter.decrement();
(...skipping 81 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() ) {
293 RefPtr<RawData> rawData = RawData::create();
294 size = m_binaryResponseBuilder->size();
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 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 options.timeoutMilliseconds = m_timeoutMilliseconds; 861 options.timeoutMilliseconds = m_timeoutMilliseconds;
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 m_downloadingToFile = responseTypeCode() == ResponseTypeBlob;
872 if (m_downloadingToFile) {
857 request.setDownloadToFile(true); 873 request.setDownloadToFile(true);
858 resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData; 874 resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData;
859 } 875 }
860 876
861 m_exceptionCode = 0; 877 m_exceptionCode = 0;
862 m_error = false; 878 m_error = false;
863 879
864 if (m_async) { 880 if (m_async) {
865 if (m_upload) 881 if (m_upload)
866 request.setReportUploadProgress(true); 882 request.setReportUploadProgress(true);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 m_receivedLength = 0; 991 m_receivedLength = 0;
976 992
977 m_response = ResourceResponse(); 993 m_response = ResourceResponse();
978 994
979 m_responseText.clear(); 995 m_responseText.clear();
980 996
981 m_parsedResponse = false; 997 m_parsedResponse = false;
982 m_responseDocument = nullptr; 998 m_responseDocument = nullptr;
983 999
984 m_responseBlob = nullptr; 1000 m_responseBlob = nullptr;
985 m_downloadedBlobLength = 0; 1001
1002 m_downloadingToFile = false;
1003 m_lengthDownloadedToFile = 0;
986 1004
987 m_responseLegacyStream = nullptr; 1005 m_responseLegacyStream = nullptr;
988 m_responseStream = nullptr; 1006 m_responseStream = nullptr;
989 1007
990 // These variables may referred by the response accessors. So, we can clear 1008 // These variables may referred by the response accessors. So, we can clear
991 // this only when we clear the response holder variables above. 1009 // this only when we clear the response holder variables above.
992 m_binaryResponseBuilder.clear(); 1010 m_binaryResponseBuilder.clear();
993 m_responseArrayBuffer.clear(); 1011 m_responseArrayBuffer.clear();
994 } 1012 }
995 1013
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 } 1430 }
1413 1431
1414 if (responseIsHTML()) 1432 if (responseIsHTML())
1415 return TextResourceDecoder::create("text/html", "UTF-8"); 1433 return TextResourceDecoder::create("text/html", "UTF-8");
1416 1434
1417 return TextResourceDecoder::create("text/plain", "UTF-8"); 1435 return TextResourceDecoder::create("text/plain", "UTF-8");
1418 } 1436 }
1419 1437
1420 void XMLHttpRequest::didReceiveData(const char* data, int len) 1438 void XMLHttpRequest::didReceiveData(const char* data, int len)
1421 { 1439 {
1422 ASSERT(m_responseTypeCode != ResponseTypeBlob); 1440 ASSERT(!m_downloadingToFile);
1423 1441
1424 if (m_error) 1442 if (m_error)
1425 return; 1443 return;
1426 1444
1427 if (m_state < HEADERS_RECEIVED) 1445 if (m_state < HEADERS_RECEIVED)
1428 changeState(HEADERS_RECEIVED); 1446 changeState(HEADERS_RECEIVED);
1429 1447
1430 if (!len) 1448 if (!len)
1431 return; 1449 return;
1432 1450
1433 if (len == -1) 1451 if (len == -1)
1434 len = strlen(data); 1452 len = strlen(data);
1435 1453
1436 if (m_responseTypeCode == ResponseTypeDocument && responseIsHTML()) { 1454 if (m_responseTypeCode == ResponseTypeDocument && responseIsHTML()) {
1437 parseDocumentChunk(data, len); 1455 parseDocumentChunk(data, len);
1438 } else if (m_responseTypeCode == ResponseTypeDefault || m_responseTypeCode = = ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_responseTypeCo de == ResponseTypeDocument) { 1456 } else if (m_responseTypeCode == ResponseTypeDefault || m_responseTypeCode = = ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_responseTypeCo de == ResponseTypeDocument) {
1439 if (!m_decoder) 1457 if (!m_decoder)
1440 m_decoder = createDecoder(); 1458 m_decoder = createDecoder();
1441 1459
1442 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); 1460 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len));
1443 } else if (m_responseTypeCode == ResponseTypeArrayBuffer) { 1461 } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCo de == ResponseTypeBlob) {
1444 // Buffer binary data. 1462 // Buffer binary data.
1445 if (!m_binaryResponseBuilder) 1463 if (!m_binaryResponseBuilder)
1446 m_binaryResponseBuilder = SharedBuffer::create(); 1464 m_binaryResponseBuilder = SharedBuffer::create();
1447 m_binaryResponseBuilder->append(data, len); 1465 m_binaryResponseBuilder->append(data, len);
1448 } else if (m_responseTypeCode == ResponseTypeLegacyStream) { 1466 } else if (m_responseTypeCode == ResponseTypeLegacyStream) {
1449 if (!m_responseLegacyStream) 1467 if (!m_responseLegacyStream)
1450 m_responseLegacyStream = Stream::create(executionContext(), response Type()); 1468 m_responseLegacyStream = Stream::create(executionContext(), response Type());
1451 m_responseLegacyStream->addData(data, len); 1469 m_responseLegacyStream->addData(data, len);
1452 } else if (m_responseTypeCode == ResponseTypeStream) { 1470 } else if (m_responseTypeCode == ResponseTypeStream) {
1453 if (!m_responseStream) { 1471 if (!m_responseStream) {
1454 m_responseStream = new ReadableStreamImpl<ReadableStreamChunkTypeTra its<ArrayBuffer> >(executionContext(), new ReadableStreamSource(this)); 1472 m_responseStream = new ReadableStreamImpl<ReadableStreamChunkTypeTra its<ArrayBuffer> >(executionContext(), new ReadableStreamSource(this));
1455 m_responseStream->didSourceStart(); 1473 m_responseStream->didSourceStart();
1456 } 1474 }
1457 m_responseStream->enqueue(ArrayBuffer::create(data, len)); 1475 m_responseStream->enqueue(ArrayBuffer::create(data, len));
1458 } 1476 }
1459 1477
1460 if (m_error) 1478 if (m_error)
1461 return; 1479 return;
1462 1480
1463 trackProgress(len); 1481 trackProgress(len);
1464 } 1482 }
1465 1483
1466 void XMLHttpRequest::didDownloadData(int dataLength) 1484 void XMLHttpRequest::didDownloadData(int dataLength)
1467 { 1485 {
1468 ASSERT(m_responseTypeCode == ResponseTypeBlob);
1469
1470 if (m_error) 1486 if (m_error)
1471 return; 1487 return;
1472 1488
1489 ASSERT(m_downloadingToFile);
1490
1473 if (m_state < HEADERS_RECEIVED) 1491 if (m_state < HEADERS_RECEIVED)
1474 changeState(HEADERS_RECEIVED); 1492 changeState(HEADERS_RECEIVED);
1475 1493
1476 if (!dataLength) 1494 if (!dataLength)
1477 return; 1495 return;
1478 1496
1479 // readystatechange event handler may do something to put this XHR in error 1497 // readystatechange event handler may do something to put this XHR in error
1480 // state. We need to check m_error again here. 1498 // state. We need to check m_error again here.
1481 if (m_error) 1499 if (m_error)
1482 return; 1500 return;
1483 1501
1484 m_downloadedBlobLength += dataLength; 1502 m_lengthDownloadedToFile += dataLength;
1485 1503
1486 trackProgress(dataLength); 1504 trackProgress(dataLength);
1487 } 1505 }
1488 1506
1489 void XMLHttpRequest::handleDidTimeout() 1507 void XMLHttpRequest::handleDidTimeout()
1490 { 1508 {
1491 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); 1509 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
1492 1510
1493 // Response is cleared next, save needed progress event data. 1511 // Response is cleared next, save needed progress event data.
1494 long long expectedLength = m_response.expectedContentLength(); 1512 long long expectedLength = m_response.expectedContentLength();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1547 visitor->trace(m_responseStream); 1565 visitor->trace(m_responseStream);
1548 visitor->trace(m_streamSource); 1566 visitor->trace(m_streamSource);
1549 visitor->trace(m_responseDocument); 1567 visitor->trace(m_responseDocument);
1550 visitor->trace(m_responseDocumentParser); 1568 visitor->trace(m_responseDocumentParser);
1551 visitor->trace(m_progressEventThrottle); 1569 visitor->trace(m_progressEventThrottle);
1552 visitor->trace(m_upload); 1570 visitor->trace(m_upload);
1553 XMLHttpRequestEventTarget::trace(visitor); 1571 XMLHttpRequestEventTarget::trace(visitor);
1554 } 1572 }
1555 1573
1556 } // namespace blink 1574 } // namespace blink
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