Chromium Code Reviews| 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 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 } | 269 } |
| 270 m_createdDocument = true; | 270 m_createdDocument = true; |
| 271 } | 271 } |
| 272 | 272 |
| 273 return m_responseDocument.get(); | 273 return m_responseDocument.get(); |
| 274 } | 274 } |
| 275 | 275 |
| 276 Blob* XMLHttpRequest::responseBlob() | 276 Blob* XMLHttpRequest::responseBlob() |
| 277 { | 277 { |
| 278 ASSERT(m_responseTypeCode == ResponseTypeBlob); | 278 ASSERT(m_responseTypeCode == ResponseTypeBlob); |
| 279 ASSERT(!m_binaryResponseBuilder.get()); | |
| 279 | 280 |
| 280 // We always return null before DONE. | 281 // We always return null before DONE. |
| 281 if (m_error || m_state != DONE) | 282 if (m_error || m_state != DONE) |
| 282 return 0; | 283 return 0; |
| 283 | 284 |
| 284 if (!m_responseBlob) { | 285 if (!m_responseBlob) { |
| 285 // FIXME: This causes two (or more) unnecessary copies of the data. | 286 // When "blob" is specified for the responseType attribute, |
| 286 // Chromium stores blob data in the browser process, so we're pulling th e data | 287 // we redirect the downloaded data to the file-handle directly |
|
tyoshino (SeeGerritForStatus)
2013/09/19 06:58:46
the file-handle -> a file-handle
yusukesuzuki
2013/09/19 07:19:06
Done.
| |
| 287 // from the network only to copy it into the renderer to copy it back to the browser. | 288 // in the browser process. |
| 288 // Ideally we'd get the blob/file-handle from the ResourceResponse direc tly | 289 // We get the file-path from the ResourceResponse directly |
| 289 // instead of copying the bytes. Embedders who store blob data in the | 290 // instead of copying the bytes between the browser and the renderer. |
| 290 // same process as WebCore would at least to teach BlobData to take | |
| 291 // a SharedBuffer, even if they don't get the Blob from the network laye r directly. | |
| 292 OwnPtr<BlobData> blobData = BlobData::create(); | 291 OwnPtr<BlobData> blobData = BlobData::create(); |
| 292 const String& filePath = m_response.downloadedFilePath(); | |
| 293 // If we errored out or got no data, we still return a blob, just an emp ty one. | 293 // If we errored out or got no data, we still return a blob, just an emp ty one. |
| 294 size_t size = 0; | 294 if (!filePath.isEmpty() && m_receivedLength) { |
| 295 if (m_binaryResponseBuilder) { | 295 blobData->appendFile(filePath); |
| 296 RefPtr<RawData> rawData = RawData::create(); | |
| 297 size = m_binaryResponseBuilder->size(); | |
| 298 rawData->mutableData()->append(m_binaryResponseBuilder->data(), size ); | |
| 299 blobData->appendData(rawData, 0, BlobDataItem::toEndOfFile); | |
| 300 blobData->setContentType(responseMIMEType()); // responseMIMEType de faults to text/xml which may be incorrect. | 296 blobData->setContentType(responseMIMEType()); // responseMIMEType de faults to text/xml which may be incorrect. |
| 301 m_binaryResponseBuilder.clear(); | |
| 302 } | 297 } |
| 303 m_responseBlob = Blob::create(blobData.release(), size); | 298 m_responseBlob = Blob::create(blobData.release(), m_receivedLength); |
| 304 } | 299 } |
| 305 | 300 |
| 306 return m_responseBlob.get(); | 301 return m_responseBlob.get(); |
| 307 } | 302 } |
| 308 | 303 |
| 309 ArrayBuffer* XMLHttpRequest::responseArrayBuffer() | 304 ArrayBuffer* XMLHttpRequest::responseArrayBuffer() |
| 310 { | 305 { |
| 311 ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer); | 306 ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer); |
| 312 | 307 |
| 313 if (m_error || m_state != DONE) | 308 if (m_error || m_state != DONE) |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 m_sameOriginRequest = securityOrigin()->canRequest(m_url); | 740 m_sameOriginRequest = securityOrigin()->canRequest(m_url); |
| 746 | 741 |
| 747 // We also remember whether upload events should be allowed for this request in case the upload listeners are | 742 // We also remember whether upload events should be allowed for this request in case the upload listeners are |
| 748 // added after the request is started. | 743 // added after the request is started. |
| 749 m_uploadEventsAllowed = m_sameOriginRequest || uploadEvents || !isSimpleCros sOriginAccessRequest(m_method, m_requestHeaders); | 744 m_uploadEventsAllowed = m_sameOriginRequest || uploadEvents || !isSimpleCros sOriginAccessRequest(m_method, m_requestHeaders); |
| 750 | 745 |
| 751 ResourceRequest request(m_url); | 746 ResourceRequest request(m_url); |
| 752 request.setHTTPMethod(m_method); | 747 request.setHTTPMethod(m_method); |
| 753 request.setTargetType(ResourceRequest::TargetIsXHR); | 748 request.setTargetType(ResourceRequest::TargetIsXHR); |
| 754 | 749 |
| 750 // When "blob" is specified for the responseType attribute, | |
| 751 // we redirect the downloaded data to the file-handle directly | |
| 752 // and get the file-path as the result. | |
| 753 if (responseTypeCode() == ResponseTypeBlob) | |
| 754 request.setDownloadToFile(true); | |
| 755 | |
| 755 InspectorInstrumentation::willLoadXHR(scriptExecutionContext(), this, m_meth od, m_url, m_async, m_requestEntityBody ? m_requestEntityBody->deepCopy() : 0, m _requestHeaders, m_includeCredentials); | 756 InspectorInstrumentation::willLoadXHR(scriptExecutionContext(), this, m_meth od, m_url, m_async, m_requestEntityBody ? m_requestEntityBody->deepCopy() : 0, m _requestHeaders, m_includeCredentials); |
| 756 | 757 |
| 757 if (m_requestEntityBody) { | 758 if (m_requestEntityBody) { |
| 758 ASSERT(m_method != "GET"); | 759 ASSERT(m_method != "GET"); |
| 759 ASSERT(m_method != "HEAD"); | 760 ASSERT(m_method != "HEAD"); |
| 760 request.setHTTPBody(m_requestEntityBody.release()); | 761 request.setHTTPBody(m_requestEntityBody.release()); |
| 761 } | 762 } |
| 762 | 763 |
| 763 if (m_requestHeaders.size() > 0) | 764 if (m_requestHeaders.size() > 0) |
| 764 request.addHTTPHeaderFields(m_requestHeaders); | 765 request.addHTTPHeaderFields(m_requestHeaders); |
| 765 | 766 |
| 766 ThreadableLoaderOptions options; | 767 ThreadableLoaderOptions options; |
| 767 options.sendLoadCallbacks = SendCallbacks; | 768 options.sendLoadCallbacks = SendCallbacks; |
| 768 options.sniffContent = DoNotSniffContent; | 769 options.sniffContent = DoNotSniffContent; |
| 769 options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight; | 770 options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight; |
| 770 options.allowCredentials = (m_sameOriginRequest || m_includeCredentials) ? A llowStoredCredentials : DoNotAllowStoredCredentials; | 771 options.allowCredentials = (m_sameOriginRequest || m_includeCredentials) ? A llowStoredCredentials : DoNotAllowStoredCredentials; |
| 771 options.credentialsRequested = m_includeCredentials ? ClientRequestedCredent ials : ClientDidNotRequestCredentials; | 772 options.credentialsRequested = m_includeCredentials ? ClientRequestedCredent ials : ClientDidNotRequestCredentials; |
| 772 options.crossOriginRequestPolicy = m_allowCrossOriginRequests ? AllowCrossOr iginRequests : UseAccessControl; | 773 options.crossOriginRequestPolicy = m_allowCrossOriginRequests ? AllowCrossOr iginRequests : UseAccessControl; |
| 773 options.securityOrigin = securityOrigin(); | 774 options.securityOrigin = securityOrigin(); |
| 774 options.initiator = FetchInitiatorTypeNames::xmlhttprequest; | 775 options.initiator = FetchInitiatorTypeNames::xmlhttprequest; |
| 775 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa ssMainWorld(scriptExecutionContext()) ? DoNotEnforceContentSecurityPolicy : Enfo rceConnectSrcDirective; | 776 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa ssMainWorld(scriptExecutionContext()) ? DoNotEnforceContentSecurityPolicy : Enfo rceConnectSrcDirective; |
| 776 options.mixedContentBlockingTreatment = TreatAsActiveContent; | 777 options.mixedContentBlockingTreatment = TreatAsActiveContent; |
| 777 options.timeoutMilliseconds = m_timeoutMilliseconds; | 778 options.timeoutMilliseconds = m_timeoutMilliseconds; |
| 778 | 779 |
| 780 // Since we redirect the downloaded data to the file-handle directly | |
| 781 // when "blob" is specified for the responseType attribute, | |
| 782 // buffering is not needed. | |
| 783 if (responseTypeCode() == ResponseTypeBlob) | |
| 784 options.dataBufferingPolicy = DoNotBufferData; | |
| 785 | |
| 779 m_exceptionCode = 0; | 786 m_exceptionCode = 0; |
| 780 m_error = false; | 787 m_error = false; |
| 781 | 788 |
| 782 if (m_async) { | 789 if (m_async) { |
| 783 if (m_upload) | 790 if (m_upload) |
| 784 request.setReportUploadProgress(true); | 791 request.setReportUploadProgress(true); |
| 785 | 792 |
| 786 // ThreadableLoader::create can return null here, for example if we're n o longer attached to a page. | 793 // ThreadableLoader::create can return null here, for example if we're n o longer attached to a page. |
| 787 // This is true while running onunload handlers. | 794 // This is true while running onunload handlers. |
| 788 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload , <http://bugs.webkit.org/show_bug.cgi?id=10904>. | 795 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload , <http://bugs.webkit.org/show_bug.cgi?id=10904>. |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1169 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); | 1176 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); |
| 1170 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride); | 1177 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride); |
| 1171 } | 1178 } |
| 1172 | 1179 |
| 1173 if (m_responseEncoding.isEmpty()) | 1180 if (m_responseEncoding.isEmpty()) |
| 1174 m_responseEncoding = response.textEncodingName(); | 1181 m_responseEncoding = response.textEncodingName(); |
| 1175 } | 1182 } |
| 1176 | 1183 |
| 1177 void XMLHttpRequest::didReceiveData(const char* data, int len) | 1184 void XMLHttpRequest::didReceiveData(const char* data, int len) |
| 1178 { | 1185 { |
| 1186 ASSERT(m_responseTypeCode != ResponseTypeBlob); | |
| 1187 | |
| 1179 if (m_error) | 1188 if (m_error) |
| 1180 return; | 1189 return; |
| 1181 | 1190 |
| 1182 if (m_state < HEADERS_RECEIVED) | 1191 if (m_state < HEADERS_RECEIVED) |
| 1183 changeState(HEADERS_RECEIVED); | 1192 changeState(HEADERS_RECEIVED); |
| 1184 | 1193 |
| 1185 bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTyp eCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_respons eTypeCode == ResponseTypeDocument; | 1194 bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTyp eCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_respons eTypeCode == ResponseTypeDocument; |
| 1186 | 1195 |
| 1187 if (useDecoder && !m_decoder) { | 1196 if (useDecoder && !m_decoder) { |
| 1188 if (m_responseTypeCode == ResponseTypeJSON) | 1197 if (m_responseTypeCode == ResponseTypeJSON) |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1201 } | 1210 } |
| 1202 | 1211 |
| 1203 if (!len) | 1212 if (!len) |
| 1204 return; | 1213 return; |
| 1205 | 1214 |
| 1206 if (len == -1) | 1215 if (len == -1) |
| 1207 len = strlen(data); | 1216 len = strlen(data); |
| 1208 | 1217 |
| 1209 if (useDecoder) { | 1218 if (useDecoder) { |
| 1210 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); | 1219 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); |
| 1211 } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCo de == ResponseTypeBlob) { | 1220 } else if (m_responseTypeCode == ResponseTypeArrayBuffer) { |
| 1212 // Buffer binary data. | 1221 // Buffer binary data. |
| 1213 if (!m_binaryResponseBuilder) | 1222 if (!m_binaryResponseBuilder) |
| 1214 m_binaryResponseBuilder = SharedBuffer::create(); | 1223 m_binaryResponseBuilder = SharedBuffer::create(); |
| 1215 m_binaryResponseBuilder->append(data, len); | 1224 m_binaryResponseBuilder->append(data, len); |
| 1216 } else if (m_responseTypeCode == ResponseTypeStream) { | 1225 } else if (m_responseTypeCode == ResponseTypeStream) { |
| 1217 if (!m_responseStream) | 1226 if (!m_responseStream) |
| 1218 m_responseStream = Stream::create(responseMIMEType()); | 1227 m_responseStream = Stream::create(responseMIMEType()); |
| 1219 m_responseStream->addData(data, len); | 1228 m_responseStream->addData(data, len); |
| 1220 } | 1229 } |
| 1221 | 1230 |
| 1222 if (!m_error) { | 1231 if (!m_error) { |
| 1223 long long expectedLength = m_response.expectedContentLength(); | 1232 long long expectedLength = m_response.expectedContentLength(); |
| 1224 m_receivedLength += len; | 1233 m_receivedLength += len; |
| 1225 | 1234 |
| 1226 if (m_async) { | 1235 if (m_async) { |
| 1227 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex pectedLength; | 1236 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex pectedLength; |
| 1228 unsigned long long total = lengthComputable ? expectedLength : 0; | 1237 unsigned long long total = lengthComputable ? expectedLength : 0; |
| 1229 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re ceivedLength, total); | 1238 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re ceivedLength, total); |
| 1230 } | 1239 } |
| 1231 | 1240 |
| 1232 if (m_state != LOADING) | 1241 if (m_state != LOADING) |
| 1233 changeState(LOADING); | 1242 changeState(LOADING); |
| 1234 else | 1243 else |
| 1235 // Firefox calls readyStateChanged every time it receives data, 4449 442 | 1244 // Firefox calls readyStateChanged every time it receives data, 4449 442 |
| 1236 callReadyStateChangeListener(); | 1245 callReadyStateChangeListener(); |
| 1237 } | 1246 } |
| 1238 } | 1247 } |
| 1239 | 1248 |
| 1249 void XMLHttpRequest::didDownloadData(int len) | |
| 1250 { | |
| 1251 ASSERT(m_responseTypeCode == ResponseTypeBlob); | |
| 1252 | |
| 1253 if (m_error) | |
| 1254 return; | |
| 1255 | |
| 1256 if (m_state < HEADERS_RECEIVED) | |
| 1257 changeState(HEADERS_RECEIVED); | |
| 1258 | |
| 1259 if (!len) | |
| 1260 return; | |
| 1261 | |
| 1262 if (!m_error) { | |
|
tyoshino (SeeGerritForStatus)
2013/09/19 06:58:46
factor out L1232-1245 and reuse it
yusukesuzuki
2013/09/19 07:19:06
Done. Seeing the m_receivedLength comment, named `
| |
| 1263 long long expectedLength = m_response.expectedContentLength(); | |
| 1264 m_receivedLength += len; | |
| 1265 | |
| 1266 if (m_async) { | |
| 1267 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex pectedLength; | |
| 1268 unsigned long long total = lengthComputable ? expectedLength : 0; | |
| 1269 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re ceivedLength, total); | |
| 1270 } | |
| 1271 | |
| 1272 if (m_state != LOADING) { | |
| 1273 changeState(LOADING); | |
| 1274 } else { | |
| 1275 // Firefox calls readyStateChanged every time it receives data, 4449 442 | |
| 1276 callReadyStateChangeListener(); | |
| 1277 } | |
| 1278 } | |
| 1279 } | |
| 1280 | |
| 1240 void XMLHttpRequest::didTimeout() | 1281 void XMLHttpRequest::didTimeout() |
| 1241 { | 1282 { |
| 1242 // internalAbort() calls dropProtection(), which may release the last refere nce. | 1283 // internalAbort() calls dropProtection(), which may release the last refere nce. |
| 1243 RefPtr<XMLHttpRequest> protect(this); | 1284 RefPtr<XMLHttpRequest> protect(this); |
| 1244 internalAbort(); | 1285 internalAbort(); |
| 1245 | 1286 |
| 1246 clearResponse(); | 1287 clearResponse(); |
| 1247 clearRequest(); | 1288 clearRequest(); |
| 1248 | 1289 |
| 1249 m_error = true; | 1290 m_error = true; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1295 { | 1336 { |
| 1296 return eventNames().interfaceForXMLHttpRequest; | 1337 return eventNames().interfaceForXMLHttpRequest; |
| 1297 } | 1338 } |
| 1298 | 1339 |
| 1299 ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const | 1340 ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const |
| 1300 { | 1341 { |
| 1301 return ActiveDOMObject::scriptExecutionContext(); | 1342 return ActiveDOMObject::scriptExecutionContext(); |
| 1302 } | 1343 } |
| 1303 | 1344 |
| 1304 } // namespace WebCore | 1345 } // namespace WebCore |
| OLD | NEW |