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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 { | 182 { |
183 ASSERT(m_responseTypeCode == ResponseTypeJSON); | 183 ASSERT(m_responseTypeCode == ResponseTypeJSON); |
184 | 184 |
185 if (m_error || m_state != DONE) | 185 if (m_error || m_state != DONE) |
186 return ScriptString(); | 186 return ScriptString(); |
187 return m_responseText; | 187 return m_responseText; |
188 } | 188 } |
189 | 189 |
190 void XMLHttpRequest::initResponseDocument() | 190 void XMLHttpRequest::initResponseDocument() |
191 { | 191 { |
192 AtomicString mimeType = responseMIMEType(); | 192 AtomicString mimeType = finalMIMEType(); |
sof
2014/08/11 12:19:37
Shouldn't this be finalMIMETypeWithFallback() for
tyoshino (SeeGerritForStatus)
2014/08/11 13:10:46
Wow, good catch! Done.
| |
193 bool isHTML = equalIgnoringCase(mimeType, "text/html"); | 193 bool isHTML = equalIgnoringCase(mimeType, "text/html"); |
194 | 194 |
195 // The W3C spec requires the final MIME type to be some valid XML type, or t ext/html. | 195 // The W3C spec requires the final MIME type to be some valid XML type, or t ext/html. |
196 // If it is text/html, then the responseType of "document" must have been su pplied explicitly. | 196 // If it is text/html, then the responseType of "document" must have been su pplied explicitly. |
197 if ((m_response.isHTTP() && !responseIsXML() && !isHTML) | 197 if ((m_response.isHTTP() && !responseIsXML() && !isHTML) |
198 || (isHTML && m_responseTypeCode == ResponseTypeDefault) | 198 || (isHTML && m_responseTypeCode == ResponseTypeDefault) |
199 || executionContext()->isWorkerGlobalScope()) { | 199 || executionContext()->isWorkerGlobalScope()) { |
200 m_responseDocument = nullptr; | 200 m_responseDocument = nullptr; |
201 return; | 201 return; |
202 } | 202 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
251 // When responseType is set to "blob", we redirect the downloaded data | 251 // When responseType is set to "blob", we redirect the downloaded data |
252 // to a file-handle directly in the browser process. We get the | 252 // to a file-handle directly in the browser process. We get the |
253 // file-path from the ResourceResponse directly instead of copying the | 253 // file-path from the ResourceResponse directly instead of copying the |
254 // bytes between the browser and the renderer. | 254 // bytes between the browser and the renderer. |
255 OwnPtr<BlobData> blobData = BlobData::create(); | 255 OwnPtr<BlobData> blobData = BlobData::create(); |
256 String filePath = m_response.downloadedFilePath(); | 256 String filePath = m_response.downloadedFilePath(); |
257 // If we errored out or got no data, we still return a blob, just an | 257 // If we errored out or got no data, we still return a blob, just an |
258 // empty one. | 258 // empty one. |
259 if (!filePath.isEmpty() && m_downloadedBlobLength) { | 259 if (!filePath.isEmpty() && m_downloadedBlobLength) { |
260 blobData->appendFile(filePath); | 260 blobData->appendFile(filePath); |
261 blobData->setContentType(responseMIMEType()); // responseMIMEType de faults to text/xml which may be incorrect. | 261 // FIXME: finalMIMETypeWithFallback() defaults to text/xml which |
262 // may be incorrect. Replace it with finalMIMEType() after | |
263 // compatibility investigation. | |
264 blobData->setContentType(finalMIMETypeWithFallback()); | |
262 } | 265 } |
263 m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), m_downloadedBlobLength)); | 266 m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), m_downloadedBlobLength)); |
264 } | 267 } |
265 | 268 |
266 return m_responseBlob.get(); | 269 return m_responseBlob.get(); |
267 } | 270 } |
268 | 271 |
269 ArrayBuffer* XMLHttpRequest::responseArrayBuffer() | 272 ArrayBuffer* XMLHttpRequest::responseArrayBuffer() |
270 { | 273 { |
271 ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer); | 274 ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer); |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
871 ASSERT(!m_loader); | 874 ASSERT(!m_loader); |
872 handleRequestError(0, EventTypeNames::abort, receivedLength, expectedLen gth); | 875 handleRequestError(0, EventTypeNames::abort, receivedLength, expectedLen gth); |
873 } | 876 } |
874 m_state = UNSENT; | 877 m_state = UNSENT; |
875 } | 878 } |
876 | 879 |
877 void XMLHttpRequest::clearVariablesForLoading() | 880 void XMLHttpRequest::clearVariablesForLoading() |
878 { | 881 { |
879 m_decoder.clear(); | 882 m_decoder.clear(); |
880 | 883 |
881 m_responseEncoding = String(); | 884 m_finalCharset = String(); |
882 } | 885 } |
883 | 886 |
884 bool XMLHttpRequest::internalAbort() | 887 bool XMLHttpRequest::internalAbort() |
885 { | 888 { |
886 m_error = true; | 889 m_error = true; |
887 | 890 |
888 clearVariablesForLoading(); | 891 clearVariablesForLoading(); |
889 | 892 |
890 InspectorInstrumentation::didFailXHRLoading(executionContext(), this, this); | 893 InspectorInstrumentation::didFailXHRLoading(executionContext(), this, this); |
891 | 894 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1022 // Note: The below event dispatch may be called while |hasPendingActivity() == false|, | 1025 // Note: The below event dispatch may be called while |hasPendingActivity() == false|, |
1023 // when |handleRequestError| is called after |internalAbort()|. | 1026 // when |handleRequestError| is called after |internalAbort()|. |
1024 // This is safe, however, as |this| will be kept alive from a strong ref |Ev ent::m_target|. | 1027 // This is safe, however, as |this| will be kept alive from a strong ref |Ev ent::m_target|. |
1025 dispatchProgressEvent(EventTypeNames::progress, receivedLength, expectedLeng th); | 1028 dispatchProgressEvent(EventTypeNames::progress, receivedLength, expectedLeng th); |
1026 dispatchProgressEvent(type, receivedLength, expectedLength); | 1029 dispatchProgressEvent(type, receivedLength, expectedLength); |
1027 dispatchProgressEvent(EventTypeNames::loadend, receivedLength, expectedLengt h); | 1030 dispatchProgressEvent(EventTypeNames::loadend, receivedLength, expectedLengt h); |
1028 } | 1031 } |
1029 | 1032 |
1030 void XMLHttpRequest::overrideMimeType(const AtomicString& override) | 1033 void XMLHttpRequest::overrideMimeType(const AtomicString& override) |
1031 { | 1034 { |
1035 // FIXME: This method must throw an InvalidStateError exception when the | |
1036 // XHR is in the LOADING or DONE state. http://crbug.com/402375 | |
1037 | |
1032 m_mimeTypeOverride = override; | 1038 m_mimeTypeOverride = override; |
1033 } | 1039 } |
1034 | 1040 |
1035 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const AtomicStri ng& value, ExceptionState& exceptionState) | 1041 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const AtomicStri ng& value, ExceptionState& exceptionState) |
1036 { | 1042 { |
1037 if (m_state != OPENED || m_loader) { | 1043 if (m_state != OPENED || m_loader) { |
1038 exceptionState.throwDOMException(InvalidStateError, "The object's state must be OPENED."); | 1044 exceptionState.throwDOMException(InvalidStateError, "The object's state must be OPENED."); |
1039 return; | 1045 return; |
1040 } | 1046 } |
1041 | 1047 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1118 HTTPHeaderSet accessControlExposeHeaderSet; | 1124 HTTPHeaderSet accessControlExposeHeaderSet; |
1119 parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access- Control-Expose-Headers"), accessControlExposeHeaderSet); | 1125 parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access- Control-Expose-Headers"), accessControlExposeHeaderSet); |
1120 | 1126 |
1121 if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name) && !accessControlExposeHeaderSet.contains(name)) { | 1127 if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name) && !accessControlExposeHeaderSet.contains(name)) { |
1122 logConsoleError(executionContext(), "Refused to get unsafe header \"" + name + "\""); | 1128 logConsoleError(executionContext(), "Refused to get unsafe header \"" + name + "\""); |
1123 return nullAtom; | 1129 return nullAtom; |
1124 } | 1130 } |
1125 return m_response.httpHeaderField(name); | 1131 return m_response.httpHeaderField(name); |
1126 } | 1132 } |
1127 | 1133 |
1128 AtomicString XMLHttpRequest::responseMIMEType() const | 1134 AtomicString XMLHttpRequest::finalMIMEType() const |
1129 { | 1135 { |
1130 AtomicString mimeType = extractMIMETypeFromMediaType(m_mimeTypeOverride); | 1136 AtomicString overriddenType = extractMIMETypeFromMediaType(m_mimeTypeOverrid e); |
1131 if (mimeType.isEmpty()) { | 1137 if (!overriddenType.isEmpty()) |
1132 if (m_response.isHTTP()) | 1138 return overriddenType; |
1133 mimeType = extractMIMETypeFromMediaType(m_response.httpHeaderField(" Content-Type")); | |
1134 else | |
1135 mimeType = m_response.mimeType(); | |
1136 } | |
1137 if (mimeType.isEmpty()) | |
1138 mimeType = AtomicString("text/xml", AtomicString::ConstructFromLiteral); | |
1139 | 1139 |
1140 return mimeType; | 1140 if (m_response.isHTTP()) |
1141 return extractMIMETypeFromMediaType(m_response.httpHeaderField("Content- Type")); | |
1142 | |
1143 return m_response.mimeType(); | |
1144 } | |
1145 | |
1146 AtomicString XMLHttpRequest::finalMIMETypeWithFallback() const | |
1147 { | |
1148 AtomicString finalType = finalMIMEType(); | |
1149 if (!finalType.isEmpty()) | |
1150 return finalType; | |
1151 | |
1152 // FIXME: This fallback is not specified in the final MIME type algorithm | |
1153 // of the XHR spec. Move this to more appropriate place. | |
1154 return AtomicString("text/xml", AtomicString::ConstructFromLiteral); | |
1141 } | 1155 } |
1142 | 1156 |
1143 bool XMLHttpRequest::responseIsXML() const | 1157 bool XMLHttpRequest::responseIsXML() const |
1144 { | 1158 { |
1145 return DOMImplementation::isXMLMIMEType(responseMIMEType()); | 1159 return DOMImplementation::isXMLMIMEType(finalMIMETypeWithFallback()); |
1146 } | 1160 } |
1147 | 1161 |
1148 int XMLHttpRequest::status() const | 1162 int XMLHttpRequest::status() const |
1149 { | 1163 { |
1150 if (m_state == UNSENT || m_state == OPENED || m_error) | 1164 if (m_state == UNSENT || m_state == OPENED || m_error) |
1151 return 0; | 1165 return 0; |
1152 | 1166 |
1153 if (m_response.httpStatusCode()) | 1167 if (m_response.httpStatusCode()) |
1154 return m_response.httpStatusCode(); | 1168 return m_response.httpStatusCode(); |
1155 | 1169 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1242 } | 1256 } |
1243 } | 1257 } |
1244 | 1258 |
1245 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource Response& response) | 1259 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource Response& response) |
1246 { | 1260 { |
1247 WTF_LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifi er); | 1261 WTF_LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifi er); |
1248 | 1262 |
1249 m_response = response; | 1263 m_response = response; |
1250 if (!m_mimeTypeOverride.isEmpty()) { | 1264 if (!m_mimeTypeOverride.isEmpty()) { |
1251 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); | 1265 m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride); |
1252 m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride); | 1266 m_finalCharset = extractCharsetFromMediaType(m_mimeTypeOverride); |
1253 } | 1267 } |
1254 | 1268 |
1255 if (m_responseEncoding.isEmpty()) | 1269 if (m_finalCharset.isEmpty()) |
1256 m_responseEncoding = response.textEncodingName(); | 1270 m_finalCharset = response.textEncodingName(); |
1257 } | 1271 } |
1258 | 1272 |
1259 PassOwnPtr<TextResourceDecoder> XMLHttpRequest::createDecoder() const | 1273 PassOwnPtr<TextResourceDecoder> XMLHttpRequest::createDecoder() const |
1260 { | 1274 { |
1261 if (m_responseTypeCode == ResponseTypeJSON) | 1275 if (m_responseTypeCode == ResponseTypeJSON) |
1262 return TextResourceDecoder::create("application/json", "UTF-8"); | 1276 return TextResourceDecoder::create("application/json", "UTF-8"); |
1263 | 1277 |
1264 if (!m_responseEncoding.isEmpty()) | 1278 if (!m_finalCharset.isEmpty()) |
1265 return TextResourceDecoder::create("text/plain", m_responseEncoding); | 1279 return TextResourceDecoder::create("text/plain", m_finalCharset); |
1266 | 1280 |
1267 // allow TextResourceDecoder to look inside the m_response if it's XML or HT ML | 1281 // allow TextResourceDecoder to look inside the m_response if it's XML or HT ML |
1268 if (responseIsXML()) { | 1282 if (responseIsXML()) { |
1269 OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("appli cation/xml"); | 1283 OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("appli cation/xml"); |
1270 // Don't stop on encoding errors, unlike it is done for other kinds | 1284 // Don't stop on encoding errors, unlike it is done for other kinds |
1271 // of XML resources. This matches the behavior of previous WebKit | 1285 // of XML resources. This matches the behavior of previous WebKit |
1272 // versions, Firefox and Opera. | 1286 // versions, Firefox and Opera. |
1273 decoder->useLenientXMLDecoding(); | 1287 decoder->useLenientXMLDecoding(); |
1274 | 1288 |
1275 return decoder.release(); | 1289 return decoder.release(); |
1276 } | 1290 } |
1277 | 1291 |
1278 if (equalIgnoringCase(responseMIMEType(), "text/html")) | 1292 if (equalIgnoringCase(finalMIMEType(), "text/html")) |
1279 return TextResourceDecoder::create("text/html", "UTF-8"); | 1293 return TextResourceDecoder::create("text/html", "UTF-8"); |
1280 | 1294 |
1281 return TextResourceDecoder::create("text/plain", "UTF-8"); | 1295 return TextResourceDecoder::create("text/plain", "UTF-8"); |
1282 } | 1296 } |
1283 | 1297 |
1284 void XMLHttpRequest::didReceiveData(const char* data, int len) | 1298 void XMLHttpRequest::didReceiveData(const char* data, int len) |
1285 { | 1299 { |
1286 ASSERT(m_responseTypeCode != ResponseTypeBlob); | 1300 ASSERT(m_responseTypeCode != ResponseTypeBlob); |
1287 | 1301 |
1288 if (m_error) | 1302 if (m_error) |
(...skipping 14 matching lines...) Expand all Loading... | |
1303 m_decoder = createDecoder(); | 1317 m_decoder = createDecoder(); |
1304 | 1318 |
1305 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); | 1319 m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len)); |
1306 } else if (m_responseTypeCode == ResponseTypeArrayBuffer) { | 1320 } else if (m_responseTypeCode == ResponseTypeArrayBuffer) { |
1307 // Buffer binary data. | 1321 // Buffer binary data. |
1308 if (!m_binaryResponseBuilder) | 1322 if (!m_binaryResponseBuilder) |
1309 m_binaryResponseBuilder = SharedBuffer::create(); | 1323 m_binaryResponseBuilder = SharedBuffer::create(); |
1310 m_binaryResponseBuilder->append(data, len); | 1324 m_binaryResponseBuilder->append(data, len); |
1311 } else if (m_responseTypeCode == ResponseTypeLegacyStream) { | 1325 } else if (m_responseTypeCode == ResponseTypeLegacyStream) { |
1312 if (!m_responseStream) | 1326 if (!m_responseStream) |
1313 m_responseStream = Stream::create(executionContext(), responseMIMETy pe()); | 1327 m_responseStream = Stream::create(executionContext(), finalMIMEType( )); |
1314 m_responseStream->addData(data, len); | 1328 m_responseStream->addData(data, len); |
1315 } | 1329 } |
1316 | 1330 |
1317 if (m_error) | 1331 if (m_error) |
1318 return; | 1332 return; |
1319 | 1333 |
1320 trackProgress(len); | 1334 trackProgress(len); |
1321 } | 1335 } |
1322 | 1336 |
1323 void XMLHttpRequest::didDownloadData(int dataLength) | 1337 void XMLHttpRequest::didDownloadData(int dataLength) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1401 { | 1415 { |
1402 visitor->trace(m_responseBlob); | 1416 visitor->trace(m_responseBlob); |
1403 visitor->trace(m_responseStream); | 1417 visitor->trace(m_responseStream); |
1404 visitor->trace(m_responseDocument); | 1418 visitor->trace(m_responseDocument); |
1405 visitor->trace(m_progressEventThrottle); | 1419 visitor->trace(m_progressEventThrottle); |
1406 visitor->trace(m_upload); | 1420 visitor->trace(m_upload); |
1407 XMLHttpRequestEventTarget::trace(visitor); | 1421 XMLHttpRequestEventTarget::trace(visitor); |
1408 } | 1422 } |
1409 | 1423 |
1410 } // namespace blink | 1424 } // namespace blink |
OLD | NEW |