src/declarative/qml/qdeclarativexmlhttprequest.cpp
changeset 37 758a864f9613
parent 30 5dc02b23752f
equal deleted inserted replaced
36:ef0373b55136 37:758a864f9613
    56 #include <QtCore/qtextcodec.h>
    56 #include <QtCore/qtextcodec.h>
    57 #include <QtCore/qxmlstream.h>
    57 #include <QtCore/qxmlstream.h>
    58 #include <QtCore/qstack.h>
    58 #include <QtCore/qstack.h>
    59 #include <QtCore/qdebug.h>
    59 #include <QtCore/qdebug.h>
    60 
    60 
       
    61 #ifndef QT_NO_XMLSTREAMREADER
       
    62 
    61 // From DOM-Level-3-Core spec
    63 // From DOM-Level-3-Core spec
    62 // http://www.w3.org/TR/DOM-Level-3-Core/core.html
    64 // http://www.w3.org/TR/DOM-Level-3-Core/core.html
    63 #define INDEX_SIZE_ERR 1
    65 #define INDEX_SIZE_ERR 1
    64 #define DOMSTRING_SIZE_ERR 2
    66 #define DOMSTRING_SIZE_ERR 2
    65 #define HIERARCHY_REQUEST_ERR 3
    67 #define HIERARCHY_REQUEST_ERR 3
   961     QString header(const QString &name);
   963     QString header(const QString &name);
   962     QString headers();
   964     QString headers();
   963     QScriptValue send(QScriptValue *me, const QByteArray &);
   965     QScriptValue send(QScriptValue *me, const QByteArray &);
   964     QScriptValue abort(QScriptValue *me);
   966     QScriptValue abort(QScriptValue *me);
   965 
   967 
   966     QString responseBody() const;
   968     QString responseBody();
   967     const QByteArray & rawResponseBody() const;
   969     const QByteArray & rawResponseBody() const;
       
   970     bool receivedXml() const;
   968 private slots:
   971 private slots:
   969     void downloadProgress(qint64);
   972     void downloadProgress(qint64);
   970     void error(QNetworkReply::NetworkError);
   973     void error(QNetworkReply::NetworkError);
   971     void finished();
   974     void finished();
   972 
   975 
   985     typedef QPair<QByteArray, QByteArray> HeaderPair;
   988     typedef QPair<QByteArray, QByteArray> HeaderPair;
   986     typedef QList<HeaderPair> HeadersList;
   989     typedef QList<HeaderPair> HeadersList;
   987     HeadersList m_headersList;
   990     HeadersList m_headersList;
   988     void fillHeadersList();
   991     void fillHeadersList();
   989 
   992 
       
   993     bool m_gotXml;
       
   994     QByteArray m_mime;
       
   995     QByteArray m_charset;
       
   996     QTextCodec *m_textCodec;
       
   997 #ifndef QT_NO_TEXTCODEC
       
   998     QTextCodec* findTextCodec() const;
       
   999 #endif
       
  1000     void readEncoding();
       
  1001 
   990     QScriptValue m_me; // Set to the data object while a send() is ongoing (to access the callback)
  1002     QScriptValue m_me; // Set to the data object while a send() is ongoing (to access the callback)
   991 
  1003 
   992     QScriptValue dispatchCallback(QScriptValue *me);
  1004     QScriptValue dispatchCallback(QScriptValue *me);
   993     void printError(const QScriptValue&);
  1005     void printError(const QScriptValue&);
   994 
  1006 
  1002     QNetworkAccessManager *networkAccessManager() { return m_nam; }
  1014     QNetworkAccessManager *networkAccessManager() { return m_nam; }
  1003 };
  1015 };
  1004 
  1016 
  1005 QDeclarativeXMLHttpRequest::QDeclarativeXMLHttpRequest(QNetworkAccessManager *manager)
  1017 QDeclarativeXMLHttpRequest::QDeclarativeXMLHttpRequest(QNetworkAccessManager *manager)
  1006 : m_state(Unsent), m_errorFlag(false), m_sendFlag(false),
  1018 : m_state(Unsent), m_errorFlag(false), m_sendFlag(false),
  1007   m_redirectCount(0), m_network(0), m_nam(manager)
  1019   m_redirectCount(0), m_gotXml(false), m_textCodec(0), m_network(0), m_nam(manager)
  1008 {
  1020 {
  1009 }
  1021 }
  1010 
  1022 
  1011 QDeclarativeXMLHttpRequest::~QDeclarativeXMLHttpRequest()
  1023 QDeclarativeXMLHttpRequest::~QDeclarativeXMLHttpRequest()
  1012 {
  1024 {
  1273         fillHeadersList ();
  1285         fillHeadersList ();
  1274         QScriptValue cbv = dispatchCallback(&m_me);
  1286         QScriptValue cbv = dispatchCallback(&m_me);
  1275         if (cbv.isError()) printError(cbv);
  1287         if (cbv.isError()) printError(cbv);
  1276     }
  1288     }
  1277     m_responseEntityBody.append(m_network->readAll());
  1289     m_responseEntityBody.append(m_network->readAll());
       
  1290     readEncoding();
  1278 
  1291 
  1279     if (xhrDump()) {
  1292     if (xhrDump()) {
  1280         qWarning().nospace() << "XMLHttpRequest: RESPONSE " << qPrintable(m_url.toString());
  1293         qWarning().nospace() << "XMLHttpRequest: RESPONSE " << qPrintable(m_url.toString());
  1281         if (!m_responseEntityBody.isEmpty()) {
  1294         if (!m_responseEntityBody.isEmpty()) {
  1282             qWarning().nospace() << "                " 
  1295             qWarning().nospace() << "                " 
  1298 
  1311 
  1299     m_me = QScriptValue();
  1312     m_me = QScriptValue();
  1300 }
  1313 }
  1301 
  1314 
  1302 
  1315 
  1303 QString QDeclarativeXMLHttpRequest::responseBody() const
  1316 void QDeclarativeXMLHttpRequest::readEncoding()
  1304 {
  1317 {
  1305     QXmlStreamReader reader(m_responseEntityBody);
  1318     foreach (const HeaderPair &header, m_headersList) {
  1306     reader.readNext();
  1319         if (header.first == "content-type") {
  1307     QTextCodec *codec = QTextCodec::codecForName(reader.documentEncoding().toString().toUtf8());
  1320             int separatorIdx = header.second.indexOf(';');
  1308     if (codec)
  1321             if (separatorIdx == -1) {
  1309         return codec->toUnicode(m_responseEntityBody);
  1322                 m_mime == header.second;
       
  1323             } else {
       
  1324                 m_mime = header.second.mid(0, separatorIdx);
       
  1325                 int charsetIdx = header.second.indexOf("charset=");
       
  1326                 if (charsetIdx != -1) {
       
  1327                     charsetIdx += 8;
       
  1328                     separatorIdx = header.second.indexOf(';', charsetIdx);
       
  1329                     m_charset = header.second.mid(charsetIdx, separatorIdx >= 0 ? separatorIdx : header.second.length());
       
  1330                 }
       
  1331             }
       
  1332             break;
       
  1333         }
       
  1334     }
       
  1335 
       
  1336     if (m_mime.isEmpty() || m_mime == "text/xml" || m_mime == "application/xml" || m_mime.endsWith("+xml")) 
       
  1337         m_gotXml = true;
       
  1338 }
       
  1339 
       
  1340 bool QDeclarativeXMLHttpRequest::receivedXml() const
       
  1341 {
       
  1342     return m_gotXml;
       
  1343 }
       
  1344 
       
  1345 
       
  1346 #ifndef QT_NO_TEXTCODEC
       
  1347 QTextCodec* QDeclarativeXMLHttpRequest::findTextCodec() const
       
  1348 {
       
  1349     QTextCodec *codec = 0;
       
  1350 
       
  1351     if (!m_charset.isEmpty()) 
       
  1352         codec = QTextCodec::codecForName(m_charset);
       
  1353 
       
  1354     if (!codec && m_gotXml) {
       
  1355         QXmlStreamReader reader(m_responseEntityBody);
       
  1356         reader.readNext();
       
  1357         codec = QTextCodec::codecForName(reader.documentEncoding().toString().toUtf8());
       
  1358     }
       
  1359 
       
  1360     if (!codec && m_mime == "text/html") 
       
  1361         codec = QTextCodec::codecForHtml(m_responseEntityBody, 0);
       
  1362 
       
  1363     if (!codec)
       
  1364         codec = QTextCodec::codecForUtfText(m_responseEntityBody, 0);
       
  1365 
       
  1366     if (!codec)
       
  1367         codec = QTextCodec::codecForName("UTF-8");
       
  1368     return codec;
       
  1369 }
       
  1370 #endif
       
  1371 
       
  1372 
       
  1373 QString QDeclarativeXMLHttpRequest::responseBody()
       
  1374 {
       
  1375 #ifndef QT_NO_TEXTCODEC
       
  1376     if (!m_textCodec)
       
  1377         m_textCodec = findTextCodec();
       
  1378     if (m_textCodec)
       
  1379         return m_textCodec->toUnicode(m_responseEntityBody);
       
  1380 #endif
  1310 
  1381 
  1311     return QString::fromUtf8(m_responseEntityBody);
  1382     return QString::fromUtf8(m_responseEntityBody);
  1312 }
  1383 }
  1313 
  1384 
  1314 const QByteArray &QDeclarativeXMLHttpRequest::rawResponseBody() const
  1385 const QByteArray &QDeclarativeXMLHttpRequest::rawResponseBody() const
  1566 {
  1637 {
  1567     QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(context->thisObject().data().toQObject());
  1638     QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(context->thisObject().data().toQObject());
  1568     if (!request) 
  1639     if (!request) 
  1569         THROW_REFERENCE("Not an XMLHttpRequest object");
  1640         THROW_REFERENCE("Not an XMLHttpRequest object");
  1570 
  1641 
  1571     if (request->readyState() != QDeclarativeXMLHttpRequest::Loading &&
  1642     if (!request->receivedXml() ||
       
  1643         request->readyState() != QDeclarativeXMLHttpRequest::Loading &&
  1572         request->readyState() != QDeclarativeXMLHttpRequest::Done)
  1644         request->readyState() != QDeclarativeXMLHttpRequest::Done)
  1573         return engine->nullValue();
  1645         return engine->nullValue();
  1574     else  
  1646     else  
  1575         return Document::load(engine, request->rawResponseBody());
  1647         return Document::load(engine, request->rawResponseBody());
  1576 }
  1648 }
  1660     engine->globalObject().setProperty(QLatin1String("DOMException"), domExceptionPrototype);
  1732     engine->globalObject().setProperty(QLatin1String("DOMException"), domExceptionPrototype);
  1661 }
  1733 }
  1662 
  1734 
  1663 QT_END_NAMESPACE
  1735 QT_END_NAMESPACE
  1664 
  1736 
       
  1737 #endif // QT_NO_XMLSTREAMREADER
       
  1738 
  1665 #include <qdeclarativexmlhttprequest.moc>
  1739 #include <qdeclarativexmlhttprequest.moc>