PDA

View Full Version : QNetworkAccessManager strange problem and behavior



creation
16th April 2013, 05:15
Hi all, I have strange problem with QNetworAccessManager.

I was trying to make a web service application with Qt with OAuth.
I manage to create my own OAuth service for my need based on QOAuth.
But the problem is not in OAuth.
The problem is in QNetworkAccessManager.


For example, there is this url that produced by OAuth,
if I open that url with QNetworkManager, like this

QNetworkAccessManager manager = new QNetworkAccessManager();
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));

// this is just for illustration not real consumer key and signature, the link produced by my OAuth
QString url = "https://www.my-example-site.com/oauth/content?oauth_consumer_key=1234567890&oauth_nonce=1824974157&oauth_signature=aBAy4KWZcs5762N4VPjiDj%2FtyqY%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1366080188&oauth_version=1.0";
QNetworkRequest request;
request.setUrl( url );
request.setRawHeader( "Content-Type", "application/x-www-form-urlencoded");
QNetworkReply *reply = manager->get( request );


It gave error "Host Require Authentication", "Error 401", "oauth_problem=invalid_signature"

but, if I generate new url with my OAuth and open that link on firefox, it will produce correct result.
I also try libcurl for c++.

CURL* curl;

curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();

// another illustration, not real consumer key and signature
curl_easy_setopt(curl, CURLOPT_URL, "https://www.my-example-site.com/oauth/content?oauth_consumer_key=1234567890&oauth_nonce=1824974157&oauth_signature=a9Vy4+CZcs5762N4VPjiDj%2FtyqY%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1366080200&oauth_version=1.0");
// curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writeCallback);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

curl_easy_perform(curl);

curl_easy_cleanup(curl);
curl_global_cleanup();
It gave correct result and no error.

I also try QHttp.

QHttp http = new QHttp();
connect(http, SIGNAL(requestFinished(int,bool)), this, SLOT(requestFinished(int,bool)));
http->setHost("https://www.my-example-site.com", QHttp::ConnectionModeHttps);
http->get("/oauth/content?oauth_consumer_key=1234567890&oauth_nonce=1824974157&oauth_signature=a9Vy4+ABCDEF62N4VPjiDj%2FtyqY%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1366080300&oauth_version=1.0");

It also gave correct result and no error.


So, what is wrong with the way I use QNetworkAccessManager?
I try it in qtcreator with Qt 4.8 and Qt 5, but no luck.
They gave same error result.

I want to keep on using QNetworkAccessManager, but if I can't resolve this problem, what should I do?
Should I use curl or QHttp? or is there another network library that I can use?

thank you.

ChrisW67
16th April 2013, 05:56
The first obvious difference is that you are issuing a GET but setting the content type to "application/x-www-form-urlencoded" which is typically only used for POST requests where a request body exists.

creation
16th April 2013, 06:11
The first obvious difference is that you are issuing a GET but setting the content type to "application/x-www-form-urlencoded" which is typically only used for POST requests where a request body exists.

Hi ChrisW67, thanks for reply.
Originally, it was like this


QByteArray authorizationHeader = paramsToString( *pm, ParseForHeaderArguments );
request.setRawHeader( "Authorization", authorizationHeader );
request.setRawHeader( "Content-Type", "application/x-www-form-urlencoded");
// request.setRawHeader( "Content-Type", "text/html; charset=utf-8;");
request.setRawHeader( "User-Agent", "My agent");

but when I comment all the lines, it still gave same error.
I've tried many things from yesterday, but still no luck.
I'm kind of out of idea here. :confused:

creation
16th April 2013, 17:08
I just figure out what happened.
The problem is in url.

I don't know how to explain correctly it, but I think QNetworkAccessManager has auto url encode function.

for example if my signature contain "+" and I encode it with toPercentEncoding() it will become "%2B",
When I call get(), it will be encoded again automatically by QNetworkAccessManager and become "%252B".
And that's why it gave "oauth_problem=signature_invalid".

So, I don't need to encode my url and this problem was solved and closed.