1/* 2 * Copyright (C) 2011 Zeno Albisser <zeno@webkit.org> 3 * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 * THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "config.h" 28#include "QtNetworkAccessManager.h" 29 30#include "SharedMemory.h" 31#include "WebFrameNetworkingContext.h" 32#include "WebPage.h" 33#include "WebPageProxyMessages.h" 34#include "WebProcess.h" 35#include <QAuthenticator> 36#include <QNetworkProxy> 37#include <QNetworkReply> 38#include <QNetworkRequest> 39 40namespace WebKit { 41 42QtNetworkAccessManager::QtNetworkAccessManager(WebProcess* webProcess) 43 : QNetworkAccessManager() 44 , m_webProcess(webProcess) 45{ 46 connect(this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), SLOT(onAuthenticationRequired(QNetworkReply*, QAuthenticator*))); 47 connect(this, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), SLOT(onProxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*))); 48#ifndef QT_NO_SSL 49 connect(this, SIGNAL(sslErrors(QNetworkReply*, QList<QSslError>)), SLOT(onSslErrors(QNetworkReply*, QList<QSslError>))); 50#endif 51} 52 53WebPage* QtNetworkAccessManager::obtainOriginatingWebPage(const QNetworkRequest& request) 54{ 55 QObject* originatingObject = request.originatingObject(); 56 if (!originatingObject) 57 return 0; 58 59 qulonglong pageID = originatingObject->property("pageID").toULongLong(); 60 return m_webProcess->webPage(pageID); 61} 62 63QNetworkReply* QtNetworkAccessManager::createRequest(Operation operation, const QNetworkRequest& request, QIODevice* outData) 64{ 65 WebPage* webPage = obtainOriginatingWebPage(request); 66 if (webPage && m_applicationSchemes.contains(webPage, request.url().scheme().toLower())) { 67 QtNetworkReply* reply = new QtNetworkReply(request, this); 68 webPage->receivedApplicationSchemeRequest(request, reply); 69 return reply; 70 } 71 72 return QNetworkAccessManager::createRequest(operation, request, outData); 73} 74 75void QtNetworkAccessManager::registerApplicationScheme(const WebPage* page, const QString& scheme) 76{ 77 m_applicationSchemes.insert(page, scheme.toLower()); 78} 79 80void QtNetworkAccessManager::onProxyAuthenticationRequired(const QNetworkProxy& proxy, QAuthenticator* authenticator) 81{ 82 // FIXME: Check if there is a better way to get a reference to the page. 83 WebPage* webPage = m_webProcess->focusedWebPage(); 84 85 if (!webPage) 86 return; 87 88 String hostname = proxy.hostName(); 89 uint16_t port = static_cast<uint16_t>(proxy.port()); 90 String prefilledUsername = authenticator->user(); 91 String username; 92 String password; 93 94 if (webPage->sendSync( 95 Messages::WebPageProxy::ProxyAuthenticationRequiredRequest(hostname, port, prefilledUsername), 96 Messages::WebPageProxy::ProxyAuthenticationRequiredRequest::Reply(username, password))) { 97 if (!username.isEmpty()) 98 authenticator->setUser(username); 99 if (!password.isEmpty()) 100 authenticator->setPassword(password); 101 } 102 103} 104 105void QtNetworkAccessManager::onAuthenticationRequired(QNetworkReply* reply, QAuthenticator* authenticator) 106{ 107 WebPage* webPage = obtainOriginatingWebPage(reply->request()); 108 109 // FIXME: This check can go away once our Qt version is up-to-date. See: QTBUG-23512. 110 if (!webPage) 111 return; 112 113 String hostname = reply->url().toString(QUrl::RemovePath | QUrl::RemoveQuery | QUrl::RemoveFragment | QUrl::StripTrailingSlash); 114 String realm = authenticator->realm(); 115 String prefilledUsername = authenticator->user(); 116 String username; 117 String password; 118 119 if (webPage->sendSync( 120 Messages::WebPageProxy::AuthenticationRequiredRequest(hostname, realm, prefilledUsername), 121 Messages::WebPageProxy::AuthenticationRequiredRequest::Reply(username, password))) { 122 if (!username.isEmpty()) 123 authenticator->setUser(username); 124 if (!password.isEmpty()) 125 authenticator->setPassword(password); 126 } 127} 128 129void QtNetworkAccessManager::onSslErrors(QNetworkReply* reply, const QList<QSslError>& qSslErrors) 130{ 131#ifndef QT_NO_SSL 132 WebPage* webPage = obtainOriginatingWebPage(reply->request()); 133 134 // FIXME: This check can go away once our Qt version is up-to-date. See: QTBUG-23512. 135 if (!webPage) 136 return; 137 138 String hostname = reply->url().host(); 139 bool ignoreErrors = false; 140 141 if (webPage->sendSync( 142 Messages::WebPageProxy::CertificateVerificationRequest(hostname), 143 Messages::WebPageProxy::CertificateVerificationRequest::Reply(ignoreErrors))) { 144 if (ignoreErrors) 145 reply->ignoreSslErrors(qSslErrors); 146 } 147#endif 148} 149 150} 151 152#include "moc_QtNetworkAccessManager.cpp" 153