12

Clean install of Qt SDK 1.1.4 on Windows 7 with Visual C++ 2008 SP1; I'm using Qt Creator. Why does this code not load some web pages?

#include <QtGui/QApplication>
#include <QtWebKit/QWebView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWebView b;
    b.load(QUrl("https://gmail.com")); // doesn't work
    //b.load(QUrl("https://accounts.google.com")); // works
    //b.load(QUrl("https://google.com")); // doesn't work
    //b.load(QUrl("https://www.google.com")); // works
    b.show();

    return a.exec();
}

Why do some of the URLs not work, and others do?

I think the google.com / www.google.com is especially telling; google.com normally redirects to www.google.com. And gmail.com is redirecting to accounts.google.com. Is WebKit not allowing secure pages to redirect? If so, how to fix that?

By the way, Qt SDK 1.1.4 seems to include OpenSSL; I noticed its presence at C:\QtSDK\Desktop\Qt\4.7.4\msvc2008\bin\ssleay32.dll. Also notice that some pages seem to work, just not others.

EDIT: Two more URLs:

b.load(QUrl("https://support.motionview3d.com/help/_media/images/directory.png")); // doesn't work
b.load(QUrl("https://mail.google.com")); // works

Again, both of these work fine in other web browsers.

James Johnston
  • 9,264
  • 9
  • 48
  • 76

2 Answers2

19

You are probably getting SSL errors which you can handle in a slot. Although not the best final solution, you can use the slot to ignore all SSL errors. I did this by subclassing QWebView:

qwebview.h:

#ifndef WEBVIEW_H
#define WEBVIEW_H

#include <QWebView>

class WebView : public QWebView
{
    Q_OBJECT

    public:
        WebView(QWidget *parent = 0);
    private slots:
        void handleSslErrors(QNetworkReply* reply, const QList<QSslError> &errors);
};

#endif // WEBVIEW_H

qwebview.cpp:

#include "webview.h"
#include <QNetworkReply>
#include <QtDebug>
#include <QSslError>

WebView::WebView(QWidget *parent) :
    QWebView(parent)
{
    load(QUrl("https://gmail.com"));

    connect(page()->networkAccessManager(),
            SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError> & )),
            this,
            SLOT(handleSslErrors(QNetworkReply*, const QList<QSslError> & )));  
}

void WebView::handleSslErrors(QNetworkReply* reply, const QList<QSslError> &errors)
{
    qDebug() << "handleSslErrors: ";
    foreach (QSslError e, errors)
    {
        qDebug() << "ssl error: " << e;
    }

    reply->ignoreSslErrors();
}

main.cpp"

#include <QApplication>
#include "WebView.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    WebView w;
    w.show();
    return a.exec();
}

Running this should produce debug output like this:

handleSslErrors:  
ssl error:  "The host name did not match any of the valid hosts for this certificate" 
ssl error:  "No error" 
ssl error:  "No error" 
...

In your final program, you will of course want to handle SSL errors properly :)

Arnold Spence
  • 21,942
  • 7
  • 74
  • 67
  • 1
    What the mess? Seems like there are only two possibilities here: (1) The HTTP spec allows a bad certificate when redirecting or other special cases, but Qt has a bug and refuses to access the redirect in the first place (it's being "too strict"). Or (2) Google administrators made a mistake but didn't notice because Internet Explorer, FireFox, Chrome, and other major browsers have a serious security hole. What's going on here? – James Johnston Dec 05 '11 at 15:35
  • 2
    Well, it seems that Qt is less tolerant of SSL errors than the average web browser. It turns out that the webmaster on the server I really care about hasn't installed intermediate certificates on the server: http://www.sslshopper.com/ssl-certificate-not-trusted-error.html (see last option). – James Johnston Dec 05 '11 at 16:38
  • It is also possible to combine this with ```examples/network/securesocketclient``` to display these errors in the ui. – Sebastian Wagner Mar 11 '14 at 13:04
1

I usually use the "Arnold Spence"s solution but sometimes that wont work.

in that case just change the default Ssl configuration like this

QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration();
QList<QSslCertificate> cert_list = sslconf.caCertificates();
QList<QSslCertificate> cert_new = QSslCertificate::fromData("CaCertificates");
cert_list += cert_new;

sslconf.setCaCertificates(cert_list);
sslconf.setProtocol(QSsl::AnyProtocol);
QSslConfiguration::setDefaultConfiguration(sslconf);

Here we altered the configuration for the entire application .

I recommend you handle the sslErrors signal too ..

Midhun
  • 3,850
  • 1
  • 23
  • 26
  • Is upper code block resolve errors? Can I open secure pages after adding this block? Wher should I add this code? Kindly guide me. – Pankaj Vavadiya Dec 30 '18 at 09:48