Giter Club home page Giter Club logo

qhttpserver's Introduction

QHttpServer is NOT actively maintained. Amir Zamani's qhttp fixes some of the bugs here and is generally a nicer place to start from.

QHttpServer

A Qt HTTP Server - because hard-core programmers write web-apps in C++ :)

It uses Joyent's HTTP Parser and is asynchronous and does not require any inheritance.

QHttpServer is available under the MIT License.

NOTE: QHttpServer is NOT fully HTTP compliant right now! DO NOT use it for anything complex

Installation

Requires Qt 4 or Qt 5.

qmake && make && su -c 'make install'

To link to your projects put this in your project's qmake project file

LIBS += -lqhttpserver

By default, the installation prefix is /usr/local. To change that to /usr, for example, run:

qmake -r PREFIX=/usr

Usage

Include the headers

#include <qhttpserver.h>
#include <qhttprequest.h>
#include <qhttpresponse.h>

Create a server, and connect to the signal for new requests

QHttpServer *server = new QHttpServer;
connect(server, SIGNAL(newRequest(QHttpRequest*, QHttpResponse*)),
        handler, SLOT(handle(QHttpRequest*, QHttpResponse*)));

// let's go
server->listen(8080);

In the handler, you may dispatch on routes or do whatever other things you want. See the API documentation for what information is provided about the request via the QHttpRequest object.

To send data back to the browser and end the request:

void Handler::handle(QHttpRequest *req, QHttpResponse *resp)
{
	resp->setHeader("Content-Length", 11);
	resp->writeHead(200); // everything is OK
	resp->write("Hello World");
	resp->end();
}

The server and request/response objects emit various signals and have guarantees about memory management. See the API documentation for these.

Contribute

Feel free to file issues, branch and send pull requests. If you plan to work on a major feature (say WebSocket support), please run it by me first by filing an issue! qhttpserver has a narrow scope and API and I'd like to keep it that way, so a thousand line patch that implements the kitchen sink is unlikely to be accepted.

  • Nikhil Marathe (maintainer)

Everybody who has ever contributed shows up in Contributors.

qhttpserver's People

Contributors

carbn avatar christian-sahlmann avatar davidiw avatar hporten avatar kmatheussen avatar mxnemu avatar nikhilm avatar qw0101 avatar skycoder42 avatar vdudouyt avatar viking avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qhttpserver's Issues

leak in qhttpserver ?

Hi
I was testing some stuff with Visual Leak Detector and came across the m_tcpServer doesent get freed on destruction of the QHttpServer. Maybe this is intentional, I can see there was some other cleanup code in the history before, but is changed/removed.. ?

and thanks for the library btw :)

Gavin

Host static web pages

Hi there, QHttpServer looks promising for our projects.

We would like to use QHttpServer to host a static web site within a QT application. Is there a simple way to host the HTML/CSS/JS files etc from QT resources?

Thanks in advance!
Jake

Leaking QHttpRequest objects

The request object passed to the QHttpServer::newRequest(QHttpRequest*, QHttpResponse*) signal is never deleted. Neither the code samples, nor the inline documentation suggest that the user is responsible for deleting the request.

I suggest that the request object should be deleted automatically when the response is deleted:

connect(response, SIGNAL(destroyed(), request, SLOT(deleteLater()));

Further, if the user fails to connect and properly handle the newRequest() signal, both request and response (and connection) objects will leak. The response and connection objects are destroyed when the connection is closed by the client, but the request is never destroyed. I suggest passing these objects wrapped in a QSharedPointer rather than naked pointers. That would make the API safe(r) by design.

Nice library thou, thank you for sharing 👍

How to handle a request from client?

Hello,

I have some problems to understand how to handle a request which is send by a client. I understand (because of the examples) how to send a response to a client but not the way in the other direction.

Can you help me?

Furthermore, the next step would be to use the request within QML in "newConnection()" signal.

For the qml example have a look here:

https://github.com/rschroll/qhttpserver/blob/master/examples/qml/app.qml

I think you already use the because of the forking...

Impossible to create multithreaded server ?

Hi,

I wonder if it is possible to create a multithreaded server using QHttpServer ?
If I use QHttpResponse in a thread, it fails because it is then not in the same thread than the server socket (which belongs to QHttpConnection which itself remains in the main thread).

Here is what I do:
the handleRequest slot connected to newRequest creates a SearchThread object which is a QObject and a QRunnable.
The searchThread is connected to the request end() signal. This startSearch method calls QThreadPool::globalInstance()->start(this);
Finally, the run method of the searchThread calls moveToThread on the request and the answer (I know this last part is wrong in itself but it's here to give an idea of what I try to do).

I see no other way to run the handling of a request in a separate tread.

Writing headers without a status code

void QHttpResponse::writeHeaders()

method is private and called automatically by

QHttpResponse::writeHead(int status)

right after writing the status code to the client.

This makes it impossible to write headers without writing a status code which prevents me from creating an mjpeg server that needs to respond to clients in the following format :

HTTP/1.0 200 OK
Content-Type: multipart/x-mixed-replace;boundary=boundary
--boundary

--boundary
Content-Type: image/jpeg
Content-Length: 67856

<binary JPEG image data>
--boundary
Content-Type: image/jpeg
Content-Length: 52856

<binary JPEG Image data>
--boundary 
...

Suggestion : Cancel the automatic call to QHttpResponse::writeHeaders() and make it public.

Building with make -j4 fails

Without the -j4 flag, it works fine.

% make -j4
cd src/ && /usr/bin/qmake-qt4 /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/src/src.pro -o Makefile
cd tests/ && /usr/bin/qmake-qt4 /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/tests/tests.pro -o Makefile
cd examples/ && /usr/bin/qmake-qt4 /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/examples/examples.pro -o Makefile
cd examples/ && make -f Makefile
cd tests/ && make -f Makefile
make[1]: Entering directory /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/examples' cd helloworld/ && /usr/bin/qmake-qt4 /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/examples/helloworld/helloworld.pro -o Makefile cd greeting/ && /usr/bin/qmake-qt4 /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/examples/greeting/greeting.pro -o Makefile cd bodydata/ && /usr/bin/qmake-qt4 /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/examples/bodydata/bodydata.pro -o Makefile make[1]: Entering directory/tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/tests'
g++ -c -m64 -pipe -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I../src -I. -o test.o test.cpp
cd src/ && make -f Makefile
g++ -m64 -Wl,-O1,--sort-common,--as-needed,-z,relro -Wl,-O1 -o tests test.o -L/usr/lib -L../lib/ -lqhttpserver -lQtGui -lQtNetwork -lQtCore -lpthread
cd greeting/ && make -f Makefile
cd bodydata/ && make -f Makefile
make[1]: Entering directory /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/src' g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build -o ../build/qhttpconnection.o qhttpconnection.cpp /usr/bin/ld: cannot find -lqhttpserver collect2: error: ld returned 1 exit status make[1]: *** [tests] Error 1 make[1]: Leaving directory/tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/tests'
make[2]: Entering directory /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/examples/greeting' g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../../src -I. -o greeting.o greeting.cpp make: *** [sub-tests-make_default] Error 2 make: *** Waiting for unfinished jobs.... g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build -o ../build/qhttprequest.o qhttprequest.cpp make[2]: Entering directory/tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/examples/bodydata'
g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../../src -I. -o bodydata.o bodydata.cpp
/usr/lib/qt4/bin/moc -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../../src -I. bodydata.h -o moc_bodydata.cpp
g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build -o ../build/qhttpresponse.o qhttpresponse.cpp
/usr/lib/qt4/bin/moc -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../../src -I. greeting.h -o moc_greeting.cpp
g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../../src -I. -o moc_bodydata.o moc_bodydata.cpp
bodydata.cpp: In Elementfunktion »void BodyData::handle(QHttpRequest_, QHttpResponse_)«:
bodydata.cpp:66:16: Warnung: Variable »r« wird nicht verwendet [-Wunused-variable]
Responder r = new Responder(req, resp);
^
g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build -o ../build/qhttpserver.o qhttpserver.cpp
g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../../src -I. -o moc_greeting.o moc_greeting.cpp
gcc -c -m64 -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build -o ../build/http_parser.o ../http-parser/http_parser.c
g++ -m64 -Wl,-O1,--sort-common,--as-needed,-z,relro -o bodydata bodydata.o moc_bodydata.o -L/usr/lib -L../../lib -lqhttpserver -lQtNetwork -lQtCore -lpthread
/usr/lib/qt4/bin/moc -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build qhttpconnection.h -o ../build/moc_qhttpconnection.cpp
g++ -m64 -Wl,-O1,--sort-common,--as-needed,-z,relro -o greeting greeting.o moc_greeting.o -L/usr/lib -L../../lib -lqhttpserver -lQtNetwork -lQtCore -lpthread
/usr/lib/qt4/bin/moc -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build qhttpserver.h -o ../build/moc_qhttpserver.cpp
/usr/bin/ld: cannot find -lqhttpserver
collect2: error: ld returned 1 exit status
make[2]: *
* [bodydata] Error 1
make[2]: Leaving directory /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/examples/bodydata' make[1]: *** [sub-bodydata-make_default] Error 2 make[1]: *** Waiting for unfinished jobs.... /usr/lib/qt4/bin/moc -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build qhttprequest.h -o ../build/moc_qhttprequest.cpp /usr/bin/ld: cannot find -lqhttpserver collect2: error: ld returned 1 exit status make[2]: *** [greeting] Error 1 make[2]: Leaving directory/tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/examples/greeting'
make[1]: /usr/lib/qt4/bin/moc -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build qhttpresponse.h -o ../build/moc_qhttpresponse.cpp
*** [sub-greeting-make_default] Error 2
make[1]: Leaving directory /tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/examples' make: *** [sub-examples-make_default] Error 2 g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build -o ../build/moc_qhttpconnection.o ../build/moc_qhttpconnection.cpp g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build -o ../build/moc_qhttpserver.o ../build/moc_qhttpserver.cpp g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build -o ../build/moc_qhttprequest.o ../build/moc_qhttprequest.cpp g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4 -I../http-parser -I../build -o ../build/moc_qhttpresponse.o ../build/moc_qhttpresponse.cpp rm -f libqhttpserver.so.0.1.0 libqhttpserver.so libqhttpserver.so.0 libqhttpserver.so.0.1 g++ -m64 -Wl,-O1,--sort-common,--as-needed,-z,relro -shared -Wl,-soname,libqhttpserver.so.0 -o libqhttpserver.so.0.1.0 ../build/qhttpconnection.o ../build/qhttprequest.o ../build/qhttpresponse.o ../build/qhttpserver.o ../build/http_parser.o ../build/moc_qhttpconnection.o ../build/moc_qhttpserver.o ../build/moc_qhttprequest.o ../build/moc_qhttpresponse.o -L/usr/lib -lQtNetwork -lQtCore -lpthread ln -s libqhttpserver.so.0.1.0 libqhttpserver.so ln -s libqhttpserver.so.0.1.0 libqhttpserver.so.0 ln -s libqhttpserver.so.0.1.0 libqhttpserver.so.0.1 rm -f ../lib/libqhttpserver.so.0.1.0 rm -f ../lib/libqhttpserver.so rm -f ../lib/libqhttpserver.so.0 rm -f ../lib/libqhttpserver.so.0.1 mv -f libqhttpserver.so.0.1.0 libqhttpserver.so libqhttpserver.so.0 libqhttpserver.so.0.1 ../lib/ { test -z "../lib/" || cd "../lib/"; } && test $(gdb --version | sed -e 's,[^0-9]\+\([0-9]\)\.\([0-9]\).*,\1\2,;q') -gt 72 && gdb --nx --batch --quiet -ex 'set confirm off' -ex "save gdb-index ." -ex quit 'libqhttpserver.so.0.1.0' && test -f libqhttpserver.so.0.1.0.gdb-index && objcopy --add-section '.gdb_index=libqhttpserver.so.0.1.0.gdb-index' --set-section-flags '.gdb_index=readonly' 'libqhttpserver.so.0.1.0' 'libqhttpserver.so.0.1.0' && rm -f libqhttpserver.so.0.1.0.gdb-index || true make[1]: Leaving directory/tmp/yaourt-tmp-cbuehler/aur-qhttpserver/src/qhttpserver/src'

I am using QT Creator IDE for develop Cplusplus Rest API using “qhttpserver” http server . We are unable to import “pkcs#12” “.pfx” certificate file

Hi, nikhilm
I have spent couple of week on this problem, i did not reach any solution. Actually i am using cross-platform mechanism for develop so Web server and App server run on different port or system.
These below code i am using , but i don't know where i receive request as file multipart "QHttpRequest" request so that i can write file into server directory.

RestMain::RestMain()
{
try {
QHttpServer server = new QHttpServer(this);
connect(server, SIGNAL(newRequest(QHttpRequest
, QHttpResponse_)),
this, SLOT(handleRequest(QHttpRequest_, QHttpResponse_)));
server->listen(QHostAddress::Any, 8080);
} catch (std::exception& e)
{
qDebug() << "Exception:" << e.what() << '\n';
}
}
// request handler mathod
void RestMain::handleRequest(QHttpRequest *req, QHttpResponse *resp)
{
try{
resp->setHeader("Access-Control-Allow-Origin", "_");
resp->setHeader("Access-Control-Allow-Methods", "GET,POST");
resp->setHeader("Access-Control-Allow-Headers", "origin, x-requested-with, content-type");
} catch (std::exception& e)
{
qDebug() << "Exception:" << e.what() << '\n';
}
}

Large size files are not uploaded using ajax request

I try to upload a text file of 20MB and saved it in a file test.txt but not all contents are uploaded and saved, file size is just 48KB.
I used ajax request to send files using multipart/form-data as enctype.
Is that because of qhttp server uploading file size limit or anything else?

EXC_BAD_ACCESS in QHttpConnection::socketDisconnected()

0 QtCore 0x00000001002a6c31 QMetaObject::activate(QObject_, QMetaObject const_, int, void**) + 97
1 StreamServer 0x000000010005d27b QHttpRequest::end() + 43 (moc_qhttprequest.cpp:192)
2 StreamServer 0x00000001000516c0 QHttpConnection::socketDisconnected() + 432 (qhttpconnection.cpp:82)
3 StreamServer 0x000000010005d899 QHttpConnection::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 217 (moc_qhttpconnection.cpp:57)
4 QtCore 0x00000001002a71ee QMetaObject::activate(QObject_, QMetaObject const_, int, void**) + 1566
5 QtNetwork 0x00000001005699f8 QAbstractSocket::disconnectFromHostImplementation() + 856

I have deleted request in responder, like in example.
After request is deleted it is used in QHttpConnection::socketDisconnected().

Cleanup needed in QHttpConnection::MessageComplete:
theConnection->m_request = 0;

Unable to upload pcks#12 certificate using QHttpServer

Hello nikhilm,
I am using "QHttpserver" to delelop Cplusplus rest API from last 3 month. I am new to use this server and i am facing some problem of upload file.
Issue list
1-
We are using QT Creator IDE for develop Cplusplus Rest API using “qhttpserver” http server . We are unable to import “pkcs#12” “.pfx” because this file bind with private key. Let us know how can we import “pkcs#12” .pfx file.
2-
We are using “qhttpserver” http server and it run on http protocol .We want to run on https protocol using ssl certificate . Let us know what is the process of enable https using ss.

send me a sample code of upload any file include “pkcs#12” . Certificate import is most important.

Interpreting username:password part of HTTP request

Hi
Do you have an idea how one could get the authority part of the request?
(https://en.wikipedia.org/wiki/URI_scheme#Generic_syntax)

Usually one would get this part through QUrl, but it isn't set in QUrl as QUrl is just build from the information you get from QHttpConnection::parseRequest() which gets the data from the QTcpSocket.
From the QTcpSocket I can only get the IP & Port.

Any ideas? This is so far the only thing I'm missing in this library.

QHttpResponse::write(QString) converts written data to UTF-8

Hello,
I found this to be confusing, because the result of QString::toUtf8::size is not the same size as QString::size when the string contains special unicode characters.
This messed up my "Content-Length" header.

What is wrong now:

resp->setHeader("Content-Length", str.size());
resp->end(str); // client will not get the whole string when it contains special chars

Here is a test to proof my case:

    QVERIFY(QString("☆☆☆").toUtf8().size() != QString("☆☆☆").toLatin1().size());
    QVERIFY(QString("☆☆☆").toUtf8().size() > 3);
    QVERIFY(QString("☆☆☆").size() == 3);
    QVERIFY(QString("☆☆☆").toLatin1().size() == 3);

My suggestion:

  • use QString::toLatin1 instead of utf8, since it wields the same result as QString::size
  • alternative: remove QHttpResponse::write(QString) and force the user to choose an encoding by having to use QHttpResponse::write(QByteArray)

Affected line: link

Current workaround:

QByteArray bytes = str.toUtf8();
resp->setHeader("Content-Length", bytes.size());
resp->write(bytes); // sends whole string with correct encoding
resp->end();

Replace or add CMake

Hi , Thanks for the repo; it's awesome.
I think adding CMake to the repository is very useful. if it's possible.
Thanks

possible memory leak in QHttpResponse::

I might be misunderstanding how this library works - however in the example code for bodydata we are recommended to use the following pattern:

Responder::Responder(QHttpRequest *req, QHttpResponse *resp)
....
    connect(m_resp, SIGNAL(done()), this, SLOT(deleteLater()));

This looks like a nice way to automatically delete the Responder when the QHttpResponse is deleted (which in turn was deleted when the underlying QHttpConnection disconnected)

However if the connection is closed mid-session (without QHttpResponse::end() being called), the QHttpResponse::done() signal is not emitted. This means that the Responder object does not get deleted, and we end up with memory leaking each time a connection is terminated by the client. The problem is caused by this code (I think):

void QHttpResponse::connectionClosed()
{
    m_finished = true;
    deleteLater();
}

So maybe the solution is to emit the done() signal in the connectionClosed() function.... but maybe that's not the intended semantics of done() ?

I solved this temporarily by connecting to the QHttpResponse::destroyed signal instead:

Responder::Responder(QHttpRequest *req, QHttpResponse *resp)
....
    connect(m_resp, SIGNAL(destroyed()), this, SLOT(deleteLater()));

It prevents the memory leaking at least. Hope this makes sense?

awesome little library btw

qhttprequest needs better memory management

While it is easy to say not to delete until end() has been emitted, library users may delete it anyway. There are points in qhttpconnection where this deleted m_request may be used, which is not good.

MemLeak

The QHttpRequest object is not deleted after a disconnect!

QHttpRequest::m_body always empty?

When i tried to receive some content sent via POST (which is as far as i understood in the HTTP body) QHttpRequest's m_body is always empty.

I'm not sure if this is a bug (didn't find any appendToBody(QByteArray) calls anywhere) or if i'm using the code wrong.

Can anyone confirm this ?

So i added two qDebug() s in QHttpConnection::parseRequest() at the end of the while loop. This is their output:

    qDebug() << "Parsed HTTP Connection Request: komplett:" << arr;
    qDebug() << "Parsed HTTP Connection Request: body:" << this->m_request->body();
Parsed HTTP Connection Request: komplett: "POST /login.ass HTTP/1.1 Host: localhost:4225 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0 Accept: _/_ Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Referer: http://localhost:4225/ Content-Length: 117 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache

user_b64=YXNk&passw_b64=MjAyY2I5NjJhYzU5MDc1Yjk2NGIwNzE1MmQyMzRiNzA%3D&desktop_env=ZGVuaWJhX2Rlc2t0b3BfY2xhc3NpY28%3D"

Parsed HTTP Connection Request: body: ""

segfault

I'm running a load test on a rest api I implemented based on the project and I'm running into a seg fault.

This is my request handling code -

RestApi::RestApi(Controller* controller)
    : controller_(controller)
{
    QHttpServer *server = new QHttpServer(this);
    connect(server, SIGNAL(newRequest(QHttpRequest*, QHttpResponse*)),
            this, SLOT(handleRequest(QHttpRequest*, QHttpResponse*)));

    server->listen(QHostAddress::Any, 8080);
}

void RestApi::handleRequest(QHttpRequest *req, QHttpResponse *resp)
{
    new Responder(req, resp, controller_);
}

Responder::Responder(QHttpRequest *req, QHttpResponse *resp, Controller* controller) :
    req_(req), resp_(resp), controller_(controller) {


    connect(req, SIGNAL(data(const QByteArray&)), this, SLOT(accumulate(const QByteArray&)));
    connect(req, SIGNAL(end()), this, SLOT(parse_json()));
    connect(resp_, SIGNAL(done()), this, SLOT(deleteLater()));
    connect(this, SIGNAL(handleRequest(QJsonDocument&)), controller_, SLOT(handleRequest(QJsonDocument&)));
}

void Responder::parse_json()
{
   QJsonParseError error;
   QJsonDocument json_doc = QJsonDocument::fromJson(req_message, &error);
   if (error.error != QJsonParseError::NoError) {
       resp_->writeHead(500);
       resp_->end(error.errorString().toUtf8());
   } else {
       resp_->writeHead(200);
       resp_->end();
       emit handleRequest(json_doc);
   }
}

void Responder::accumulate(const QByteArray &array) {
    req_message.append(array);
}

error:

Program received signal SIGSEGV, Segmentation fault.
0x76126f68 in QMetaObject::activate(QObject_, int, int, void_) ()
from /usr/local/Qt-rasp2-5.5.0/lib/libQt5Core.so.5
(gdb) bt
#0 0x76126f68 in QMetaObject::activate(QObject_, int, int, void_
) ()

from /usr/local/Qt-rasp2-5.5.0/lib/libQt5Core.so.5
#1 0x0001e244 in QHttpRequest::end (this=0x6b2f0720) at moc_qhttprequest.cpp:271
#2 0x76126c04 in QMetaObject::activate(QObject_, int, int, void_*) ()

from /usr/local/Qt-rasp2-5.5.0/lib/libQt5Core.so.5
#3 0x763f0610 in QAbstractSocket::disconnectFromHost() () from /usr/local/Qt-rasp2-5.5.0/lib/libQt5Network.so.5
#4 0x763f1c34 in ?? () from /usr/local/Qt-rasp2-5.5.0/lib/libQt5Network.so.5
#5 0x763f1c34 in ?? () from /usr/local/Qt-rasp2-5.5.0/lib/libQt5Network.so.5

Backtrace stopped: previous frame identical to this frame (corrupt stack?)

cors

how can I add cors information to header?

qhttpserver and reading from another socket

I am using qhttpserver to develop a client application that will reside on a device that also contains another application that is the server. The client communicates to the server using a socket.

I am running into a problem where the client sends data to the server from within qhttpserver but the responses are not received until the QHttpResponse is sent.

Could someone provide me with an example of writing to a socket and then reading the response from within qhttpserver?

Thanks in advance

have a error when i compile source

have a error in when compile source

error source(qhttpserver-master\http-parser\http_parser.c):
int hasBody = parser->flags & F_CHUNKED ||
(parser->content_length > 0 && parser->content_length != ULLONG_MAX);
if (parser->upgrade && (parser->method == HTTP_CONNECT ||
(parser->flags & F_SKIPBODY) || !hasBody)) {
/* Exit, the rest of the message is in a different protocol. */
UPDATE_STATE(NEW_MESSAGE());
CALLBACK_NOTIFY(message_complete);
RETURN((p - data) + 1);
}
the reason of error:
Error: C2143: syntax error : missing ';' before 'type'
Error: C2065: 'hasBody' : undeclared identifier

How to get data from Main Class function when replying

How to get data from Main Class function (public variable in main class) when do the replying (in class Responder)?

From your example script of the bodydata (https://github.com/nikhilm/qhttpserver/tree/master/examples/bodydata), i added the public varible (example QString code = "123456") on class BodyData. And when receiving data, i can not get the value of variable "code" in class Responder. The main goal is to send value of "code" (123456) in class Responder. Please help me. I will appriciate your help.

Thank you.

HTTPS Support

Hi,

I like your work. I want to request support for secured HTTP (HTTPS) connection.

By the way, QSslSocket can support "unencrypted" mode, so there will be no problem in migrating from QTcpSocket to QSslSocket. I think more work will be focused on how to make the QTcpServer support it.

Thank you and more powers!

a better approach to solve multithreading, SSL (HTTPS) and better memory management

at the moment QHttpServer implements a QHttpServer::newConnection() slot and connects a QTcpServer::newConnection() signal to that slot.

it's convenient but IMHO it's far better to:

  • let QHttpServer inherit directly from QTcpServer (instead of containing a pointer to it). in fact, an http-server is-a socket-server.
  • then let users to override QTcpServer::incomingConnection(int socketDescriptor) function.
  • now it's quite easy to try some SSL idea:
void
SampleHttpsServer::incomingConnection(int socketDescriptor) {
    QSslSocket* sok = new QSslSocket(this);
    sok->setSocketDescriptor(socketDescriptor);

    QHttpConnection *connection =
        new QHttpConnection(m_tcpServer->nextPendingConnection(), this);
    connect(connection, SIGNAL(newRequest(QHttpRequest *, QHttpResponse *)), this,
            SIGNAL(newRequest(QHttpRequest *, QHttpResponse *)));
}
  • or to implement a multi-threaded server:
class SampleConnectionThread : public QThread
{
    int  isocketDescriptor;

public:
    explicit SampleConnectionThread(int socketDescriptor, QObject *parent) : QThread(parent), isocketDescriptor(socketDescriptor) {
    }

    void run() {
        // socket and connection have to be created in another thread.
        QTcpSocket      sok;
        sok.setSocketDescriptor(isocketDescriptor);
        QHttpConnection conn(&sok);
        QObject::connect(&sok,        SIGNAL(disconnected()),
                         this,        SLOT(quit()));
        // other stuff

        exec();  // enters event loop
    }
};

void
SampleThreadedHttpServer::incomingConnection(int socketDescriptor) {
    SampleConnectionThread *thread = new SampleConnectionThread(socketDescriptor, this);
    QObject::connect(thread,       SIGNAL(finished()),
                     thread,       SLOT(deleteLater()));
    thread->start();
}

in some scenario we need multi-threading, ex when there are some blocking Db queries for each request, ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.