About HTTP requests and PHP variables
-
I'm using a QNetworkAccessManager item to get a text file from an http server containing a list of ip addresses, in my main program I try to connect to those addresses and if it doesn't succeed the ip address is removed from the text file and this is the hard part. I developed a php script to delete the unresponsive ip from the list but it requires the ip to be passed as an argument through the url (the php GET method), the script works fine when accessed from a browser but when I try accessing it through my program using
@
// Examples definitions:
// QNetworkAccessManager http;
// QString Giocatori::PathToHttpServer="http://myhost.com";
// QString ipnr="127.0.0.1";QUrl url(Giocatori::PathToHttpServer+"/NotResponding.php");
url.addQueryItem("IPNotResponding",ipnr);
http.get(QNetworkRequest(url));
@it doesn't work at all. I already tried to feed him the complete url string but it doesn't change behavior.
I searched this and other forums and looked at the examples but I didn't find anything that helped, please save me!
Thanks in advance -
Is your URL working on the command line? You can try with tools like curl or wget.
-
Does the
QNetworkAccessManager
live long enough to actually execute the request ? You seem to allocate it on the stack, and it might be destroyed before the control is given back to the event loop.And are you even running an event loop (QCoreApplication::, QThread::, QEventLoop:: or QApplication::exec() ) ?
-
@Volker: I tried with curl and it works fine, this is worrying :(
@alexisdm: The definitions I gave there were just examples to let you understand what type were the variables, they are not the true definitions, the manager is allocated on the heap, it's part of a widget and I started the event queue and the other functions that use it work perfectly, the problem arises just when I try to pass variables through the url
-
Does your php script or web server make a HTTP redirection ?
QNetworkAccessManager doesn't handle redirections, you have to check the http status code from the QNetworkReply ("attribute()":http://qt-project.org/doc/qt-4.8/qnetworkreply.html#attributex with "QNetworkRequest::HttpStatusCodeAttribute":http://qt-project.org/doc/qt-4.8/qnetworkrequest.html#Attribute-enum) and relaunch another request with the new URL (the browsers, curl and wget do that automatically).
-
Now my network manager handles redirections:
@GestoreServers::GestoreServers(QObject parent)
: QObject(parent)
{
http=new QNetworkAccessManager(this);
connect(http, SIGNAL(finished(QNetworkReply)), this, SLOT(httpDone(QNetworkReply*)));
}@
@void GestoreServers::httpDone(QNetworkReply* reply)
{
QString fetched("");
if (reply->error() != QNetworkReply::NoError) {
emit erroreConnessione();
errore=true;
}
else{
QUrl redirectUrl=reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (!redirectUrl.isEmpty() && redirectUrl!=OldUrl){
OldUrl=redirectUrl;
getFile(OldUrl);
}
else{
QTextStream in(reply);
while(!in.atEnd()) {
fetched.append(in.readLine());
fetched.append('\n');
}
}
}
emit done(fetched);}@
but still no luck :( -
Forgot to mention that the redirection is never executed, I put a debug breakpoint in that function to check if the redirection really happened and neither my host nor my script (about the script I was sure a priori) ever redirect the url. I'm beginning to become desperate :(
-
You could use a network sniffer (wireshark) to see if there is any difference between what Qt and curl are sending to the server.
-
The sniffer was helpfull. it seems like my request isn't sent at all. so it never emits the finished signal :(
What did I do wrong?
-
i solved one problem but another arises. I managed to successfully get to the script with the correct variable, I did it just by deleting the QNAM each time if finishes processing a request and recreate it when a new request is sent:
@void GestoreServers::getFile(const QUrl &url)
{
QNetworkRequest indirizzo(url);
http=new QNetworkAccessManager(this);
connect(http, SIGNAL(finished(QNetworkReply*)), this, SLOT(httpDone(QNetworkReply*)));
http->get(indirizzo);
}
void GestoreServers::httpDone(QNetworkReply* reply)
{
QString fetched("");
if (reply->error() != QNetworkReply::NoError) {
emit erroreConnessione();
}
else{
QUrl redirectUrl=reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (!redirectUrl.isEmpty() && redirectUrl!=OldUrl){
OldUrl=redirectUrl;
getFile(OldUrl);
}
else{
QTextStream in(reply);
while(!in.atEnd()) {
fetched.append(in.readLine());
fetched.append('\n');
}
}
}
emit done(fetched);
http->deleteLater();}@
now the problem is that the requests without variables passed emits the finished() signal, but when I access the script passing the variable the finished signal is never emitted even if the script actually worked :( -
QNAM is not designed to be deleted and re-created frequently. You just need to keep track of the requests and replies and connect the signals to some slots that handle the data.
-
[quote author="Volker" date="1335806200"]QNAM is not designed to be deleted and re-created frequently. You just need to keep track of the requests and replies and connect the signals to some slots that handle the data.[/quote]
That's what i did before, but after I send a get once and it emits a finished() signal using get on the same object with another url doesn't seems to work, as I said before the request wasn't sent at all... any idea why that happened?
-
You need to create a new QNetworkRequest and use that on the existing QNAM. Make sure to connect to the signals of the newly returned QNetworkReply (or to those of the QNAM).