summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qdeclarativexmlhttprequest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/qdeclarativexmlhttprequest.cpp')
-rw-r--r--src/declarative/qml/qdeclarativexmlhttprequest.cpp87
1 files changed, 78 insertions, 9 deletions
diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
index ff1a0e9..d832638 100644
--- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp
+++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
@@ -965,8 +965,9 @@ public:
QScriptValue send(QScriptValue *me, const QByteArray &);
QScriptValue abort(QScriptValue *me);
- QString responseBody() const;
+ QString responseBody();
const QByteArray & rawResponseBody() const;
+ bool receivedXml() const;
private slots:
void downloadProgress(qint64);
void error(QNetworkReply::NetworkError);
@@ -989,6 +990,15 @@ private:
HeadersList m_headersList;
void fillHeadersList();
+ bool m_gotXml;
+ QByteArray m_mime;
+ QByteArray m_charset;
+ QTextCodec *m_textCodec;
+#ifndef QT_NO_TEXTCODEC
+ QTextCodec* findTextCodec() const;
+#endif
+ void readEncoding();
+
QScriptValue m_me; // Set to the data object while a send() is ongoing (to access the callback)
QScriptValue dispatchCallback(QScriptValue *me);
@@ -1006,7 +1016,7 @@ private:
QDeclarativeXMLHttpRequest::QDeclarativeXMLHttpRequest(QNetworkAccessManager *manager)
: m_state(Unsent), m_errorFlag(false), m_sendFlag(false),
- m_redirectCount(0), m_network(0), m_nam(manager)
+ m_redirectCount(0), m_gotXml(false), m_textCodec(0), m_network(0), m_nam(manager)
{
}
@@ -1277,6 +1287,7 @@ void QDeclarativeXMLHttpRequest::finished()
if (cbv.isError()) printError(cbv);
}
m_responseEntityBody.append(m_network->readAll());
+ readEncoding();
if (xhrDump()) {
qWarning().nospace() << "XMLHttpRequest: RESPONSE " << qPrintable(m_url.toString());
@@ -1302,15 +1313,72 @@ void QDeclarativeXMLHttpRequest::finished()
}
-QString QDeclarativeXMLHttpRequest::responseBody() const
+void QDeclarativeXMLHttpRequest::readEncoding()
+{
+ foreach (const HeaderPair &header, m_headersList) {
+ if (header.first == "content-type") {
+ int separatorIdx = header.second.indexOf(';');
+ if (separatorIdx == -1) {
+ m_mime == header.second;
+ } else {
+ m_mime = header.second.mid(0, separatorIdx);
+ int charsetIdx = header.second.indexOf("charset=");
+ if (charsetIdx != -1) {
+ charsetIdx += 8;
+ separatorIdx = header.second.indexOf(';', charsetIdx);
+ m_charset = header.second.mid(charsetIdx, separatorIdx >= 0 ? separatorIdx : header.second.length());
+ }
+ }
+ break;
+ }
+ }
+
+ if (m_mime.isEmpty() || m_mime == "text/xml" || m_mime == "application/xml" || m_mime.endsWith("+xml"))
+ m_gotXml = true;
+}
+
+bool QDeclarativeXMLHttpRequest::receivedXml() const
+{
+ return m_gotXml;
+}
+
+
+#ifndef QT_NO_TEXTCODEC
+QTextCodec* QDeclarativeXMLHttpRequest::findTextCodec() const
+{
+ QTextCodec *codec = 0;
+
+ if (!m_charset.isEmpty())
+ codec = QTextCodec::codecForName(m_charset);
+
+ if (!codec && m_gotXml) {
+ QXmlStreamReader reader(m_responseEntityBody);
+ reader.readNext();
+ codec = QTextCodec::codecForName(reader.documentEncoding().toString().toUtf8());
+ }
+
+ if (!codec && m_mime == "text/html")
+ codec = QTextCodec::codecForHtml(m_responseEntityBody, 0);
+
+ if (!codec)
+ codec = QTextCodec::codecForUtfText(m_responseEntityBody, 0);
+
+ if (!codec)
+ codec = QTextCodec::codecForName("UTF-8");
+ return codec;
+}
+#endif
+
+
+QString QDeclarativeXMLHttpRequest::responseBody()
{
- QXmlStreamReader reader(m_responseEntityBody);
- reader.readNext();
#ifndef QT_NO_TEXTCODEC
- QTextCodec *codec = QTextCodec::codecForName(reader.documentEncoding().toString().toUtf8());
- if (codec)
- return codec->toUnicode(m_responseEntityBody);
+ if (!m_textCodec)
+ m_textCodec = findTextCodec();
+ if (m_textCodec)
+ return m_textCodec->toUnicode(m_responseEntityBody);
#endif
+
return QString::fromUtf8(m_responseEntityBody);
}
@@ -1571,7 +1639,8 @@ static QScriptValue qmlxmlhttprequest_responseXML(QScriptContext *context, QScri
if (!request)
THROW_REFERENCE("Not an XMLHttpRequest object");
- if (request->readyState() != QDeclarativeXMLHttpRequest::Loading &&
+ if (!request->receivedXml() ||
+ request->readyState() != QDeclarativeXMLHttpRequest::Loading &&
request->readyState() != QDeclarativeXMLHttpRequest::Done)
return engine->nullValue();
else