QUrlQuery append? - c++

Is it possible to use QUrlQuery to append data without striping the url?
Using the code bellow will strip everything after the "?" and
the result is:
https://foobar.com/Info.xml.aspx?userdata=1234
I would like to get:
https://foobar.com/Info.xml.aspx?user=jack&userdata=1234
QUrl url("https://foobar.com/Info.xml.aspx?user=jack&");
QString data = "1234";
QUrlQuery query;
query.addQueryItem("userdata", data);
url.setQuery(query);
I'm asking because i need to make multiple calls, every time adding a new parameter and "building" the url from scratch every time is annoying.

You have to get the query and then add the item:
QUrl url("https://foobar.com/Info.xml.aspx?user=jack&");
QString data = "1234";
QUrlQuery query(url.query());
query.addQueryItem("userdata", data);
url.setQuery(query);
qDebug()<<url;
Output:
QUrl("https://foobar.com/Info.xml.aspx?user=jack&userdata=1234")

Related

Add dynamic variables to an url

I would like to add dynamic variables to an url example:
QNetworkRequest req( QUrl( QString("http://website.com/?test=1&id=1") ) );
But when i try this:
// the HTTP request
varUrl = "http://website.com/?test=";
varUrl += info;
varUrl += "&id=";
varUrl += info_2;
QNetworkRequest req( QUrl( QString(varUrl) ) );
QNetworkReply *reply = mgr.get(req);
eventLoop.exec(); // blocks stack until "finished()" has been called
i get this error:
The error message you posted is partly unrelated. Your actual problem is this:
QNetworkRequest req( QUrl( QString(varUrl) ) );
This is treated as a function declaration. This is a corner case in C++ and it's commonly referred to as the "most vexing parse". See https://en.wikipedia.org/wiki/Most_vexing_parse for an explanation.
In any event, use the QUrl::fromUserInput() static function instead of passing the query string directly. This will encode the query correctly (otherwise you'd need to manually encode the query correctly by hand.) So in short, change the above line to:
QNetworkRequest req(QUrl::fromUserInput(varUrl));
This also fixes the parsing issue; the above is treated correctly like a variable definition, not a function declaration, and your code should now compile fine.
As a side-note, you can use the QString::arg() function to construct your string in one go, without having to use append (+=) operations. So you can construct your URL string like this:
varUrl = QString("http://website.com/?test=%1&id=%2").arg(info).arg(info_2);
%1 will be replaced with the contents of info, and %2 with the contents of info_2.
According to the documentation:
The QUrlQuery class provides a way to manipulate a key-value pairs in
a URL's query.
It is used to parse the query strings found in URLs like the
following:
Posible solution is to use QUrlQuery:
QString info = "1";
QString info_2 = "1";
QUrl url("http://website.com/");
QUrlQuery query;
query.addQueryItem("test", info);
query.addQueryItem("id", info_2);
url.setQuery(query);

Qt QUrlQuery param split

I use the Qt v5.5. I need http get a request like this
QUrlQuery urlQuery;
urlQuery.setQuery("https://lalala.com/login");
urlQuery.addQueryItem("submit", "");
urlQuery.addQueryItem("email", "email#email.com");
urlQuery.addQueryItem("pass", "unbelievable_password");
when I call urlQuery.query(); the url is
"https://lalala.com/login&submit=&email=email#email.com&pass=unbelievable_password"
the param "submit" is the first param, it need use '?' split the param name, but the param is split by '&'.
You want to get the URL into a QUrl, then add query items on that -- and not have the URL as a query item itself!
QUrl url("https://www.foo.com");
QUrlQuery query;
query.addQueryItem("email", "foo#bar.com");
query.addQueryItem("pass", "secret");
url.setQuery(query);
qDebug() << url;
Correctly prints
QUrl("https://www.foo.com?email=foo#bar.com&pass=secret")
Looks like there's been discussion here on SO already. In general it looks as though any "sub-delims" should be accepted with or without a value: https://www.rfc-editor.org/rfc/rfc3986#appendix-A
Truth is, it's too bad that the QUrlQuery doesn't have the option for a value-less query without a trailing equal sign

C++ - QWebView Formatting Url as (string,QUrl)

I am trying to set QwebView's Url as "http://" and other part of url entered from linedit. Here's my function:
void MainWindow::on_git_clicked()
{
QUrl adrs;
adrs=ui->lineEdit->text();
ui->webView->setUrl(QUrl("http://" + adrs);
}
But it does nothing. But it was working on Python with same way. Thanks for help.
How about this, since your using QUrl and trying to append it to "http://" why not just use a QString instead? this might be your problem
QString adrs(ui->lineEdit->text());
ui->webview->setURL(QUrl("http://" + adrs));

QNetworkRequest URL containing '?' - not requesting properly because of QUrl encoding

I have the next code to make a request:
void HTTPClient::post(QString connectionString, QHttpMultiPart* _multiPart, bool returnProgress) {
QUrl url;
if (ssl)
url.setScheme("https");
else
url.setScheme("http");
url.setHost(host);
url.setPort(port);
url.setPath(connectionString);
url.setUrl(url.toEncoded());
QNetworkRequest request(url);
request.setRawHeader("User-Agent", QCoreApplication::applicationName().toLatin1());
/*...irrelevant code...*/
}
The requested url should be
https://somewebpage.domain:443/REST/login.php?method=login_md5
but the QNetworkRequest requests this one despite I set the url as encoded (debugging url.toEncoded() prints the '?' correctly):
https://somewebpage.domain:443/REST/login.php%3Fmethod=login_md5
This results in a 404 not found page. I have tried setting the url with url.toString() and just url, but the '?' keeps messing up. What can I do to request the link properly?
I have tried building the QUrl in the constructor like this:
QUrl url("https://"+host+port+connectionString);
But results in the next string:
https://somewebpage.xn--domain-efa/REST/login.php?method=login_md5
You can try QUrl::fromEncoded
url.setUrl( QUrl::fromPercentEncoding(url.toEncoded()));
Parses input and returns the corresponding QUrl. input is assumed to
be in encoded form, containing only ASCII characters.
to correctly handle characters.
The encoded URL seems valid, maybe a problem with your webserver?
You can setPath() and setQuery() separatly. What come before the '?' is the path and after is the query arguments.
const QStringList path_part = path.split('?');
url.setPath(path_part.at(0));
if(path_part.size() > 1)
url.setQuery(path_part.at(1));

How can I POST data to a url using QNetworkAccessManager

I have a webservice that I need to POST some data to using Qt.
I figured that I can use a QByteArray when POSTing to the web service.
My question is, how can I format this array in order to be parsed correctly at the other end?
This is the code I have so far:
// Setup the webservice url
QUrl serviceUrl = QUrl("http://myserver/myservice.asmx");
QByteArray postData;
/*
Setup the post data somehow
I want to transmit:
param1=string,
param2=string
*/
// Call the webservice
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*)));
networkManager->post(QNetworkRequest(serviceUrl), postData);
Thanks!
Since some parameters and values might need to be utf-8 and percent encoded (spaces, &, =, special chars...), you should rather use QUrl (for Qt 4) or QUrlQuery (for Qt 5) to build the posted string.
Example code for Qt 4:
QUrl postData;
postData.addQueryItem("param1", "string");
postData.addQueryItem("param2", "string");
...
QNetworkRequest request(serviceUrl);
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded");
networkManager->post(request, postData.encodedQuery());
and for Qt 5:
QUrlQuery postData;
postData.addQueryItem("param1", "string");
postData.addQueryItem("param2", "string");
...
QNetworkRequest request(serviceUrl);
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded");
networkManager->post(request, postData.toString(QUrl::FullyEncoded).toUtf8());
Starting with Qt 4.8 you can also use QHttpMultiPart if you need to upload files.
I used:
QByteArray postData;
postData.append("param1=string&");
postData.append("param2=string");
So & instead of newline after each parameter.
Updating alexisdm answer to Qt5:
// Setup the webservice url
QUrl serviceUrl = QUrl("http://your.url");
QByteArray postData;
QUrlQuery query;
query.addQueryItem("param1","string1");
query.addQueryItem("param2","string2");
postData = query.toString(QUrl::FullyEncoded).toUtf8();
// Call the webservice
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
connect(networkManager, SIGNAL(finished(QNetworkReply*)),
SLOT(onPostAnswer(QNetworkReply*)));
QNetworkRequest networkRequest(serviceUrl);
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
networkManager->post(networkRequest,postData);
Don't forget to include
QT += network
in .pro.
the actually answer is
QByteArray postData;
postData.append("param1=string&");
postData.append("param2=string");
NOTE: use "&" here!!!.
I didn't notice Juha's answer here, and waste much time on testing my code using the ",\n" approach.
Please change the correct answer to Juha's.
Here is another way to handle this, i am using your code also to give a complete code:
// Setup the webservice url
QUrl serviceUrl = QUrl("http://myserver/myservice.asmx");
QByteArray postData;
QUrl params;
params.addQueryItem("param1","string1");
params.addQueryItem("param2","string2");
postData = params.encodedQuery();
// Call the webservice
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*)));
networkManager->post(QNetworkRequest(serviceUrl), postData);
QByteArray postData;
postData.append("param1=string,\n");
postData.append("param2=string\n");