예제 #1
0
void SslTlsSocket::delayedStart()
{
    QSslSocket *sock = qobject_cast<QSslSocket *>(d);
    Q_ASSERT(sock);

    switch (m_proxySettings) {
    case Streams::ProxySettings::RespectSystemProxy:
    {
        QNetworkProxy setting;
        QNetworkProxyQuery query = QNetworkProxyQuery(host, port, m_protocolTag, QNetworkProxyQuery::TcpSocket);

        // set to true if a capable setting is found
        bool capableSettingFound = false;

        // set to true if at least one valid setting is found
        bool settingFound = false;

        // FIXME: this static function works particularly slow in Windows
        QList<QNetworkProxy> proxySettingsList = QNetworkProxyFactory::systemProxyForQuery(query);

        /* Proxy Settings are read from the user's environment variables by the above static method.
         * A peculiar case is with *nix systems, where an undefined environment variable is returned as
         * an empty string. Such entries *might* exist in our proxySettingsList, and shouldn't be processed.
         * One good check is to use hostName() of the QNetworkProxy object, and treat the Proxy Setting as invalid if
         * the host name is empty. */
        Q_FOREACH (setting, proxySettingsList) {
            if (!setting.hostName().isEmpty()) {
                settingFound = true;

                // now check whether setting has capabilities
                if (setting.capabilities().testFlag(QNetworkProxy::TunnelingCapability)) {
                    sock->setProxy(setting);
                    capableSettingFound = true;
                    break;
                }
            }
        }

        if (!settingFound || proxySettingsList.isEmpty()) {
            sock->setProxy(QNetworkProxy::NoProxy);
        } else if (!capableSettingFound) {
            emit disconnected(tr("The underlying socket is having troubles when processing connection to %1:%2: %3")
                              .arg(host, QString::number(port), QStringLiteral("Cannot find proxy setting capable of tunneling")));
        }
        break;
    }
    case Streams::ProxySettings::DirectConnect:
        sock->setProxy(QNetworkProxy::NoProxy);
        break;
    }

    if (startEncrypted)
        sock->connectToHostEncrypted(host, port);
    else
        sock->connectToHost(host, port);
}
예제 #2
0
int main(int argc, char** argv) {
	// Parse options
	// TODO: http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKCmdLineArgs.html
	{
		QStringList arguments = getCliArguments(argc, argv);
		if ((arguments.indexOf("-h") != -1) || (arguments.indexOf("--help") != -1)) {
			qDebug() << "QtWeb options:";
			qDebug() << "";
			qDebug() << "--maximize";
			qDebug() << "";
			qDebug() << "--url";
			qDebug() << "--user-agent";
			qDebug() << "--socks host:port";
			qDebug() << "--socks-resolver";
			qDebug() << "--extra-enabled";

			return EXIT_SUCCESS;
		}

		int optionIndex = 0;

		// maximize 
		if ((optionIndex = arguments.indexOf("--maximize")) != -1) {
			options.maximize = true;
		}
		// url
		if ((optionIndex = arguments.indexOf("--url")) != -1) {
			options.url = arguments.at(optionIndex + 1);
		}
		// user agent
		if ((optionIndex = arguments.indexOf("--user-agent")) != -1) {
			options.userAgent = arguments.at(optionIndex + 1);
			Wrapper::QWebPage::userAgent = options.userAgent;
		}
		// socks
		if ((optionIndex = arguments.indexOf("--socks")) != -1) {
			options.socks = arguments.at(optionIndex + 1);
		}
		// socks resolver
		if ((optionIndex = arguments.indexOf("--socks-resolver")) != -1) {
			options.socksResolver = true; 
		}
		// enable extra
		if ((optionIndex = arguments.indexOf("--extra-enabled")) != -1) {
			options.extraEnabled = true;
		}

		qDebug() << "Maximize" << options.maximize;
		qDebug() << "Load" << options.url;
		qDebug() << "User-agent" << options.userAgent;
		qDebug() << "Socks" << options.socks;
		qDebug() << "Socks resolver" << options.socksResolver;
		qDebug() << "Extra enabled" << options.extraEnabled;
	}

	QApplication a(argc, argv);

	// release view
	Lambda qHandler([&]() {
		view.reset();
	});
	QObject::connect(&a, SIGNAL(aboutToQuit()), &qHandler, SLOT(call()));
	
	view.reset(new QWebView);
	view->setPage(new Wrapper::QWebPage);

	// add "http://"
	if (options.url.indexOf("://") == -1) {
		options.url = QLatin1String("http://") + options.url;
	}

	// socks
	if (options.socks.length()) {
		QNetworkProxy proxy;
		proxy.setType(QNetworkProxy::Socks5Proxy);

		int colonPosition = options.socks.lastIndexOf(":");
		if (colonPosition == -1) {
			qDebug() << "Malformed proxy (HOST:PORT is needed)";
			return EXIT_FAILURE;
		}

		proxy.setHostName(options.socks.left(colonPosition));
		proxy.setPort(options.socks.right(options.socks.length() - 1 - colonPosition).toInt());

		if (options.socksResolver) {
			proxy.setCapabilities(proxy.capabilities() | QNetworkProxy::HostNameLookupCapability);
		} else {
			proxy.setCapabilities(proxy.capabilities() & ~QNetworkProxy::HostNameLookupCapability);
		}

		view->page()->networkAccessManager()->setProxy(proxy);
		
		qDebug() << "Proxy installed";
	}

    // Add inspector.
	view->page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
	if (options.extraEnabled) {
		view->page()->settings()->setAttribute(QWebSettings::PluginsEnabled, true);
		view->page()->settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true);
		view->page()->settings()->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, true);
		view->page()->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true);
		view->page()->settings()->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, true);
	}

	view->load(QUrl(options.url));
	if (options.maximize) {
		view->showMaximized();
	} else {
		view->show();
	}

	// execute JS
	{
		// Reinterpret pointer to Wrapper class
		Wrapper::QWebPage *page = reinterpret_cast<Wrapper::QWebPage *>(view->page());

		// async read from STDIN
		// and eval this as JS code
		stdinNotifier.reset(new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read));
		QObject::connect(&(*stdinNotifier), SIGNAL(activated(int)), new Lambda([&] {
			qDebug() << Q_FUNC_INFO;

			QTextStream stream(stdin, QIODevice::ReadOnly);
			QString jsToExecute;

			forever {
				fd_set stdinfd;
				FD_ZERO( &stdinfd );
				FD_SET( STDIN_FILENO, &stdinfd );
				struct timeval tv;
				tv.tv_sec = 0;
				tv.tv_usec = 0;
				int ready = select(1, &stdinfd, NULL, NULL, &tv);

				if (ready > 0) {
					jsToExecute += stream.readLine();
				} else {
					break;
				}
			}

			// TODO : drop code duplicating
			if (jsToExecute.startsWith(options.moveToElementPrefix)) {
				QString moveMouseToElementSelector = jsToExecute.remove(0, options.moveToElementPrefix.length());

				page->moveMouseTo(page->mainFrame()->findFirstElement(moveMouseToElementSelector));
			} else if (jsToExecute.startsWith(options.clickToElementPrefix)) {
				QString clickMouseToElementSelector = jsToExecute.remove(0, options.clickToElementPrefix.length());

				page->clickTo(page->mainFrame()->findFirstElement(clickMouseToElementSelector));
			} else if (jsToExecute.startsWith(options.cursorSetToElementPrefix)) {
				QString setCursorToElementSelector = jsToExecute.remove(0, options.cursorSetToElementPrefix.length());

				page->setCursorTo(page->mainFrame()->findFirstElement(setCursorToElementSelector));
			} else {
				view->page()->mainFrame()->evaluateJavaScript(jsToExecute);	
			}
		}), SLOT(call()));
		stdinNotifier->setEnabled(true);
	}