QNetworkAccessManager and Python http server
-
I'm making a GUI application that works with PHP back-end using JSON-RPC.
It is a good thing to make some test server for myself, because the main server is being developed by another man and it's not always available. I've found python's http.server and made a simple CGI application that runs as a CGI script. CGI application receives text input, parses it as JSON-RPC and returns some output based on method and parameters. As usual.
I'm using QNetworkAccessManager to handle HTTP requests. But it fails to work with Python test server (but it works with main PHP server on Apache).
What it SHOULD look like (and how it actually looks for the Apache):
- Client connects via TCP, sends HTTP header and HTTP payload (json).
- Server starts the CGI binary, reads its output, sends back HTTP header and HTTP payload.
- Client reads the input, parses out the payload and gives it to the main program somewhere in the slot connected to "finished" signal from the manager. The program can parse this json and read the reply:
POST /rpc HTTP/1.1 Content-Type: application/json-rpc Accept: application/json-rpc Content-Length: 80 Connection: Keep-Alive Accept-Encoding: gzip, deflate Accept-Language: ru-RU,en,* User-Agent: Mozilla/5.0 Host: <...> {"id":0,"jsonrpc":"2.0","method":"auth","params":{"ID":"user","pin":"1234"}}HTTP/1.1 200 OK Date: Mon, 23 Oct 2017 19:51:52 GMT Server: Apache/2.4.6 (CentOS) PHP/7.0.22 X-Powered-By: PHP/7.0.22 Content-Length: 41 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: application/json {"id":"0","result":false,"jsonrpc":"2.0"}
- Everything is done as a single TCP connection.
However, Python sends HTTP header before the client's payload is received, which shreds everything into pieces:
- QNetworkAccessManager actually makes THREE TCP connections.
- The second connection is CLOSED by the client.
- The first and the third yields fine output, however reply header comes before request's payload:
POST /cgi-bin/rpc.exe HTTP/1.1 Content-Type: application/json-rpc Accept: application/json-rpc Content-Length: 80 Connection: Keep-Alive Accept-Encoding: gzip, deflate Accept-Language: ru-RU,en,* User-Agent: Mozilla/5.0 Host: 192.168.11.133:8000 HTTP/1.0 200 Script output follows Server: SimpleHTTP/0.6 Python/3.5.4 Date: Mon, 23 Oct 2017 18:10:43 GMT {"id":0,"jsonrpc":"2.0","method":"auth","params":{"ID":"terminal","pin":"1234"}}{"id":0,"jsonrpc":"2.0","result":true}
- Finally,
void myClass::httpFinished(QNetworkReply *r) { QByteArray s = r->readAll(); //.... }
Variable "s" is empty. No data is returned by QNetworkReply.
Is there a way to handle this, or I should install something heavy like Apache on my laptop?
For example, can I force QNetworkAccessManager to send the whole request (header + payload) as a single packet?I've tried to make a simple HTTP request using QTcpSocket. I send everything, than receive everything until the server disconnects. Everyting works fine.
Thanks.P.S. I have a Wireshark dump of an interchange between Qt application and Python server, but I can't attach it to the post. The listings above are taken from Wireshark.
-
I used same python http server to expose the my directory. It worked fine with same kind of setup. Keeping this in mind, since it is response issue from HTTP server side, can you check is there some logic issue or some other request is sent in-between from client to server ?
-
There's nothing wrong with GET request, since it has no payload, just a header.
Problems begin with POST.Server side is pretty simple, with one exception: it sends HTTP reply header ASAP and THEN launches CGI script.
Here is a Wireshark dump of an interconnection with python server: http://umod47.ru/qtfail.pcapng