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 |
11 * version 2 of the License, or (at your option) any later version. | 11 * version 2 of the License, or (at your option) any later version. |
12 * | 12 * |
13 * This library is distributed in the hope that it will be useful, | 13 * This library is distributed in the hope that it will be useful, |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 * Lesser General Public License for more details. | 16 * Lesser General Public License for more details. |
17 * | 17 * |
18 * You should have received a copy of the GNU Lesser General Public | 18 * You should have received a copy of the GNU Lesser General Public |
19 * License along with this library; if not, write to the Free Software | 19 * License along with this library; if not, write to the Free Software |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 U
SA | 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 U
SA |
21 */ | 21 */ |
22 | 22 |
23 #include "config.h" | 23 #include "config.h" |
24 #include "core/xml/XMLHttpRequest.h" | 24 #include "core/xml/XMLHttpRequest.h" |
25 | 25 |
26 #include "FetchInitiatorTypeNames.h" | 26 #include "FetchInitiatorTypeNames.h" |
| 27 #include "RuntimeEnabledFeatures.h" |
27 #include "bindings/v8/ExceptionMessages.h" | 28 #include "bindings/v8/ExceptionMessages.h" |
28 #include "bindings/v8/ExceptionState.h" | 29 #include "bindings/v8/ExceptionState.h" |
29 #include "core/dom/ContextFeatures.h" | 30 #include "core/dom/ContextFeatures.h" |
30 #include "core/dom/DOMImplementation.h" | 31 #include "core/dom/DOMImplementation.h" |
31 #include "core/dom/Event.h" | 32 #include "core/dom/Event.h" |
32 #include "core/dom/EventListener.h" | 33 #include "core/dom/EventListener.h" |
33 #include "core/dom/EventNames.h" | 34 #include "core/dom/EventNames.h" |
34 #include "core/dom/ExceptionCode.h" | 35 #include "core/dom/ExceptionCode.h" |
35 #include "core/editing/markup.h" | 36 #include "core/editing/markup.h" |
36 #include "core/fetch/TextResourceDecoder.h" | 37 #include "core/fetch/TextResourceDecoder.h" |
37 #include "core/fileapi/Blob.h" | 38 #include "core/fileapi/Blob.h" |
38 #include "core/fileapi/File.h" | 39 #include "core/fileapi/File.h" |
| 40 #include "core/fileapi/Stream.h" |
39 #include "core/html/DOMFormData.h" | 41 #include "core/html/DOMFormData.h" |
40 #include "core/html/HTMLDocument.h" | 42 #include "core/html/HTMLDocument.h" |
41 #include "core/inspector/InspectorInstrumentation.h" | 43 #include "core/inspector/InspectorInstrumentation.h" |
42 #include "core/loader/CrossOriginAccessControl.h" | 44 #include "core/loader/CrossOriginAccessControl.h" |
43 #include "core/loader/ThreadableLoader.h" | 45 #include "core/loader/ThreadableLoader.h" |
44 #include "core/page/ContentSecurityPolicy.h" | 46 #include "core/page/ContentSecurityPolicy.h" |
45 #include "core/page/Settings.h" | 47 #include "core/page/Settings.h" |
46 #include "core/platform/HistogramSupport.h" | 48 #include "core/platform/HistogramSupport.h" |
47 #include "core/platform/SharedBuffer.h" | 49 #include "core/platform/SharedBuffer.h" |
48 #include "core/platform/network/BlobData.h" | 50 #include "core/platform/network/BlobData.h" |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 return 0; | 313 return 0; |
312 | 314 |
313 if (!m_responseArrayBuffer.get() && m_binaryResponseBuilder.get() && m_binar
yResponseBuilder->size() > 0) { | 315 if (!m_responseArrayBuffer.get() && m_binaryResponseBuilder.get() && m_binar
yResponseBuilder->size() > 0) { |
314 m_responseArrayBuffer = m_binaryResponseBuilder->getAsArrayBuffer(); | 316 m_responseArrayBuffer = m_binaryResponseBuilder->getAsArrayBuffer(); |
315 m_binaryResponseBuilder.clear(); | 317 m_binaryResponseBuilder.clear(); |
316 } | 318 } |
317 | 319 |
318 return m_responseArrayBuffer.get(); | 320 return m_responseArrayBuffer.get(); |
319 } | 321 } |
320 | 322 |
| 323 Stream* XMLHttpRequest::responseStream() |
| 324 { |
| 325 ASSERT(m_responseTypeCode == ResponseTypeStream); |
| 326 |
| 327 if (m_error || (m_state != LOADING && m_state != DONE)) |
| 328 return 0; |
| 329 |
| 330 return m_responseStream.get(); |
| 331 } |
| 332 |
321 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionState& es) | 333 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionState& es) |
322 { | 334 { |
323 // FIXME: Need to trigger or update the timeout Timer here, if needed. http:
//webkit.org/b/98156 | 335 // FIXME: Need to trigger or update the timeout Timer here, if needed. http:
//webkit.org/b/98156 |
324 // XHR2 spec, 4.7.3. "This implies that the timeout attribute can be set whi
le fetching is in progress. If that occurs it will still be measured relative to
the start of fetching." | 336 // XHR2 spec, 4.7.3. "This implies that the timeout attribute can be set whi
le fetching is in progress. If that occurs it will still be measured relative to
the start of fetching." |
325 if (scriptExecutionContext()->isDocument() && !m_async) { | 337 if (scriptExecutionContext()->isDocument() && !m_async) { |
326 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToSet(
"timeout", "XMLHttpRequest", "timeouts cannot be set for synchronous requests ma
de from a document.")); | 338 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToSet(
"timeout", "XMLHttpRequest", "timeouts cannot be set for synchronous requests ma
de from a document.")); |
327 return; | 339 return; |
328 } | 340 } |
329 m_timeoutMilliseconds = timeout; | 341 m_timeoutMilliseconds = timeout; |
330 } | 342 } |
331 | 343 |
332 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState&
es) | 344 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState&
es) |
333 { | 345 { |
334 if (m_state >= LOADING) { | 346 if (m_state >= LOADING) { |
335 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToSet("
responseType", "XMLHttpRequest", "the response type cannot be set if the object'
s state is LOADING or DONE.")); | 347 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToSet("
responseType", "XMLHttpRequest", "the response type cannot be set if the object'
s state is LOADING or DONE.")); |
336 return; | 348 return; |
337 } | 349 } |
338 | 350 |
339 // Newer functionality is not available to synchronous requests in window co
ntexts, as a spec-mandated | 351 // Newer functionality is not available to synchronous requests in window co
ntexts, as a spec-mandated |
340 // attempt to discourage synchronous XHR use. responseType is one such piece
of functionality. | 352 // attempt to discourage synchronous XHR use. responseType is one such piece
of functionality. |
341 // We'll only disable this functionality for HTTP(S) requests since sync req
uests for local protocols | 353 // We'll only disable this functionality for HTTP(S) requests since sync req
uests for local protocols |
342 // such as file: and data: still make sense to allow. | 354 // such as file: and data: still make sense to allow. |
343 if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsIn
HTTPFamily()) { | 355 if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsIn
HTTPFamily()) { |
344 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToSet(
"responseType", "XMLHttpRequest", "the response type can only be changed for asy
nchronous HTTP requests made from a document.")); | 356 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToSet(
"responseType", "XMLHttpRequest", "the response type can only be changed for asy
nchronous HTTP requests made from a document.")); |
345 return; | 357 return; |
346 } | 358 } |
347 | 359 |
348 if (responseType == "") | 360 if (responseType == "") { |
349 m_responseTypeCode = ResponseTypeDefault; | 361 m_responseTypeCode = ResponseTypeDefault; |
350 else if (responseType == "text") | 362 } else if (responseType == "text") { |
351 m_responseTypeCode = ResponseTypeText; | 363 m_responseTypeCode = ResponseTypeText; |
352 else if (responseType == "json") | 364 } else if (responseType == "json") { |
353 m_responseTypeCode = ResponseTypeJSON; | 365 m_responseTypeCode = ResponseTypeJSON; |
354 else if (responseType == "document") | 366 } else if (responseType == "document") { |
355 m_responseTypeCode = ResponseTypeDocument; | 367 m_responseTypeCode = ResponseTypeDocument; |
356 else if (responseType == "blob") | 368 } else if (responseType == "blob") { |
357 m_responseTypeCode = ResponseTypeBlob; | 369 m_responseTypeCode = ResponseTypeBlob; |
358 else if (responseType == "arraybuffer") | 370 } else if (responseType == "arraybuffer") { |
359 m_responseTypeCode = ResponseTypeArrayBuffer; | 371 m_responseTypeCode = ResponseTypeArrayBuffer; |
360 else | 372 } else if (responseType == "stream") { |
| 373 if (RuntimeEnabledFeatures::streamEnabled()) |
| 374 m_responseTypeCode = ResponseTypeStream; |
| 375 else |
| 376 return; |
| 377 } else { |
361 ASSERT_NOT_REACHED(); | 378 ASSERT_NOT_REACHED(); |
| 379 } |
362 } | 380 } |
363 | 381 |
364 String XMLHttpRequest::responseType() | 382 String XMLHttpRequest::responseType() |
365 { | 383 { |
366 switch (m_responseTypeCode) { | 384 switch (m_responseTypeCode) { |
367 case ResponseTypeDefault: | 385 case ResponseTypeDefault: |
368 return ""; | 386 return ""; |
369 case ResponseTypeText: | 387 case ResponseTypeText: |
370 return "text"; | 388 return "text"; |
371 case ResponseTypeJSON: | 389 case ResponseTypeJSON: |
372 return "json"; | 390 return "json"; |
373 case ResponseTypeDocument: | 391 case ResponseTypeDocument: |
374 return "document"; | 392 return "document"; |
375 case ResponseTypeBlob: | 393 case ResponseTypeBlob: |
376 return "blob"; | 394 return "blob"; |
377 case ResponseTypeArrayBuffer: | 395 case ResponseTypeArrayBuffer: |
378 return "arraybuffer"; | 396 return "arraybuffer"; |
| 397 case ResponseTypeStream: |
| 398 return "stream"; |
379 } | 399 } |
380 return ""; | 400 return ""; |
381 } | 401 } |
382 | 402 |
383 XMLHttpRequestUpload* XMLHttpRequest::upload() | 403 XMLHttpRequestUpload* XMLHttpRequest::upload() |
384 { | 404 { |
385 if (!m_upload) | 405 if (!m_upload) |
386 m_upload = XMLHttpRequestUpload::create(this); | 406 m_upload = XMLHttpRequestUpload::create(this); |
387 return m_upload.get(); | 407 return m_upload.get(); |
388 } | 408 } |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 void XMLHttpRequest::internalAbort(DropProtection async) | 838 void XMLHttpRequest::internalAbort(DropProtection async) |
819 { | 839 { |
820 m_error = true; | 840 m_error = true; |
821 | 841 |
822 // FIXME: when we add the support for multi-part XHR, we will have to think
be careful with this initialization. | 842 // FIXME: when we add the support for multi-part XHR, we will have to think
be careful with this initialization. |
823 m_receivedLength = 0; | 843 m_receivedLength = 0; |
824 m_decoder = 0; | 844 m_decoder = 0; |
825 | 845 |
826 InspectorInstrumentation::didFailXHRLoading(scriptExecutionContext(), this); | 846 InspectorInstrumentation::didFailXHRLoading(scriptExecutionContext(), this); |
827 | 847 |
828 if (m_loader) { | 848 if (m_responseStream && m_state != DONE) |
829 m_loader->cancel(); | 849 m_responseStream->abort(); |
830 m_loader = 0; | |
831 | 850 |
832 if (async == DropProtectionAsync) | 851 if (!m_loader) |
833 dropProtectionSoon(); | 852 return; |
834 else | 853 |
835 dropProtection(); | 854 m_loader->cancel(); |
836 } | 855 m_loader = 0; |
| 856 |
| 857 if (async == DropProtectionAsync) |
| 858 dropProtectionSoon(); |
| 859 else |
| 860 dropProtection(); |
837 } | 861 } |
838 | 862 |
839 void XMLHttpRequest::clearResponse() | 863 void XMLHttpRequest::clearResponse() |
840 { | 864 { |
841 m_response = ResourceResponse(); | 865 m_response = ResourceResponse(); |
842 clearResponseBuffers(); | 866 clearResponseBuffers(); |
843 } | 867 } |
844 | 868 |
845 void XMLHttpRequest::clearResponseBuffers() | 869 void XMLHttpRequest::clearResponseBuffers() |
846 { | 870 { |
847 m_responseText.clear(); | 871 m_responseText.clear(); |
848 m_responseEncoding = String(); | 872 m_responseEncoding = String(); |
849 m_createdDocument = false; | 873 m_createdDocument = false; |
850 m_responseDocument = 0; | 874 m_responseDocument = 0; |
851 m_responseBlob = 0; | 875 m_responseBlob = 0; |
| 876 m_responseStream = 0; |
852 m_binaryResponseBuilder.clear(); | 877 m_binaryResponseBuilder.clear(); |
853 m_responseArrayBuffer.clear(); | 878 m_responseArrayBuffer.clear(); |
854 } | 879 } |
855 | 880 |
856 void XMLHttpRequest::clearRequest() | 881 void XMLHttpRequest::clearRequest() |
857 { | 882 { |
858 m_requestHeaders.clear(); | 883 m_requestHeaders.clear(); |
859 m_requestEntityBody = 0; | 884 m_requestEntityBody = 0; |
860 } | 885 } |
861 | 886 |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1089 { | 1114 { |
1090 if (m_error) | 1115 if (m_error) |
1091 return; | 1116 return; |
1092 | 1117 |
1093 if (m_state < HEADERS_RECEIVED) | 1118 if (m_state < HEADERS_RECEIVED) |
1094 changeState(HEADERS_RECEIVED); | 1119 changeState(HEADERS_RECEIVED); |
1095 | 1120 |
1096 if (m_decoder) | 1121 if (m_decoder) |
1097 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); | 1122 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); |
1098 | 1123 |
| 1124 if (m_responseStream) |
| 1125 m_responseStream->finalize(); |
| 1126 |
1099 InspectorInstrumentation::didFinishXHRLoading(scriptExecutionContext(), this
, identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); | 1127 InspectorInstrumentation::didFinishXHRLoading(scriptExecutionContext(), this
, identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); |
1100 | 1128 |
1101 // Prevent dropProtection releasing the last reference, and retain |this| un
til the end of this method. | 1129 // Prevent dropProtection releasing the last reference, and retain |this| un
til the end of this method. |
1102 RefPtr<XMLHttpRequest> protect(this); | 1130 RefPtr<XMLHttpRequest> protect(this); |
1103 | 1131 |
1104 if (m_loader) { | 1132 if (m_loader) { |
1105 m_loader = 0; | 1133 m_loader = 0; |
1106 dropProtection(); | 1134 dropProtection(); |
1107 } | 1135 } |
1108 | 1136 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 else | 1193 else |
1166 m_decoder = TextResourceDecoder::create("text/plain", "UTF-8"); | 1194 m_decoder = TextResourceDecoder::create("text/plain", "UTF-8"); |
1167 } | 1195 } |
1168 | 1196 |
1169 if (!len) | 1197 if (!len) |
1170 return; | 1198 return; |
1171 | 1199 |
1172 if (len == -1) | 1200 if (len == -1) |
1173 len = strlen(data); | 1201 len = strlen(data); |
1174 | 1202 |
1175 if (useDecoder) | 1203 if (useDecoder) { |
1176 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data,
len)); | 1204 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data,
len)); |
1177 else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCode
== ResponseTypeBlob) { | 1205 } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCo
de == ResponseTypeBlob) { |
1178 // Buffer binary data. | 1206 // Buffer binary data. |
1179 if (!m_binaryResponseBuilder) | 1207 if (!m_binaryResponseBuilder) |
1180 m_binaryResponseBuilder = SharedBuffer::create(); | 1208 m_binaryResponseBuilder = SharedBuffer::create(); |
1181 m_binaryResponseBuilder->append(data, len); | 1209 m_binaryResponseBuilder->append(data, len); |
| 1210 } else if (m_responseTypeCode == ResponseTypeStream) { |
| 1211 if (!m_responseStream) |
| 1212 m_responseStream = Stream::create(responseMIMEType()); |
| 1213 m_responseStream->addData(data, len); |
1182 } | 1214 } |
1183 | 1215 |
1184 if (!m_error) { | 1216 if (!m_error) { |
1185 long long expectedLength = m_response.expectedContentLength(); | 1217 long long expectedLength = m_response.expectedContentLength(); |
1186 m_receivedLength += len; | 1218 m_receivedLength += len; |
1187 | 1219 |
1188 if (m_async) { | 1220 if (m_async) { |
1189 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex
pectedLength; | 1221 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex
pectedLength; |
1190 unsigned long long total = lengthComputable ? expectedLength : 0; | 1222 unsigned long long total = lengthComputable ? expectedLength : 0; |
1191 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re
ceivedLength, total); | 1223 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re
ceivedLength, total); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 { | 1289 { |
1258 return eventNames().interfaceForXMLHttpRequest; | 1290 return eventNames().interfaceForXMLHttpRequest; |
1259 } | 1291 } |
1260 | 1292 |
1261 ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const | 1293 ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const |
1262 { | 1294 { |
1263 return ActiveDOMObject::scriptExecutionContext(); | 1295 return ActiveDOMObject::scriptExecutionContext(); |
1264 } | 1296 } |
1265 | 1297 |
1266 } // namespace WebCore | 1298 } // namespace WebCore |
OLD | NEW |