PDA

View Full Version : A Qhttp::host() && QHttp::request() fully functionnal example ?



Nyphel
27th March 2007, 14:29
Hi,

I'm having troubles with the QHttp class.

I need to use the QHttp class in order to fill a HTTPs form on our Intranet network.
So, since this morning, I'm traning the QHttp class... But the fact we use HTTPs seems not to help me.
I would like to test it with an external web form, like www.google.com.

I'm testing all the source codes I have found, but I can't get the answer :(

As somebody a fully functionnal QHttp:: post() && QHttp:: request() example, that allow to fill the www.google.com form and see the result, please ?

Thanks for your help :)

jpn
27th March 2007, 20:16
Google's search form seems to use GET method so it should be something as simple as:


QHttp http("www.google.com");
http.get("/search?q=Qt");

You can use tools like LiveHTTPHeaders (http://livehttpheaders.mozdev.org/) to sniff HTTP requests.

Nyphel
28th March 2007, 08:34
Oh yes, thanks... :D
So, I need a Post() example ;)

I set a simple PHP script here (http://www.membres.lycos.fr/nyphel/Essais_stage/essai.php).
I takes a login and a password.
The sumbit button calls the same page with the post() method, and display the results.
If the two fields are filed with "root", the answers says "OK".

With this simple script I can train my code, and if you want, you can help me :).

Here is the essai.php source code :

<html>
<head></head>
<body>

<?php
$log_id=$_POST['a'];
$log_mdp=$_POST['b'];

echo("Login : $log_id <br>");
echo("Password : $log_mdp");

if($log_id=='root' && $log_mdp=='root'){echo("<br><br><B>Good identifiers !</B>\n");}
else{echo("<br><br><B>Bad indentifiers !</B><br>(Only Login=\"root\" and Password=\"root\" will be accepted)");}
?>

<br><br><br><hr><br>

<form action='http://www.membres.lycos.fr/nyphel/Essais_stage/essai.php' method='post'>
<br>Login : <input type='text' name='a' value=''><br>
<br>Password : <input type='text' name='b' value=''><br>
<br><input type='submit' name='c' value='submit'>
</form>

</body>
</html>

And now the headers informations given by LiveHTTPHeaders (http://livehttpheaders.mozdev.org/index.html) :

REQUEST :


REQUEST : GET /nyphel/Essais_stage/essai.php HTTP/1.1
HOST : www.membres.lycos.fr
USER AGENT : Mozilla/5.0 (Windows; U; Windows NT 5.0; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
ACCEPT : text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
ACCEPT-LANGUAGE : fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
ACCEPT-ENCODING : gzip,deflate
ACCEPT-CHARSET : ISO-8859-1,utf-8;q=0.7,*;q=0.7
KEPP ALIVE : 300
PROXY-CONNECTION : keep-alive
COOKIE : adFrameForcePHP=1; LBC=1f58389ba9f43fbd0c089c99bd202084; utgc=Z2Q9TTpwY29kZT03ODQ1MTpkb2I9MTk4NDA1MDg%3D; lsua=bnlwaGVsbDpOeXBoZWw6TGUgQmVsOmZy; adsprefs=31%3A313938342d30352d3038%3A3738343531%3A 460a193e; lsud=c34a2f6e668bf6648c112d85c818794b%3A1175066941


ANSWER :


RESPONSE : HTTP/1.0 200 OK
DATE : Wed, 28 Mar 2007 07:35:43 GMT
SERVER : Apache
X-POWERED-BY: PHP/4.3.2
CONTENT-TYPE : text/html
X-CACHE : MISS from www.membres.lycos.fr, MISS from melita.bayonne.fr
CONTENT-ENCODING : gzip
CONTENT-LENGHT : 1446
X-CACHE-LOOKUP : MISS from melita.bayonne.fr:3128

jpn
28th March 2007, 10:42
I expected it to be this simple:


QHttp http("www.membres.lycos.fr");
QByteArray content("a=root&b=root&c=submit");
http.post("/nyphel/Essais_stage/essai.php", content);


But it turns out that the content type must be set appropriately so it ended up like this:


// content
QByteArray content("a=root&b=root&c=submit");

// header
QHttpRequestHeader header("POST", "/nyphel/Essais_stage/essai.php");
header.setValue("Host", "www.membres.lycos.fr");
header.setContentType("application/x-www-form-urlencoded"); // important
header.setContentLength(content.length());

// request
QHttp http("www.membres.lycos.fr");
http.request(header, content);

Nyphel
28th March 2007, 11:10
Thanks jpn, but how do you see the response (answer) ?

I have tried to redirect the response to a file, but nothing has been writen into.

http_bis.request(header, content, file);

And why the content-type isn't "text/html" ?
The LiveHTTPHeaders plug-in saif that the Content-type of the response was "text/html".

jpn
28th March 2007, 11:27
Thanks jpn, but how do you see the response (answer) ?

I have tried to redirect the response to a file, but nothing has been writen into.

http_bis.request(header, content, file);
I used QHttp::readAll() and debug output, but I have now attached a compilable example which writes the result into a file called result.html.



And why the content-type isn't "text/html" ?
The LiveHTTPHeaders plug-in saif that the Content-type of the response was "text/html".
It's the content type of the answer sent by the server. The content type of the request is what matters, that's what we build by hand.

Nyphel
28th March 2007, 11:49
Thanks for your help jpn, but the file isn't created on my computer.
Perhaps there is connection error, due to the proxy or the port.
I'll try to check it out :(.

In my previous post I said the file was created, but it was created by a simple fileOpen() ;).
I used Ethereal to analyze my network, and I noted that no HTTP packet were emitted.

Now I understand better what happens, and why everybody says me : "Don't use post(), use request() !". The post() don't allow me to set my own headers like it is necessary :)

Thanks for all, I'll try to do it :)

Nyphel
28th March 2007, 13:21
That's done !

Thanks a lot JPN, you helped me so much !
Now I understand well the QHttp class :).

My network (Intranet, proxy settings, etc.) didn't help me, and drove me in error.




:)

Nyphel
2nd April 2007, 09:22
Hi :o

Here is your main.cpp :

#include <QtCore>
#include <QtDebug>
#include <QtNetwork>
#include <iostream>

int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);

// content
QByteArray content("a=root&b=root&c=submit");

// header
QHttpRequestHeader header("POST", "/nyphel/Essais_stage/essai.php");
header.setValue("Host", "www.membres.lycos.fr");
header.setContentType("application/x-www-form-urlencoded"); // important
header.setContentLength(content.length());

// request
QFile file("result.html");
QHttp http("www.membres.lycos.fr", 80);
http.setProxy("172.16.1.1", 8080);
http.request(header, content, &file);

a.connect(&http, SIGNAL(done(bool)), &a, SLOT(quit()));
return a.exec();

}




Here is my HTTPChecker class :


main.cpp

#include <QApplication>
#include <QtGui>

#include "HTTPChecker.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

HTTPChecker *httpChecker = new HTTPChecker();
httpChecker->Check();

return app.exec();
}
HTTPChecker.h

#ifndef HTTPChecker_h
#define HTTPChecker_h

#include <QObject>
#include <QHttp>

#include <QtCore>
#include <QtDebug>
#include <QtNetwork>
#include <iostream>

class HTTPChecker : public QObject
{
Q_OBJECT

public:
HTTPChecker();
void Check();

private slots:
void SLOT_showPage();

private:

};

#endif // HTTPChecker_h
HTTPChecker.cpp

#include "HTTPChecker.h"

HTTPChecker::HTTPChecker() : QObject()
{
}

void HTTPChecker::Check()
{
// content
QByteArray content("a=root&b=root&c=submit");

// header
QHttpRequestHeader header("POST", "/nyphel/Essais_stage/essai.php");
header.setValue("Host", "www.membres.lycos.fr");
header.setContentType("application/x-www-form-urlencoded");
header.setContentLength(content.length());

// request
QFile file("result.html");
QHttp http("www.membres.lycos.fr", 80);
http.setProxy("172.16.1.1", 8080);
http.request(header, content, &file);

connect(&http, SIGNAL(done(bool)), this, SLOT(SLOT_showPage()));
}

void HTTPChecker::SLOT_showPage()
{
std::cout << "\n\tOK !" << std::endl;
exit(0);
}



I don't understand why, but :
- your main.cpp works well and creates the result.html file
- my class doesn't create any file ("OK !" is displayed in the console... Immediatly :( )

jpn
2nd April 2007, 09:29
You have to allocate the QHttp and QFile objects on the heap (with keyword "new"). Otherwise they get automatically destroyed while going out of scope at the end of HTTPChecker::Check(). In my example, "a.exec()" blocks as long as the application is running so they won't get destroyed before the application quits and so it works.

Nyphel
2nd April 2007, 09:37
Oh yes... That's true !
I forbid that the request was scheduled and performed asynchronously...


If the IO device to is not 0, the content data of the response is written directly to the device. Make sure that the to pointer is valid for the duration of the operation (it is safe to delete it when the requestFinished() signal is emitted).

The function does not block and returns immediately. The request is scheduled, and its execution is performed asynchronously. The function returns a unique identifier which is passed by requestStarted() and requestFinished().

Thank you, onemore time... :)

krunoslav
20th January 2009, 14:10
There is also one nice solution for posting to web forms: http://www.tuckdesign.com/sources/Qt