diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-02-08 08:58:02 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-02-08 08:59:29 (GMT) |
commit | 5f6456d420a762cf935271c9329178ad7112c4a1 (patch) | |
tree | eb23f267a0bec59c4083c35606e22bdd1067606d | |
parent | 78fce53374d4aad0e51d7086268579913c19a1ac (diff) | |
download | Qt-5f6456d420a762cf935271c9329178ad7112c4a1.zip Qt-5f6456d420a762cf935271c9329178ad7112c4a1.tar.gz Qt-5f6456d420a762cf935271c9329178ad7112c4a1.tar.bz2 |
XMLHttpRequest collection bug
QmlXMLHttpRequest was holding a reference to the callback function
indefinately. If the callback function also referenced the XMLHttpRequest
(which they always do) the QmlXMLHttpRequest would not be destroyed until
the application exited.
-rw-r--r-- | src/declarative/qml/qmlxmlhttprequest.cpp | 90 |
1 files changed, 45 insertions, 45 deletions
diff --git a/src/declarative/qml/qmlxmlhttprequest.cpp b/src/declarative/qml/qmlxmlhttprequest.cpp index 86bec20..1883d1b 100644 --- a/src/declarative/qml/qmlxmlhttprequest.cpp +++ b/src/declarative/qml/qmlxmlhttprequest.cpp @@ -943,21 +943,19 @@ public: QmlXMLHttpRequest(QNetworkAccessManager *manager); virtual ~QmlXMLHttpRequest(); - QScriptValue callback() const; - void setCallback(const QScriptValue &); - bool sendFlag() const; bool errorFlag() const; quint32 readyState() const; int replyStatus() const; QString replyStatusText() const; - QScriptValue open(const QString &, const QUrl &); + QScriptValue open(QScriptValue *me, const QString &, const QUrl &); + void addHeader(const QString &, const QString &); QString header(const QString &name); QString headers(); - QScriptValue send(const QByteArray &); - QScriptValue abort(); + QScriptValue send(QScriptValue *me, const QByteArray &); + QScriptValue abort(QScriptValue *me); QString responseBody() const; private slots: @@ -982,8 +980,9 @@ private: HeadersList m_headersList; void fillHeadersList(); - QScriptValue dispatchCallback(); - QScriptValue m_callback; + QScriptValue m_me; // Set to the data object while a send() is ongoing (to access the callback) + + QScriptValue dispatchCallback(QScriptValue *me); void printError(const QScriptValue&); int m_status; @@ -1007,16 +1006,6 @@ QmlXMLHttpRequest::~QmlXMLHttpRequest() destroyNetwork(); } -QScriptValue QmlXMLHttpRequest::callback() const -{ - return m_callback; -} - -void QmlXMLHttpRequest::setCallback(const QScriptValue &c) -{ - m_callback = c; -} - bool QmlXMLHttpRequest::sendFlag() const { return m_sendFlag; @@ -1042,7 +1031,7 @@ QString QmlXMLHttpRequest::replyStatusText() const return m_statusText; } -QScriptValue QmlXMLHttpRequest::open(const QString &method, const QUrl &url) +QScriptValue QmlXMLHttpRequest::open(QScriptValue *me, const QString &method, const QUrl &url) { destroyNetwork(); m_sendFlag = false; @@ -1051,7 +1040,7 @@ QScriptValue QmlXMLHttpRequest::open(const QString &method, const QUrl &url) m_method = method; m_url = url; m_state = Opened; - return dispatchCallback(); + return dispatchCallback(me); } void QmlXMLHttpRequest::addHeader(const QString &name, const QString &value) @@ -1155,19 +1144,20 @@ void QmlXMLHttpRequest::requestFromUrl(const QUrl &url) this, SLOT(finished())); } -QScriptValue QmlXMLHttpRequest::send(const QByteArray &data) +QScriptValue QmlXMLHttpRequest::send(QScriptValue *me, const QByteArray &data) { m_errorFlag = false; m_sendFlag = true; m_redirectCount = 0; m_data = data; + m_me = *me; requestFromUrl(m_url); return QScriptValue(); } -QScriptValue QmlXMLHttpRequest::abort() +QScriptValue QmlXMLHttpRequest::abort(QScriptValue *me) { destroyNetwork(); m_responseEntityBody = QByteArray(); @@ -1180,7 +1170,7 @@ QScriptValue QmlXMLHttpRequest::abort() m_state = Done; m_sendFlag = false; - QScriptValue cbv = dispatchCallback(); + QScriptValue cbv = dispatchCallback(me); if (cbv.isError()) return cbv; } @@ -1200,7 +1190,7 @@ void QmlXMLHttpRequest::downloadProgress(qint64 bytes) if (m_state < HeadersReceived) { m_state = HeadersReceived; fillHeadersList (); - QScriptValue cbv = dispatchCallback(); + QScriptValue cbv = dispatchCallback(&m_me); if (cbv.isError()) printError(cbv); } @@ -1208,7 +1198,7 @@ void QmlXMLHttpRequest::downloadProgress(qint64 bytes) m_responseEntityBody.append(m_network->readAll()); if (wasEmpty && !m_responseEntityBody.isEmpty()) { m_state = Loading; - QScriptValue cbv = dispatchCallback(); + QScriptValue cbv = dispatchCallback(&m_me); if (cbv.isError()) printError(cbv); } } @@ -1233,14 +1223,14 @@ void QmlXMLHttpRequest::error(QNetworkReply::NetworkError error) error == QNetworkReply::AuthenticationRequiredError || error == QNetworkReply::ContentReSendError) { m_state = Loading; - QScriptValue cbv = dispatchCallback(); + QScriptValue cbv = dispatchCallback(&m_me); if (cbv.isError()) printError(cbv); } else { m_errorFlag = true; } m_state = Done; - QScriptValue cbv = dispatchCallback(); + QScriptValue cbv = dispatchCallback(&m_me); if (cbv.isError()) printError(cbv); } @@ -1266,7 +1256,7 @@ void QmlXMLHttpRequest::finished() if (m_state < HeadersReceived) { m_state = HeadersReceived; fillHeadersList (); - QScriptValue cbv = dispatchCallback(); + QScriptValue cbv = dispatchCallback(&m_me); if (cbv.isError()) printError(cbv); } m_responseEntityBody.append(m_network->readAll()); @@ -1274,12 +1264,14 @@ void QmlXMLHttpRequest::finished() destroyNetwork(); if (m_state < Loading) { m_state = Loading; - QScriptValue cbv = dispatchCallback(); + QScriptValue cbv = dispatchCallback(&m_me); if (cbv.isError()) printError(cbv); } m_state = Done; - QScriptValue cbv = dispatchCallback(); + QScriptValue cbv = dispatchCallback(&m_me); if (cbv.isError()) printError(cbv); + + m_me = QScriptValue(); } @@ -1288,9 +1280,10 @@ QString QmlXMLHttpRequest::responseBody() const return QString::fromUtf8(m_responseEntityBody); } -QScriptValue QmlXMLHttpRequest::dispatchCallback() +QScriptValue QmlXMLHttpRequest::dispatchCallback(QScriptValue *me) { - return m_callback.call(); + QScriptValue v = me->property(QLatin1String("callback")); + return v.call(); } void QmlXMLHttpRequest::printError(const QScriptValue& sv) @@ -1312,7 +1305,8 @@ void QmlXMLHttpRequest::destroyNetwork() // XMLHttpRequest methods static QScriptValue qmlxmlhttprequest_open(QScriptContext *context, QScriptEngine *engine) { - QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); + QScriptValue dataObject = context->thisObject().data(); + QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(dataObject.toQObject()); if (!request) THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1354,7 +1348,7 @@ static QScriptValue qmlxmlhttprequest_open(QScriptContext *context, QScriptEngin if (!username.isNull()) url.setUserName(username); if (!password.isNull()) url.setPassword(password); - return request->open(method, url); + return request->open(&dataObject, method, url); } static QScriptValue qmlxmlhttprequest_setRequestHeader(QScriptContext *context, QScriptEngine *engine) @@ -1405,9 +1399,10 @@ static QScriptValue qmlxmlhttprequest_setRequestHeader(QScriptContext *context, return engine->undefinedValue(); } -static QScriptValue qmlxmlhttprequest_send(QScriptContext *context, QScriptEngine *engine) +static QScriptValue qmlxmlhttprequest_send(QScriptContext *context, QScriptEngine *) { - QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); + QScriptValue dataObject = context->thisObject().data(); + QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(dataObject.toQObject()); if (!request) THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1421,16 +1416,17 @@ static QScriptValue qmlxmlhttprequest_send(QScriptContext *context, QScriptEngin if (context->argumentCount() > 0) data = context->argument(0).toString().toUtf8(); - return request->send(data); + return request->send(&dataObject, data); } static QScriptValue qmlxmlhttprequest_abort(QScriptContext *context, QScriptEngine *) { - QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); + QScriptValue dataObject = context->thisObject().data(); + QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(dataObject.toQObject()); if (!request) THROW_REFERENCE("Not an XMLHttpRequest object"); - return request->abort(); + return request->abort(&dataObject); } static QScriptValue qmlxmlhttprequest_getResponseHeader(QScriptContext *context, QScriptEngine *engine) @@ -1545,15 +1541,19 @@ static QScriptValue qmlxmlhttprequest_responseXML(QScriptContext *context, QScri static QScriptValue qmlxmlhttprequest_onreadystatechange(QScriptContext *context, QScriptEngine *engine) { - Q_UNUSED(engine) - QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); + Q_UNUSED(engine); + QScriptValue dataObject = context->thisObject().data(); + QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(dataObject.toQObject()); if (!request) THROW_REFERENCE("Not an XMLHttpRequest object"); - if (context->argumentCount()) - request->setCallback(context->argument(0)); - - return request->callback(); + if (context->argumentCount()) { + QScriptValue v = context->argument(0); + dataObject.setProperty(QLatin1String("callback"), v); + return v; + } else { + return dataObject.property(QLatin1String("callback")); + } } // Constructor |