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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 return xmlHttpRequest.release(); | 161 return xmlHttpRequest.release(); |
162 } | 162 } |
163 | 163 |
164 XMLHttpRequest::XMLHttpRequest(ExecutionContext* context, PassRefPtr<SecurityOri
gin> securityOrigin) | 164 XMLHttpRequest::XMLHttpRequest(ExecutionContext* context, PassRefPtr<SecurityOri
gin> securityOrigin) |
165 : ActiveDOMObject(context) | 165 : ActiveDOMObject(context) |
166 , m_async(true) | 166 , m_async(true) |
167 , m_includeCredentials(false) | 167 , m_includeCredentials(false) |
168 , m_timeoutMilliseconds(0) | 168 , m_timeoutMilliseconds(0) |
169 , m_state(UNSENT) | 169 , m_state(UNSENT) |
170 , m_createdDocument(false) | 170 , m_createdDocument(false) |
171 , m_downloadedBlobLength(0) | |
172 , m_error(false) | 171 , m_error(false) |
173 , m_uploadEventsAllowed(true) | 172 , m_uploadEventsAllowed(true) |
174 , m_uploadComplete(false) | 173 , m_uploadComplete(false) |
175 , m_sameOriginRequest(true) | 174 , m_sameOriginRequest(true) |
176 , m_receivedLength(0) | 175 , m_receivedLength(0) |
177 , m_lastSendLineNumber(0) | 176 , m_lastSendLineNumber(0) |
178 , m_exceptionCode(0) | 177 , m_exceptionCode(0) |
179 , m_progressEventThrottle(this) | 178 , m_progressEventThrottle(this) |
180 , m_responseTypeCode(ResponseTypeDefault) | 179 , m_responseTypeCode(ResponseTypeDefault) |
181 , m_dropProtectionRunner(this, &XMLHttpRequest::dropProtection) | 180 , m_dropProtectionRunner(this, &XMLHttpRequest::dropProtection) |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 } | 264 } |
266 m_createdDocument = true; | 265 m_createdDocument = true; |
267 } | 266 } |
268 | 267 |
269 return m_responseDocument.get(); | 268 return m_responseDocument.get(); |
270 } | 269 } |
271 | 270 |
272 Blob* XMLHttpRequest::responseBlob() | 271 Blob* XMLHttpRequest::responseBlob() |
273 { | 272 { |
274 ASSERT(m_responseTypeCode == ResponseTypeBlob); | 273 ASSERT(m_responseTypeCode == ResponseTypeBlob); |
275 ASSERT(!m_binaryResponseBuilder.get()); | |
276 | 274 |
277 // We always return null before DONE. | 275 // We always return null before DONE. |
278 if (m_error || m_state != DONE) | 276 if (m_error || m_state != DONE) |
279 return 0; | 277 return 0; |
280 | 278 |
281 if (!m_responseBlob) { | 279 if (!m_responseBlob) { |
282 // When "blob" is specified for the responseType attribute, | 280 // FIXME: Once RedirectToFileResourceHandler is fixed in Chromium, |
283 // we redirect the downloaded data to a file-handle directly | 281 // re-enable download-to-file optimization introduced by Blink revision |
284 // in the browser process. | 282 // 163141. |
285 // We get the file-path from the ResourceResponse directly | |
286 // instead of copying the bytes between the browser and the renderer. | |
287 OwnPtr<BlobData> blobData = BlobData::create(); | 283 OwnPtr<BlobData> blobData = BlobData::create(); |
288 String filePath = m_response.downloadedFilePath(); | 284 size_t size = 0; |
289 // If we errored out or got no data, we still return a blob, just an emp
ty one. | 285 if (m_binaryResponseBuilder.get() && m_binaryResponseBuilder->size() > 0
) { |
290 if (!filePath.isEmpty() && m_downloadedBlobLength) { | 286 RefPtr<RawData> rawData = RawData::create(); |
291 blobData->appendFile(filePath); | 287 size = m_binaryResponseBuilder->size(); |
| 288 rawData->mutableData()->append(m_binaryResponseBuilder->data(), size
); |
| 289 blobData->appendData(rawData, 0, BlobDataItem::toEndOfFile); |
292 blobData->setContentType(responseMIMEType()); // responseMIMEType de
faults to text/xml which may be incorrect. | 290 blobData->setContentType(responseMIMEType()); // responseMIMEType de
faults to text/xml which may be incorrect. |
| 291 m_binaryResponseBuilder.clear(); |
293 } | 292 } |
294 m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(),
m_downloadedBlobLength)); | 293 m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(),
size)); |
295 } | 294 } |
296 | 295 |
297 return m_responseBlob.get(); | 296 return m_responseBlob.get(); |
298 } | 297 } |
299 | 298 |
300 ArrayBuffer* XMLHttpRequest::responseArrayBuffer() | 299 ArrayBuffer* XMLHttpRequest::responseArrayBuffer() |
301 { | 300 { |
302 ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer); | 301 ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer); |
303 | 302 |
304 if (m_error || m_state != DONE) | 303 if (m_error || m_state != DONE) |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 m_sameOriginRequest = securityOrigin()->canRequest(m_url); | 792 m_sameOriginRequest = securityOrigin()->canRequest(m_url); |
794 | 793 |
795 // We also remember whether upload events should be allowed for this request
in case the upload listeners are | 794 // We also remember whether upload events should be allowed for this request
in case the upload listeners are |
796 // added after the request is started. | 795 // added after the request is started. |
797 m_uploadEventsAllowed = m_sameOriginRequest || uploadEvents || !isSimpleCros
sOriginAccessRequest(m_method, m_requestHeaders); | 796 m_uploadEventsAllowed = m_sameOriginRequest || uploadEvents || !isSimpleCros
sOriginAccessRequest(m_method, m_requestHeaders); |
798 | 797 |
799 ResourceRequest request(m_url); | 798 ResourceRequest request(m_url); |
800 request.setHTTPMethod(m_method); | 799 request.setHTTPMethod(m_method); |
801 request.setTargetType(ResourceRequest::TargetIsXHR); | 800 request.setTargetType(ResourceRequest::TargetIsXHR); |
802 | 801 |
803 // When "blob" is specified for the responseType attribute, | |
804 // we redirect the downloaded data to a file-handle directly | |
805 // and get the file-path as the result. | |
806 if (responseTypeCode() == ResponseTypeBlob) | |
807 request.setDownloadToFile(true); | |
808 | |
809 InspectorInstrumentation::willLoadXHR(executionContext(), this, this, m_meth
od, m_url, m_async, m_requestEntityBody ? m_requestEntityBody->deepCopy() : 0, m
_requestHeaders, m_includeCredentials); | 802 InspectorInstrumentation::willLoadXHR(executionContext(), this, this, m_meth
od, m_url, m_async, m_requestEntityBody ? m_requestEntityBody->deepCopy() : 0, m
_requestHeaders, m_includeCredentials); |
810 | 803 |
811 if (m_requestEntityBody) { | 804 if (m_requestEntityBody) { |
812 ASSERT(m_method != "GET"); | 805 ASSERT(m_method != "GET"); |
813 ASSERT(m_method != "HEAD"); | 806 ASSERT(m_method != "HEAD"); |
814 request.setHTTPBody(m_requestEntityBody.release()); | 807 request.setHTTPBody(m_requestEntityBody.release()); |
815 } | 808 } |
816 | 809 |
817 if (m_requestHeaders.size() > 0) | 810 if (m_requestHeaders.size() > 0) |
818 request.addHTTPHeaderFields(m_requestHeaders); | 811 request.addHTTPHeaderFields(m_requestHeaders); |
819 | 812 |
820 ThreadableLoaderOptions options; | 813 ThreadableLoaderOptions options; |
821 options.sniffContent = DoNotSniffContent; | 814 options.sniffContent = DoNotSniffContent; |
822 options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight; | 815 options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight; |
823 options.allowCredentials = (m_sameOriginRequest || m_includeCredentials) ? A
llowStoredCredentials : DoNotAllowStoredCredentials; | 816 options.allowCredentials = (m_sameOriginRequest || m_includeCredentials) ? A
llowStoredCredentials : DoNotAllowStoredCredentials; |
824 options.credentialsRequested = m_includeCredentials ? ClientRequestedCredent
ials : ClientDidNotRequestCredentials; | 817 options.credentialsRequested = m_includeCredentials ? ClientRequestedCredent
ials : ClientDidNotRequestCredentials; |
825 options.crossOriginRequestPolicy = UseAccessControl; | 818 options.crossOriginRequestPolicy = UseAccessControl; |
826 options.securityOrigin = securityOrigin(); | 819 options.securityOrigin = securityOrigin(); |
827 options.initiator = FetchInitiatorTypeNames::xmlhttprequest; | 820 options.initiator = FetchInitiatorTypeNames::xmlhttprequest; |
828 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa
ssMainWorld(executionContext()) ? DoNotEnforceContentSecurityPolicy : EnforceCon
nectSrcDirective; | 821 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa
ssMainWorld(executionContext()) ? DoNotEnforceContentSecurityPolicy : EnforceCon
nectSrcDirective; |
829 // TODO(tsepez): Specify TreatAsActiveContent per http://crbug.com/305303. | 822 // TODO(tsepez): Specify TreatAsActiveContent per http://crbug.com/305303. |
830 options.mixedContentBlockingTreatment = TreatAsPassiveContent; | 823 options.mixedContentBlockingTreatment = TreatAsPassiveContent; |
831 options.timeoutMilliseconds = m_timeoutMilliseconds; | 824 options.timeoutMilliseconds = m_timeoutMilliseconds; |
832 | 825 |
833 // Since we redirect the downloaded data to a file-handle directly | |
834 // when "blob" is specified for the responseType attribute, | |
835 // buffering is not needed. | |
836 if (responseTypeCode() == ResponseTypeBlob) | |
837 options.dataBufferingPolicy = DoNotBufferData; | |
838 | |
839 m_exceptionCode = 0; | 826 m_exceptionCode = 0; |
840 m_error = false; | 827 m_error = false; |
841 | 828 |
842 if (m_async) { | 829 if (m_async) { |
843 if (m_upload) | 830 if (m_upload) |
844 request.setReportUploadProgress(true); | 831 request.setReportUploadProgress(true); |
845 | 832 |
846 // ThreadableLoader::create can return null here, for example if we're n
o longer attached to a page. | 833 // ThreadableLoader::create can return null here, for example if we're n
o longer attached to a page. |
847 // This is true while running onunload handlers. | 834 // This is true while running onunload handlers. |
848 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload
, <http://bugs.webkit.org/show_bug.cgi?id=10904>. | 835 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload
, <http://bugs.webkit.org/show_bug.cgi?id=10904>. |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 // be careful with this initialization. | 938 // be careful with this initialization. |
952 m_receivedLength = 0; | 939 m_receivedLength = 0; |
953 | 940 |
954 m_response = ResourceResponse(); | 941 m_response = ResourceResponse(); |
955 | 942 |
956 m_responseText.clear(); | 943 m_responseText.clear(); |
957 | 944 |
958 m_createdDocument = false; | 945 m_createdDocument = false; |
959 m_responseDocument = 0; | 946 m_responseDocument = 0; |
960 | 947 |
961 m_responseBlob = 0; | 948 m_responseBlob = nullptr; |
962 | 949 |
963 m_responseStream = 0; | 950 m_responseStream = 0; |
964 | 951 |
965 // These variables may referred by the response accessors. So, we can clear | 952 // These variables may referred by the response accessors. So, we can clear |
966 // this only when we clear the response holder variables above. | 953 // this only when we clear the response holder variables above. |
967 m_binaryResponseBuilder.clear(); | 954 m_binaryResponseBuilder.clear(); |
968 m_responseArrayBuffer.clear(); | 955 m_responseArrayBuffer.clear(); |
969 } | 956 } |
970 | 957 |
971 void XMLHttpRequest::clearRequest() | 958 void XMLHttpRequest::clearRequest() |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); | 1287 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); |
1301 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride); | 1288 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride); |
1302 } | 1289 } |
1303 | 1290 |
1304 if (m_responseEncoding.isEmpty()) | 1291 if (m_responseEncoding.isEmpty()) |
1305 m_responseEncoding = response.textEncodingName(); | 1292 m_responseEncoding = response.textEncodingName(); |
1306 } | 1293 } |
1307 | 1294 |
1308 void XMLHttpRequest::didReceiveData(const char* data, int len) | 1295 void XMLHttpRequest::didReceiveData(const char* data, int len) |
1309 { | 1296 { |
1310 ASSERT(m_responseTypeCode != ResponseTypeBlob); | |
1311 | |
1312 if (m_error) | 1297 if (m_error) |
1313 return; | 1298 return; |
1314 | 1299 |
1315 if (m_state < HEADERS_RECEIVED) | 1300 if (m_state < HEADERS_RECEIVED) |
1316 changeState(HEADERS_RECEIVED); | 1301 changeState(HEADERS_RECEIVED); |
1317 | 1302 |
1318 bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTyp
eCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_respons
eTypeCode == ResponseTypeDocument; | 1303 bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTyp
eCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_respons
eTypeCode == ResponseTypeDocument; |
1319 | 1304 |
1320 if (useDecoder && !m_decoder) { | 1305 if (useDecoder && !m_decoder) { |
1321 if (m_responseTypeCode == ResponseTypeJSON) | 1306 if (m_responseTypeCode == ResponseTypeJSON) |
(...skipping 12 matching lines...) Expand all Loading... |
1334 } | 1319 } |
1335 | 1320 |
1336 if (!len) | 1321 if (!len) |
1337 return; | 1322 return; |
1338 | 1323 |
1339 if (len == -1) | 1324 if (len == -1) |
1340 len = strlen(data); | 1325 len = strlen(data); |
1341 | 1326 |
1342 if (useDecoder) { | 1327 if (useDecoder) { |
1343 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data,
len)); | 1328 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data,
len)); |
1344 } else if (m_responseTypeCode == ResponseTypeArrayBuffer) { | 1329 } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCo
de == ResponseTypeBlob) { |
1345 // Buffer binary data. | 1330 // Buffer binary data. |
1346 if (!m_binaryResponseBuilder) | 1331 if (!m_binaryResponseBuilder) |
1347 m_binaryResponseBuilder = SharedBuffer::create(); | 1332 m_binaryResponseBuilder = SharedBuffer::create(); |
1348 m_binaryResponseBuilder->append(data, len); | 1333 m_binaryResponseBuilder->append(data, len); |
1349 } else if (m_responseTypeCode == ResponseTypeStream) { | 1334 } else if (m_responseTypeCode == ResponseTypeStream) { |
1350 if (!m_responseStream) | 1335 if (!m_responseStream) |
1351 m_responseStream = Stream::create(executionContext(), responseMIMETy
pe()); | 1336 m_responseStream = Stream::create(executionContext(), responseMIMETy
pe()); |
1352 m_responseStream->addData(data, len); | 1337 m_responseStream->addData(data, len); |
1353 } | 1338 } |
1354 | 1339 |
1355 if (m_error) | 1340 if (m_error) |
1356 return; | 1341 return; |
1357 | 1342 |
1358 trackProgress(len); | 1343 trackProgress(len); |
1359 } | 1344 } |
1360 | 1345 |
1361 void XMLHttpRequest::didDownloadData(int dataLength) | |
1362 { | |
1363 ASSERT(m_responseTypeCode == ResponseTypeBlob); | |
1364 | |
1365 if (m_error) | |
1366 return; | |
1367 | |
1368 if (m_state < HEADERS_RECEIVED) | |
1369 changeState(HEADERS_RECEIVED); | |
1370 | |
1371 if (!dataLength) | |
1372 return; | |
1373 | |
1374 if (m_error) | |
1375 return; | |
1376 | |
1377 m_downloadedBlobLength += dataLength; | |
1378 trackProgress(dataLength); | |
1379 } | |
1380 | |
1381 void XMLHttpRequest::handleDidTimeout() | 1346 void XMLHttpRequest::handleDidTimeout() |
1382 { | 1347 { |
1383 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); | 1348 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); |
1384 | 1349 |
1385 // internalAbort() calls dropProtection(), which may release the last refere
nce. | 1350 // internalAbort() calls dropProtection(), which may release the last refere
nce. |
1386 RefPtr<XMLHttpRequest> protect(this); | 1351 RefPtr<XMLHttpRequest> protect(this); |
1387 | 1352 |
1388 // Response is cleared next, save needed progress event data. | 1353 // Response is cleared next, save needed progress event data. |
1389 long long expectedLength = m_response.expectedContentLength(); | 1354 long long expectedLength = m_response.expectedContentLength(); |
1390 long long receivedLength = m_receivedLength; | 1355 long long receivedLength = m_receivedLength; |
(...skipping 30 matching lines...) Expand all Loading... |
1421 { | 1386 { |
1422 return EventTargetNames::XMLHttpRequest; | 1387 return EventTargetNames::XMLHttpRequest; |
1423 } | 1388 } |
1424 | 1389 |
1425 ExecutionContext* XMLHttpRequest::executionContext() const | 1390 ExecutionContext* XMLHttpRequest::executionContext() const |
1426 { | 1391 { |
1427 return ActiveDOMObject::executionContext(); | 1392 return ActiveDOMObject::executionContext(); |
1428 } | 1393 } |
1429 | 1394 |
1430 } // namespace WebCore | 1395 } // namespace WebCore |
OLD | NEW |