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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 #include "core/xmlhttprequest/XMLHttpRequestProgressEvent.h" | 63 #include "core/xmlhttprequest/XMLHttpRequestProgressEvent.h" |
64 #include "core/xmlhttprequest/XMLHttpRequestUpload.h" | 64 #include "core/xmlhttprequest/XMLHttpRequestUpload.h" |
65 #include "platform/Logging.h" | 65 #include "platform/Logging.h" |
66 #include "platform/RuntimeEnabledFeatures.h" | 66 #include "platform/RuntimeEnabledFeatures.h" |
67 #include "platform/SharedBuffer.h" | 67 #include "platform/SharedBuffer.h" |
68 #include "platform/blob/BlobData.h" | 68 #include "platform/blob/BlobData.h" |
69 #include "platform/network/HTTPParsers.h" | 69 #include "platform/network/HTTPParsers.h" |
70 #include "platform/network/ParsedContentType.h" | 70 #include "platform/network/ParsedContentType.h" |
71 #include "platform/network/ResourceError.h" | 71 #include "platform/network/ResourceError.h" |
72 #include "platform/network/ResourceRequest.h" | 72 #include "platform/network/ResourceRequest.h" |
| 73 #include "public/platform/Platform.h" |
73 #include "public/platform/WebURLRequest.h" | 74 #include "public/platform/WebURLRequest.h" |
74 #include "wtf/Assertions.h" | 75 #include "wtf/Assertions.h" |
75 #include "wtf/StdLibExtras.h" | 76 #include "wtf/StdLibExtras.h" |
76 #include "wtf/text/CString.h" | 77 #include "wtf/text/CString.h" |
77 | 78 |
78 namespace blink { | 79 namespace blink { |
79 | 80 |
80 namespace { | 81 namespace { |
81 | 82 |
82 // This class protects the wrapper of the associated XMLHttpRequest object | 83 // This class protects the wrapper of the associated XMLHttpRequest object |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 125 |
125 void logConsoleError(ExecutionContext* context, const String& message) | 126 void logConsoleError(ExecutionContext* context, const String& message) |
126 { | 127 { |
127 if (!context) | 128 if (!context) |
128 return; | 129 return; |
129 // FIXME: It's not good to report the bad usage without indicating what sour
ce line it came from. | 130 // FIXME: It's not good to report the bad usage without indicating what sour
ce line it came from. |
130 // We should pass additional parameters so we can tell the console where the
mistake occurred. | 131 // We should pass additional parameters so we can tell the console where the
mistake occurred. |
131 context->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMess
ageLevel, message)); | 132 context->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMess
ageLevel, message)); |
132 } | 133 } |
133 | 134 |
| 135 enum HeaderValueCategoryByRFC7230 { |
| 136 HeaderValueInvalid, |
| 137 HeaderValueAffectedByNormalization, |
| 138 HeaderValueValid, |
| 139 HeaderValueCategoryByRFC7230End |
| 140 }; |
| 141 |
134 } // namespace | 142 } // namespace |
135 | 143 |
136 class XMLHttpRequest::BlobLoader final : public GarbageCollectedFinalized<XMLHtt
pRequest::BlobLoader>, public FileReaderLoaderClient { | 144 class XMLHttpRequest::BlobLoader final : public GarbageCollectedFinalized<XMLHtt
pRequest::BlobLoader>, public FileReaderLoaderClient { |
137 public: | 145 public: |
138 static BlobLoader* create(XMLHttpRequest* xhr, PassRefPtr<BlobDataHandle> ha
ndle) | 146 static BlobLoader* create(XMLHttpRequest* xhr, PassRefPtr<BlobDataHandle> ha
ndle) |
139 { | 147 { |
140 return new BlobLoader(xhr, handle); | 148 return new BlobLoader(xhr, handle); |
141 } | 149 } |
142 | 150 |
143 // FileReaderLoaderClient functions. | 151 // FileReaderLoaderClient functions. |
(...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 if (!isValidHTTPToken(name)) { | 1175 if (!isValidHTTPToken(name)) { |
1168 exceptionState.throwDOMException(SyntaxError, "'" + name + "' is not a v
alid HTTP header field name."); | 1176 exceptionState.throwDOMException(SyntaxError, "'" + name + "' is not a v
alid HTTP header field name."); |
1169 return; | 1177 return; |
1170 } | 1178 } |
1171 | 1179 |
1172 if (!isValidHTTPHeaderValue(value)) { | 1180 if (!isValidHTTPHeaderValue(value)) { |
1173 exceptionState.throwDOMException(SyntaxError, "'" + value + "' is not a
valid HTTP header field value."); | 1181 exceptionState.throwDOMException(SyntaxError, "'" + value + "' is not a
valid HTTP header field value."); |
1174 return; | 1182 return; |
1175 } | 1183 } |
1176 | 1184 |
1177 // Show deprecation warnings and count occurrences of such deprecated header
values. | |
1178 if (!value.isEmpty() && !isValidHTTPFieldContentRFC7230(value)) | |
1179 UseCounter::countDeprecation(executionContext(), UseCounter::HeaderValue
NotMatchingRFC7230); | |
1180 | |
1181 // No script (privileged or not) can set unsafe headers. | 1185 // No script (privileged or not) can set unsafe headers. |
1182 if (FetchUtils::isForbiddenHeaderName(name)) { | 1186 if (FetchUtils::isForbiddenHeaderName(name)) { |
1183 logConsoleError(executionContext(), "Refused to set unsafe header \"" +
name + "\""); | 1187 logConsoleError(executionContext(), "Refused to set unsafe header \"" +
name + "\""); |
1184 return; | 1188 return; |
1185 } | 1189 } |
1186 | 1190 |
1187 setRequestHeaderInternal(name, value); | 1191 setRequestHeaderInternal(name, value); |
1188 } | 1192 } |
1189 | 1193 |
1190 void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const At
omicString& value) | 1194 void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const At
omicString& value) |
1191 { | 1195 { |
| 1196 HeaderValueCategoryByRFC7230 headerValueCategory = HeaderValueValid; |
| 1197 |
1192 HTTPHeaderMap::AddResult result = m_requestHeaders.add(name, value); | 1198 HTTPHeaderMap::AddResult result = m_requestHeaders.add(name, value); |
1193 if (!result.isNewEntry) | 1199 if (!result.isNewEntry) { |
1194 result.storedValue->value = result.storedValue->value + ", " + value; | 1200 AtomicString newValue = result.storedValue->value + ", " + value; |
| 1201 |
| 1202 // Without normalization at XHR level here, the actual header value |
| 1203 // sent to the network is |newValue| with leading/trailing whitespaces |
| 1204 // stripped (i.e. |normalizeHeaderValue(newValue)|). |
| 1205 // With normalization at XHR level here as the spec requires, the |
| 1206 // actual header value sent to the network is |normalizedNewValue|. |
| 1207 // If these two are different, introducing normalization here affects |
| 1208 // the header value sent to the network. |
| 1209 String normalizedNewValue = FetchUtils::normalizeHeaderValue(result.stor
edValue->value) + ", " + FetchUtils::normalizeHeaderValue(value); |
| 1210 if (FetchUtils::normalizeHeaderValue(newValue) != normalizedNewValue) |
| 1211 headerValueCategory = HeaderValueAffectedByNormalization; |
| 1212 |
| 1213 result.storedValue->value = newValue; |
| 1214 } |
| 1215 |
| 1216 String normalizedValue = FetchUtils::normalizeHeaderValue(value); |
| 1217 if (!normalizedValue.isEmpty() && !isValidHTTPFieldContentRFC7230(normalized
Value)) |
| 1218 headerValueCategory = HeaderValueInvalid; |
| 1219 |
| 1220 Platform::current()->histogramEnumeration("Blink.XHR.setRequestHeader.Header
ValueCategoryInRFC7230", headerValueCategory, HeaderValueCategoryByRFC7230End); |
1195 } | 1221 } |
1196 | 1222 |
1197 const AtomicString& XMLHttpRequest::getRequestHeader(const AtomicString& name) c
onst | 1223 const AtomicString& XMLHttpRequest::getRequestHeader(const AtomicString& name) c
onst |
1198 { | 1224 { |
1199 return m_requestHeaders.get(name); | 1225 return m_requestHeaders.get(name); |
1200 } | 1226 } |
1201 | 1227 |
1202 String XMLHttpRequest::getAllResponseHeaders() const | 1228 String XMLHttpRequest::getAllResponseHeaders() const |
1203 { | 1229 { |
1204 if (m_state < HEADERS_RECEIVED || m_error) | 1230 if (m_state < HEADERS_RECEIVED || m_error) |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1688 visitor->trace(m_responseDocumentParser); | 1714 visitor->trace(m_responseDocumentParser); |
1689 visitor->trace(m_progressEventThrottle); | 1715 visitor->trace(m_progressEventThrottle); |
1690 visitor->trace(m_upload); | 1716 visitor->trace(m_upload); |
1691 visitor->trace(m_blobLoader); | 1717 visitor->trace(m_blobLoader); |
1692 XMLHttpRequestEventTarget::trace(visitor); | 1718 XMLHttpRequestEventTarget::trace(visitor); |
1693 DocumentParserClient::trace(visitor); | 1719 DocumentParserClient::trace(visitor); |
1694 ActiveDOMObject::trace(visitor); | 1720 ActiveDOMObject::trace(visitor); |
1695 } | 1721 } |
1696 | 1722 |
1697 } // namespace blink | 1723 } // namespace blink |
OLD | NEW |