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 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa
ssMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceConn
ectSrcDirective; | 848 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa
ssMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceConn
ectSrcDirective; |
848 options.timeoutMilliseconds = m_timeoutMilliseconds; | 849 options.timeoutMilliseconds = m_timeoutMilliseconds; |
849 | 850 |
850 ResourceLoaderOptions resourceLoaderOptions; | 851 ResourceLoaderOptions resourceLoaderOptions; |
851 resourceLoaderOptions.allowCredentials = (m_sameOriginRequest || m_includeCr
edentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials; | 852 resourceLoaderOptions.allowCredentials = (m_sameOriginRequest || m_includeCr
edentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials; |
852 resourceLoaderOptions.credentialsRequested = m_includeCredentials ? ClientRe
questedCredentials : ClientDidNotRequestCredentials; | 853 resourceLoaderOptions.credentialsRequested = m_includeCredentials ? ClientRe
questedCredentials : ClientDidNotRequestCredentials; |
853 resourceLoaderOptions.securityOrigin = securityOrigin(); | 854 resourceLoaderOptions.securityOrigin = securityOrigin(); |
854 // TODO(tsepez): Specify TreatAsActiveContent per http://crbug.com/305303. | 855 // TODO(tsepez): Specify TreatAsActiveContent per http://crbug.com/305303. |
855 resourceLoaderOptions.mixedContentBlockingTreatment = TreatAsPassiveContent; | 856 resourceLoaderOptions.mixedContentBlockingTreatment = TreatAsPassiveContent; |
856 | 857 |
| 858 // When responseType is set to "blob", we redirect the downloaded data to a |
| 859 // file-handle directly. |
| 860 if (responseTypeCode() == ResponseTypeBlob) { |
| 861 request.setDownloadToFile(true); |
| 862 resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData; |
| 863 } |
| 864 |
857 m_exceptionCode = 0; | 865 m_exceptionCode = 0; |
858 m_error = false; | 866 m_error = false; |
859 | 867 |
860 if (m_async) { | 868 if (m_async) { |
861 if (m_upload) | 869 if (m_upload) |
862 request.setReportUploadProgress(true); | 870 request.setReportUploadProgress(true); |
863 | 871 |
864 // ThreadableLoader::create can return null here, for example if we're n
o longer attached to a page. | 872 // ThreadableLoader::create can return null here, for example if we're n
o longer attached to a page. |
865 // This is true while running onunload handlers. | 873 // This is true while running onunload handlers. |
866 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload
, <http://bugs.webkit.org/show_bug.cgi?id=10904>. | 874 // 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... |
970 m_receivedLength = 0; | 978 m_receivedLength = 0; |
971 | 979 |
972 m_response = ResourceResponse(); | 980 m_response = ResourceResponse(); |
973 | 981 |
974 m_responseText.clear(); | 982 m_responseText.clear(); |
975 | 983 |
976 m_createdDocument = false; | 984 m_createdDocument = false; |
977 m_responseDocument = nullptr; | 985 m_responseDocument = nullptr; |
978 | 986 |
979 m_responseBlob = nullptr; | 987 m_responseBlob = nullptr; |
| 988 m_downloadedBlobLength = 0; |
980 | 989 |
981 m_responseStream = nullptr; | 990 m_responseStream = nullptr; |
982 | 991 |
983 // These variables may referred by the response accessors. So, we can clear | 992 // These variables may referred by the response accessors. So, we can clear |
984 // this only when we clear the response holder variables above. | 993 // this only when we clear the response holder variables above. |
985 m_binaryResponseBuilder.clear(); | 994 m_binaryResponseBuilder.clear(); |
986 m_responseArrayBuffer.clear(); | 995 m_responseArrayBuffer.clear(); |
987 } | 996 } |
988 | 997 |
989 void XMLHttpRequest::clearRequest() | 998 void XMLHttpRequest::clearRequest() |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); | 1316 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); |
1308 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride); | 1317 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride); |
1309 } | 1318 } |
1310 | 1319 |
1311 if (m_responseEncoding.isEmpty()) | 1320 if (m_responseEncoding.isEmpty()) |
1312 m_responseEncoding = response.textEncodingName(); | 1321 m_responseEncoding = response.textEncodingName(); |
1313 } | 1322 } |
1314 | 1323 |
1315 void XMLHttpRequest::didReceiveData(const char* data, int len) | 1324 void XMLHttpRequest::didReceiveData(const char* data, int len) |
1316 { | 1325 { |
| 1326 ASSERT(m_responseTypeCode != ResponseTypeBlob); |
| 1327 |
1317 if (m_error) | 1328 if (m_error) |
1318 return; | 1329 return; |
1319 | 1330 |
1320 if (m_state < HEADERS_RECEIVED) | 1331 if (m_state < HEADERS_RECEIVED) |
1321 changeState(HEADERS_RECEIVED); | 1332 changeState(HEADERS_RECEIVED); |
1322 | 1333 |
1323 bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTyp
eCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_respons
eTypeCode == ResponseTypeDocument; | 1334 bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTyp
eCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_respons
eTypeCode == ResponseTypeDocument; |
1324 | 1335 |
1325 if (useDecoder && !m_decoder) { | 1336 if (useDecoder && !m_decoder) { |
1326 if (m_responseTypeCode == ResponseTypeJSON) | 1337 if (m_responseTypeCode == ResponseTypeJSON) |
(...skipping 12 matching lines...) Expand all Loading... |
1339 } | 1350 } |
1340 | 1351 |
1341 if (!len) | 1352 if (!len) |
1342 return; | 1353 return; |
1343 | 1354 |
1344 if (len == -1) | 1355 if (len == -1) |
1345 len = strlen(data); | 1356 len = strlen(data); |
1346 | 1357 |
1347 if (useDecoder) { | 1358 if (useDecoder) { |
1348 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data,
len)); | 1359 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data,
len)); |
1349 } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCo
de == ResponseTypeBlob) { | 1360 } else if (m_responseTypeCode == ResponseTypeArrayBuffer) { |
1350 // Buffer binary data. | 1361 // Buffer binary data. |
1351 if (!m_binaryResponseBuilder) | 1362 if (!m_binaryResponseBuilder) |
1352 m_binaryResponseBuilder = SharedBuffer::create(); | 1363 m_binaryResponseBuilder = SharedBuffer::create(); |
1353 m_binaryResponseBuilder->append(data, len); | 1364 m_binaryResponseBuilder->append(data, len); |
1354 } else if (m_responseTypeCode == ResponseTypeStream) { | 1365 } else if (m_responseTypeCode == ResponseTypeStream) { |
1355 if (!m_responseStream) | 1366 if (!m_responseStream) |
1356 m_responseStream = Stream::create(executionContext(), responseMIMETy
pe()); | 1367 m_responseStream = Stream::create(executionContext(), responseMIMETy
pe()); |
1357 m_responseStream->addData(data, len); | 1368 m_responseStream->addData(data, len); |
1358 } | 1369 } |
1359 | 1370 |
1360 if (m_error) | 1371 if (m_error) |
1361 return; | 1372 return; |
1362 | 1373 |
1363 trackProgress(len); | 1374 trackProgress(len); |
1364 } | 1375 } |
1365 | 1376 |
| 1377 void XMLHttpRequest::didDownloadData(int dataLength) |
| 1378 { |
| 1379 ASSERT(m_responseTypeCode == ResponseTypeBlob); |
| 1380 |
| 1381 if (m_error) |
| 1382 return; |
| 1383 |
| 1384 if (m_state < HEADERS_RECEIVED) |
| 1385 changeState(HEADERS_RECEIVED); |
| 1386 |
| 1387 if (!dataLength) |
| 1388 return; |
| 1389 |
| 1390 // readystatechange event handler may do something to put this XHR in error |
| 1391 // state. We need to check m_error again here. |
| 1392 if (m_error) |
| 1393 return; |
| 1394 |
| 1395 m_downloadedBlobLength += dataLength; |
| 1396 |
| 1397 trackProgress(dataLength); |
| 1398 } |
| 1399 |
1366 void XMLHttpRequest::handleDidTimeout() | 1400 void XMLHttpRequest::handleDidTimeout() |
1367 { | 1401 { |
1368 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); | 1402 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); |
1369 | 1403 |
1370 // internalAbort() calls dropProtection(), which may release the last refere
nce. | 1404 // internalAbort() calls dropProtection(), which may release the last refere
nce. |
1371 RefPtrWillBeRawPtr<XMLHttpRequest> protect(this); | 1405 RefPtrWillBeRawPtr<XMLHttpRequest> protect(this); |
1372 | 1406 |
1373 // Response is cleared next, save needed progress event data. | 1407 // Response is cleared next, save needed progress event data. |
1374 long long expectedLength = m_response.expectedContentLength(); | 1408 long long expectedLength = m_response.expectedContentLength(); |
1375 long long receivedLength = m_receivedLength; | 1409 long long receivedLength = m_receivedLength; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 { | 1450 { |
1417 visitor->trace(m_responseBlob); | 1451 visitor->trace(m_responseBlob); |
1418 visitor->trace(m_responseStream); | 1452 visitor->trace(m_responseStream); |
1419 visitor->trace(m_responseDocument); | 1453 visitor->trace(m_responseDocument); |
1420 visitor->trace(m_progressEventThrottle); | 1454 visitor->trace(m_progressEventThrottle); |
1421 visitor->trace(m_upload); | 1455 visitor->trace(m_upload); |
1422 XMLHttpRequestEventTarget::trace(visitor); | 1456 XMLHttpRequestEventTarget::trace(visitor); |
1423 } | 1457 } |
1424 | 1458 |
1425 } // namespace WebCore | 1459 } // namespace WebCore |
OLD | NEW |