0

This is a follow up of this question. At first I thought the issue was resolved after checking out the example from the Qt wiki (I use the same code without a single change). However it appears that it's the URL that is the culprit. I tried using the links provided in this answer to test my http GET request. Using the Http Requester (Firefox addon for Http requests (GET, POST etc.)) and curl shows no issues with this link^:

$~: curl --request GET --url "http://httpbin.org/ip" 

For some reason Qt gets stuck and the readyRead()/finished() signals are never emitted.

As a result the request gets cancelled after some time due to socket timeout...For something that is really small and opened by Firefox in less than a second.

I'm far from an expert when it comes to Http stuff. I'd like to know why this behaviour occurs in Qt while there is no sign of it when working with other tools.

EDIT: I've also tested the problematic URLs using Python and its urllib

import urllib.request
res = urllib.request.urlopen("http://httpbin.org/ip").read().decode("utf-8") 

import xml.etree.ElementTree as ET
doc = ET.fromstring(res)

and it works just fine. Clearly there is something with Qt going on and/or me missing something when using it.

EDIT2: I've also tried another test service for HTTP requests - https://postman-echo.com. With curl there is no problem:

$~: curl --request GET --url "https://postman-echo.com/get?foo1=bar1&foo2=bar2"

For my surprise though there is no problem with Qt either! The only thing that I see here as a huge difference is that postman-echo.com uses HTTPS while the other URLs I've tried were HTTP. I exclude the https://www.qt.io which was the default URL in the Qt example and worked just fine (though it didn't have any parameters).

rbaleksandar
  • 8,713
  • 7
  • 76
  • 161
  • You still need to show your code in order to help us understand the problem. – vahancho Oct 13 '17 at 07:47
  • @vahancho I use the exact same code from the Qt wiki. Not a single line changed. – rbaleksandar Oct 13 '17 at 07:48
  • In order to get the root cause of the problem you have to answer on the following questions: 1) Does my application send proper requests?, 2) Does application get responses from the server? 3) Does the application properly handle responses it gets from the server? – vahancho Oct 13 '17 at 07:56
  • The example works with many other URLs I've tried including downloading big files (like the ISO image for Ubuntu 17.04), which means that in *general* it does send proper a request, gets the response from the server and handles it without any problem. However I have no idea how to check if the proper request is being sent in the case I've described above. I do know that things work asynchronously so I do expect delays in getting the response from the server. – rbaleksandar Oct 13 '17 at 08:03
  • Do you handle errors after sending requests to that server? It might be, that the server tries to recognize "who" sends the requests, and if it's unknown, just refuses to respond properly. You could check that idea too. – vahancho Oct 13 '17 at 08:20
  • The only error handling is done through the `sslErrors()` signal of `QNetworkAccessManager` and the `sslErrors()` slot of the application itself. It doesn't get triggered at all. I'll see what other possible ways there are to retrieve error data. – rbaleksandar Oct 13 '17 at 08:44
  • Connected the `error()` signal to a slot in the application but it never gets triggered so no errors to report either. – rbaleksandar Oct 13 '17 at 08:59

2 Answers2

0

Try executing that in an event loop. Here is something similar to what I do in a non-gui application:

QUrl req_url = QUrl(href);
QNetworkRequest request(req_url);

//request.setRawHeader("Content-Type", "application/json;utf8");
//q_nam is QNetworkAccessManager created earlier
QNetworkReply *reply = q_nam->get(request);

QEventLoop event_loop;
connect(q_nam, SIGNAL(finished(QNetworkReply * ) ), &event_loop, SLOT(quit() ) );
event_loop.exec(); // blocks stack until "finished()" has been called
event_loop.processEvents(QEventLoop::ExcludeUserInputEvents, 500 );//what events to processed and for how long
event_loop.exit();

QNetworkReply::NetworkError er = reply->error();
// ....continue handling
cantSleepNow
  • 9,691
  • 5
  • 31
  • 42
  • Doesn't work and I still get the socket timeout. Also the example from the Qt wiki is actually a widget but thanks for the effort. My own application will be console-based so it's good to know I need this too. – rbaleksandar Oct 13 '17 at 10:53
  • Just to make sure that I got it right - the URL is `http://bvg.hafas.de/bin/monitor_hci/stboard.exe/dn?input=9054102&start=1&output=xml` ? – cantSleepNow Oct 13 '17 at 11:10
  • Both don't work - httpbin.org and the one from bvg.hafas.de. I've tested the application with many other URLs and hadn't had a problem. But with these two...I don't know. – rbaleksandar Oct 13 '17 at 11:13
  • Ah, I think I have to use `QUrlQuery` since these URLs actually also contain parameters. *facepalm* – rbaleksandar Oct 13 '17 at 11:36
  • :) let me know how it goes – cantSleepNow Oct 13 '17 at 11:37
  • Not working. I tried even to split the path from the main URL. In addition using `QUrlQuery` I added the parameters to the URL. Printing it out showed me the same result as when I directly passed the URL to my `QUrl` as a string. The result - still not working. For the httpbin.org/ip for example I only have the path, no parameters at all. It seems that `QUrl` actually has internal parsing of the string that you pass and does the job automatically. – rbaleksandar Oct 13 '17 at 11:52
0

I forgot to mention that I'm behind. Frankly I feel rather stupid for missing this and also not checking through the guest network at work (which circumvents the stupid proxy). A colleague of mine tried using HTTPS instead of HTTP (which is the original link). The HTTPS is also something that the proxy just lets go through without any issues. And it worked.

However a more neutral solution is (as my colleagues found out) to use QNetworkProxyFactory::setUseSystemConfiguration(true) which takes the proxy configuration that I have system-wide.

rbaleksandar
  • 8,713
  • 7
  • 76
  • 161