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 <wtf/ArrayBuffer.h> | 26 #include "RuntimeEnabledFeatures.h" |
27 #include <wtf/ArrayBufferView.h> | |
28 #include <wtf/RefCountedLeakCounter.h> | |
29 #include <wtf/StdLibExtras.h> | |
30 #include <wtf/text/CString.h> | |
31 #include <wtf/UnusedParam.h> | |
32 #include "core/dom/ContextFeatures.h" | 27 #include "core/dom/ContextFeatures.h" |
33 #include "core/dom/DOMImplementation.h" | 28 #include "core/dom/DOMImplementation.h" |
34 #include "core/dom/Event.h" | 29 #include "core/dom/Event.h" |
35 #include "core/dom/EventListener.h" | 30 #include "core/dom/EventListener.h" |
36 #include "core/dom/EventNames.h" | 31 #include "core/dom/EventNames.h" |
37 #include "core/dom/ExceptionCode.h" | 32 #include "core/dom/ExceptionCode.h" |
38 #include "core/dom/WebCoreMemoryInstrumentation.h" | 33 #include "core/dom/WebCoreMemoryInstrumentation.h" |
39 #include "core/editing/markup.h" | 34 #include "core/editing/markup.h" |
40 #include "core/fileapi/Blob.h" | 35 #include "core/fileapi/Blob.h" |
41 #include "core/fileapi/File.h" | 36 #include "core/fileapi/File.h" |
37 #include "core/fileapi/Stream.h" | |
42 #include "core/html/DOMFormData.h" | 38 #include "core/html/DOMFormData.h" |
43 #include "core/html/HTMLDocument.h" | 39 #include "core/html/HTMLDocument.h" |
44 #include "core/inspector/InspectorInstrumentation.h" | 40 #include "core/inspector/InspectorInstrumentation.h" |
45 #include "core/loader/CrossOriginAccessControl.h" | 41 #include "core/loader/CrossOriginAccessControl.h" |
46 #include "core/loader/TextResourceDecoder.h" | 42 #include "core/loader/TextResourceDecoder.h" |
47 #include "core/loader/ThreadableLoader.h" | 43 #include "core/loader/ThreadableLoader.h" |
48 #include "core/loader/cache/CachedResourceRequestInitiators.h" | 44 #include "core/loader/cache/CachedResourceRequestInitiators.h" |
49 #include "core/page/ContentSecurityPolicy.h" | 45 #include "core/page/ContentSecurityPolicy.h" |
50 #include "core/page/Settings.h" | 46 #include "core/page/Settings.h" |
51 #include "core/platform/HistogramSupport.h" | 47 #include "core/platform/HistogramSupport.h" |
52 #include "core/platform/SharedBuffer.h" | 48 #include "core/platform/SharedBuffer.h" |
53 #include "core/platform/network/BlobData.h" | 49 #include "core/platform/network/BlobData.h" |
54 #include "core/platform/network/HTTPParsers.h" | 50 #include "core/platform/network/HTTPParsers.h" |
55 #include "core/platform/network/ParsedContentType.h" | 51 #include "core/platform/network/ParsedContentType.h" |
56 #include "core/platform/network/ResourceError.h" | 52 #include "core/platform/network/ResourceError.h" |
57 #include "core/platform/network/ResourceRequest.h" | 53 #include "core/platform/network/ResourceRequest.h" |
58 #include "core/xml/XMLHttpRequestProgressEvent.h" | 54 #include "core/xml/XMLHttpRequestProgressEvent.h" |
59 #include "core/xml/XMLHttpRequestUpload.h" | 55 #include "core/xml/XMLHttpRequestUpload.h" |
60 #include "weborigin/SecurityOrigin.h" | 56 #include "weborigin/SecurityOrigin.h" |
57 #include "wtf/ArrayBuffer.h" | |
58 #include "wtf/ArrayBufferView.h" | |
59 #include "wtf/RefCountedLeakCounter.h" | |
60 #include "wtf/StdLibExtras.h" | |
61 #include "wtf/UnusedParam.h" | |
62 #include "wtf/text/CString.h" | |
61 | 63 |
62 namespace WebCore { | 64 namespace WebCore { |
63 | 65 |
64 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, xmlHttpRequestCounter, ("XM LHttpRequest")); | 66 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, xmlHttpRequestCounter, ("XM LHttpRequest")); |
65 | 67 |
66 // Histogram enum to see when we can deprecate xhr.send(ArrayBuffer). | 68 // Histogram enum to see when we can deprecate xhr.send(ArrayBuffer). |
67 enum XMLHttpRequestSendArrayBufferOrView { | 69 enum XMLHttpRequestSendArrayBufferOrView { |
68 XMLHttpRequestSendArrayBuffer, | 70 XMLHttpRequestSendArrayBuffer, |
69 XMLHttpRequestSendArrayBufferView, | 71 XMLHttpRequestSendArrayBufferView, |
70 XMLHttpRequestSendArrayBufferOrViewMax, | 72 XMLHttpRequestSendArrayBufferOrViewMax, |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
306 return 0; | 308 return 0; |
307 | 309 |
308 if (!m_responseArrayBuffer.get() && m_binaryResponseBuilder.get() && m_binar yResponseBuilder->size() > 0) { | 310 if (!m_responseArrayBuffer.get() && m_binaryResponseBuilder.get() && m_binar yResponseBuilder->size() > 0) { |
309 m_responseArrayBuffer = m_binaryResponseBuilder->getAsArrayBuffer(); | 311 m_responseArrayBuffer = m_binaryResponseBuilder->getAsArrayBuffer(); |
310 m_binaryResponseBuilder.clear(); | 312 m_binaryResponseBuilder.clear(); |
311 } | 313 } |
312 | 314 |
313 return m_responseArrayBuffer.get(); | 315 return m_responseArrayBuffer.get(); |
314 } | 316 } |
315 | 317 |
318 Stream* XMLHttpRequest::responseStream(ExceptionCode& ec) | |
319 { | |
320 if (m_responseTypeCode != ResponseTypeStream) { | |
321 ec = InvalidStateError; | |
322 return 0; | |
323 } | |
324 | |
325 if (m_error || (m_state != LOADING && m_state != DONE)) | |
326 return 0; | |
327 | |
328 return m_responseStream.get(); | |
329 } | |
330 | |
316 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionCode& ec) | 331 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionCode& ec) |
317 { | 332 { |
318 // FIXME: Need to trigger or update the timeout Timer here, if needed. http: //webkit.org/b/98156 | 333 // FIXME: Need to trigger or update the timeout Timer here, if needed. http: //webkit.org/b/98156 |
319 // 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." | 334 // 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." |
320 if (scriptExecutionContext()->isDocument() && !m_async) { | 335 if (scriptExecutionContext()->isDocument() && !m_async) { |
321 logConsoleError(scriptExecutionContext(), "XMLHttpRequest.timeout cannot be set for synchronous HTTP(S) requests made from the window context."); | 336 logConsoleError(scriptExecutionContext(), "XMLHttpRequest.timeout cannot be set for synchronous HTTP(S) requests made from the window context."); |
322 ec = InvalidAccessError; | 337 ec = InvalidAccessError; |
323 return; | 338 return; |
324 } | 339 } |
325 m_timeoutMilliseconds = timeout; | 340 m_timeoutMilliseconds = timeout; |
326 } | 341 } |
327 | 342 |
328 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionCode& ec) | 343 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionCode& ec) |
329 { | 344 { |
330 if (m_state >= LOADING) { | 345 if (m_state >= LOADING) { |
331 ec = InvalidStateError; | 346 ec = InvalidStateError; |
332 return; | 347 return; |
333 } | 348 } |
334 | 349 |
335 // Newer functionality is not available to synchronous requests in window co ntexts, as a spec-mandated | 350 // Newer functionality is not available to synchronous requests in window co ntexts, as a spec-mandated |
336 // attempt to discourage synchronous XHR use. responseType is one such piece of functionality. | 351 // attempt to discourage synchronous XHR use. responseType is one such piece of functionality. |
337 // We'll only disable this functionality for HTTP(S) requests since sync req uests for local protocols | 352 // We'll only disable this functionality for HTTP(S) requests since sync req uests for local protocols |
338 // such as file: and data: still make sense to allow. | 353 // such as file: and data: still make sense to allow. |
339 if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsIn HTTPFamily()) { | 354 if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsIn HTTPFamily()) { |
340 logConsoleError(scriptExecutionContext(), "XMLHttpRequest.responseType c annot be changed for synchronous HTTP(S) requests made from the window context." ); | 355 logConsoleError(scriptExecutionContext(), "XMLHttpRequest.responseType c annot be changed for synchronous HTTP(S) requests made from the window context." ); |
341 ec = InvalidAccessError; | 356 ec = InvalidAccessError; |
342 return; | 357 return; |
343 } | 358 } |
344 | 359 |
345 if (responseType == "") | 360 if (responseType == "") { |
346 m_responseTypeCode = ResponseTypeDefault; | 361 m_responseTypeCode = ResponseTypeDefault; |
347 else if (responseType == "text") | 362 } else if (responseType == "text") { |
348 m_responseTypeCode = ResponseTypeText; | 363 m_responseTypeCode = ResponseTypeText; |
349 else if (responseType == "document") | 364 } else if (responseType == "document") { |
350 m_responseTypeCode = ResponseTypeDocument; | 365 m_responseTypeCode = ResponseTypeDocument; |
351 else if (responseType == "blob") | 366 } else if (responseType == "blob") { |
352 m_responseTypeCode = ResponseTypeBlob; | 367 m_responseTypeCode = ResponseTypeBlob; |
353 else if (responseType == "arraybuffer") | 368 } else if (responseType == "arraybuffer") { |
354 m_responseTypeCode = ResponseTypeArrayBuffer; | 369 m_responseTypeCode = ResponseTypeArrayBuffer; |
355 else | 370 } else if (responseType == "stream") { |
371 if (RuntimeEnabledFeatures::streamEnabled()) | |
372 m_responseTypeCode = ResponseTypeStream; | |
373 else | |
374 return; | |
375 } else { | |
356 ASSERT_NOT_REACHED(); | 376 ASSERT_NOT_REACHED(); |
377 } | |
357 } | 378 } |
358 | 379 |
359 String XMLHttpRequest::responseType() | 380 String XMLHttpRequest::responseType() |
360 { | 381 { |
361 switch (m_responseTypeCode) { | 382 switch (m_responseTypeCode) { |
362 case ResponseTypeDefault: | 383 case ResponseTypeDefault: |
363 return ""; | 384 return ASCIILiteral(""); |
364 case ResponseTypeText: | 385 case ResponseTypeText: |
365 return "text"; | 386 return ASCIILiteral("text"); |
366 case ResponseTypeDocument: | 387 case ResponseTypeDocument: |
367 return "document"; | 388 return ASCIILiteral("document"); |
368 case ResponseTypeBlob: | 389 case ResponseTypeBlob: |
369 return "blob"; | 390 return ASCIILiteral("blob"); |
370 case ResponseTypeArrayBuffer: | 391 case ResponseTypeArrayBuffer: |
371 return "arraybuffer"; | 392 return ASCIILiteral("arraybuffer"); |
393 case ResponseTypeStream: | |
394 return ASCIILiteral("stream"); | |
372 } | 395 } |
373 return ""; | 396 return ASCIILiteral(""); |
374 } | 397 } |
375 | 398 |
376 XMLHttpRequestUpload* XMLHttpRequest::upload() | 399 XMLHttpRequestUpload* XMLHttpRequest::upload() |
377 { | 400 { |
378 if (!m_upload) | 401 if (!m_upload) |
379 m_upload = XMLHttpRequestUpload::create(this); | 402 m_upload = XMLHttpRequestUpload::create(this); |
380 return m_upload.get(); | 403 return m_upload.get(); |
381 } | 404 } |
382 | 405 |
383 void XMLHttpRequest::changeState(State newState) | 406 void XMLHttpRequest::changeState(State newState) |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
931 | 954 |
932 String XMLHttpRequest::getRequestHeader(const AtomicString& name) const | 955 String XMLHttpRequest::getRequestHeader(const AtomicString& name) const |
933 { | 956 { |
934 return m_requestHeaders.get(name); | 957 return m_requestHeaders.get(name); |
935 } | 958 } |
936 | 959 |
937 String XMLHttpRequest::getAllResponseHeaders(ExceptionCode& ec) const | 960 String XMLHttpRequest::getAllResponseHeaders(ExceptionCode& ec) const |
938 { | 961 { |
939 if (m_state < HEADERS_RECEIVED) { | 962 if (m_state < HEADERS_RECEIVED) { |
940 ec = InvalidStateError; | 963 ec = InvalidStateError; |
941 return ""; | 964 return ASCIILiteral(""); |
942 } | 965 } |
943 | 966 |
944 StringBuilder stringBuilder; | 967 StringBuilder stringBuilder; |
945 | 968 |
946 HTTPHeaderSet accessControlExposeHeaderSet; | 969 HTTPHeaderSet accessControlExposeHeaderSet; |
947 parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access- Control-Expose-Headers"), accessControlExposeHeaderSet); | 970 parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access- Control-Expose-Headers"), accessControlExposeHeaderSet); |
948 HTTPHeaderMap::const_iterator end = m_response.httpHeaderFields().end(); | 971 HTTPHeaderMap::const_iterator end = m_response.httpHeaderFields().end(); |
949 for (HTTPHeaderMap::const_iterator it = m_response.httpHeaderFields().begin( ); it!= end; ++it) { | 972 for (HTTPHeaderMap::const_iterator it = m_response.httpHeaderFields().begin( ); it!= end; ++it) { |
950 // Hide Set-Cookie header fields from the XMLHttpRequest client for thes e reasons: | 973 // Hide Set-Cookie header fields from the XMLHttpRequest client for thes e reasons: |
951 // 1) If the client did have access to the fields, then it could rea d HTTP-only | 974 // 1) If the client did have access to the fields, then it could rea d HTTP-only |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1079 return; | 1102 return; |
1080 | 1103 |
1081 if (m_state < HEADERS_RECEIVED) | 1104 if (m_state < HEADERS_RECEIVED) |
1082 changeState(HEADERS_RECEIVED); | 1105 changeState(HEADERS_RECEIVED); |
1083 | 1106 |
1084 if (m_decoder) | 1107 if (m_decoder) |
1085 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); | 1108 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); |
1086 | 1109 |
1087 InspectorInstrumentation::didFinishXHRLoading(scriptExecutionContext(), this , identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); | 1110 InspectorInstrumentation::didFinishXHRLoading(scriptExecutionContext(), this , identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); |
1088 | 1111 |
1112 if (m_responseStream) | |
1113 m_responseStream->finalize(); | |
1114 | |
1089 bool hadLoader = m_loader; | 1115 bool hadLoader = m_loader; |
1090 m_loader = 0; | 1116 m_loader = 0; |
1091 | 1117 |
1092 changeState(DONE); | 1118 changeState(DONE); |
1093 m_decoder = 0; | 1119 m_decoder = 0; |
1094 | 1120 |
1095 if (hadLoader) | 1121 if (hadLoader) |
1096 dropProtection(); | 1122 dropProtection(); |
1097 } | 1123 } |
1098 | 1124 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1155 if (len == -1) | 1181 if (len == -1) |
1156 len = strlen(data); | 1182 len = strlen(data); |
1157 | 1183 |
1158 if (useDecoder) | 1184 if (useDecoder) |
1159 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); | 1185 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); |
1160 else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCode == ResponseTypeBlob) { | 1186 else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCode == ResponseTypeBlob) { |
1161 // Buffer binary data. | 1187 // Buffer binary data. |
1162 if (!m_binaryResponseBuilder) | 1188 if (!m_binaryResponseBuilder) |
1163 m_binaryResponseBuilder = SharedBuffer::create(); | 1189 m_binaryResponseBuilder = SharedBuffer::create(); |
1164 m_binaryResponseBuilder->append(data, len); | 1190 m_binaryResponseBuilder->append(data, len); |
1191 } else if (m_responseTypeCode == ResponseTypeStream) { | |
1192 if (!m_responseStream) | |
1193 m_responseStream = Stream::create(responseMIMEType()); | |
1194 m_responseStream->addData(data, len); | |
michaeln
2013/07/24 03:57:22
Also, it it a desired characteristic of this imple
| |
1165 } | 1195 } |
1166 | 1196 |
1167 if (!m_error) { | 1197 if (!m_error) { |
1168 long long expectedLength = m_response.expectedContentLength(); | 1198 long long expectedLength = m_response.expectedContentLength(); |
1169 m_receivedLength += len; | 1199 m_receivedLength += len; |
1170 | 1200 |
1171 if (m_async) { | 1201 if (m_async) { |
1172 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex pectedLength; | 1202 bool lengthComputable = expectedLength > 0 && m_receivedLength <= ex pectedLength; |
1173 unsigned long long total = lengthComputable ? expectedLength : 0; | 1203 unsigned long long total = lengthComputable ? expectedLength : 0; |
1174 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re ceivedLength, total); | 1204 m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_re ceivedLength, total); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1276 info.addMember(m_responseDocument, "responseDocument"); | 1306 info.addMember(m_responseDocument, "responseDocument"); |
1277 info.addMember(m_binaryResponseBuilder, "binaryResponseBuilder"); | 1307 info.addMember(m_binaryResponseBuilder, "binaryResponseBuilder"); |
1278 info.addMember(m_responseArrayBuffer, "responseArrayBuffer"); | 1308 info.addMember(m_responseArrayBuffer, "responseArrayBuffer"); |
1279 info.addMember(m_lastSendURL, "lastSendURL"); | 1309 info.addMember(m_lastSendURL, "lastSendURL"); |
1280 info.addMember(m_eventTargetData, "eventTargetData"); | 1310 info.addMember(m_eventTargetData, "eventTargetData"); |
1281 info.addMember(m_progressEventThrottle, "progressEventThrottle"); | 1311 info.addMember(m_progressEventThrottle, "progressEventThrottle"); |
1282 info.addMember(m_securityOrigin, "securityOrigin"); | 1312 info.addMember(m_securityOrigin, "securityOrigin"); |
1283 } | 1313 } |
1284 | 1314 |
1285 } // namespace WebCore | 1315 } // namespace WebCore |
OLD | NEW |