QNetworkRequest and Unable to Connect



  • Hello everybody :)

    I have problem with QNetworkRequest :( I need to login into web api and get information by query from web service but before anything I need to login into webserver.

    This is my query : QUrl url("http://www.whoisxmlapi.com/whoisserver/WhoisService?cmd=GET_DN_AVAILABILITY&domainName=" + Domain + "&username=" + username + "&password=" + password + "");

    Please Show me example of QNetworkRequest with Authentication. of course just for Qt 5 or later :)



  • It depends on how the server is demanding a username and password.

    If you try to fetch a page and get an HTTP response code 401 Unauthorized (possibly shows as QNetworkReply::ContentAccessDenied in your error handling slot) then you can probably just use QUrl::setUserName() and QUrl::setPassword() before you create and send your QNetworkRequest.

    If you mean the server sends you to a separate HTML page that has a form requesting user name and password then you need to make two separate requests in sequence:

    • An HTTP POST (or, less likely, GET) to the form's submit URL with encoded data to mimic submitting the authentication form. You will need to arrange keeping any cookies the server sends in the response.
    • An HTTP GET to fetch the resource you wanted.

    It seems to be moot because that URL returns results without authentication anyway.



  • Thank you for reply .., but I Need a example :)
    Of course i need to set Basic Authentication (Host requires Authentication)



  • You don't need an example for that URL; it doesn't require authentication.

    Example for the first option, straight from the documentation:
    [url=http://qt-project.org/doc/qt-5/qtnetwork-http-example.html]HTTP Example[/url]

    A generic example for the second option is difficult because every "authentication" page is different.



  • I Don't need to authentication !? but why ? i write a function for it on C++ .NET it's good work please see my code this code doesn't work without authentication :

    @
    String^ username = "username";
    String^ password = "password";
    String^ _template = "http://www.whoisxmlapi.com/whoisserver/WhoisService?cmd=GET_DN_AVAILABILITY&domainName=" + Domain + "&username="+username+"&password="+password+"";

    /* Requests the parsed WHOIS record for the domain

    • and returns an Array containing the parsed WHOIS properties.
    • @param string $domain The domain to lookup.
    • @return array
      */

    HttpWebRequest^ req = dynamic_cast<HttpWebRequest^>(WebRequest::Create(_template));
    String^ auth = "Basic " + Convert::ToBase64String(System::Text::Encoding::Default->GetBytes(username + ":" + password));

            req->PreAuthenticate = true;
            req->AuthenticationLevel = System::Net::Security::AuthenticationLevel::MutualAuthRequested;
            req->Headers->Add("Authorization", auth);
            req->UserAgent = "System &#40;C&#41; Name (R) System Console";
    

    String^ Res;

            WebResponse^ resp = req->GetResponse();
    

    Stream^ receiveStream = resp->GetResponseStream();
    StreamReader^ reader = gcnew StreamReader(receiveStream, Encoding::UTF8);

            String^ content = reader->ReadToEnd();//Read from server respouns.
    

    StreamWriter^ Writer = gcnew StreamWriter("Temp//domain.xml");
    Writer->Write(content);
    Writer->Close();

    XmlTextReader^ READER = gcnew XmlTextReader ("Temp//domain.xml");
    System::Xml::XmlDocument^ CompSpecs = gcnew System::Xml::XmlDocument();// Set up the XmlDocument (CompSpecs) //
    CompSpecs->Load(READER); //Load the data from the file into the XmlDocument (CompSpecs) //
    System::Xml::XmlNodeList^ NodeList = CompSpecs->GetElementsByTagName("DomainInfo"); // Create a list of the nodes in the xml file //
    Res = NodeList[0]->FirstChild->ChildNodes[0]->InnerText;

    return Res->ToString();
    @

    now i need to this function in C++ native by boost / poco / standard and or Qt libraries.



  • And this is sample of PHP Code :

    @
    $username="YOUR_USERNAME";
    $password="YOUR_PASSWORD";
    $contents = file_get_contents("http://www.whoisxmlapi.com/whoisserver/WhoisService?domainName=google.com&cmd=GET_DN_AVAILABILITY&username=$username&password=$password&outputFormat=JSON");
    // echo $contents;
    $res=json_decode($contents);
    if($res){
    if($res->ErrorMessage){
    echo $res->ErrorMessage->msg;
    }
    else{
    $domainInfo = $res->DomainInfo;
    if($domainInfo){
    echo "Domain name: " . print_r($domainInfo->domainName,1) ."<br/>";
    echo "Domain Availability: " .print_r($domainInfo->domainAvailability,1) ."<br/>";
    //print_r($domainInfo);
    }
    }
    }
    @

    we need to authentication for get return from query.
    Now with Qt how can solve this problem ? :(



  • This is how I know the web service you asked about does not require authentication:
    @
    $ curl -D - 'http://www.whoisxmlapi.com/whoisserver/WhoisService?domainName=google.com&cmd=GET_DN_AVAILABILITY'
    HTTP/1.1 200 OK
    Date: Wed, 30 Apr 2014 21:20:55 GMT
    Content-Type: text/xml;charset=UTF-8
    Cache-Control: max-age=86400
    Expires: Thu, 01 May 2014 21:20:55 GMT
    Connection: close
    Transfer-Encoding: chunked

    <?xml version="1.0" encoding="utf-8"?><DomainInfo>
    <domainAvailability>UNAVAILABLE</domainAvailability>
    <domainName>google.com</domainName>
    </DomainInfo>
    @
    The HTTP response code is not "401 Authentication required" and the response body is not an HTML authentication page, ergo the service did not require authentication.

    Or, if you prefer, in Qt C++:
    @
    #include <QCoreApplication>
    #include <QObject>
    #include <QUrl>
    #include <QUrlQuery>
    #include <QNetworkAccessManager>
    #include <QNetworkRequest>
    #include <QNetworkReply>
    #include <QDebug>

    class Fetcher: public QObject
    {
    Q_OBJECT
    public:
    Fetcher(QObject *p = 0): QObject(p), reply(0) {
    QUrl url("http://www.whoisxmlapi.com/whoisserver/WhoisService");
    QUrlQuery qry;
    qry.addQueryItem("cmd", "GET_DN_AVAILABILITY");
    qry.addQueryItem("domainName", "google.com");
    url.setQuery(qry);

        reply = nam.get(QNetworkRequest(url));
        connect(reply, SIGNAL(finished()), SLOT(slotFinished()));
        connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(slotError(QNetworkReply::NetworkError)));
    }
    

    public slots:
    void slotError(QNetworkReply::NetworkError code) {
    qDebug() << Q_FUNC_INFO << "Error" << code;
    }

    void slotFinished() {
        QByteArray ba = reply->readAll();
        qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)
            << reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute);
        qDebug() << ba;
        reply->deleteLater();
        reply = 0;
        qApp->quit();
    }
    

    private:
    QNetworkAccessManager nam;
    QNetworkReply *reply;
    };

    int main(int argc, char *argv[])
    {
    QCoreApplication app(argc, argv);
    Fetcher f;
    return app.exec();
    }
    #include "main.moc"
    @
    Gives:
    @
    QVariant(int, 200) QVariant(QString, "OK")
    "<?xml version="1.0" encoding="utf-8"?><DomainInfo>
    <domainAvailability>UNAVAILABLE</domainAvailability>
    <domainName>google.com</domainName>
    </DomainInfo>"
    @

    Had I received a 401 HTTP error then adding:
    @
    url.setUserName("foo");
    url.setPassword("barbaz");
    @
    would do the correct thing for HTTP basic authentication.

    Your attempt tries adding a username and password parameter, equivalent to:
    @
    qry.addQueryItem("username", "foo");
    qry.addQueryItem("password", "barbaz");
    @
    This produces a different XML response if the service cannot validate the username/password pair (The HTTP transaction is still successful (200) though). In your code if the user name or password is not correctly encoded then this may cause rejection of what appears to be valid inputs.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.