diff --git a/example/example.pro b/example/example.pro index 949ebaf..bf3fbe5 100644 --- a/example/example.pro +++ b/example/example.pro @@ -2,8 +2,4 @@ TEMPLATE = subdirs SUBDIRS += helloworld SUBDIRS += basic-server -SUBDIRS += httpclient -SUBDIRS += httpclient-qt -SUBDIRS += httpclient-raw -SUBDIRS += httpjsonserver SUBDIRS += benchmark diff --git a/example/httpclient-qt/httpclient-qt.pro b/example/httpclient-qt/httpclient-qt.pro deleted file mode 100644 index 5ef2ac7..0000000 --- a/example/httpclient-qt/httpclient-qt.pro +++ /dev/null @@ -1,24 +0,0 @@ -QT += core network -QT -= gui -CONFIG += console -CONFIG += c++11 -osx:CONFIG -= app_bundle - -TARGET = httpclient-qt -TEMPLATE = app -PRJDIR = ../.. -include($$PRJDIR/commondir.pri) - -INCLUDEPATH += .. - - -SOURCES += main.cpp \ - httpclient.cpp \ - ../include/gason.cpp - -HEADERS += \ - httpclient.hpp \ - ../include/gason.hpp \ - ../include/jsonbuilder.hpp - -LIBS += $$PRJDIR/xbin/libqhttpserver.a diff --git a/example/httpclient-qt/httpclient.cpp b/example/httpclient-qt/httpclient.cpp deleted file mode 100644 index 7b13e98..0000000 --- a/example/httpclient-qt/httpclient.cpp +++ /dev/null @@ -1,210 +0,0 @@ -#include "httpclient.hpp" -#include "include/jsonbuilder.hpp" -#include "include/gason.hpp" - -#include -#include - -#include -#include -#include -/////////////////////////////////////////////////////////////////////////////// -class HttpClient::Private -{ - static const size_t KPacketMaxLength = 4096; - HttpClient* iparent; - -public: - QNetworkAccessManager inetworkManager; - int iclientId; - - quint32 isleep; - quint32 icommandCounter; - quint32 irequests; - - QBasicTimer itimer; - QString iaddress; - quint16 iport; - - bool ikeepAlive; - - gason::JsonAllocator ijsonAllocator; - -public: - explicit Private(int clientId, HttpClient* p) : iparent(p), inetworkManager(p) { - iclientId = clientId; - isleep = 0; - icommandCounter = 0; - irequests = 0; - - QObject::connect(&inetworkManager, &QNetworkAccessManager::finished, [this](QNetworkReply* rep){ - onFinished(rep); - }); - } - -public: - void sendRequest() { - if ( icommandCounter >= irequests ) { - emit iparent->finished(iclientId, icommandCounter); - return; - } - - QNetworkRequest req(QString("http://%1:%2/testPath") - .arg(iaddress) - .arg(iport) - ); - if ( !ikeepAlive ) - req.setRawHeader("connection", "close"); - req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - - char buffer[KPacketMaxLength+1] = {0}; - gason::JSonBuilder doc(buffer, KPacketMaxLength); - doc.startObject() - .addValue("clientId", iclientId) - .addValue("requestId", (int) icommandCounter++) - .addValue("command", "request") - .endObject(); - - inetworkManager.post(req, QByteArray(buffer)); - } - - void onFinished(QNetworkReply* reply) { - char buffer[KPacketMaxLength+1] = {0}; - reply->read(buffer, KPacketMaxLength); - - reply->deleteLater(); - - onIncomingData(buffer); - - if ( isleep > 0 ) - itimer.start(isleep, iparent); - else - QMetaObject::invokeMethod(iparent, "start"); - } - -protected: - bool onIncomingData(char* buffer) { - gason::JsonValue root; - - if ( gason::jsonParse(buffer, root, ijsonAllocator) != gason::JSON_PARSE_OK ) - return false; - - gason::JsonValue clientId = root("clientId"); - gason::JsonValue reqId = root("requestId"); - gason::JsonValue command = root("command"); - - bool bok = false; - - if ( strncmp("response", command.toString(&bok), 8) != 0 ) { - puts(" invalid command!\n"); - return false; - } - - if ( !clientId.isNumber() || clientId.toInt(&bok) != iclientId ) { - puts(" invalid clientId!\n"); - return false; - } - - if ( !reqId.isNumber() || reqId.toInt(&bok) != (int)icommandCounter ) { - puts(" invalid requestId!\n"); - return false; - } - - return true; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// - -HttpClient::HttpClient(quint32 clientId, QObject *parent) : QObject(parent), pimp(nullptr) { - - pimp = new Private(clientId, this); -} - -HttpClient::~HttpClient() { - if ( pimp != nullptr ) { - delete pimp; - pimp = nullptr; - } -} - -quint32 -HttpClient::clientId() const { - return pimp->iclientId; -} - -const QString& -HttpClient::address() const { - return pimp->iaddress; -} - -void -HttpClient::setAddress(const QString& addr) { - pimp->iaddress = addr; -} - -quint16 -HttpClient::port() const { - return pimp->iport; -} - -void -HttpClient::setPort(quint16 p) { - pimp->iport = p; -} - -quint32 -HttpClient::requestCount() const { - return pimp->irequests; -} - -void -HttpClient::setRequestCount(quint32 rc) { - pimp->irequests = rc; -} - -quint32 -HttpClient::sleepTime() const { - return pimp->isleep; -} - -void -HttpClient::setSleepTime(quint32 sleep) { - if ( sleep < 10000 ) - pimp->isleep = sleep; - else - pimp->isleep = 100; -} - -quint32 -HttpClient::commandCount() const { - return pimp->icommandCounter; -} - -bool -HttpClient::keepAlive() const { - return pimp->ikeepAlive; -} - -void -HttpClient::setKeepAlive(bool b) { - pimp->ikeepAlive = b; -} - -void -HttpClient::start() { - Private& d = *pimp; - - d.sendRequest(); -} - -void -HttpClient::timerEvent(QTimerEvent* e) { - if ( pimp != nullptr ) { - if ( e->timerId() == pimp->itimer.timerId() ) - pimp->sendRequest(); - } -} -/////////////////////////////////////////////////////////////////////////////// - diff --git a/example/httpclient-qt/httpclient.hpp b/example/httpclient-qt/httpclient.hpp deleted file mode 100644 index 8895a79..0000000 --- a/example/httpclient-qt/httpclient.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef HTTPCLIENT_HPP -#define HTTPCLIENT_HPP -/////////////////////////////////////////////////////////////////////////////// -#include - -/////////////////////////////////////////////////////////////////////////////// - -class HttpClient : public QObject -{ - Q_OBJECT - - Q_PROPERTY(quint32 clientId READ clientId) - Q_PROPERTY(QString address READ address WRITE setAddress) - Q_PROPERTY(quint16 port READ port WRITE setPort) - Q_PROPERTY(quint32 requestCount READ requestCount WRITE setRequestCount) - Q_PROPERTY(quint32 sleepTime READ sleepTime WRITE setSleepTime) - Q_PROPERTY(quint32 commandCount READ commandCount) - Q_PROPERTY(bool keepAlive READ keepAlive WRITE setKeepAlive) - -public: - explicit HttpClient(quint32 clientId, QObject *parent = 0); - virtual ~HttpClient(); - -signals: - void finished(int clientId, size_t sentCommands); - -public slots: - void start(); - -public: // properties - quint32 clientId() const; - - const QString& address() const; - void setAddress(const QString&); - - quint16 port() const; - void setPort(quint16); - - quint32 requestCount() const; - void setRequestCount(quint32); - - quint32 sleepTime() const; - void setSleepTime(quint32); - - quint32 commandCount() const; - - bool keepAlive() const; - void setKeepAlive(bool); - -protected: - void timerEvent(QTimerEvent*); - class Private; - Private* pimp; -}; - -/////////////////////////////////////////////////////////////////////////////// -#endif // HTTPCLIENT_HPP diff --git a/example/httpclient-qt/main.cpp b/example/httpclient-qt/main.cpp deleted file mode 100644 index 6029ebc..0000000 --- a/example/httpclient-qt/main.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include - -#include -#include - - -#include "httpclient.hpp" -#include "include/ticktock.hxx" - -/////////////////////////////////////////////////////////////////////////////// -class Application : public QCoreApplication -{ -public: - explicit Application(int &argc, char** argv) : QCoreApplication(argc, argv) { - setApplicationName("httpclient"); - setApplicationVersion("1.0.0"); - - QCommandLineParser parser; - parser.setApplicationDescription("attacks an http server by sending JSon requests and parses the responses.\n" \ - "by Amir Zamani."); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addPositionalArgument("server", - "optional server address as address[:port]. default: localhost:8080"); - - parser.addOption(QCommandLineOption(QStringList() << "p" << "port", - "server's port number. default: 8080", - "portNumber", "8080")); - - parser.addOption(QCommandLineOption(QStringList() << "s" << "server", - "server's address (url or ip). default: localhost", - "ip", "127.0.0.1")); - - parser.addOption(QCommandLineOption(QStringList() << "c" << "count", - "number of sockets to be connected to the server. default: 10", - "number", "10")); - - parser.addOption(QCommandLineOption(QStringList() << "r" << "requests", - "number of requests for each socket. default: 100", - "number", "100")); - - parser.addOption(QCommandLineOption(QStringList() << "i" << "interval", - "time interval between each request in [mSec]. default: 1000", - "number", "1000")); - - parser.addOption(QCommandLineOption(QStringList() << "k" << "keep", - "keep a connection alive or disconnect after each response. default: yes", - "yes/no", "yes")); - - parser.process(*this); - QStringList args = parser.positionalArguments(); - - iport = 0; - if ( args.size() >= 1 ) { - QString server = args.at(0); - QStringList items = server.split(":", QString::SkipEmptyParts); - if ( items.size() >= 1 ) - iaddress = items.at(0); - if ( items.size() >= 2 ) - iport = items.at(1).toUShort(); - } - - if ( iport == 0 ) - iport = parser.value("port").toUShort(); - if ( iaddress.isEmpty() ) - iaddress = parser.value("server"); - iclientCount = parser.value("count").toUInt(); - irequestCount = parser.value("requests").toUInt(); - itimeOut = parser.value("interval").toUInt(); - ikeepAlive = parser.value("keep").toLower() == "yes"; - - printf("\nconnecting to %s:%d --count %lu --requests %lu --interval %u --keep %s\n\n", - iaddress.toUtf8().constData(), iport, - iclientCount, irequestCount, itimeOut, - (ikeepAlive) ? "yes": "no"); - } - - ~Application() { - } - - void startClients() { - ifinishedPackets = 0; - ifinishedCount = 0; - - itick.tick(); - for ( size_t i = 0; i < iclientCount; i++ ) { - HttpClient* client = new HttpClient(i+1, this); - iclients.insert(i+1, client); - client->setAddress(iaddress); - client->setPort(iport); - client->setRequestCount(irequestCount); - client->setSleepTime(itimeOut); - client->setKeepAlive(ikeepAlive); - - QObject::connect(client, &HttpClient::finished, - [this](int clientId, size_t packets) { - yetAnotherFinished(clientId, packets); - }); - client->start(); - } - } - -protected: - void yetAnotherFinished(int clientId, size_t packets) { - ifinishedPackets += packets; - ifinishedCount++; - - HttpClient* client = iclients.value(clientId); - if ( client ) - client->deleteLater(); - iclients.remove(clientId); - printf("client #%d finished.\n", clientId); - - if ( ifinishedCount == iclientCount ) { - uint32_t diff = itick.tock(); - printf("\n%lu JSON packets have been transfered by %lu sockets in %u [mSec].\n", - ifinishedPackets, iclientCount, - diff); - quit(); - } - } - -protected: - QString iaddress; - quint16 iport; - size_t iclientCount; - size_t irequestCount; - quint32 itimeOut; - bool ikeepAlive; - - -protected: - typedef QHash TClients; - - am::TickTock itick; - size_t ifinishedCount; - size_t ifinishedPackets; - - TClients iclients; -}; - -/////////////////////////////////////////////////////////////////////////////// - -int main(int argc, char *argv[]) { - Application app(argc, argv); - app.startClients(); - - - app.exec(); - puts("\n\nend of http client.\n\n"); - return 0; -} - - diff --git a/example/httpclient-raw/httpclient-raw.pro b/example/httpclient-raw/httpclient-raw.pro deleted file mode 100644 index fdc788e..0000000 --- a/example/httpclient-raw/httpclient-raw.pro +++ /dev/null @@ -1,24 +0,0 @@ -QT += core network -QT -= gui -CONFIG += console -CONFIG += c++11 -osx:CONFIG -= app_bundle - -TARGET = httpclient-raw -TEMPLATE = app -PRJDIR = ../.. -include($$PRJDIR/commondir.pri) - -INCLUDEPATH += .. - - -SOURCES += main.cpp \ - httpclient.cpp \ - ../include/gason.cpp - -HEADERS += \ - httpclient.hpp \ - ../include/gason.hpp \ - ../include/jsonbuilder.hpp - -LIBS += $$PRJDIR/xbin/libqhttpserver.a diff --git a/example/httpclient-raw/httpclient.cpp b/example/httpclient-raw/httpclient.cpp deleted file mode 100644 index 3eb49b9..0000000 --- a/example/httpclient-raw/httpclient.cpp +++ /dev/null @@ -1,241 +0,0 @@ -#include "httpclient.hpp" -#include "include/jsonbuilder.hpp" -#include "include/gason.hpp" - -#include -#include - -#include -#include -/////////////////////////////////////////////////////////////////////////////// -class HttpClient::Private -{ - static const size_t KPacketMaxLength = 1024; - HttpClient* iparent; - -public: - QTcpSocket isocket; - int iclientId; - - quint32 isleep; - quint32 icommandCounter; - quint32 irequests; - - QBasicTimer itimer; - QString iaddress; - quint16 iport; - - bool ikeepAlive; - - gason::JsonAllocator ijsonAllocator; - QByteArray ibuffer; - -public: - explicit Private(int clientId, HttpClient* p) : iparent(p), isocket(p) { - iclientId = clientId; - isleep = 0; - icommandCounter = 0; - irequests = 0; - - QObject::connect(&isocket, &QTcpSocket::connected, [this](){ - QMetaObject::invokeMethod(iparent, "start"); - }); - QObject::connect(&isocket, &QTcpSocket::disconnected, [this](){ - isocket.close(); - if ( isleep == 0 ) - QMetaObject::invokeMethod(iparent, "start"); - }); - QObject::connect(&isocket, &QTcpSocket::readyRead, [this](){ - if ( ibuffer.size() > (int) KPacketMaxLength ) { - // buffer overflow! - isocket.disconnectFromHost(); - - } else { - ibuffer.append( isocket.readAll() ); - onIncomingData(); - } - }); - } - -public: - bool shouldSend() { - if ( icommandCounter < irequests ) - return true; - - itimer.stop(); - isocket.disconnectFromHost(); - emit iparent->finished(iclientId, icommandCounter); - return false; - } - - void requestStart() { - if ( !shouldSend() ) - return; - - if ( !isocket.isOpen() ) { - isocket.connectToHost(iaddress, iport); - return; - } - - ibuffer.clear(); - ibuffer.reserve(1024); - - char requestData[257] = {0}; - gason::JSonBuilder json(requestData, 256); - json.startObject() - .addValue("clientId", iclientId) - .addValue("requestId", (int)icommandCounter++) - .addValue("command", "request") - .endObject(); - - char requestHeader[257] = {0}; - gason::StringBuilder http(requestHeader, 256); - - http << "POST / HTTP/1.1\r\n" - << "host: " << iaddress << ":" << (int)iport << "\r\n" - << "connection: " << ( (ikeepAlive) ? "keep-alive" : "close" ) << "\r\n" - << "content-length: " << (int)strlen(requestData) << "\r\n" - << "\r\n"; - - isocket.write(requestHeader); - isocket.write(requestData); - isocket.flush(); - - if ( isleep > 0 ) - itimer.start(isleep, iparent); - } - -protected: - bool onIncomingData() { - int index = ibuffer.indexOf("\r\n\r\n"); - if ( index < 0 ) - return false; - - index += 4; - char buffer[513] = {0}; - strncpy(buffer, ibuffer.constData() + index, 512); - - gason::JsonValue root; - - if ( gason::jsonParse(buffer, root, ijsonAllocator) != gason::JSON_PARSE_OK ) - return false; - - gason::JsonValue clientId = root("clientId"); - gason::JsonValue reqId = root("requestId"); - gason::JsonValue command = root("command"); - - bool bok = false; - - if ( strncmp("response", command.toString(&bok), 8) != 0 ) { - puts(" invalid command!\n"); - return false; - } - - if ( !clientId.isNumber() || clientId.toInt(&bok) != iclientId ) { - puts(" invalid clientId!\n"); - return false; - } - - if ( !reqId.isNumber() || reqId.toInt(&bok) != (int)icommandCounter ) { - puts(" invalid requestId!\n"); - return false; - } - - return true; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// - -HttpClient::HttpClient(quint32 clientId, QObject *parent) : QObject(parent), pimp(nullptr) { - - pimp = new Private(clientId, this); -} - -HttpClient::~HttpClient() { - if ( pimp != nullptr ) { - delete pimp; - pimp = nullptr; - } -} - -quint32 -HttpClient::clientId() const { - return pimp->iclientId; -} - -const QString& -HttpClient::address() const { - return pimp->iaddress; -} - -void -HttpClient::setAddress(const QString& addr) { - pimp->iaddress = addr; -} - -quint16 -HttpClient::port() const { - return pimp->iport; -} - -void -HttpClient::setPort(quint16 p) { - pimp->iport = p; -} - -quint32 -HttpClient::requestCount() const { - return pimp->irequests; -} - -void -HttpClient::setRequestCount(quint32 rc) { - pimp->irequests = rc; -} - -quint32 -HttpClient::sleepTime() const { - return pimp->isleep; -} - -void -HttpClient::setSleepTime(quint32 sleep) { - if ( sleep < 10000 ) - pimp->isleep = sleep; - else - pimp->isleep = 100; -} - -quint32 -HttpClient::commandCount() const { - return pimp->icommandCounter; -} - -bool -HttpClient::keepAlive() const { - return pimp->ikeepAlive; -} - -void -HttpClient::setKeepAlive(bool b) { - pimp->ikeepAlive = b; -} - -void -HttpClient::start() { - Private& d = *pimp; - - d.requestStart(); -} - -void -HttpClient::timerEvent(QTimerEvent* e) { - if ( pimp != nullptr ) { - if ( e->timerId() == pimp->itimer.timerId() ) - QMetaObject::invokeMethod(this, "start"); - } -} -/////////////////////////////////////////////////////////////////////////////// - diff --git a/example/httpclient-raw/httpclient.hpp b/example/httpclient-raw/httpclient.hpp deleted file mode 100644 index 8895a79..0000000 --- a/example/httpclient-raw/httpclient.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef HTTPCLIENT_HPP -#define HTTPCLIENT_HPP -/////////////////////////////////////////////////////////////////////////////// -#include - -/////////////////////////////////////////////////////////////////////////////// - -class HttpClient : public QObject -{ - Q_OBJECT - - Q_PROPERTY(quint32 clientId READ clientId) - Q_PROPERTY(QString address READ address WRITE setAddress) - Q_PROPERTY(quint16 port READ port WRITE setPort) - Q_PROPERTY(quint32 requestCount READ requestCount WRITE setRequestCount) - Q_PROPERTY(quint32 sleepTime READ sleepTime WRITE setSleepTime) - Q_PROPERTY(quint32 commandCount READ commandCount) - Q_PROPERTY(bool keepAlive READ keepAlive WRITE setKeepAlive) - -public: - explicit HttpClient(quint32 clientId, QObject *parent = 0); - virtual ~HttpClient(); - -signals: - void finished(int clientId, size_t sentCommands); - -public slots: - void start(); - -public: // properties - quint32 clientId() const; - - const QString& address() const; - void setAddress(const QString&); - - quint16 port() const; - void setPort(quint16); - - quint32 requestCount() const; - void setRequestCount(quint32); - - quint32 sleepTime() const; - void setSleepTime(quint32); - - quint32 commandCount() const; - - bool keepAlive() const; - void setKeepAlive(bool); - -protected: - void timerEvent(QTimerEvent*); - class Private; - Private* pimp; -}; - -/////////////////////////////////////////////////////////////////////////////// -#endif // HTTPCLIENT_HPP diff --git a/example/httpclient-raw/main.cpp b/example/httpclient-raw/main.cpp deleted file mode 100644 index 3d485f2..0000000 --- a/example/httpclient-raw/main.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include -#include - -#include -#include - - -#include "httpclient.hpp" -#include "include/ticktock.hxx" - -/////////////////////////////////////////////////////////////////////////////// -class Application : public QCoreApplication -{ -public: - explicit Application(int &argc, char** argv) : QCoreApplication(argc, argv) { - setApplicationName("httpclient-raw"); - setApplicationVersion("1.0.0"); - - QCommandLineParser parser; - parser.setApplicationDescription("attacks an http server by sending JSon requests and parses the responses.\n" \ - "by Amir Zamani."); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addPositionalArgument("server", - "optional server address as address[:port]. default: localhost:8080"); - - parser.addOption(QCommandLineOption(QStringList() << "p" << "port", - "server's port number. default: 8080", - "portNumber", "8080")); - - parser.addOption(QCommandLineOption(QStringList() << "s" << "server", - "server's address (url or ip). default: localhost", - "ip", "127.0.0.1")); - - parser.addOption(QCommandLineOption(QStringList() << "c" << "count", - "number of sockets to be connected to the server. default: 10", - "number", "10")); - - parser.addOption(QCommandLineOption(QStringList() << "r" << "requests", - "number of requests for each socket. default: 100", - "number", "100")); - - parser.addOption(QCommandLineOption(QStringList() << "i" << "interval", - "time interval between each request in [mSec]. default: 0", - "number", "0")); - - parser.addOption(QCommandLineOption(QStringList() << "k" << "keep", - "keep a connection alive or disconnect after each response. default: no", - "yes/no", "no")); - - parser.process(*this); - QStringList args = parser.positionalArguments(); - - iport = 0; - if ( args.size() >= 1 ) { - QString server = args.at(0); - QStringList items = server.split(":", QString::SkipEmptyParts); - if ( items.size() >= 1 ) - iaddress = items.at(0); - if ( items.size() >= 2 ) - iport = items.at(1).toUShort(); - } - - if ( iport == 0 ) - iport = parser.value("port").toUShort(); - if ( iaddress.isEmpty() ) - iaddress = parser.value("server"); - iclientCount = parser.value("count").toUInt(); - irequestCount = parser.value("requests").toUInt(); - itimeOut = parser.value("interval").toUInt(); - ikeepAlive = parser.value("keep").toLower() == "yes"; - - printf("\nconnecting to %s:%d --count %lu --requests %lu --interval %u --keep %s\n\n", - iaddress.toUtf8().constData(), iport, - iclientCount, irequestCount, itimeOut, - (ikeepAlive) ? "yes": "no"); - } - - ~Application() { - } - - void startClients() { - ifinishedPackets = 0; - ifinishedCount = 0; - - for ( size_t i = 0; i < iclientCount; i++ ) { - HttpClient* client = new HttpClient(i+1, this); - iclients.insert(i+1, client); - client->setAddress(iaddress); - client->setPort(iport); - client->setRequestCount(irequestCount); - client->setSleepTime(itimeOut); - client->setKeepAlive(ikeepAlive); - - QObject::connect(client, &HttpClient::finished, - [this](int clientId, size_t packets) { - yetAnotherFinished(clientId, packets); - }); - } - - itick.tick(); - for ( size_t i = 0; i < iclientCount; i++ ) { - HttpClient* cli = iclients.value(i+1); - QMetaObject::invokeMethod(cli, "start"); - } - } - -protected: - void yetAnotherFinished(int clientId, size_t packets) { - ifinishedPackets += packets; - ifinishedCount++; - - HttpClient* client = iclients.value(clientId); - if ( client ) - client->deleteLater(); - iclients.remove(clientId); - printf("client #%d finished.\n", clientId); - fflush(stdout); - - if ( ifinishedCount == iclientCount ) { - uint32_t diff = itick.tock(); - printf("\n%lu JSON packets have been transfered by %lu sockets in %u [mSec].\n", - ifinishedPackets, iclientCount, - diff); - quit(); - } - } - -protected: - QString iaddress; - quint16 iport; - size_t iclientCount; - size_t irequestCount; - quint32 itimeOut; - bool ikeepAlive; - - -protected: - typedef QHash TClients; - - am::TickTock itick; - size_t ifinishedCount; - size_t ifinishedPackets; - - TClients iclients; -}; - -/////////////////////////////////////////////////////////////////////////////// - -int main(int argc, char *argv[]) { - Application app(argc, argv); - app.startClients(); - - - app.exec(); - puts("\n\nend of http client.\n\n"); - return 0; -} - - diff --git a/example/httpclient/httpclient.cpp b/example/httpclient/httpclient.cpp deleted file mode 100644 index d0d9321..0000000 --- a/example/httpclient/httpclient.cpp +++ /dev/null @@ -1,250 +0,0 @@ -#define QHTTP_MEMORY_LOG 0 -#include "httpclient.hpp" -#include "include/jsonbuilder.hpp" -#include "include/gason.hpp" - -#include "qhttpclient.hpp" -#include "qhttpclientrequest.hpp" -#include "qhttpclientresponse.hpp" - -#include -#include - -#include -#include - -/////////////////////////////////////////////////////////////////////////////// -class HttpClientPrivate -{ - HttpClient* const q_ptr; - -public: - const int iclientId; - - quint32 isleep; - quint32 icommandCounter; - quint32 irequests; - - QBasicTimer isleepTimer; - QString iaddress; - quint16 iport; - - bool ikeepAlive; - - gason::JsonAllocator ijsonAllocator; - QByteArray ibuffer; - -public: - explicit HttpClientPrivate(int clientId, HttpClient* q) - : q_ptr(q), iclientId(clientId) { - - isleep = 0; - icommandCounter = 0; - irequests = 0; - - QHTTP_LINE_LOG - } - - virtual ~HttpClientPrivate() { - QHTTP_LINE_LOG - } - -public: - bool shouldSend() { - if ( icommandCounter < irequests ) - return true; - - isleepTimer.stop(); - emit q_ptr->finished(iclientId, icommandCounter); - return false; - } - - void requestStart() { - if ( !shouldSend() ) - return; - - qhttp::client::QHttpClient* client = new qhttp::client::QHttpClient(q_ptr); - - QObject::connect(client, &qhttp::client::QHttpClient::disconnected, - [this](){ - QMetaObject::invokeMethod(q_ptr, "start"); - }); - QObject::connect(client, &qhttp::client::QHttpClient::httpConnected, - [this](qhttp::client::QHttpRequest* req){ - onRequestReady(req); - }); - QObject::connect(client, &qhttp::client::QHttpClient::newResponse, - [this](qhttp::client::QHttpResponse* res){ - onResponseReady(res); - }); - - - QUrl url; - url.setScheme("http"); - url.setHost(iaddress); - url.setPort(iport); - url.setPath("/aPath/users"); - - client->request(qhttp::EHTTP_POST, url); - } - - bool onIncomming() { - char buffer[1025] = {0}; - strncpy(buffer, ibuffer.constData(), 1024); - - gason::JsonValue root; - - if ( gason::jsonParse(buffer, root, ijsonAllocator) != gason::JSON_PARSE_OK ) { - puts("invalid json response, parsing failed."); - return false; - } - - gason::JsonValue clientId = root("clientId"); - gason::JsonValue reqId = root("requestId"); - gason::JsonValue command = root("command"); - - bool bok = false; - - if ( strncmp("response", command.toString(&bok), 8) != 0 ) { - puts(" invalid command!\n"); - return false; - } - - if ( !clientId.isNumber() || clientId.toInt(&bok) != iclientId ) { - puts(" invalid clientId!\n"); - return false; - } - - if ( !reqId.isNumber() || reqId.toInt(&bok) != (int)icommandCounter ) { - puts(" invalid requestId!\n"); - return false; - } - - return true; - } - - void onRequestReady(qhttp::client::QHttpRequest *req) { - char requestData[257] = {0}; - gason::JSonBuilder json(requestData, 256); - json.startObject() - .addValue("clientId", iclientId) - .addValue("requestId", (int)icommandCounter++) - .addValue("command", "request") - .endObject(); - - req->addHeader("connection", (ikeepAlive) ? "keep-alive" : "close"); - req->addHeader("content-length", QByteArray::number((int)strlen(requestData))); - - req->end(requestData); - } - - void onResponseReady(qhttp::client::QHttpResponse *res) { - ibuffer.clear(); - ibuffer.reserve(1024); - - QObject::connect(res, &qhttp::client::QHttpResponse::data, - [this](const QByteArray& chunk){ - ibuffer.append(chunk); - }); - - QObject::connect(res, &qhttp::client::QHttpResponse::end, - [this, res](){ - onIncomming(); - res->connection()->close(); - }); - } - -}; - - -/////////////////////////////////////////////////////////////////////////////// - -HttpClient::HttpClient(quint32 clientId, QObject *parent) : QObject(parent), - d_ptr(new HttpClientPrivate(clientId, this)) { -} - -HttpClient::~HttpClient() { -} - -quint32 -HttpClient::clientId() const { - return d_func()->iclientId; -} - -const QString& -HttpClient::address() const { - return d_func()->iaddress; -} - -void -HttpClient::setAddress(const QString& addr) { - d_func()->iaddress = addr; -} - -quint16 -HttpClient::port() const { - return d_func()->iport; -} - -void -HttpClient::setPort(quint16 p) { - d_func()->iport = p; -} - -quint32 -HttpClient::requestCount() const { - return d_func()->irequests; -} - -void -HttpClient::setRequestCount(quint32 rc) { - d_func()->irequests = rc; -} - -quint32 -HttpClient::sleepTime() const { - return d_func()->isleep; -} - -void -HttpClient::setSleepTime(quint32 sleep) { - if ( sleep < 100000 ) - d_func()->isleep = sleep; - else - d_func()->isleep = 100; -} - -quint32 -HttpClient::commandCount() const { - return d_func()->icommandCounter; -} - -bool -HttpClient::keepAlive() const { - return d_func()->ikeepAlive; -} - -void -HttpClient::setKeepAlive(bool b) { - d_func()->ikeepAlive = b; -} - -void -HttpClient::start() { - Q_D(HttpClient); - - if ( d->isleepTimer.isActive() ) - return; - - if ( d->isleep > 0 ) - d->isleepTimer.start(d->isleep, Qt::CoarseTimer, this); - else - d->requestStart(); -} - -void -HttpClient::timerEvent(QTimerEvent* e) { - Q_D(HttpClient); - if ( e->timerId() == d->isleepTimer.timerId() ) - d->requestStart(); -} diff --git a/example/httpclient/httpclient.hpp b/example/httpclient/httpclient.hpp deleted file mode 100644 index 7c5975f..0000000 --- a/example/httpclient/httpclient.hpp +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef HTTPCLIENT_HPP -#define HTTPCLIENT_HPP -/////////////////////////////////////////////////////////////////////////////// -#include -/////////////////////////////////////////////////////////////////////////////// -class HttpClientPrivate; - -class HttpClient : public QObject -{ - Q_OBJECT - - Q_PROPERTY(quint32 clientId READ clientId) - Q_PROPERTY(QString address READ address WRITE setAddress) - Q_PROPERTY(quint16 port READ port WRITE setPort) - Q_PROPERTY(quint32 requestCount READ requestCount WRITE setRequestCount) - Q_PROPERTY(quint32 sleepTime READ sleepTime WRITE setSleepTime) - Q_PROPERTY(quint32 commandCount READ commandCount) - Q_PROPERTY(bool keepAlive READ keepAlive WRITE setKeepAlive) - -public: - explicit HttpClient(quint32 clientId, QObject *parent = 0); - virtual ~HttpClient(); - -signals: - void finished(int clientId, size_t sentCommands); - -public slots: - void start(); - -public: // properties - quint32 clientId() const; - - const QString& address() const; - void setAddress(const QString&); - - quint16 port() const; - void setPort(quint16); - - quint32 requestCount() const; - void setRequestCount(quint32); - - quint32 sleepTime() const; - void setSleepTime(quint32); - - quint32 commandCount() const; - - bool keepAlive() const; - void setKeepAlive(bool); - -protected: - void timerEvent(QTimerEvent*); - -private: - Q_DECLARE_PRIVATE(HttpClient) - Q_DISABLE_COPY(HttpClient) - - QScopedPointer d_ptr; -}; - -/////////////////////////////////////////////////////////////////////////////// -#endif // HTTPCLIENT_HPP diff --git a/example/httpclient/httpclient.pro b/example/httpclient/httpclient.pro deleted file mode 100644 index 0797dc0..0000000 --- a/example/httpclient/httpclient.pro +++ /dev/null @@ -1,24 +0,0 @@ -QT += core network -QT -= gui -CONFIG += console -CONFIG += c++11 -osx:CONFIG -= app_bundle - -TARGET = httpclient -TEMPLATE = app -PRJDIR = ../.. -include($$PRJDIR/commondir.pri) - -INCLUDEPATH += .. - - -SOURCES += main.cpp \ - httpclient.cpp \ - ../include/gason.cpp - -HEADERS += \ - httpclient.hpp \ - ../include/gason.hpp \ - ../include/jsonbuilder.hpp - -LIBS += $$PRJDIR/xbin/libqhttpserver.a diff --git a/example/httpclient/main.cpp b/example/httpclient/main.cpp deleted file mode 100644 index 46a4592..0000000 --- a/example/httpclient/main.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include -#include - -#include -#include - - -#include "httpclient.hpp" -#include "include/ticktock.hxx" - -/////////////////////////////////////////////////////////////////////////////// -class Application : public QCoreApplication -{ -public: - explicit Application(int &argc, char** argv) : QCoreApplication(argc, argv) { - setApplicationName("httpclient"); - setApplicationVersion("1.0.0"); - - QCommandLineParser parser; - parser.setApplicationDescription("attacks an http server by sending JSon requests and parses the responses.\n" \ - "by Amir Zamani."); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addPositionalArgument("server", - "optional server address as address[:port]. default: localhost:8080"); - - parser.addOption(QCommandLineOption(QStringList() << "p" << "port", - "server's port number. default: 8080", - "portNumber", "8080")); - - parser.addOption(QCommandLineOption(QStringList() << "s" << "server", - "server's address (url or ip). default: localhost", - "ip", "127.0.0.1")); - - parser.addOption(QCommandLineOption(QStringList() << "c" << "count", - "number of sockets to be connected to the server. default: 10", - "number", "10")); - - parser.addOption(QCommandLineOption(QStringList() << "r" << "requests", - "number of requests for each socket. default: 100", - "number", "100")); - - parser.addOption(QCommandLineOption(QStringList() << "i" << "interval", - "time interval between each request in [mSec]. default: 0", - "number", "0")); - - parser.addOption(QCommandLineOption(QStringList() << "k" << "keep", - "keep a connection alive or disconnect after each response. default: no", - "yes/no", "no")); - - parser.process(*this); - QStringList args = parser.positionalArguments(); - - iport = 0; - if ( args.size() >= 1 ) { - QString server = args.at(0); - QStringList items = server.split(":", QString::SkipEmptyParts); - if ( items.size() >= 1 ) - iaddress = items.at(0); - if ( items.size() >= 2 ) - iport = items.at(1).toUShort(); - } - - if ( iport == 0 ) - iport = parser.value("port").toUShort(); - if ( iaddress.isEmpty() ) - iaddress = parser.value("server"); - iclientCount = parser.value("count").toUInt(); - irequestCount = parser.value("requests").toUInt(); - itimeOut = parser.value("interval").toUInt(); - ikeepAlive = parser.value("keep").toLower() == "yes"; - - printf("\nconnecting to %s:%d --count %lu --requests %lu --interval %u --keep %s\n\n", - iaddress.toUtf8().constData(), iport, - iclientCount, irequestCount, itimeOut, - (ikeepAlive) ? "yes": "no"); - } - - ~Application() { - } - - void startClients() { - ifinishedPackets = 0; - ifinishedCount = 0; - - for ( size_t i = 0; i < iclientCount; i++ ) { - HttpClient* client = new HttpClient(i+1, this); - iclients.insert(i+1, client); - client->setAddress(iaddress); - client->setPort(iport); - client->setRequestCount(irequestCount); - client->setSleepTime(itimeOut); - client->setKeepAlive(ikeepAlive); - - QObject::connect(client, &HttpClient::finished, - [this](int clientId, size_t packets) { - yetAnotherFinished(clientId, packets); - }); - } - - itick.tick(); - for ( size_t i = 0; i < iclientCount; i++ ) { - HttpClient* cli = iclients.value(i+1); - QMetaObject::invokeMethod(cli, "start"); - } - } - -protected: - void yetAnotherFinished(int clientId, size_t packets) { - ifinishedPackets += packets; - ifinishedCount++; - - HttpClient* client = iclients.value(clientId); - if ( client ) - client->deleteLater(); - iclients.remove(clientId); - printf("client #%d finished.\n", clientId); - fflush(stdout); - - if ( ifinishedCount == iclientCount ) { - uint32_t diff = itick.tock(); - printf("\n%lu JSON packets have been transfered by %lu sockets in %u [mSec].\n", - ifinishedPackets, iclientCount, - diff); - quit(); - } - } - -protected: - QString iaddress; - quint16 iport; - size_t iclientCount; - size_t irequestCount; - quint32 itimeOut; - bool ikeepAlive; - - -protected: - typedef QHash TClients; - - am::TickTock itick; - size_t ifinishedCount; - size_t ifinishedPackets; - - TClients iclients; -}; - -/////////////////////////////////////////////////////////////////////////////// - -int main(int argc, char *argv[]) { - Application app(argc, argv); - app.startClients(); - - - app.exec(); - puts("\n\nend of http client.\n\n"); - return 0; -} - - diff --git a/example/httpjsonserver/httpjsonserver.pro b/example/httpjsonserver/httpjsonserver.pro deleted file mode 100644 index 50699a0..0000000 --- a/example/httpjsonserver/httpjsonserver.pro +++ /dev/null @@ -1,22 +0,0 @@ -QT += core network -QT -= gui -CONFIG += console -CONFIG += c++11 -osx:CONFIG -= app_bundle - -TARGET = httpjsonserver -TEMPLATE = app -PRJDIR = ../.. -include($$PRJDIR/commondir.pri) - -INCLUDEPATH += .. - - -SOURCES += main.cpp \ - ../include/gason.cpp - -HEADERS += \ - ../include/gason.hpp \ - ../include/jsonbuilder.hpp - -LIBS += $$PRJDIR/xbin/libqhttpserver.a diff --git a/example/httpjsonserver/main.cpp b/example/httpjsonserver/main.cpp deleted file mode 100644 index 3c33144..0000000 --- a/example/httpjsonserver/main.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include -#include -#include -#include - -#include "qhttpserver.hpp" -#include "qhttpserverconnection.hpp" -#include "qhttpserverrequest.hpp" -#include "qhttpserverresponse.hpp" - -#include "../include/gason.hpp" -#include "../include/jsonbuilder.hpp" - -/////////////////////////////////////////////////////////////////////////////// - -class ClientHandler : public QObject -{ -public: - explicit ClientHandler(qhttp::server::QHttpRequest* req, - qhttp::server::QHttpResponse* res) : QObject(res) { - - QObject::connect(req, &qhttp::server::QHttpRequest::data, - [this, req](const QByteArray& chunk) { - // data attack! - if ( ibody.size() > 4096 ) - req->connection()->close(); - else - ibody.append(chunk); - }); - - QObject::connect(req, &qhttp::server::QHttpRequest::end, [this, req, res](){ - res->addHeader("connection", "close"); - - // gason++ writes lots of \0 into source buffer. so we have to make a writeable copy. - char buffer[4907] = {0}; - strncpy(buffer, ibody.constData(), 4096); - - gason::JsonAllocator allocator; - gason::JsonValue root; - - bool clientStatus = false; - - if ( gason::jsonParse(buffer, root, allocator) == gason::JSON_PARSE_OK ) { - gason::JsonValue command = root("command"); - gason::JsonValue clientId = root("clientId"); - gason::JsonValue requestId = root("requestId"); - - bool ok = false; - if ( strncmp(command.toString(&ok), "request", 7) == 0 && - clientId.isNumber() && requestId.isNumber() ) { - - memset(buffer, 0, 4096); - gason::JSonBuilder doc(buffer, 4096); - doc.startObject() - .addValue("command", "response") - .addValue("clientId", clientId.toInt(&ok)) - .addValue("requestId", requestId.toInt(&ok) + 1) - .endObject(); - - res->addHeader("content-length", QByteArray::number((int)strlen(buffer))); - - clientStatus = true; - } - } - - if ( clientStatus ) { - res->setStatusCode(qhttp::ESTATUS_OK); - res->end(QByteArray(buffer)); - - } else { - res->setStatusCode(qhttp::ESTATUS_BAD_REQUEST); - res->end("bad request: the json value is not present or invalid!\n"); - } - - if ( req->headers().keyHasValue("command", "quit" ) ) { - puts("a quit header is received!"); - - QCoreApplication::instance()->quit(); - } - }); - } - -protected: - QByteArray ibody; -}; - -/////////////////////////////////////////////////////////////////////////////// - -class Application : public QCoreApplication -{ -public: - explicit Application(int& argc, char** argv) - : QCoreApplication(argc, argv), iserver(this) { - setApplicationName("qtjsonserver"); - setApplicationVersion("1.0.0"); - - QCommandLineParser parser; - parser.setApplicationDescription("a simple http server for responding incomming JSon.\n" \ - "by Amir Zamani."); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addPositionalArgument("port", - "listening port. default: 5533"); - - parser.addOption(QCommandLineOption(QStringList() << "t" << "timeout", - "maximum timeout for an open connection. default: 5000", - "number", "5000")); - - parser.process(*this); - - iport = 5533; - itimeOut = parser.value("timeout").toUInt(); - iserver.setTimeOut(itimeOut); - - QStringList args = parser.positionalArguments(); - if ( args.size() >= 1 ) { - iport = args.at(0).toUShort(); - } - - printf("listening @ %d --timeout %u\n\n", - iport, itimeOut); - } - - bool start() { - using namespace qhttp::server; - QObject::connect(&iserver, &QHttpServer::newRequest, - [this](QHttpRequest* req, QHttpResponse* res){ - new ClientHandler(req, res); - }); - - if ( !iserver.listen(QHostAddress::Any, iport) ) { - printf("can not listen on port #%d.\n", iport); - return false; - } - - return true; - } - -protected: - qhttp::server::QHttpServer iserver; - - quint16 iport; - size_t imaxPendingConnections; - quint32 itimeOut; -}; - -/////////////////////////////////////////////////////////////////////////////// - -int main(int argc, char *argv[]) { - Application app(argc, argv); - if ( app.start() ) - app.exec(); - - puts("\n\nend of http server.\n\n"); - return 0; -} - -