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 |