QWebView / Qt WebKit won't open some SSL pages; redirects not allowed?
Asked Answered
I

2

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.

Inaudible answered 2/12, 2011 at 20:53 Comment(0)
G
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 :)

Gennagennaro answered 3/12, 2011 at 1:33 Comment(3)
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?Inaudible
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: sslshopper.com/ssl-certificate-not-trusted-error.html (see last option).Inaudible
It is also possible to combine this with examples/network/securesocketclient to display these errors in the ui.Norvol
M
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 ..

Masticatory answered 28/10, 2015 at 6:37 Comment(1)
Is upper code block resolve errors? Can I open secure pages after adding this block? Wher should I add this code? Kindly guide me.Dogmatism

© 2022 - 2024 — McMap. All rights reserved.