Browse Source
Conflicts: mix/ClientModel.cpp mix/ClientModel.h mix/qml.qrc mix/qml/TransactionDialog.qmlcl-refactor
154 changed files with 15084 additions and 2517 deletions
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,114 +0,0 @@ |
|||
/* |
|||
This file is part of ethereum.js. |
|||
|
|||
ethereum.js is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ethereum.js is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file autoprovider.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* Marian Oancea <marian@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
/* |
|||
* @brief if qt object is available, uses QtProvider, |
|||
* if not tries to connect over websockets |
|||
* if it fails, it uses HttpRpcProvider |
|||
*/ |
|||
|
|||
var web3 = require('./web3'); // jshint ignore:line
|
|||
if (process.env.NODE_ENV !== 'build') { |
|||
var WebSocket = require('ws'); // jshint ignore:line
|
|||
} |
|||
|
|||
/** |
|||
* AutoProvider object prototype is implementing 'provider protocol' |
|||
* Automatically tries to setup correct provider(Qt, WebSockets or HttpRpc) |
|||
* First it checkes if we are ethereum browser (if navigator.qt object is available) |
|||
* if yes, we are using QtProvider |
|||
* if no, we check if it is possible to establish websockets connection with ethereum (ws://localhost:40404/eth is default)
|
|||
* if it's not possible, we are using httprpc provider (http://localhost:8080)
|
|||
* The constructor allows you to specify uris on which we are trying to connect over http or websockets |
|||
* You can do that by passing objects with fields httrpc and websockets |
|||
*/ |
|||
var AutoProvider = function (userOptions) { |
|||
if (web3.haveProvider()) { |
|||
return; |
|||
} |
|||
|
|||
// before we determine what provider we are, we have to cache request
|
|||
this.sendQueue = []; |
|||
this.onmessageQueue = []; |
|||
|
|||
if (navigator.qt) { |
|||
this.provider = new web3.providers.QtProvider(); |
|||
return; |
|||
} |
|||
|
|||
userOptions = userOptions || {}; |
|||
var options = { |
|||
httprpc: userOptions.httprpc || 'http://localhost:8080', |
|||
websockets: userOptions.websockets || 'ws://localhost:40404/eth' |
|||
}; |
|||
|
|||
var self = this; |
|||
var closeWithSuccess = function (success) { |
|||
ws.close(); |
|||
if (success) { |
|||
self.provider = new web3.providers.WebSocketProvider(options.websockets); |
|||
} else { |
|||
self.provider = new web3.providers.HttpRpcProvider(options.httprpc); |
|||
self.poll = self.provider.poll.bind(self.provider); |
|||
} |
|||
self.sendQueue.forEach(function (payload) { |
|||
self.provider.send(payload); |
|||
}); |
|||
self.onmessageQueue.forEach(function (handler) { |
|||
self.provider.onmessage = handler; |
|||
}); |
|||
}; |
|||
|
|||
var ws = new WebSocket(options.websockets); |
|||
|
|||
ws.onopen = function() { |
|||
closeWithSuccess(true); |
|||
}; |
|||
|
|||
ws.onerror = function() { |
|||
closeWithSuccess(false); |
|||
}; |
|||
}; |
|||
|
|||
/// Sends message forward to the provider, that is being used
|
|||
/// if provider is not yet set, enqueues the message
|
|||
AutoProvider.prototype.send = function (payload) { |
|||
if (this.provider) { |
|||
this.provider.send(payload); |
|||
return; |
|||
} |
|||
this.sendQueue.push(payload); |
|||
}; |
|||
|
|||
/// On incoming message sends the message to the provider that is currently being used
|
|||
Object.defineProperty(AutoProvider.prototype, 'onmessage', { |
|||
set: function (handler) { |
|||
if (this.provider) { |
|||
this.provider.onmessage = handler; |
|||
return; |
|||
} |
|||
this.onmessageQueue.push(handler); |
|||
} |
|||
}); |
|||
|
|||
module.exports = AutoProvider; |
@ -1,126 +0,0 @@ |
|||
/* |
|||
This file is part of ethereum.js. |
|||
|
|||
ethereum.js is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ethereum.js is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file httprpc.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* Marian Oancea <marian@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
// TODO: is these line is supposed to be here?
|
|||
if (process.env.NODE_ENV !== 'build') { |
|||
var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line
|
|||
} |
|||
|
|||
/** |
|||
* HttpRpcProvider object prototype is implementing 'provider protocol' |
|||
* Should be used when we want to connect to ethereum backend over http && jsonrpc |
|||
* It's compatible with cpp client |
|||
* The contructor allows to specify host uri |
|||
* This provider is using in-browser polling mechanism |
|||
*/ |
|||
var HttpRpcProvider = function (host) { |
|||
this.handlers = []; |
|||
this.host = host; |
|||
}; |
|||
|
|||
/// Transforms inner message to proper jsonrpc object
|
|||
/// @param inner message object
|
|||
/// @returns jsonrpc object
|
|||
function formatJsonRpcObject(object) { |
|||
return { |
|||
jsonrpc: '2.0', |
|||
method: object.call, |
|||
params: object.args, |
|||
id: object._id |
|||
}; |
|||
} |
|||
|
|||
/// Transforms jsonrpc object to inner message
|
|||
/// @param incoming jsonrpc message
|
|||
/// @returns inner message object
|
|||
function formatJsonRpcMessage(message) { |
|||
var object = JSON.parse(message); |
|||
|
|||
return { |
|||
_id: object.id, |
|||
data: object.result, |
|||
error: object.error |
|||
}; |
|||
} |
|||
|
|||
/// Prototype object method
|
|||
/// Asynchronously sends request to server
|
|||
/// @param payload is inner message object
|
|||
/// @param cb is callback which is being called when response is comes back
|
|||
HttpRpcProvider.prototype.sendRequest = function (payload, cb) { |
|||
var data = formatJsonRpcObject(payload); |
|||
|
|||
var request = new XMLHttpRequest(); |
|||
request.open("POST", this.host, true); |
|||
request.send(JSON.stringify(data)); |
|||
request.onreadystatechange = function () { |
|||
if (request.readyState === 4 && cb) { |
|||
cb(request); |
|||
} |
|||
}; |
|||
}; |
|||
|
|||
/// Prototype object method
|
|||
/// Should be called when we want to send single api request to server
|
|||
/// Asynchronous
|
|||
/// On response it passes message to handlers
|
|||
/// @param payload is inner message object
|
|||
HttpRpcProvider.prototype.send = function (payload) { |
|||
var self = this; |
|||
this.sendRequest(payload, function (request) { |
|||
self.handlers.forEach(function (handler) { |
|||
handler.call(self, formatJsonRpcMessage(request.responseText)); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
/// Prototype object method
|
|||
/// Should be called only for polling requests
|
|||
/// Asynchronous
|
|||
/// On response it passege message to handlers, but only if message's result is true or not empty array
|
|||
/// Otherwise response is being silently ignored
|
|||
/// @param payload is inner message object
|
|||
/// @id is id of poll that we are calling
|
|||
HttpRpcProvider.prototype.poll = function (payload, id) { |
|||
var self = this; |
|||
this.sendRequest(payload, function (request) { |
|||
var parsed = JSON.parse(request.responseText); |
|||
if (parsed.error || (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result)) { |
|||
return; |
|||
} |
|||
self.handlers.forEach(function (handler) { |
|||
handler.call(self, {_event: payload.call, _id: id, data: parsed.result}); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
/// Prototype object property
|
|||
/// Should be used to set message handlers for this provider
|
|||
Object.defineProperty(HttpRpcProvider.prototype, "onmessage", { |
|||
set: function (handler) { |
|||
this.handlers.push(handler); |
|||
} |
|||
}); |
|||
|
|||
module.exports = HttpRpcProvider; |
|||
|
@ -0,0 +1,66 @@ |
|||
/* |
|||
This file is part of ethereum.js. |
|||
|
|||
ethereum.js is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ethereum.js is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file httpsync.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* Marian Oancea <marian@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
var HttpSyncProvider = function (host) { |
|||
this.handlers = []; |
|||
this.host = host || 'http://localhost:8080'; |
|||
}; |
|||
|
|||
/// Transforms inner message to proper jsonrpc object
|
|||
/// @param inner message object
|
|||
/// @returns jsonrpc object
|
|||
function formatJsonRpcObject(object) { |
|||
return { |
|||
jsonrpc: '2.0', |
|||
method: object.call, |
|||
params: object.args, |
|||
id: object._id |
|||
}; |
|||
} |
|||
|
|||
/// Transforms jsonrpc object to inner message
|
|||
/// @param incoming jsonrpc message
|
|||
/// @returns inner message object
|
|||
function formatJsonRpcMessage(message) { |
|||
var object = JSON.parse(message); |
|||
|
|||
return { |
|||
_id: object.id, |
|||
data: object.result, |
|||
error: object.error |
|||
}; |
|||
} |
|||
|
|||
HttpSyncProvider.prototype.send = function (payload) { |
|||
var data = formatJsonRpcObject(payload); |
|||
|
|||
var request = new XMLHttpRequest(); |
|||
request.open('POST', this.host, false); |
|||
request.send(JSON.stringify(data)); |
|||
|
|||
// check request.status
|
|||
return request.responseText; |
|||
}; |
|||
|
|||
module.exports = HttpSyncProvider; |
|||
|
@ -1,57 +0,0 @@ |
|||
/* |
|||
This file is part of ethereum.js. |
|||
|
|||
ethereum.js is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ethereum.js is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file qt.js |
|||
* @authors: |
|||
* Jeffrey Wilcke <jeff@ethdev.com> |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
/** |
|||
* QtProvider object prototype is implementing 'provider protocol' |
|||
* Should be used inside ethereum browser. It's compatible with cpp and go clients. |
|||
* It uses navigator.qt object to pass the messages to native bindings |
|||
*/ |
|||
var QtProvider = function() { |
|||
this.handlers = []; |
|||
|
|||
var self = this; |
|||
navigator.qt.onmessage = function (message) { |
|||
self.handlers.forEach(function (handler) { |
|||
handler.call(self, JSON.parse(message.data)); |
|||
}); |
|||
}; |
|||
}; |
|||
|
|||
/// Prototype object method
|
|||
/// Should be called when we want to send single api request to native bindings
|
|||
/// Asynchronous
|
|||
/// Response will be received by navigator.qt.onmessage method and passed to handlers
|
|||
/// @param payload is inner message object
|
|||
QtProvider.prototype.send = function(payload) { |
|||
navigator.qt.postMessage(JSON.stringify(payload)); |
|||
}; |
|||
|
|||
/// Prototype object property
|
|||
/// Should be used to set message handlers for this provider
|
|||
Object.defineProperty(QtProvider.prototype, "onmessage", { |
|||
set: function(handler) { |
|||
this.handlers.push(handler); |
|||
} |
|||
}); |
|||
|
|||
module.exports = QtProvider; |
@ -0,0 +1,32 @@ |
|||
/* |
|||
This file is part of ethereum.js. |
|||
|
|||
ethereum.js is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ethereum.js is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file qtsync.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* Marian Oancea <marian@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
var QtSyncProvider = function () { |
|||
}; |
|||
|
|||
QtSyncProvider.prototype.send = function (payload) { |
|||
return navigator.qt.callMethod(JSON.stringify(payload)); |
|||
}; |
|||
|
|||
module.exports = QtSyncProvider; |
|||
|
@ -1,98 +0,0 @@ |
|||
/* |
|||
This file is part of ethereum.js. |
|||
|
|||
ethereum.js is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ethereum.js is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file websocket.js |
|||
* @authors: |
|||
* Jeffrey Wilcke <jeff@ethdev.com> |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* Marian Oancea <marian@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
// TODO: is these line is supposed to be here?
|
|||
if (process.env.NODE_ENV !== 'build') { |
|||
var WebSocket = require('ws'); // jshint ignore:line
|
|||
} |
|||
|
|||
/** |
|||
* WebSocketProvider object prototype is implementing 'provider protocol' |
|||
* Should be used when we want to connect to ethereum backend over websockets |
|||
* It's compatible with go client |
|||
* The constructor allows to specify host uri |
|||
*/ |
|||
var WebSocketProvider = function(host) { |
|||
|
|||
// onmessage handlers
|
|||
this.handlers = []; |
|||
|
|||
// queue will be filled with messages if send is invoked before the ws is ready
|
|||
this.queued = []; |
|||
this.ready = false; |
|||
|
|||
this.ws = new WebSocket(host); |
|||
|
|||
var self = this; |
|||
this.ws.onmessage = function(event) { |
|||
for(var i = 0; i < self.handlers.length; i++) { |
|||
self.handlers[i].call(self, JSON.parse(event.data), event); |
|||
} |
|||
}; |
|||
|
|||
this.ws.onopen = function() { |
|||
self.ready = true; |
|||
|
|||
for (var i = 0; i < self.queued.length; i++) { |
|||
// Resend
|
|||
self.send(self.queued[i]); |
|||
} |
|||
}; |
|||
}; |
|||
|
|||
/// Prototype object method
|
|||
/// Should be called when we want to send single api request to server
|
|||
/// Asynchronous, it's using websockets
|
|||
/// Response for the call will be received by ws.onmessage
|
|||
/// @param payload is inner message object
|
|||
WebSocketProvider.prototype.send = function(payload) { |
|||
if (this.ready) { |
|||
var data = JSON.stringify(payload); |
|||
|
|||
this.ws.send(data); |
|||
} else { |
|||
this.queued.push(payload); |
|||
} |
|||
}; |
|||
|
|||
/// Prototype object method
|
|||
/// Should be called to add handlers
|
|||
WebSocketProvider.prototype.onMessage = function(handler) { |
|||
this.handlers.push(handler); |
|||
}; |
|||
|
|||
/// Prototype object method
|
|||
/// Should be called to close websockets connection
|
|||
WebSocketProvider.prototype.unload = function() { |
|||
this.ws.close(); |
|||
}; |
|||
|
|||
/// Prototype object property
|
|||
/// Should be used to set message handlers for this provider
|
|||
Object.defineProperty(WebSocketProvider.prototype, "onmessage", { |
|||
set: function(provider) { this.onMessage(provider); } |
|||
}); |
|||
|
|||
if (typeof(module) !== "undefined") |
|||
module.exports = WebSocketProvider; |
@ -0,0 +1,69 @@ |
|||
|
|||
/** |
|||
* This plugin exposes 'evaluateExpression' method which should be used |
|||
* to evaluate natspec description |
|||
* It should be reloaded each time we want to evaluate set of expressions |
|||
* Just because of security reasons |
|||
* TODO: make use of sync api (once it's finished) and remove unnecessary |
|||
* code from 'getContractMethods' |
|||
* TODO: unify method signature creation with abi.js (and make a separate method from it) |
|||
*/ |
|||
|
|||
/// Should be called to copy values from object to global context
|
|||
var copyToContext = function (obj, context) { |
|||
var keys = Object.keys(obj); |
|||
keys.forEach(function (key) { |
|||
context[key] = obj[key]; |
|||
}); |
|||
} |
|||
|
|||
/// Function called to get all contract's storage values
|
|||
/// @returns hashmap with contract properties which are used
|
|||
var getContractProperties = function (address, abi) { |
|||
return {}; |
|||
}; |
|||
|
|||
/// Function called to get all contract's methods
|
|||
/// @returns hashmap with used contract's methods
|
|||
var getContractMethods = function (address, abi) { |
|||
return web3.eth.contract(address, abi); |
|||
}; |
|||
|
|||
/// Should be called to evaluate single expression
|
|||
/// Is internally using javascript's 'eval' method
|
|||
/// Should be checked if it is safe
|
|||
var evaluateExpression = function (expression) { |
|||
|
|||
var self = this; |
|||
var abi = web3._currentContractAbi; |
|||
var address = web3._currentContractAddress; |
|||
|
|||
var storage = getContractProperties(address, abi); |
|||
var methods = getContractMethods(address, abi); |
|||
|
|||
copyToContext(storage, self); |
|||
copyToContext(methods, self); |
|||
|
|||
// TODO: test if it is safe
|
|||
var evaluatedExpression = ""; |
|||
|
|||
// match everything in `` quotes
|
|||
var pattern = /\`(?:\\.|[^`\\])*\`/gim |
|||
var match; |
|||
var lastIndex = 0; |
|||
while ((match = pattern.exec(expression)) !== null) { |
|||
var startIndex = pattern.lastIndex - match[0].length; |
|||
|
|||
var toEval = match[0].slice(1, match[0].length - 1); |
|||
|
|||
evaluatedExpression += expression.slice(lastIndex, startIndex); |
|||
evaluatedExpression += eval(toEval).toString(); |
|||
|
|||
lastIndex = pattern.lastIndex; |
|||
} |
|||
|
|||
evaluatedExpression += expression.slice(lastIndex); |
|||
|
|||
return evaluatedExpression; |
|||
}; |
|||
|
@ -0,0 +1,170 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file HttpServer.cpp
|
|||
* @author Arkadiy Paronyan arkadiy@ethdev.com |
|||
* @date 2015 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#include <memory> |
|||
#include <QTcpSocket> |
|||
#include "HttpServer.h" |
|||
|
|||
|
|||
using namespace dev::mix; |
|||
|
|||
HttpServer::HttpServer() |
|||
: m_port(0) , m_listen(false) , m_accept(true) , m_componentCompleted(true) |
|||
{ |
|||
} |
|||
|
|||
HttpServer::~HttpServer() |
|||
{ |
|||
setListen(false); |
|||
} |
|||
|
|||
void HttpServer::classBegin() |
|||
{ |
|||
m_componentCompleted = false; |
|||
} |
|||
|
|||
void HttpServer::componentComplete() |
|||
{ |
|||
init(); |
|||
m_componentCompleted = true; |
|||
} |
|||
|
|||
QUrl HttpServer::url() const |
|||
{ |
|||
QUrl url; |
|||
url.setPort(m_port); |
|||
url.setHost("localhost"); |
|||
url.setScheme("http"); |
|||
return url; |
|||
} |
|||
|
|||
void HttpServer::setPort(int _port) |
|||
{ |
|||
if (_port == m_port) |
|||
return; |
|||
|
|||
m_port = _port; |
|||
emit portChanged(_port); |
|||
emit urlChanged(url()); |
|||
|
|||
if (m_componentCompleted && this->isListening()) |
|||
updateListening(); |
|||
} |
|||
|
|||
QString HttpServer::errorString() const |
|||
{ |
|||
return this->errorString(); |
|||
} |
|||
|
|||
void HttpServer::setListen(bool _listen) |
|||
{ |
|||
if (_listen == m_listen) |
|||
return; |
|||
|
|||
m_listen = _listen; |
|||
emit listenChanged(_listen); |
|||
|
|||
if (m_componentCompleted) |
|||
updateListening(); |
|||
} |
|||
|
|||
void HttpServer::setAccept(bool _accept) |
|||
{ |
|||
if (_accept == m_accept) |
|||
return; |
|||
|
|||
m_accept = _accept; |
|||
emit acceptChanged(_accept); |
|||
} |
|||
|
|||
void HttpServer::init() |
|||
{ |
|||
updateListening(); |
|||
} |
|||
|
|||
void HttpServer::updateListening() |
|||
{ |
|||
if (this->isListening()) |
|||
this->close(); |
|||
|
|||
if (!m_listen || QTcpServer::listen(QHostAddress::LocalHost, m_port)) |
|||
return; |
|||
} |
|||
|
|||
void HttpServer::incomingConnection(qintptr _socket) |
|||
{ |
|||
if (!m_accept) |
|||
return; |
|||
|
|||
QTcpSocket* s = new QTcpSocket(this); |
|||
connect(s, SIGNAL(readyRead()), this, SLOT(readClient())); |
|||
connect(s, SIGNAL(disconnected()), this, SLOT(discardClient())); |
|||
s->setSocketDescriptor(_socket); |
|||
} |
|||
|
|||
void HttpServer::readClient() |
|||
{ |
|||
if (!m_accept) |
|||
return; |
|||
|
|||
QTcpSocket* socket = (QTcpSocket*)sender(); |
|||
try |
|||
{ |
|||
if (socket->canReadLine()) |
|||
{ |
|||
QString hdr = QString(socket->readLine()); |
|||
if (hdr.startsWith("POST")) |
|||
{ |
|||
QString l; |
|||
do |
|||
l = socket->readLine(); |
|||
while (!(l.isEmpty() || l == "\r" || l == "\r\n")); |
|||
|
|||
QString content = socket->readAll(); |
|||
QUrl url; |
|||
std::unique_ptr<HttpRequest> request(new HttpRequest(this, url, content)); |
|||
clientConnected(request.get()); |
|||
QTextStream os(socket); |
|||
os.setAutoDetectUnicode(true); |
|||
///@todo: allow setting response content-type, charset, etc
|
|||
os << "HTTP/1.0 200 Ok\r\n" |
|||
"Content-Type: text/plain; charset=\"utf-8\"\r\n" |
|||
"\r\n"; |
|||
os << request->m_response; |
|||
} |
|||
} |
|||
} |
|||
catch(...) |
|||
{ |
|||
delete socket; |
|||
throw; |
|||
} |
|||
socket->close(); |
|||
if (socket->state() == QTcpSocket::UnconnectedState) |
|||
delete socket; |
|||
} |
|||
|
|||
void HttpServer::discardClient() |
|||
{ |
|||
QTcpSocket* socket = (QTcpSocket*)sender(); |
|||
socket->deleteLater(); |
|||
} |
@ -0,0 +1,123 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file HttpServer.h
|
|||
* @author Arkadiy Paronyan arkadiy@ethdev.com |
|||
* @date 2015 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QObject> |
|||
#include <QTcpServer> |
|||
#include <QUrl> |
|||
#include <QQmlParserStatus> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
/// Simple http server for serving jsonrpc requests
|
|||
class HttpRequest : public QObject |
|||
{ |
|||
Q_OBJECT |
|||
/// Request url
|
|||
Q_PROPERTY(QUrl url MEMBER m_url CONSTANT) |
|||
/// Request body contents
|
|||
Q_PROPERTY(QString content MEMBER m_content CONSTANT) |
|||
|
|||
private: |
|||
HttpRequest(QObject* _parent, QUrl const& _url, QString const& _content): |
|||
QObject(_parent), m_url(_url), m_content(_content) |
|||
{ |
|||
} |
|||
|
|||
public: |
|||
/// Set response for a request
|
|||
/// @param _response Response body. If no response is set, server returns status 200 with empty body
|
|||
Q_INVOKABLE void setResponse(QString const& _response) { m_response = _response; } |
|||
|
|||
private: |
|||
QUrl m_url; |
|||
QString m_content; |
|||
QString m_response; |
|||
friend class HttpServer; |
|||
}; |
|||
|
|||
class HttpServer : public QTcpServer, public QQmlParserStatus |
|||
{ |
|||
Q_OBJECT |
|||
Q_DISABLE_COPY(HttpServer) |
|||
Q_INTERFACES(QQmlParserStatus) |
|||
|
|||
/// Server url
|
|||
Q_PROPERTY(QUrl url READ url NOTIFY urlChanged) |
|||
/// Server port
|
|||
Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged) |
|||
/// Listen for connections
|
|||
Q_PROPERTY(bool listen READ listen WRITE setListen NOTIFY listenChanged) |
|||
/// Accept new connections
|
|||
Q_PROPERTY(bool accept READ accept WRITE setAccept NOTIFY acceptChanged) |
|||
/// Error string if any
|
|||
Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged) |
|||
|
|||
public: |
|||
explicit HttpServer(); |
|||
virtual ~HttpServer(); |
|||
|
|||
QUrl url() const; |
|||
int port() const { return m_port; } |
|||
void setPort(int _port); |
|||
bool listen() const { return m_listen; } |
|||
void setListen(bool _listen); |
|||
bool accept() const { return m_accept; } |
|||
void setAccept(bool _accept); |
|||
QString errorString() const; |
|||
|
|||
protected: |
|||
virtual void classBegin() override; |
|||
virtual void componentComplete() override; |
|||
virtual void incomingConnection(qintptr _socket) override; |
|||
|
|||
signals: |
|||
void clientConnected(HttpRequest* _request); |
|||
void errorStringChanged(QString const& _errorString); |
|||
void urlChanged(QUrl const& _url); |
|||
void portChanged(int _port); |
|||
void listenChanged(bool _listen); |
|||
void acceptChanged(bool _accept); |
|||
|
|||
private: |
|||
void init(); |
|||
void updateListening(); |
|||
void newConnection(); |
|||
void serverError(); |
|||
|
|||
private slots: |
|||
void readClient(); |
|||
void discardClient(); |
|||
|
|||
private: |
|||
int m_port; |
|||
bool m_listen; |
|||
bool m_accept; |
|||
bool m_componentCompleted; |
|||
}; |
|||
|
|||
} |
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue