Commit 1771a7fc authored by tyoshino@chromium.org's avatar tyoshino@chromium.org

Refactor MIME type related methods in XHR for readability

- Give more descriptive names to MIME type related methods
- Split responseMIMEType() into one without fallback to text/xml and one
  with it as this fallback is requird only a few places
- Add some FIXMEs to address issues found during this refactoring later

BUG=none

Review URL: https://codereview.chromium.org/450103003

git-svn-id: svn://svn.chromium.org/blink/trunk@179950 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 3f8035f9
......@@ -190,7 +190,7 @@ ScriptString XMLHttpRequest::responseJSONSource()
void XMLHttpRequest::initResponseDocument()
{
AtomicString mimeType = responseMIMEType();
AtomicString mimeType = finalResponseMIMETypeWithFallback();
bool isHTML = equalIgnoringCase(mimeType, "text/html");
// The W3C spec requires the final MIME type to be some valid XML type, or text/html.
......@@ -259,7 +259,10 @@ Blob* XMLHttpRequest::responseBlob()
// empty one.
if (!filePath.isEmpty() && m_downloadedBlobLength) {
blobData->appendFile(filePath);
blobData->setContentType(responseMIMEType()); // responseMIMEType defaults to text/xml which may be incorrect.
// FIXME: finalResponseMIMETypeWithFallback() defaults to text/xml
// which may be incorrect. Replace it with finalResponseMIMEType()
// after compatibility investigation.
blobData->setContentType(finalResponseMIMETypeWithFallback());
}
m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), m_downloadedBlobLength));
}
......@@ -879,7 +882,7 @@ void XMLHttpRequest::clearVariablesForLoading()
{
m_decoder.clear();
m_responseEncoding = String();
m_finalResponseCharset = String();
}
bool XMLHttpRequest::internalAbort()
......@@ -1030,6 +1033,9 @@ void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const Atomi
void XMLHttpRequest::overrideMimeType(const AtomicString& override)
{
// FIXME: This method must throw an InvalidStateError exception when the
// XHR is in the LOADING or DONE state. http://crbug.com/402375
m_mimeTypeOverride = override;
}
......@@ -1126,24 +1132,32 @@ const AtomicString& XMLHttpRequest::getResponseHeader(const AtomicString& name)
return m_response.httpHeaderField(name);
}
AtomicString XMLHttpRequest::responseMIMEType() const
AtomicString XMLHttpRequest::finalResponseMIMEType() const
{
AtomicString mimeType = extractMIMETypeFromMediaType(m_mimeTypeOverride);
if (mimeType.isEmpty()) {
if (m_response.isHTTP())
mimeType = extractMIMETypeFromMediaType(m_response.httpHeaderField("Content-Type"));
else
mimeType = m_response.mimeType();
}
if (mimeType.isEmpty())
mimeType = AtomicString("text/xml", AtomicString::ConstructFromLiteral);
AtomicString overriddenType = extractMIMETypeFromMediaType(m_mimeTypeOverride);
if (!overriddenType.isEmpty())
return overriddenType;
if (m_response.isHTTP())
return extractMIMETypeFromMediaType(m_response.httpHeaderField("Content-Type"));
return m_response.mimeType();
}
AtomicString XMLHttpRequest::finalResponseMIMETypeWithFallback() const
{
AtomicString finalType = finalResponseMIMEType();
if (!finalType.isEmpty())
return finalType;
return mimeType;
// FIXME: This fallback is not specified in the final MIME type algorithm
// of the XHR spec. Move this to more appropriate place.
return AtomicString("text/xml", AtomicString::ConstructFromLiteral);
}
bool XMLHttpRequest::responseIsXML() const
{
return DOMImplementation::isXMLMIMEType(responseMIMEType());
return DOMImplementation::isXMLMIMEType(finalResponseMIMETypeWithFallback());
}
int XMLHttpRequest::status() const
......@@ -1250,11 +1264,11 @@ void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource
m_response = response;
if (!m_mimeTypeOverride.isEmpty()) {
m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride);
m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride);
m_finalResponseCharset = extractCharsetFromMediaType(m_mimeTypeOverride);
}
if (m_responseEncoding.isEmpty())
m_responseEncoding = response.textEncodingName();
if (m_finalResponseCharset.isEmpty())
m_finalResponseCharset = response.textEncodingName();
}
PassOwnPtr<TextResourceDecoder> XMLHttpRequest::createDecoder() const
......@@ -1262,8 +1276,8 @@ PassOwnPtr<TextResourceDecoder> XMLHttpRequest::createDecoder() const
if (m_responseTypeCode == ResponseTypeJSON)
return TextResourceDecoder::create("application/json", "UTF-8");
if (!m_responseEncoding.isEmpty())
return TextResourceDecoder::create("text/plain", m_responseEncoding);
if (!m_finalResponseCharset.isEmpty())
return TextResourceDecoder::create("text/plain", m_finalResponseCharset);
// allow TextResourceDecoder to look inside the m_response if it's XML or HTML
if (responseIsXML()) {
......@@ -1276,7 +1290,7 @@ PassOwnPtr<TextResourceDecoder> XMLHttpRequest::createDecoder() const
return decoder.release();
}
if (equalIgnoringCase(responseMIMEType(), "text/html"))
if (equalIgnoringCase(finalResponseMIMEType(), "text/html"))
return TextResourceDecoder::create("text/html", "UTF-8");
return TextResourceDecoder::create("text/plain", "UTF-8");
......@@ -1311,7 +1325,7 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
m_binaryResponseBuilder->append(data, len);
} else if (m_responseTypeCode == ResponseTypeLegacyStream) {
if (!m_responseStream)
m_responseStream = Stream::create(executionContext(), responseMIMEType());
m_responseStream = Stream::create(executionContext(), finalResponseMIMEType());
m_responseStream->addData(data, len);
}
......
......@@ -160,7 +160,18 @@ private:
virtual void didFail(const ResourceError&) OVERRIDE;
virtual void didFailRedirectCheck() OVERRIDE;
AtomicString responseMIMEType() const;
// Returns the MIME type part of m_mimeTypeOverride if present and
// successfully parsed, or returns one of the "Content-Type" header value
// of the received response.
//
// This method is named after the term "final MIME type" defined in the
// spec but doesn't convert the result to ASCII lowercase as specified in
// the spec. Must be lowered later or compared using case insensitive
// comparison functions if required.
AtomicString finalResponseMIMEType() const;
// The same as finalResponseMIMEType() but fallbacks to "text/xml" if
// finalResponseMIMEType() returns an empty string.
AtomicString finalResponseMIMETypeWithFallback() const;
bool responseIsXML() const;
PassOwnPtr<TextResourceDecoder> createDecoder() const;
......@@ -212,6 +223,8 @@ private:
KURL m_url;
AtomicString m_method;
HTTPHeaderMap m_requestHeaders;
// Not converted to ASCII lowercase. Must be lowered later or compared
// using case insensitive comparison functions if needed.
AtomicString m_mimeTypeOverride;
unsigned long m_timeoutMilliseconds;
RefPtrWillBeMember<Blob> m_responseBlob;
......@@ -221,7 +234,7 @@ private:
State m_state;
ResourceResponse m_response;
String m_responseEncoding;
String m_finalResponseCharset;
OwnPtr<TextResourceDecoder> m_decoder;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment