Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: Source/core/xml/XMLHttpRequest.cpp

Issue 450103003: Refactor MIME type related methods in XHR for readability (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Addressed #2 Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 = finalResponseMIMETypeWithFallback();
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
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: finalResponseMIMETypeWithFallback() defaults to text/xml
262 // which may be incorrect. Replace it with finalResponseMIMEType()
263 // after compatibility investigation.
264 blobData->setContentType(finalResponseMIMETypeWithFallback());
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
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_finalResponseCharset = 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
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
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::finalResponseMIMEType() 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::finalResponseMIMETypeWithFallback() const
1147 {
1148 AtomicString finalType = finalResponseMIMEType();
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(finalResponseMIMETypeWithFallback()) ;
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
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_finalResponseCharset = extractCharsetFromMediaType(m_mimeTypeOverride) ;
1253 } 1267 }
1254 1268
1255 if (m_responseEncoding.isEmpty()) 1269 if (m_finalResponseCharset.isEmpty())
1256 m_responseEncoding = response.textEncodingName(); 1270 m_finalResponseCharset = 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_finalResponseCharset.isEmpty())
1265 return TextResourceDecoder::create("text/plain", m_responseEncoding); 1279 return TextResourceDecoder::create("text/plain", m_finalResponseCharset) ;
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(finalResponseMIMEType(), "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
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(), finalResponseM IMEType());
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
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
OLDNEW
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698