History

Add GET of local files to JavaScript XMLHttpRequest

David Rowe committed 12 years ago

Commit 33ffed71 parent 6027f4d4 files · +210 −17Browse files

Showing the changes to libraries/script-engine/src/XMLHttpRequestClass.cpp (1 of 4 files). Show all

Unified · Split

libraries/script-engine/src/XMLHttpRequestClass.cpp+106−17
@@ -13,6 +13,7 @@ · 12 unmodified lines
13//13//
14 14
15#include <QEventLoop>15#include <QEventLoop>
16#include <QFile>
16 17
17#include <NetworkAccessManager.h>18#include <NetworkAccessManager.h>
18 19
@@ -33,6 +34,7 @@ XMLHttpRequestClass::XMLHttpRequestClass(QScriptEngine* engine) : · 14 unmodified lines
33 _onReadyStateChange(QScriptValue::NullValue),34 _onReadyStateChange(QScriptValue::NullValue),
34 _readyState(XMLHttpRequestClass::UNSENT),35 _readyState(XMLHttpRequestClass::UNSENT),
35 _errorCode(QNetworkReply::NoError),36 _errorCode(QNetworkReply::NoError),
37 _file(NULL),
36 _timeout(0),38 _timeout(0),
37 _timer(this),39 _timer(this),
38 _numRedirects(0) {40 _numRedirects(0) {
@@ -52,6 +54,19 @@ QScriptValue XMLHttpRequestClass::constructor(QScriptContext* context, QScriptEn · 13 unmodified lines
52QScriptValue XMLHttpRequestClass::getStatus() const {54QScriptValue XMLHttpRequestClass::getStatus() const {
53 if (_reply) {55 if (_reply) {
54 return QScriptValue(_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt());56 return QScriptValue(_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt());
57 } else if(_url.isLocalFile()) {
58 switch (_errorCode) {
59 case QNetworkReply::NoError:
60 return QScriptValue(200);
61 case QNetworkReply::ContentNotFoundError:
62 return QScriptValue(404);
63 case QNetworkReply::ContentAccessDenied:
64 return QScriptValue(409);
65 case QNetworkReply::TimeoutError:
66 return QScriptValue(408);
67 case QNetworkReply::ContentOperationNotPermittedError:
68 return QScriptValue(501);
69 }
55 }70 }
56 return QScriptValue(0);71 return QScriptValue(0);
57}72}
@@ -59,6 +74,19 @@ QScriptValue XMLHttpRequestClass::getStatus() const { · 1 unmodified line
59QString XMLHttpRequestClass::getStatusText() const {74QString XMLHttpRequestClass::getStatusText() const {
60 if (_reply) {75 if (_reply) {
61 return _reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();76 return _reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
77 } else if (_url.isLocalFile()) {
78 switch (_errorCode) {
79 case QNetworkReply::NoError:
80 return "OK";
81 case QNetworkReply::ContentNotFoundError:
82 return "Not Found";
83 case QNetworkReply::ContentAccessDenied:
84 return "Conflict";
85 case QNetworkReply::TimeoutError:
86 return "Timeout";
87 case QNetworkReply::ContentOperationNotPermittedError:
88 return "Not Implemented";
89 }
62 }90 }
63 return "";91 return "";
64}92}
@@ -126,17 +154,42 @@ void XMLHttpRequestClass::setReadyState(ReadyState readyState) { · 61 unmodified lines
126void XMLHttpRequestClass::open(const QString& method, const QString& url, bool async, const QString& username,154void XMLHttpRequestClass::open(const QString& method, const QString& url, bool async, const QString& username,
127 const QString& password) {155 const QString& password) {
128 if (_readyState == UNSENT) {156 if (_readyState == UNSENT) {
129 _async = async;157 _method = method;
130 _url.setUrl(url);158 _url.setUrl(url);
131 if (!username.isEmpty()) {159 _async = async;
132 _url.setUserName(username);160
133 }161 if (_url.isLocalFile()) {
134 if (!password.isEmpty()) {162 if (_method.toUpper() == "GET" && !_async && username.isEmpty() && password.isEmpty()) {
135 _url.setPassword(password);163 _file = new QFile(_url.toLocalFile());
164 if (!_file->exists()) {
165 qDebug() << "Can't find file " << _url.fileName();
166 abortRequest();
167 _errorCode = QNetworkReply::ContentNotFoundError;
168 setReadyState(DONE);
169 emit requestComplete();
170 } else if (!_file->open(QIODevice::ReadOnly)) {
171 qDebug() << "Can't open file " << _url.fileName();
172 abortRequest();
173 //_errorCode = QNetworkReply::ContentConflictError; // TODO: Use this status when update to Qt 5.3
174 _errorCode = QNetworkReply::ContentAccessDenied;
175 setReadyState(DONE);
176 emit requestComplete();
177 } else {
178 setReadyState(OPENED);
179 }
180 } else {
181 notImplemented();
182 }
183 } else {
184 if (!username.isEmpty()) {
185 _url.setUserName(username);
186 }
187 if (!password.isEmpty()) {
188 _url.setPassword(password);
189 }
190 _request.setUrl(_url);
191 setReadyState(OPENED);
136 }192 }
137 _request.setUrl(_url);
138 _method = method;
139 setReadyState(OPENED);
140 }193 }
141}194}
142 195
@@ -147,13 +200,18 @@ void XMLHttpRequestClass::send() { · 4 unmodified lines
147void XMLHttpRequestClass::send(const QString& data) {200void XMLHttpRequestClass::send(const QString& data) {
148 if (_readyState == OPENED && !_reply) {201 if (_readyState == OPENED && !_reply) {
149 if (!data.isNull()) {202 if (!data.isNull()) {
150 _sendData = new QBuffer(this);203 if (_url.isLocalFile()) {
151 _sendData->setData(data.toUtf8());204 notImplemented();
205 return;
206 } else {
207 _sendData = new QBuffer(this);
208 _sendData->setData(data.toUtf8());
209 }
152 }210 }
153 211
154 doSend();212 doSend();
155 213
156 if (!_async) {214 if (!_async && !_url.isLocalFile()) {
157 QEventLoop loop;215 QEventLoop loop;
158 connect(this, SIGNAL(requestComplete()), &loop, SLOT(quit()));216 connect(this, SIGNAL(requestComplete()), &loop, SLOT(quit()));
159 loop.exec();217 loop.exec();
@@ -162,14 +220,24 @@ void XMLHttpRequestClass::send(const QString& data) { · 2 unmodified lines
162}220}
163 221
164void XMLHttpRequestClass::doSend() {222void XMLHttpRequestClass::doSend() {
165 _reply = NetworkAccessManager::getInstance().sendCustomRequest(_request, _method.toLatin1(), _sendData);223
166 224 if (!_url.isLocalFile()) {
167 connectToReply(_reply);225 _reply = NetworkAccessManager::getInstance().sendCustomRequest(_request, _method.toLatin1(), _sendData);
226 connectToReply(_reply);
227 }
168 228
169 if (_timeout > 0) {229 if (_timeout > 0) {
170 _timer.start(_timeout);230 _timer.start(_timeout);
171 connect(&_timer, SIGNAL(timeout()), this, SLOT(requestTimeout()));231 connect(&_timer, SIGNAL(timeout()), this, SLOT(requestTimeout()));
172 }232 }
233
234 if (_url.isLocalFile()) {
235 setReadyState(HEADERS_RECEIVED);
236 setReadyState(LOADING);
237 _rawResponseData = _file->readAll();
238 _file->close();
239 requestFinished();
240 }
173}241}
174 242
175void XMLHttpRequestClass::requestTimeout() {243void XMLHttpRequestClass::requestTimeout() {
@@ -188,9 +256,16 @@ void XMLHttpRequestClass::requestError(QNetworkReply::NetworkError code) { · 12 unmodified lines
188void XMLHttpRequestClass::requestFinished() {256void XMLHttpRequestClass::requestFinished() {
189 disconnect(&_timer, SIGNAL(timeout()), this, SLOT(requestTimeout()));257 disconnect(&_timer, SIGNAL(timeout()), this, SLOT(requestTimeout()));
190 258
191 _errorCode = _reply->error();259 if (!_url.isLocalFile()) {
260 _errorCode = _reply->error();
261 } else {
262 _errorCode = QNetworkReply::NoError;
263 }
264
192 if (_errorCode == QNetworkReply::NoError) {265 if (_errorCode == QNetworkReply::NoError) {
193 _rawResponseData.append(_reply->readAll());266 if (!_url.isLocalFile()) {
267 _rawResponseData.append(_reply->readAll());
268 }
194 269
195 if (_responseType == "json") {270 if (_responseType == "json") {
196 _responseData = _engine->evaluate("(" + QString(_rawResponseData.data()) + ")");271 _responseData = _engine->evaluate("(" + QString(_rawResponseData.data()) + ")");
@@ -204,6 +279,7 @@ void XMLHttpRequestClass::requestFinished() { · 7 unmodified lines
204 _responseData = QScriptValue(QString(_rawResponseData.data()));279 _responseData = QScriptValue(QString(_rawResponseData.data()));
205 }280 }
206 }281 }
282
207 setReadyState(DONE);283 setReadyState(DONE);
208 emit requestComplete();284 emit requestComplete();
209}285}
@@ -217,6 +293,19 @@ void XMLHttpRequestClass::abortRequest() { · 7 unmodified lines
217 delete _reply;293 delete _reply;
218 _reply = NULL;294 _reply = NULL;
219 }295 }
296
297 if (_file != NULL) {
298 _file->close();
299 _file = NULL;
300 }
301}
302
303void XMLHttpRequestClass::notImplemented() {
304 abortRequest();
305 //_errorCode = QNetworkReply::OperationNotImplementedError; TODO: Use this status code when update to Qt 5.3
306 _errorCode = QNetworkReply::ContentOperationNotPermittedError;
307 setReadyState(DONE);
308 emit requestComplete();
220}309}
221 310
222void XMLHttpRequestClass::connectToReply(QNetworkReply* reply) {311void XMLHttpRequestClass::connectToReply(QNetworkReply* reply) {