| 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, | 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 21 * Boston, MA 02110-1301 USA | 21 * Boston, MA 02110-1301 USA |
| 22 */ | 22 */ |
| 23 | 23 |
| 24 #include "core/xmlhttprequest/XMLHttpRequest.h" | 24 #include "core/xmlhttprequest/XMLHttpRequest.h" |
| 25 | 25 |
| 26 #include "bindings/core/v8/ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringO
rFormData.h" | 26 #include <memory> |
| 27 #include "bindings/core/v8/ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringO
rFormDataOrURLSearchParams.h" |
| 27 #include "bindings/core/v8/ArrayBufferOrArrayBufferViewOrBlobOrUSVString.h" | 28 #include "bindings/core/v8/ArrayBufferOrArrayBufferViewOrBlobOrUSVString.h" |
| 28 #include "bindings/core/v8/DOMWrapperWorld.h" | 29 #include "bindings/core/v8/DOMWrapperWorld.h" |
| 29 #include "bindings/core/v8/ExceptionState.h" | 30 #include "bindings/core/v8/ExceptionState.h" |
| 30 #include "bindings/core/v8/ScriptState.h" | 31 #include "bindings/core/v8/ScriptState.h" |
| 31 #include "core/dom/DOMArrayBuffer.h" | 32 #include "core/dom/DOMArrayBuffer.h" |
| 32 #include "core/dom/DOMArrayBufferView.h" | 33 #include "core/dom/DOMArrayBufferView.h" |
| 33 #include "core/dom/DOMException.h" | 34 #include "core/dom/DOMException.h" |
| 34 #include "core/dom/DOMImplementation.h" | 35 #include "core/dom/DOMImplementation.h" |
| 35 #include "core/dom/DOMTypedArray.h" | 36 #include "core/dom/DOMTypedArray.h" |
| 36 #include "core/dom/DocumentInit.h" | 37 #include "core/dom/DocumentInit.h" |
| 37 #include "core/dom/DocumentParser.h" | 38 #include "core/dom/DocumentParser.h" |
| 38 #include "core/dom/ExceptionCode.h" | 39 #include "core/dom/ExceptionCode.h" |
| 39 #include "core/dom/ExecutionContext.h" | 40 #include "core/dom/ExecutionContext.h" |
| 41 #include "core/dom/URLSearchParams.h" |
| 40 #include "core/dom/XMLDocument.h" | 42 #include "core/dom/XMLDocument.h" |
| 41 #include "core/editing/serializers/Serialization.h" | 43 #include "core/editing/serializers/Serialization.h" |
| 42 #include "core/events/Event.h" | 44 #include "core/events/Event.h" |
| 43 #include "core/events/ProgressEvent.h" | 45 #include "core/events/ProgressEvent.h" |
| 44 #include "core/fileapi/Blob.h" | 46 #include "core/fileapi/Blob.h" |
| 45 #include "core/fileapi/File.h" | 47 #include "core/fileapi/File.h" |
| 46 #include "core/fileapi/FileReaderLoader.h" | 48 #include "core/fileapi/FileReaderLoader.h" |
| 47 #include "core/fileapi/FileReaderLoaderClient.h" | 49 #include "core/fileapi/FileReaderLoaderClient.h" |
| 48 #include "core/frame/Deprecation.h" | 50 #include "core/frame/Deprecation.h" |
| 49 #include "core/frame/Settings.h" | 51 #include "core/frame/Settings.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 74 #include "platform/network/ResourceError.h" | 76 #include "platform/network/ResourceError.h" |
| 75 #include "platform/network/ResourceRequest.h" | 77 #include "platform/network/ResourceRequest.h" |
| 76 #include "platform/weborigin/SecurityOrigin.h" | 78 #include "platform/weborigin/SecurityOrigin.h" |
| 77 #include "platform/weborigin/SecurityPolicy.h" | 79 #include "platform/weborigin/SecurityPolicy.h" |
| 78 #include "platform/weborigin/Suborigin.h" | 80 #include "platform/weborigin/Suborigin.h" |
| 79 #include "public/platform/WebURLRequest.h" | 81 #include "public/platform/WebURLRequest.h" |
| 80 #include "wtf/Assertions.h" | 82 #include "wtf/Assertions.h" |
| 81 #include "wtf/AutoReset.h" | 83 #include "wtf/AutoReset.h" |
| 82 #include "wtf/StdLibExtras.h" | 84 #include "wtf/StdLibExtras.h" |
| 83 #include "wtf/text/CString.h" | 85 #include "wtf/text/CString.h" |
| 84 #include <memory> | |
| 85 | 86 |
| 86 namespace blink { | 87 namespace blink { |
| 87 | 88 |
| 88 namespace { | 89 namespace { |
| 89 | 90 |
| 90 // This class protects the wrapper of the associated XMLHttpRequest object | 91 // This class protects the wrapper of the associated XMLHttpRequest object |
| 91 // via hasPendingActivity method which returns true if | 92 // via hasPendingActivity method which returns true if |
| 92 // m_eventDispatchRecursionLevel is positive. | 93 // m_eventDispatchRecursionLevel is positive. |
| 93 class ScopedEventDispatchProtect final { | 94 class ScopedEventDispatchProtect final { |
| 94 public: | 95 public: |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 UseCounter::count(getExecutionContext(), | 698 UseCounter::count(getExecutionContext(), |
| 698 UseCounter::During_Microtask_SyncXHR); | 699 UseCounter::During_Microtask_SyncXHR); |
| 699 } | 700 } |
| 700 } | 701 } |
| 701 | 702 |
| 702 m_error = false; | 703 m_error = false; |
| 703 return true; | 704 return true; |
| 704 } | 705 } |
| 705 | 706 |
| 706 void XMLHttpRequest::send( | 707 void XMLHttpRequest::send( |
| 707 const ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringOrFormData& body, | 708 const ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringOrFormDataOrURLSea
rchParams& |
| 709 body, |
| 708 ExceptionState& exceptionState) { | 710 ExceptionState& exceptionState) { |
| 709 probe::willSendXMLHttpOrFetchNetworkRequest(getExecutionContext(), url()); | 711 probe::willSendXMLHttpOrFetchNetworkRequest(getExecutionContext(), url()); |
| 710 | 712 |
| 711 if (body.isNull()) { | 713 if (body.isNull()) { |
| 712 send(String(), exceptionState); | 714 send(String(), exceptionState); |
| 713 return; | 715 return; |
| 714 } | 716 } |
| 715 | 717 |
| 716 if (body.isArrayBuffer()) { | 718 if (body.isArrayBuffer()) { |
| 717 send(body.getAsArrayBuffer(), exceptionState); | 719 send(body.getAsArrayBuffer(), exceptionState); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 731 if (body.isDocument()) { | 733 if (body.isDocument()) { |
| 732 send(body.getAsDocument(), exceptionState); | 734 send(body.getAsDocument(), exceptionState); |
| 733 return; | 735 return; |
| 734 } | 736 } |
| 735 | 737 |
| 736 if (body.isFormData()) { | 738 if (body.isFormData()) { |
| 737 send(body.getAsFormData(), exceptionState); | 739 send(body.getAsFormData(), exceptionState); |
| 738 return; | 740 return; |
| 739 } | 741 } |
| 740 | 742 |
| 743 if (body.isURLSearchParams()) { |
| 744 send(body.getAsURLSearchParams(), exceptionState); |
| 745 return; |
| 746 } |
| 747 |
| 741 DCHECK(body.isString()); | 748 DCHECK(body.isString()); |
| 742 send(body.getAsString(), exceptionState); | 749 send(body.getAsString(), exceptionState); |
| 743 } | 750 } |
| 744 | 751 |
| 745 bool XMLHttpRequest::areMethodAndURLValidForSend() { | 752 bool XMLHttpRequest::areMethodAndURLValidForSend() { |
| 746 return m_method != HTTPNames::GET && m_method != HTTPNames::HEAD && | 753 return m_method != HTTPNames::GET && m_method != HTTPNames::HEAD && |
| 747 m_url.protocolIsInHTTPFamily(); | 754 m_url.protocolIsInHTTPFamily(); |
| 748 } | 755 } |
| 749 | 756 |
| 750 void XMLHttpRequest::send(Document* document, ExceptionState& exceptionState) { | 757 void XMLHttpRequest::send(Document* document, ExceptionState& exceptionState) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 777 | 784 |
| 778 void XMLHttpRequest::send(const String& body, ExceptionState& exceptionState) { | 785 void XMLHttpRequest::send(const String& body, ExceptionState& exceptionState) { |
| 779 NETWORK_DVLOG(1) << this << " send() String " << body; | 786 NETWORK_DVLOG(1) << this << " send() String " << body; |
| 780 | 787 |
| 781 if (!initSend(exceptionState)) | 788 if (!initSend(exceptionState)) |
| 782 return; | 789 return; |
| 783 | 790 |
| 784 RefPtr<EncodedFormData> httpBody; | 791 RefPtr<EncodedFormData> httpBody; |
| 785 | 792 |
| 786 if (!body.isNull() && areMethodAndURLValidForSend()) { | 793 if (!body.isNull() && areMethodAndURLValidForSend()) { |
| 787 String contentType = getRequestHeader(HTTPNames::Content_Type); | |
| 788 if (contentType.isEmpty()) { | |
| 789 setRequestHeaderInternal(HTTPNames::Content_Type, | |
| 790 "text/plain;charset=UTF-8"); | |
| 791 } else { | |
| 792 replaceCharsetInMediaType(contentType, "UTF-8"); | |
| 793 m_requestHeaders.set(HTTPNames::Content_Type, AtomicString(contentType)); | |
| 794 } | |
| 795 | |
| 796 httpBody = EncodedFormData::create( | 794 httpBody = EncodedFormData::create( |
| 797 UTF8Encoding().encode(body, WTF::EntitiesForUnencodables)); | 795 UTF8Encoding().encode(body, WTF::EntitiesForUnencodables)); |
| 796 updateContentTypeAndCharset("text/plain;charset=UTF-8", "UTF-8"); |
| 798 } | 797 } |
| 799 | 798 |
| 800 createRequest(std::move(httpBody), exceptionState); | 799 createRequest(std::move(httpBody), exceptionState); |
| 801 } | 800 } |
| 802 | 801 |
| 803 void XMLHttpRequest::send(Blob* body, ExceptionState& exceptionState) { | 802 void XMLHttpRequest::send(Blob* body, ExceptionState& exceptionState) { |
| 804 NETWORK_DVLOG(1) << this << " send() Blob " << body->uuid(); | 803 NETWORK_DVLOG(1) << this << " send() Blob " << body->uuid(); |
| 805 | 804 |
| 806 if (!initSend(exceptionState)) | 805 if (!initSend(exceptionState)) |
| 807 return; | 806 return; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 NETWORK_DVLOG(1) << this << " send() FormData " << body; | 838 NETWORK_DVLOG(1) << this << " send() FormData " << body; |
| 840 | 839 |
| 841 if (!initSend(exceptionState)) | 840 if (!initSend(exceptionState)) |
| 842 return; | 841 return; |
| 843 | 842 |
| 844 RefPtr<EncodedFormData> httpBody; | 843 RefPtr<EncodedFormData> httpBody; |
| 845 | 844 |
| 846 if (areMethodAndURLValidForSend()) { | 845 if (areMethodAndURLValidForSend()) { |
| 847 httpBody = body->encodeMultiPartFormData(); | 846 httpBody = body->encodeMultiPartFormData(); |
| 848 | 847 |
| 848 // TODO (sof): override any author-provided charset= in the |
| 849 // content type value to UTF-8 ? |
| 849 if (getRequestHeader(HTTPNames::Content_Type).isEmpty()) { | 850 if (getRequestHeader(HTTPNames::Content_Type).isEmpty()) { |
| 850 AtomicString contentType = | 851 AtomicString contentType = |
| 851 AtomicString("multipart/form-data; boundary=") + | 852 AtomicString("multipart/form-data; boundary=") + |
| 852 httpBody->boundary().data(); | 853 httpBody->boundary().data(); |
| 853 setRequestHeaderInternal(HTTPNames::Content_Type, contentType); | 854 setRequestHeaderInternal(HTTPNames::Content_Type, contentType); |
| 854 } | 855 } |
| 855 } | 856 } |
| 856 | 857 |
| 857 createRequest(std::move(httpBody), exceptionState); | 858 createRequest(std::move(httpBody), exceptionState); |
| 858 } | 859 } |
| 859 | 860 |
| 861 void XMLHttpRequest::send(URLSearchParams* body, |
| 862 ExceptionState& exceptionState) { |
| 863 NETWORK_DVLOG(1) << this << " send() URLSearchParams " << body; |
| 864 |
| 865 if (!initSend(exceptionState)) |
| 866 return; |
| 867 |
| 868 RefPtr<EncodedFormData> httpBody; |
| 869 |
| 870 if (areMethodAndURLValidForSend()) { |
| 871 httpBody = body->toEncodedFormData(); |
| 872 updateContentTypeAndCharset( |
| 873 "application/x-www-form-urlencoded;charset=UTF-8", "UTF-8"); |
| 874 } |
| 875 |
| 876 createRequest(std::move(httpBody), exceptionState); |
| 877 } |
| 878 |
| 860 void XMLHttpRequest::send(DOMArrayBuffer* body, | 879 void XMLHttpRequest::send(DOMArrayBuffer* body, |
| 861 ExceptionState& exceptionState) { | 880 ExceptionState& exceptionState) { |
| 862 NETWORK_DVLOG(1) << this << " send() ArrayBuffer " << body; | 881 NETWORK_DVLOG(1) << this << " send() ArrayBuffer " << body; |
| 863 | 882 |
| 864 sendBytesData(body->data(), body->byteLength(), exceptionState); | 883 sendBytesData(body->data(), body->byteLength(), exceptionState); |
| 865 } | 884 } |
| 866 | 885 |
| 867 void XMLHttpRequest::send(DOMArrayBufferView* body, | 886 void XMLHttpRequest::send(DOMArrayBufferView* body, |
| 868 ExceptionState& exceptionState) { | 887 ExceptionState& exceptionState) { |
| 869 NETWORK_DVLOG(1) << this << " send() ArrayBufferView " << body; | 888 NETWORK_DVLOG(1) << this << " send() ArrayBufferView " << body; |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1436 AtomicString XMLHttpRequest::finalResponseMIMETypeWithFallback() const { | 1455 AtomicString XMLHttpRequest::finalResponseMIMETypeWithFallback() const { |
| 1437 AtomicString finalType = finalResponseMIMEType(); | 1456 AtomicString finalType = finalResponseMIMEType(); |
| 1438 if (!finalType.isEmpty()) | 1457 if (!finalType.isEmpty()) |
| 1439 return finalType; | 1458 return finalType; |
| 1440 | 1459 |
| 1441 // FIXME: This fallback is not specified in the final MIME type algorithm | 1460 // FIXME: This fallback is not specified in the final MIME type algorithm |
| 1442 // of the XHR spec. Move this to more appropriate place. | 1461 // of the XHR spec. Move this to more appropriate place. |
| 1443 return AtomicString("text/xml"); | 1462 return AtomicString("text/xml"); |
| 1444 } | 1463 } |
| 1445 | 1464 |
| 1465 void XMLHttpRequest::updateContentTypeAndCharset( |
| 1466 const AtomicString& defaultContentType, |
| 1467 const String& charset) { |
| 1468 // http://xhr.spec.whatwg.org/#the-send()-method step 4's concilliation of |
| 1469 // "charset=" in any author-provided Content-Type: request header. |
| 1470 String contentType = getRequestHeader(HTTPNames::Content_Type); |
| 1471 if (contentType.isEmpty()) { |
| 1472 setRequestHeaderInternal(HTTPNames::Content_Type, defaultContentType); |
| 1473 return; |
| 1474 } |
| 1475 replaceCharsetInMediaType(contentType, charset); |
| 1476 m_requestHeaders.set(HTTPNames::Content_Type, AtomicString(contentType)); |
| 1477 } |
| 1478 |
| 1446 bool XMLHttpRequest::responseIsXML() const { | 1479 bool XMLHttpRequest::responseIsXML() const { |
| 1447 return DOMImplementation::isXMLMIMEType(finalResponseMIMETypeWithFallback()); | 1480 return DOMImplementation::isXMLMIMEType(finalResponseMIMETypeWithFallback()); |
| 1448 } | 1481 } |
| 1449 | 1482 |
| 1450 bool XMLHttpRequest::responseIsHTML() const { | 1483 bool XMLHttpRequest::responseIsHTML() const { |
| 1451 return equalIgnoringCase(finalResponseMIMEType(), "text/html"); | 1484 return equalIgnoringCase(finalResponseMIMEType(), "text/html"); |
| 1452 } | 1485 } |
| 1453 | 1486 |
| 1454 int XMLHttpRequest::status() const { | 1487 int XMLHttpRequest::status() const { |
| 1455 if (m_state == kUnsent || m_state == kOpened || m_error) | 1488 if (m_state == kUnsent || m_state == kOpened || m_error) |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1856 visitor->traceWrappers(m_responseDocument); | 1889 visitor->traceWrappers(m_responseDocument); |
| 1857 visitor->traceWrappers(m_responseArrayBuffer); | 1890 visitor->traceWrappers(m_responseArrayBuffer); |
| 1858 XMLHttpRequestEventTarget::traceWrappers(visitor); | 1891 XMLHttpRequestEventTarget::traceWrappers(visitor); |
| 1859 } | 1892 } |
| 1860 | 1893 |
| 1861 std::ostream& operator<<(std::ostream& ostream, const XMLHttpRequest* xhr) { | 1894 std::ostream& operator<<(std::ostream& ostream, const XMLHttpRequest* xhr) { |
| 1862 return ostream << "XMLHttpRequest " << static_cast<const void*>(xhr); | 1895 return ostream << "XMLHttpRequest " << static_cast<const void*>(xhr); |
| 1863 } | 1896 } |
| 1864 | 1897 |
| 1865 } // namespace blink | 1898 } // namespace blink |
| OLD | NEW |