OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |