├── webkit_server.pro
├── .gitignore
├── src
├── webkit_server.qrc
├── Url.h
├── Body.h
├── Header.h
├── Reset.h
├── SetProxy.h
├── Find.h
├── SetCookie.h
├── Status.h
├── Execute.h
├── Headers.h
├── Visit.h
├── ClearCookies.h
├── CurrentUrl.h
├── SetTimeout.h
├── NullCommand.h
├── RequestedUrl.h
├── ResizeWindow.h
├── SetPromptText.h
├── ClearPromptText.h
├── ConsoleMessages.h
├── GetWindowHandle.h
├── Render.h
├── SetConfirmAction.h
├── SetPromptAction.h
├── GetWindowHandles.h
├── IgnoreSslErrors.h
├── SetUrlBlacklist.h
├── Evaluate.h
├── GetTimeout.h
├── SetSkipImageLoading.h
├── Authenticate.h
├── GetCookies.h
├── JavascriptAlertMessages.h
├── EnableLogging.h
├── JavascriptPromptMessages.h
├── JavascriptConfirmMessages.h
├── Node.h
├── GetTimeout.cpp
├── EnableLogging.cpp
├── Server.h
├── SetPromptText.cpp
├── ClearPromptText.cpp
├── Reset.cpp
├── Source.h
├── WindowFocus.h
├── GetWindowHandle.cpp
├── NullCommand.cpp
├── SetPromptAction.cpp
├── SetConfirmAction.cpp
├── Status.cpp
├── CommandFactory.h
├── IgnoreSslErrors.cpp
├── NetworkCookieJar.h
├── NoOpReply.h
├── Url.cpp
├── SetSkipImageLoading.cpp
├── ClearCookies.cpp
├── JavascriptInvocation.cpp
├── Visit.cpp
├── RequestedUrl.cpp
├── CurrentUrl.cpp
├── body.cpp
├── ConsoleMessages.cpp
├── Headers.cpp
├── UnsupportedContentHandler.h
├── Evaluate.cpp
├── ResizeWindow.cpp
├── JavascriptAlertMessages.cpp
├── JavascriptPromptMessages.cpp
├── JavascriptConfirmMessages.cpp
├── Render.cpp
├── SetUrlBlacklist.cpp
├── JsonSerializer.h
├── SetCookie.cpp
├── SetTimeout.cpp
├── Execute.cpp
├── JavascriptInvocation.h
├── SocketCommand.cpp
├── Command.cpp
├── FrameFocus.h
├── GetCookies.cpp
├── Command.h
├── Find.cpp
├── Response.h
├── Authenticate.cpp
├── Source.cpp
├── GetWindowHandles.cpp
├── SocketCommand.h
├── Header.cpp
├── Server.cpp
├── Node.cpp
├── main.cpp
├── Response.cpp
├── SetProxy.cpp
├── UnsupportedContentHandler.cpp
├── CommandParser.h
├── WindowFocus.cpp
├── NoOpReply.cpp
├── Connection.h
├── TimeoutCommand.h
├── PageLoadingCommand.h
├── find_command.h
├── CommandFactory.cpp
├── NetworkAccessManager.h
├── WebPageManager.h
├── FrameFocus.cpp
├── PageLoadingCommand.cpp
├── CommandParser.cpp
├── Connection.cpp
├── TimeoutCommand.cpp
├── webkit_server.pro
├── JsonSerializer.cpp
├── WebPage.h
├── NetworkCookieJar.cpp
├── WebPageManager.cpp
├── NetworkAccessManager.cpp
├── webkit_server.js
└── WebPage.cpp
├── README.markdown
├── bin
└── Info.plist
└── LICENSE
/webkit_server.pro:
--------------------------------------------------------------------------------
1 | CONFIG += ordered
2 | SUBDIRS += src/webkit_server.pro
3 | TEMPLATE = subdirs
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.moc
3 | Makefile*
4 | qrc_*
5 | moc_*.cpp
6 | bin/webkit_server
7 | src/webkit_server
8 |
--------------------------------------------------------------------------------
/src/webkit_server.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | webkit_server.js
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/Url.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class Url : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | Url(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/Body.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class Body : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | Body(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/Header.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class Header : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | Header(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/Reset.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class Reset : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | Reset(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/SetProxy.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class SetProxy : public SocketCommand {
4 | Q_OBJECT;
5 |
6 | public:
7 | SetProxy(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/Find.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class Find : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | Find(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/SetCookie.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class SetCookie : public SocketCommand {
4 | Q_OBJECT;
5 |
6 | public:
7 | SetCookie(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/Status.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class Status : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | Status(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/Execute.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class Execute : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | Execute(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/Headers.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class Headers : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | Headers(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/Visit.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class Visit : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | Visit(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/ClearCookies.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class ClearCookies : public SocketCommand {
4 | Q_OBJECT;
5 |
6 | public:
7 | ClearCookies(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/CurrentUrl.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class CurrentUrl : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | CurrentUrl(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/SetTimeout.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class SetTimeout : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | SetTimeout(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/NullCommand.h:
--------------------------------------------------------------------------------
1 | #include "Command.h"
2 |
3 | class NullCommand : public Command {
4 | Q_OBJECT
5 |
6 | public:
7 | NullCommand(QString name, QObject *parent = 0);
8 | virtual void start();
9 |
10 | private:
11 | QString m_name;
12 | };
13 |
--------------------------------------------------------------------------------
/src/RequestedUrl.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class RequestedUrl : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | RequestedUrl(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/ResizeWindow.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class ResizeWindow : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | ResizeWindow(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/SetPromptText.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class SetPromptText : public SocketCommand {
4 | Q_OBJECT;
5 |
6 | public:
7 | SetPromptText(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/ClearPromptText.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class ClearPromptText : public SocketCommand {
4 | Q_OBJECT;
5 |
6 | public:
7 | ClearPromptText(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/ConsoleMessages.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class ConsoleMessages : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | ConsoleMessages(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/GetWindowHandle.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class GetWindowHandle : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | GetWindowHandle(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/Render.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 | #include
3 |
4 | class Render : public SocketCommand {
5 | Q_OBJECT
6 |
7 | public:
8 | Render(WebPageManager *page, QStringList &arguments, QObject *parent = 0);
9 | virtual void start();
10 | };
11 |
--------------------------------------------------------------------------------
/src/SetConfirmAction.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class SetConfirmAction : public SocketCommand {
4 | Q_OBJECT;
5 |
6 | public:
7 | SetConfirmAction(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/SetPromptAction.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class SetPromptAction : public SocketCommand {
4 | Q_OBJECT;
5 |
6 | public:
7 | SetPromptAction(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/GetWindowHandles.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class GetWindowHandles : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | GetWindowHandles(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/IgnoreSslErrors.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class IgnoreSslErrors : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | IgnoreSslErrors(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/src/SetUrlBlacklist.h:
--------------------------------------------------------------------------------
1 |
2 | #include "SocketCommand.h"
3 |
4 | class SetUrlBlacklist : public SocketCommand {
5 | Q_OBJECT
6 |
7 | public:
8 | SetUrlBlacklist(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
9 | virtual void start();
10 | };
11 |
12 |
--------------------------------------------------------------------------------
/src/Evaluate.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | #include
4 |
5 | class Evaluate : public SocketCommand {
6 | Q_OBJECT
7 |
8 | public:
9 | Evaluate(WebPageManager *, QStringList &arguments, QObject *parent = 0);
10 | virtual void start();
11 | };
12 |
13 |
--------------------------------------------------------------------------------
/src/GetTimeout.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class WebPageManager;
4 |
5 | class GetTimeout : public SocketCommand {
6 | Q_OBJECT;
7 |
8 | public:
9 | GetTimeout(WebPageManager *page, QStringList &arguments, QObject *parent = 0);
10 | virtual void start();
11 | };
12 |
--------------------------------------------------------------------------------
/src/SetSkipImageLoading.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class SetSkipImageLoading : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | SetSkipImageLoading(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/Authenticate.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class WebPage;
4 |
5 | class Authenticate : public SocketCommand {
6 | Q_OBJECT
7 |
8 | public:
9 | Authenticate(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
10 | virtual void start();
11 | };
12 |
13 |
--------------------------------------------------------------------------------
/src/GetCookies.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class GetCookies : public SocketCommand {
4 | Q_OBJECT;
5 |
6 | public:
7 | GetCookies(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 |
10 | private:
11 | QString m_buffer;
12 | };
13 |
--------------------------------------------------------------------------------
/src/JavascriptAlertMessages.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class JavascriptAlertMessages : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | JavascriptAlertMessages(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/EnableLogging.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class WebPageManager;
4 |
5 | class EnableLogging : public SocketCommand {
6 | Q_OBJECT
7 |
8 | public:
9 | EnableLogging(WebPageManager *, QStringList &arguments, QObject *parent = 0);
10 | virtual void start();
11 | };
12 |
13 |
--------------------------------------------------------------------------------
/src/JavascriptPromptMessages.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class JavascriptPromptMessages : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | JavascriptPromptMessages(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/JavascriptConfirmMessages.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class JavascriptConfirmMessages : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | JavascriptConfirmMessages(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 | };
10 |
--------------------------------------------------------------------------------
/src/Node.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 | #include
3 |
4 | class Node : public SocketCommand {
5 | Q_OBJECT
6 |
7 | public:
8 | Node(WebPageManager *manager, QStringList &arguments, QObject *parent = 0);
9 | virtual void start();
10 | virtual QString toString() const;
11 | };
12 |
13 |
--------------------------------------------------------------------------------
/src/GetTimeout.cpp:
--------------------------------------------------------------------------------
1 | #include "GetTimeout.h"
2 | #include "WebPageManager.h"
3 |
4 | GetTimeout::GetTimeout(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
5 | }
6 |
7 | void GetTimeout::start() {
8 | emitFinished(true, QString::number(manager()->getTimeout()));
9 | }
10 |
--------------------------------------------------------------------------------
/src/EnableLogging.cpp:
--------------------------------------------------------------------------------
1 | #include "EnableLogging.h"
2 | #include "WebPageManager.h"
3 |
4 | EnableLogging::EnableLogging(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
5 | }
6 |
7 | void EnableLogging::start() {
8 | manager()->enableLogging();
9 | emitFinished(true);
10 | }
11 |
--------------------------------------------------------------------------------
/src/Server.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | class QTcpServer;
4 |
5 | class Server : public QObject {
6 | Q_OBJECT
7 |
8 | public:
9 | Server(QObject *parent);
10 | bool start();
11 | quint16 server_port() const;
12 |
13 | public slots:
14 | void handleConnection();
15 |
16 | private:
17 | QTcpServer *m_tcp_server;
18 | };
19 |
20 |
--------------------------------------------------------------------------------
/src/SetPromptText.cpp:
--------------------------------------------------------------------------------
1 | #include "SetPromptText.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | SetPromptText::SetPromptText(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
6 |
7 | void SetPromptText::start()
8 | {
9 | page()->setPromptText(arguments()[0]);
10 | emitFinished(true);
11 | }
12 |
--------------------------------------------------------------------------------
/src/ClearPromptText.cpp:
--------------------------------------------------------------------------------
1 | #include "ClearPromptText.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | ClearPromptText::ClearPromptText(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
6 |
7 | void ClearPromptText::start()
8 | {
9 | page()->setPromptText(QString());
10 | emitFinished(true);
11 | }
12 |
--------------------------------------------------------------------------------
/src/Reset.cpp:
--------------------------------------------------------------------------------
1 | #include "Reset.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | Reset::Reset(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void Reset::start() {
9 | page()->triggerAction(QWebPage::Stop);
10 |
11 | manager()->reset();
12 |
13 | emitFinished(true);
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/src/Source.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class QNetworkReply;
4 |
5 | class Source : public SocketCommand {
6 | Q_OBJECT
7 |
8 | public:
9 | Source(WebPageManager *, QStringList &arguments, QObject *parent = 0);
10 | virtual void start();
11 |
12 | public slots:
13 | void sourceLoaded();
14 |
15 | private:
16 | QNetworkReply *reply;
17 | };
18 |
19 |
--------------------------------------------------------------------------------
/src/WindowFocus.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class WindowFocus : public SocketCommand {
4 | Q_OBJECT
5 |
6 | public:
7 | WindowFocus(WebPageManager *, QStringList &arguments, QObject *parent = 0);
8 | virtual void start();
9 |
10 | private:
11 | void success(WebPage *);
12 | void windowNotFound();
13 | void focusWindow(QString);
14 | };
15 |
16 |
--------------------------------------------------------------------------------
/src/GetWindowHandle.cpp:
--------------------------------------------------------------------------------
1 | #include "GetWindowHandle.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include
5 |
6 | GetWindowHandle::GetWindowHandle(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
7 | }
8 |
9 | void GetWindowHandle::start() {
10 | emitFinished(true, page()->uuid());
11 | }
12 |
--------------------------------------------------------------------------------
/src/NullCommand.cpp:
--------------------------------------------------------------------------------
1 | #include "NullCommand.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | NullCommand::NullCommand(QString name, QObject *parent) : Command(parent) {
6 | m_name = name;
7 | }
8 |
9 | void NullCommand::start() {
10 | QString failure = QString("[WebKit Server] Unknown command: ") + m_name + "\n";
11 | emitFinished(false, failure);
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/src/SetPromptAction.cpp:
--------------------------------------------------------------------------------
1 | #include "SetPromptAction.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | SetPromptAction::SetPromptAction(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
6 |
7 | void SetPromptAction::start()
8 | {
9 | page()->setPromptAction(arguments()[0]);
10 | emitFinished(true);
11 | }
12 |
--------------------------------------------------------------------------------
/src/SetConfirmAction.cpp:
--------------------------------------------------------------------------------
1 | #include "SetConfirmAction.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | SetConfirmAction::SetConfirmAction(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
6 |
7 | void SetConfirmAction::start()
8 | {
9 | page()->setConfirmAction(arguments()[0]);
10 | emitFinished(true);
11 | }
12 |
--------------------------------------------------------------------------------
/src/Status.cpp:
--------------------------------------------------------------------------------
1 | #include "Status.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include
5 |
6 | Status::Status(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
7 | }
8 |
9 | void Status::start() {
10 | int status = page()->getLastStatus();
11 | emitFinished(true, QString::number(status));
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/src/CommandFactory.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | class Command;
4 | class WebPage;
5 | class WebPageManager;
6 |
7 | class CommandFactory : public QObject {
8 | Q_OBJECT
9 |
10 | public:
11 | CommandFactory(WebPageManager *, QObject *parent = 0);
12 | Command *createCommand(const char *name, QStringList &arguments);
13 |
14 | private:
15 | WebPageManager *m_manager;
16 | };
17 |
18 |
--------------------------------------------------------------------------------
/src/IgnoreSslErrors.cpp:
--------------------------------------------------------------------------------
1 | #include "IgnoreSslErrors.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | IgnoreSslErrors::IgnoreSslErrors(WebPageManager *manager, QStringList &arguments, QObject *parent) :
6 | SocketCommand(manager, arguments, parent) {
7 | }
8 |
9 | void IgnoreSslErrors::start() {
10 | manager()->setIgnoreSslErrors(true);
11 | emitFinished(true);
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/src/NetworkCookieJar.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class NetworkCookieJar : public QNetworkCookieJar {
5 |
6 | Q_OBJECT;
7 |
8 | public:
9 |
10 | NetworkCookieJar(QObject *parent = 0);
11 |
12 | QList getAllCookies() const;
13 | void clearCookies();
14 | void overwriteCookies(const QList& cookieList);
15 | };
16 |
--------------------------------------------------------------------------------
/src/NoOpReply.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class NoOpReply : public QNetworkReply {
5 | Q_OBJECT
6 |
7 | public:
8 | NoOpReply(QNetworkRequest &request, QObject *parent = 0);
9 |
10 | void abort();
11 | qint64 bytesAvailable() const;
12 | bool isSequential() const;
13 |
14 | protected:
15 | qint64 readData(char *data, qint64 maxSize);
16 |
17 | };
18 |
19 |
--------------------------------------------------------------------------------
/src/Url.cpp:
--------------------------------------------------------------------------------
1 | #include "Url.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | Url::Url(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void Url::start() {
9 | QUrl humanUrl = page()->currentFrame()->url();
10 | QByteArray encodedBytes = humanUrl.toEncoded();
11 | emit finished(new Response(true, encodedBytes));
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/src/SetSkipImageLoading.cpp:
--------------------------------------------------------------------------------
1 | #include "SetSkipImageLoading.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | SetSkipImageLoading::SetSkipImageLoading(WebPageManager *manager, QStringList &arguments, QObject *parent) :
6 | SocketCommand(manager, arguments, parent) {
7 | }
8 |
9 | void SetSkipImageLoading::start() {
10 | page()->setSkipImageLoading(arguments().contains("true"));
11 | emitFinished(true);
12 | }
13 |
--------------------------------------------------------------------------------
/src/ClearCookies.cpp:
--------------------------------------------------------------------------------
1 | #include "ClearCookies.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "NetworkCookieJar.h"
5 | #include
6 |
7 | ClearCookies::ClearCookies(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
8 |
9 | void ClearCookies::start()
10 | {
11 | manager()->cookieJar()->clearCookies();
12 | emitFinished(true);
13 | }
14 |
--------------------------------------------------------------------------------
/src/JavascriptInvocation.cpp:
--------------------------------------------------------------------------------
1 | #include "JavascriptInvocation.h"
2 |
3 | JavascriptInvocation::JavascriptInvocation(const QString &functionName, const QStringList &arguments, QObject *parent) : QObject(parent) {
4 | m_functionName = functionName;
5 | m_arguments = arguments;
6 | }
7 |
8 | QString &JavascriptInvocation::functionName() {
9 | return m_functionName;
10 | }
11 |
12 | QStringList &JavascriptInvocation::arguments() {
13 | return m_arguments;
14 | }
15 |
--------------------------------------------------------------------------------
/src/Visit.cpp:
--------------------------------------------------------------------------------
1 | #include "Visit.h"
2 | #include "SocketCommand.h"
3 | #include "WebPage.h"
4 | #include "WebPageManager.h"
5 |
6 | Visit::Visit(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
7 | }
8 |
9 | void Visit::start() {
10 | QUrl requestedUrl = QUrl::fromEncoded(arguments()[0].toUtf8(), QUrl::StrictMode);
11 | page()->currentFrame()->load(QUrl(requestedUrl));
12 | emitFinished(true);
13 | }
14 |
--------------------------------------------------------------------------------
/src/RequestedUrl.cpp:
--------------------------------------------------------------------------------
1 | #include "RequestedUrl.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | RequestedUrl::RequestedUrl(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void RequestedUrl::start() {
9 | QUrl humanUrl = page()->currentFrame()->requestedUrl();
10 | QByteArray encodedBytes = humanUrl.toEncoded();
11 | emit finished(new Response(true, encodedBytes));
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/src/CurrentUrl.cpp:
--------------------------------------------------------------------------------
1 | #include "CurrentUrl.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | CurrentUrl::CurrentUrl(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void CurrentUrl::start() {
9 | QStringList arguments;
10 | QVariant result = page()->invokeWebKitServerFunction("currentUrl", arguments);
11 | QString url = result.toString();
12 | emitFinished(true, url);
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/src/body.cpp:
--------------------------------------------------------------------------------
1 | #include "Body.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | Body::Body(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void Body::start() {
9 | QString result;
10 | if (page()->unsupportedContentLoaded())
11 | result = page()->currentFrame()->toPlainText();
12 | else
13 | result = page()->currentFrame()->toHtml();
14 |
15 | emitFinished(true, result);
16 | }
17 |
--------------------------------------------------------------------------------
/src/ConsoleMessages.cpp:
--------------------------------------------------------------------------------
1 | #include "ConsoleMessages.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "JsonSerializer.h"
5 |
6 | ConsoleMessages::ConsoleMessages(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
7 | }
8 |
9 | void ConsoleMessages::start() {
10 | JsonSerializer serializer;
11 | QByteArray json = serializer.serialize(page()->consoleMessages());
12 | emitFinished(true, json);
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/src/Headers.cpp:
--------------------------------------------------------------------------------
1 | #include "Headers.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | Headers::Headers(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void Headers::start() {
9 | QStringList headers;
10 |
11 | foreach(QNetworkReply::RawHeaderPair header, page()->pageHeaders())
12 | headers << header.first+": "+header.second;
13 |
14 | emitFinished(true, headers.join("\n"));
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/src/UnsupportedContentHandler.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | class WebPage;
4 | class QNetworkReply;
5 |
6 | class UnsupportedContentHandler : public QObject {
7 | Q_OBJECT
8 |
9 | public:
10 | UnsupportedContentHandler(WebPage *page, QNetworkReply *reply, QObject *parent = 0);
11 | void waitForReplyToFinish();
12 | void renderNonHtmlContent();
13 |
14 | public slots:
15 | void replyFinished();
16 |
17 | private:
18 | WebPage *m_page;
19 | QNetworkReply *m_reply;
20 | };
21 |
--------------------------------------------------------------------------------
/src/Evaluate.cpp:
--------------------------------------------------------------------------------
1 | #include "Evaluate.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "JsonSerializer.h"
5 | #include
6 |
7 | Evaluate::Evaluate(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
8 | }
9 |
10 | void Evaluate::start() {
11 | QVariant result = page()->currentFrame()->evaluateJavaScript(arguments()[0]);
12 | JsonSerializer serializer;
13 | emitFinished(true, serializer.serialize(result));
14 | }
15 |
--------------------------------------------------------------------------------
/src/ResizeWindow.cpp:
--------------------------------------------------------------------------------
1 | #include "ResizeWindow.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | ResizeWindow::ResizeWindow(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void ResizeWindow::start() {
9 | int width = arguments()[0].toInt();
10 | int height = arguments()[1].toInt();
11 |
12 | QSize size(width, height);
13 | page()->setViewportSize(size);
14 |
15 | emitFinished(true);
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/JavascriptAlertMessages.cpp:
--------------------------------------------------------------------------------
1 | #include "JavascriptAlertMessages.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "JsonSerializer.h"
5 |
6 | JavascriptAlertMessages::JavascriptAlertMessages(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
7 |
8 | void JavascriptAlertMessages::start()
9 | {
10 | JsonSerializer serializer;
11 | QByteArray json = serializer.serialize(page()->alertMessages());
12 | emitFinished(true, json);
13 | }
14 |
--------------------------------------------------------------------------------
/src/JavascriptPromptMessages.cpp:
--------------------------------------------------------------------------------
1 | #include "JavascriptPromptMessages.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "JsonSerializer.h"
5 |
6 | JavascriptPromptMessages::JavascriptPromptMessages(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
7 |
8 | void JavascriptPromptMessages::start()
9 | {
10 | JsonSerializer serializer;
11 | QByteArray json = serializer.serialize(page()->promptMessages());
12 | emitFinished(true, json);
13 | }
14 |
--------------------------------------------------------------------------------
/src/JavascriptConfirmMessages.cpp:
--------------------------------------------------------------------------------
1 | #include "JavascriptConfirmMessages.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "JsonSerializer.h"
5 |
6 | JavascriptConfirmMessages::JavascriptConfirmMessages(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
7 |
8 | void JavascriptConfirmMessages::start()
9 | {
10 | JsonSerializer serializer;
11 | QByteArray json = serializer.serialize(page()->confirmMessages());
12 | emitFinished(true, json);
13 | }
14 |
--------------------------------------------------------------------------------
/src/Render.cpp:
--------------------------------------------------------------------------------
1 | #include "Render.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | Render::Render(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void Render::start() {
9 | QString imagePath = arguments()[0];
10 | int width = arguments()[1].toInt();
11 | int height = arguments()[2].toInt();
12 |
13 | QSize size(width, height);
14 |
15 | bool result = page()->render( imagePath, size );
16 |
17 | emitFinished(result);
18 | }
19 |
--------------------------------------------------------------------------------
/src/SetUrlBlacklist.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "SetUrlBlacklist.h"
3 | #include "WebPageManager.h"
4 | #include "WebPage.h"
5 | #include "NetworkAccessManager.h"
6 |
7 | SetUrlBlacklist::SetUrlBlacklist(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
8 | }
9 |
10 | void SetUrlBlacklist::start() {
11 | NetworkAccessManager* networkAccessManager = page()->networkAccessManager();
12 | networkAccessManager->setUrlBlacklist(arguments());
13 | emitFinished(true);
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/src/JsonSerializer.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class JsonSerializer : public QObject {
5 | Q_OBJECT
6 |
7 | public:
8 | JsonSerializer(QObject *parent = 0);
9 | QByteArray serialize(const QVariant &object);
10 |
11 | private:
12 | void addVariant(const QVariant &object);
13 | void addString(const QString &string);
14 | void addArray(const QVariantList &list);
15 | void addMap(const QVariantMap &map);
16 | QByteArray sanitizeString(QString string);
17 |
18 | QByteArray m_buffer;
19 | };
20 |
21 |
--------------------------------------------------------------------------------
/src/SetCookie.cpp:
--------------------------------------------------------------------------------
1 | #include "SetCookie.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "NetworkCookieJar.h"
5 | #include
6 |
7 | SetCookie::SetCookie(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
8 |
9 | void SetCookie::start()
10 | {
11 | QList cookies = QNetworkCookie::parseCookies(arguments()[0].toAscii());
12 | NetworkCookieJar *jar = manager()->cookieJar();
13 | jar->overwriteCookies(cookies);
14 | emitFinished(true);
15 | }
16 |
--------------------------------------------------------------------------------
/src/SetTimeout.cpp:
--------------------------------------------------------------------------------
1 | #include "SetTimeout.h"
2 | #include "WebPageManager.h"
3 |
4 | SetTimeout::SetTimeout(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
5 | }
6 |
7 | void SetTimeout::start() {
8 | QString timeoutString = arguments()[0];
9 | bool ok;
10 | int timeout = timeoutString.toInt(&ok);
11 |
12 | if (ok) {
13 | manager()->setTimeout(timeout);
14 | emitFinished(true);
15 | } else {
16 | emitFinished(false, QString("Invalid value for timeout"));
17 | }
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/src/Execute.cpp:
--------------------------------------------------------------------------------
1 | #include "Execute.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | Execute::Execute(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void Execute::start() {
9 | QString script = arguments()[0] + QString("; 'success'");
10 | QVariant result = page()->currentFrame()->evaluateJavaScript(script);
11 | if (result.isValid()) {
12 | emitFinished(true);
13 | } else {
14 | emitFinished(false, QString("Javascript failed to execute"));
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/JavascriptInvocation.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | class JavascriptInvocation : public QObject {
6 | Q_OBJECT
7 | Q_PROPERTY(QString functionName READ functionName)
8 | Q_PROPERTY(QStringList arguments READ arguments)
9 |
10 | public:
11 | JavascriptInvocation(const QString &functionName, const QStringList &arguments, QObject *parent = 0);
12 | QString &functionName();
13 | QStringList &arguments();
14 |
15 | private:
16 | QString m_functionName;
17 | QStringList m_arguments;
18 | };
19 |
20 |
--------------------------------------------------------------------------------
/src/SocketCommand.cpp:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | SocketCommand::SocketCommand(WebPageManager *manager, QStringList &arguments, QObject *parent) : Command(parent) {
6 | m_manager = manager;
7 | m_arguments = arguments;
8 | }
9 |
10 | WebPage *SocketCommand::page() const {
11 | return m_manager->currentPage();
12 | }
13 |
14 | const QStringList &SocketCommand::arguments() const {
15 | return m_arguments;
16 | }
17 |
18 | WebPageManager *SocketCommand::manager() const {
19 | return m_manager;
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/src/Command.cpp:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | Command::Command(QObject *parent) : QObject(parent) {
4 | }
5 |
6 | QString Command::toString() const {
7 | return metaObject()->className();
8 | }
9 |
10 | void Command::emitFinished(bool success) {
11 | emit finished(new Response(success, this));
12 | }
13 |
14 | void Command::emitFinished(bool success, QString message) {
15 | emit finished(new Response(success, message, this));
16 | }
17 |
18 | void Command::emitFinished(bool success, QByteArray message) {
19 | emit finished(new Response(success, message, this));
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/src/FrameFocus.h:
--------------------------------------------------------------------------------
1 | #include "SocketCommand.h"
2 |
3 | class QWebFrame;
4 |
5 | class FrameFocus : public SocketCommand {
6 | Q_OBJECT
7 |
8 | public:
9 | FrameFocus(WebPageManager *, QStringList &arguments, QObject *parent = 0);
10 | virtual void start();
11 |
12 | private:
13 | void findFrames();
14 |
15 | void focusParent();
16 |
17 | void focusIndex(int index);
18 | bool isFrameAtIndex(int index);
19 |
20 | void focusId(QString id);
21 |
22 | void success();
23 | void frameNotFound();
24 |
25 | QList frames;
26 | };
27 |
28 |
--------------------------------------------------------------------------------
/src/GetCookies.cpp:
--------------------------------------------------------------------------------
1 | #include "GetCookies.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "NetworkCookieJar.h"
5 |
6 | GetCookies::GetCookies(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent)
7 | {
8 | m_buffer = "";
9 | }
10 |
11 | void GetCookies::start()
12 | {
13 | NetworkCookieJar *jar = manager()->cookieJar();
14 | foreach (QNetworkCookie cookie, jar->getAllCookies()) {
15 | m_buffer.append(cookie.toRawForm());
16 | m_buffer.append("\n");
17 | }
18 | emitFinished(true, m_buffer);
19 | }
20 |
--------------------------------------------------------------------------------
/src/Command.h:
--------------------------------------------------------------------------------
1 | #ifndef COMMAND_H
2 | #define COMMAND_H
3 |
4 | #include
5 | #include "Response.h"
6 | #include
7 |
8 | class Command : public QObject {
9 | Q_OBJECT
10 |
11 | public:
12 | Command(QObject *parent = 0);
13 | virtual void start() = 0;
14 | virtual QString toString() const;
15 |
16 | protected:
17 | void emitFinished(bool success);
18 | void emitFinished(bool success, QString message);
19 | void emitFinished(bool success, QByteArray message);
20 |
21 | signals:
22 | void finished(Response *response);
23 | };
24 |
25 | #endif
26 |
27 |
--------------------------------------------------------------------------------
/src/Find.cpp:
--------------------------------------------------------------------------------
1 | #include "Find.h"
2 | #include "SocketCommand.h"
3 | #include "WebPage.h"
4 | #include "WebPageManager.h"
5 |
6 | Find::Find(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
7 | }
8 |
9 | void Find::start() {
10 | QString message;
11 | QVariant result = page()->invokeWebKitServerFunction("find", arguments());
12 |
13 | if (result.isValid()) {
14 | message = result.toString();
15 | emitFinished(true, message);
16 | } else {
17 | emitFinished(false, QString("Invalid XPath expression"));
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/src/Response.h:
--------------------------------------------------------------------------------
1 | #ifndef RESPONSE_H
2 | #define RESPONSE_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | class Response : public QObject {
9 | Q_OBJECT
10 |
11 | public:
12 | Response(bool success, QString message, QObject *parent);
13 | Response(bool success, QByteArray message, QObject *parent);
14 | Response(bool success, QObject *parent);
15 | bool isSuccess() const;
16 | QByteArray message() const;
17 | QString toString() const;
18 |
19 | private:
20 | bool m_success;
21 | QByteArray m_message;
22 | };
23 |
24 | #endif
25 |
26 |
--------------------------------------------------------------------------------
/src/Authenticate.cpp:
--------------------------------------------------------------------------------
1 | #include "Authenticate.h"
2 | #include "WebPage.h"
3 | #include "NetworkAccessManager.h"
4 |
5 | Authenticate::Authenticate(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void Authenticate::start() {
9 | QString username = arguments()[0];
10 | QString password = arguments()[1];
11 |
12 | NetworkAccessManager* networkAccessManager = page()->networkAccessManager();
13 | networkAccessManager->setUserName(username);
14 | networkAccessManager->setPassword(password);
15 |
16 | emitFinished(true);
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/src/Source.cpp:
--------------------------------------------------------------------------------
1 | #include "Source.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | Source::Source(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void Source::start() {
9 | QNetworkAccessManager* accessManager = page()->networkAccessManager();
10 | QNetworkRequest request(page()->currentFrame()->url());
11 | reply = accessManager->get(request);
12 |
13 | connect(reply, SIGNAL(finished()), this, SLOT(sourceLoaded()));
14 | }
15 |
16 | void Source::sourceLoaded() {
17 | emit finished(new Response(true, reply->readAll()));
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/src/GetWindowHandles.cpp:
--------------------------------------------------------------------------------
1 | #include "GetWindowHandles.h"
2 | #include "WebPageManager.h"
3 | #include "CommandFactory.h"
4 | #include "WebPage.h"
5 | #include "JsonSerializer.h"
6 | #include
7 |
8 | GetWindowHandles::GetWindowHandles(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
9 | }
10 |
11 | void GetWindowHandles::start() {
12 | QVariantList handles;
13 |
14 | foreach(WebPage *page, manager()->pages())
15 | handles << page->uuid();
16 |
17 | JsonSerializer serializer;
18 | QByteArray json = serializer.serialize(handles);
19 |
20 | emitFinished(true, json);
21 | }
22 |
--------------------------------------------------------------------------------
/src/SocketCommand.h:
--------------------------------------------------------------------------------
1 | #ifndef SOCKET_COMMAND_H
2 | #define SOCKET_COMMAND_H
3 |
4 | #include
5 | #include
6 | #include "Command.h"
7 |
8 | class WebPage;
9 | class WebPageManager;
10 | class Response;
11 |
12 | class SocketCommand : public Command {
13 | Q_OBJECT
14 |
15 | public:
16 | SocketCommand(WebPageManager *, QStringList &arguments, QObject *parent = 0);
17 |
18 | protected:
19 | WebPage *page() const;
20 | const QStringList &arguments() const;
21 | WebPageManager *manager() const;
22 |
23 | private:
24 | QStringList m_arguments;
25 | WebPageManager *m_manager;
26 |
27 | };
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/src/Header.cpp:
--------------------------------------------------------------------------------
1 | #include "Header.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "NetworkAccessManager.h"
5 |
6 | Header::Header(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
7 | }
8 |
9 | void Header::start() {
10 | QString key = arguments()[0];
11 | QString value = arguments()[1];
12 | NetworkAccessManager* networkAccessManager = page()->networkAccessManager();
13 | if (key.toLower().replace("-", "_") == "user_agent") {
14 | page()->setUserAgent(value);
15 | } else {
16 | networkAccessManager->addHeader(key, value);
17 | }
18 | emitFinished(true);
19 | }
20 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | # webkit-server
2 |
3 | A standalone version of the WebKit server in [capybara-webkit](https://github.com/thoughtbot/capybara-webkit).
4 |
5 | ## Dependencies
6 |
7 | webkit-server depends on a WebKit implementation from Qt, a cross-platform development toolkit. You'll need to download the Qt libraries to build the binary. See [Installing Qt](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit) for how to install it on your system.
8 |
9 | ## Building
10 |
11 | To generate the necessary files and build the binary:
12 |
13 | ./build.sh
14 |
15 | ## License
16 |
17 | webkit-server uses the MIT license. See LICENSE for more details.
18 |
--------------------------------------------------------------------------------
/src/Server.cpp:
--------------------------------------------------------------------------------
1 | #include "Server.h"
2 | #include "Connection.h"
3 | #include "WebPageManager.h"
4 |
5 | #include
6 |
7 | Server::Server(QObject *parent) : QObject(parent) {
8 | m_tcp_server = new QTcpServer(this);
9 | }
10 |
11 | bool Server::start() {
12 | connect(m_tcp_server, SIGNAL(newConnection()), this, SLOT(handleConnection()));
13 | return m_tcp_server->listen(QHostAddress::LocalHost, 0);
14 | }
15 |
16 | quint16 Server::server_port() const {
17 | return m_tcp_server->serverPort();
18 | }
19 |
20 | void Server::handleConnection() {
21 | QTcpSocket *socket = m_tcp_server->nextPendingConnection();
22 | new Connection(socket, new WebPageManager(this), this);
23 | }
24 |
--------------------------------------------------------------------------------
/src/Node.cpp:
--------------------------------------------------------------------------------
1 | #include "Node.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 |
5 | Node::Node(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
6 | }
7 |
8 | void Node::start() {
9 | QStringList functionArguments(arguments());
10 | QString functionName = functionArguments.takeFirst();
11 | QVariant result = page()->invokeWebKitServerFunction(functionName, functionArguments);
12 | QString attributeValue = result.toString();
13 | emitFinished(true, attributeValue);
14 | }
15 |
16 | QString Node::toString() const {
17 | QStringList functionArguments(arguments());
18 | return QString("Node.") + functionArguments.takeFirst();
19 | }
20 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "Server.h"
2 | #include
3 | #include
4 | #ifdef Q_OS_UNIX
5 | #include
6 | #endif
7 |
8 | int main(int argc, char **argv) {
9 | #ifdef Q_OS_UNIX
10 | if (setpgid(0, 0) < 0) {
11 | std::cerr << "Unable to set new process group." << std::endl;
12 | return 1;
13 | }
14 | #endif
15 |
16 | QApplication app(argc, argv);
17 | app.setApplicationName("webkit_server");
18 |
19 | Server server(0);
20 |
21 | if (server.start()) {
22 | std::cout << "webkit_server server started, listening on port: " << server.server_port() << std::endl;
23 | return app.exec();
24 | } else {
25 | std::cerr << "Couldn't start webkit_server." << std::endl;
26 | return 1;
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/bin/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIconFile
6 |
7 | CFBundlePackageType
8 | APPL
9 | CFBundleGetInfoString
10 | Created by Qt/QMake
11 | CFBundleSignature
12 | ????
13 | CFBundleExecutable
14 | webkit_server
15 | CFBundleIdentifier
16 | com.yourcompany.webkit_server
17 | NOTE
18 | This file was generated by Qt/QMake.
19 | LSUIElement
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/Response.cpp:
--------------------------------------------------------------------------------
1 | #include "Response.h"
2 | #include
3 |
4 | Response::Response(bool success, QString message, QObject *parent) : QObject(parent) {
5 | m_success = success;
6 | m_message = message.toUtf8();
7 | }
8 |
9 | Response::Response(bool success, QByteArray message, QObject *parent) : QObject(parent) {
10 | m_success = success;
11 | m_message = message;
12 | }
13 |
14 | Response::Response(bool success, QObject *parent) : QObject(parent) {
15 | m_success = success;
16 | }
17 |
18 | bool Response::isSuccess() const {
19 | return m_success;
20 | }
21 |
22 | QByteArray Response::message() const {
23 | return m_message;
24 | }
25 |
26 | QString Response::toString() const {
27 | return QString(m_success ? "Success(" : "Failure(") + m_message + ")";
28 | }
29 |
--------------------------------------------------------------------------------
/src/SetProxy.cpp:
--------------------------------------------------------------------------------
1 | #include "SetProxy.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "NetworkAccessManager.h"
5 | #include
6 |
7 | SetProxy::SetProxy(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {}
8 |
9 | void SetProxy::start()
10 | {
11 | // default to empty proxy
12 | QNetworkProxy proxy;
13 |
14 | if (arguments().size() > 0)
15 | proxy = QNetworkProxy(QNetworkProxy::HttpProxy,
16 | arguments()[0],
17 | (quint16)(arguments()[1].toInt()),
18 | arguments()[2],
19 | arguments()[3]);
20 |
21 | page()->networkAccessManager()->setProxy(proxy);
22 | emitFinished(true);
23 | }
24 |
--------------------------------------------------------------------------------
/src/UnsupportedContentHandler.cpp:
--------------------------------------------------------------------------------
1 | #include "UnsupportedContentHandler.h"
2 | #include "WebPage.h"
3 | #include
4 |
5 | UnsupportedContentHandler::UnsupportedContentHandler(WebPage *page, QNetworkReply *reply, QObject *parent) : QObject(parent) {
6 | m_page = page;
7 | m_reply = reply;
8 | }
9 |
10 | void UnsupportedContentHandler::renderNonHtmlContent() {
11 | QByteArray text = m_reply->readAll();
12 | m_page->mainFrame()->setContent(text, QString("text/plain"), m_reply->url());
13 | m_page->unsupportedContentFinishedReply(m_reply);
14 | this->deleteLater();
15 | }
16 |
17 | void UnsupportedContentHandler::waitForReplyToFinish() {
18 | connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
19 | }
20 |
21 | void UnsupportedContentHandler::replyFinished() {
22 | renderNonHtmlContent();
23 | }
24 |
--------------------------------------------------------------------------------
/src/CommandParser.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class QIODevice;
5 | class CommandFactory;
6 | class Command;
7 |
8 | class CommandParser : public QObject {
9 | Q_OBJECT
10 |
11 | public:
12 | CommandParser(QIODevice *device, CommandFactory *commandFactory, QObject *parent = 0);
13 |
14 | public slots:
15 | void checkNext();
16 |
17 | signals:
18 | void commandReady(Command *command);
19 |
20 | private:
21 | void readLine();
22 | void readDataBlock();
23 | void processNext(const char *line);
24 | void processArgument(const char *data);
25 | void reset();
26 | QIODevice *m_device;
27 | QString m_commandName;
28 | QStringList m_arguments;
29 | int m_argumentsExpected;
30 | int m_expectingDataSize;
31 | CommandFactory *m_commandFactory;
32 | };
33 |
34 |
--------------------------------------------------------------------------------
/src/WindowFocus.cpp:
--------------------------------------------------------------------------------
1 | #include "WindowFocus.h"
2 | #include "SocketCommand.h"
3 | #include "WebPage.h"
4 | #include "CommandFactory.h"
5 | #include "WebPageManager.h"
6 |
7 | WindowFocus::WindowFocus(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
8 | }
9 |
10 | void WindowFocus::start() {
11 | focusWindow(arguments()[0]);
12 | }
13 |
14 | void WindowFocus::windowNotFound() {
15 | emitFinished(false, QString("Unable to locate window. "));
16 | }
17 |
18 | void WindowFocus::success(WebPage *page) {
19 | page->setFocus();
20 | emitFinished(true);
21 | }
22 |
23 | void WindowFocus::focusWindow(QString selector) {
24 | foreach(WebPage *page, manager()->pages()) {
25 | if (page->matchesWindowSelector(selector)) {
26 | success(page);
27 | return;
28 | }
29 | }
30 |
31 | windowNotFound();
32 | }
33 |
--------------------------------------------------------------------------------
/src/NoOpReply.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "NoOpReply.h"
3 |
4 | NoOpReply::NoOpReply(QNetworkRequest &request, QObject *parent) : QNetworkReply(parent) {
5 | open(ReadOnly | Unbuffered);
6 | setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200);
7 | setHeader(QNetworkRequest::ContentLengthHeader, QVariant(0));
8 | setHeader(QNetworkRequest::ContentTypeHeader, QVariant(QString("text/plain")));
9 | setUrl(request.url());
10 |
11 | QTimer::singleShot( 0, this, SIGNAL(readyRead()) );
12 | QTimer::singleShot( 0, this, SIGNAL(finished()) );
13 | }
14 |
15 | void NoOpReply::abort() {
16 | // NO-OP
17 | }
18 |
19 | qint64 NoOpReply::bytesAvailable() const {
20 | return 0;
21 | }
22 |
23 | bool NoOpReply::isSequential() const {
24 | return true;
25 | }
26 |
27 | qint64 NoOpReply::readData(char *data, qint64 maxSize) {
28 | Q_UNUSED(data);
29 | Q_UNUSED(maxSize);
30 | return 0;
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/src/Connection.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class QTcpSocket;
5 | class WebPage;
6 | class Command;
7 | class Response;
8 | class CommandParser;
9 | class CommandFactory;
10 | class PageLoadingCommand;
11 | class WebPageManager;
12 |
13 | class Connection : public QObject {
14 | Q_OBJECT
15 |
16 | public:
17 | Connection(QTcpSocket *socket, WebPageManager *manager, QObject *parent = 0);
18 |
19 | public slots:
20 | void commandReady(Command *command);
21 | void finishCommand(Response *response);
22 | void pendingLoadFinished(bool success);
23 |
24 | private:
25 | void startCommand(Command *);
26 | void writeResponse(Response *response);
27 | void writePageLoadFailure();
28 |
29 | QTcpSocket *m_socket;
30 | WebPageManager *m_manager;
31 | CommandParser *m_commandParser;
32 | CommandFactory *m_commandFactory;
33 | bool m_pageSuccess;
34 | WebPage *currentPage();
35 | };
36 |
37 |
--------------------------------------------------------------------------------
/src/TimeoutCommand.h:
--------------------------------------------------------------------------------
1 | #include "Command.h"
2 | #include
3 | #include
4 |
5 | class Response;
6 | class WebPageManager;
7 | class QTimer;
8 |
9 | /* Decorates a command with a timeout.
10 | *
11 | * If the timeout, using a QTimer is reached before
12 | * the command is finished, the load page load will
13 | * be stopped and failure response will be issued.
14 | *
15 | */
16 | class TimeoutCommand : public Command {
17 | Q_OBJECT
18 |
19 | public:
20 | TimeoutCommand(Command *command, WebPageManager *page, QObject *parent = 0);
21 | virtual void start();
22 |
23 | public slots:
24 | void commandTimeout();
25 | void commandFinished(Response *response);
26 | void pageLoadingFromCommand();
27 | void pendingLoadFinished(bool);
28 |
29 | protected:
30 | void startCommand();
31 | void startTimeout();
32 |
33 | private:
34 | WebPageManager *m_manager;
35 | QTimer *m_timer;
36 | Command *m_command;
37 | };
38 |
39 |
--------------------------------------------------------------------------------
/src/PageLoadingCommand.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "Command.h"
4 |
5 | class Response;
6 | class WebPageManager;
7 |
8 | /*
9 | * Decorates a Command by deferring the finished() signal until any pending
10 | * page loads are complete.
11 | *
12 | * If a Command starts a page load, no signal will be emitted until the page
13 | * load is finished.
14 | *
15 | * If a pending page load fails, the command's response will be discarded and a
16 | * failure response will be emitted instead.
17 | */
18 | class PageLoadingCommand : public Command {
19 | Q_OBJECT
20 |
21 | public:
22 | PageLoadingCommand(Command *command, WebPageManager *page, QObject *parent = 0);
23 | virtual void start();
24 |
25 | public slots:
26 | void pageLoadingFromCommand();
27 | void pendingLoadFinished(bool success);
28 | void commandFinished(Response *response);
29 |
30 | private:
31 | WebPageManager *m_manager;
32 | Command *m_command;
33 | Response *m_pendingResponse;
34 | bool m_pageSuccess;
35 | bool m_pageLoadingFromCommand;
36 | };
37 |
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2010-2013 thoughtbot, inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/find_command.h:
--------------------------------------------------------------------------------
1 | #define CHECK_COMMAND(expectedName) \
2 | if (strcmp(#expectedName, name) == 0) { \
3 | return new expectedName(m_manager, arguments, this); \
4 | }
5 |
6 | CHECK_COMMAND(Visit)
7 | CHECK_COMMAND(Find)
8 | CHECK_COMMAND(Reset)
9 | CHECK_COMMAND(Node)
10 | CHECK_COMMAND(Evaluate)
11 | CHECK_COMMAND(Execute)
12 | CHECK_COMMAND(FrameFocus)
13 | CHECK_COMMAND(Header)
14 | CHECK_COMMAND(Render)
15 | CHECK_COMMAND(Body)
16 | CHECK_COMMAND(Status)
17 | CHECK_COMMAND(Headers)
18 | CHECK_COMMAND(SetCookie)
19 | CHECK_COMMAND(ClearCookies)
20 | CHECK_COMMAND(GetCookies)
21 | CHECK_COMMAND(SetProxy)
22 | CHECK_COMMAND(ConsoleMessages)
23 | CHECK_COMMAND(CurrentUrl)
24 | CHECK_COMMAND(ResizeWindow)
25 | CHECK_COMMAND(IgnoreSslErrors)
26 | CHECK_COMMAND(SetSkipImageLoading)
27 | CHECK_COMMAND(WindowFocus)
28 | CHECK_COMMAND(GetWindowHandles)
29 | CHECK_COMMAND(GetWindowHandle)
30 | CHECK_COMMAND(Authenticate)
31 | CHECK_COMMAND(EnableLogging)
32 | CHECK_COMMAND(SetConfirmAction)
33 | CHECK_COMMAND(SetPromptAction)
34 | CHECK_COMMAND(SetPromptText)
35 | CHECK_COMMAND(ClearPromptText)
36 | CHECK_COMMAND(JavascriptAlertMessages)
37 | CHECK_COMMAND(JavascriptConfirmMessages)
38 | CHECK_COMMAND(JavascriptPromptMessages)
39 | CHECK_COMMAND(GetTimeout)
40 | CHECK_COMMAND(SetTimeout)
41 | CHECK_COMMAND(SetUrlBlacklist)
42 |
43 |
--------------------------------------------------------------------------------
/src/CommandFactory.cpp:
--------------------------------------------------------------------------------
1 | #include "CommandFactory.h"
2 | #include "NullCommand.h"
3 | #include "SocketCommand.h"
4 | #include "Visit.h"
5 | #include "Find.h"
6 | #include "Reset.h"
7 | #include "Node.h"
8 | #include "Evaluate.h"
9 | #include "Execute.h"
10 | #include "FrameFocus.h"
11 | #include "Header.h"
12 | #include "Render.h"
13 | #include "Body.h"
14 | #include "Status.h"
15 | #include "Headers.h"
16 | #include "SetCookie.h"
17 | #include "ClearCookies.h"
18 | #include "GetCookies.h"
19 | #include "SetProxy.h"
20 | #include "ConsoleMessages.h"
21 | #include "CurrentUrl.h"
22 | #include "SetTimeout.h"
23 | #include "GetTimeout.h"
24 | #include "ResizeWindow.h"
25 | #include "IgnoreSslErrors.h"
26 | #include "SetSkipImageLoading.h"
27 | #include "WindowFocus.h"
28 | #include "GetWindowHandles.h"
29 | #include "GetWindowHandle.h"
30 | #include "WebPageManager.h"
31 | #include "Authenticate.h"
32 | #include "EnableLogging.h"
33 | #include "SetConfirmAction.h"
34 | #include "SetPromptAction.h"
35 | #include "SetPromptText.h"
36 | #include "ClearPromptText.h"
37 | #include "JavascriptAlertMessages.h"
38 | #include "JavascriptConfirmMessages.h"
39 | #include "JavascriptPromptMessages.h"
40 | #include "SetUrlBlacklist.h"
41 |
42 | CommandFactory::CommandFactory(WebPageManager *manager, QObject *parent) : QObject(parent) {
43 | m_manager = manager;
44 | }
45 |
46 | Command *CommandFactory::createCommand(const char *name, QStringList &arguments) {
47 | #include "find_command.h"
48 | return new NullCommand(QString(name));
49 | }
50 |
--------------------------------------------------------------------------------
/src/NetworkAccessManager.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | class NetworkAccessManager : public QNetworkAccessManager {
7 |
8 | Q_OBJECT
9 |
10 | struct NetworkResponse {
11 | int statusCode;
12 | QList headers;
13 | NetworkResponse() : statusCode(0) { }
14 | };
15 |
16 | public:
17 | NetworkAccessManager(QObject *parent = 0);
18 | void addHeader(QString key, QString value);
19 | void resetHeaders();
20 | void setUserName(const QString &userName);
21 | void setPassword(const QString &password);
22 | int statusFor(QUrl url);
23 | const QList &headersFor(QUrl url);
24 | void setUrlBlacklist(QStringList urlBlacklist);
25 |
26 | protected:
27 | QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice * outgoingData);
28 | QString m_userName;
29 | QString m_password;
30 | QList m_urlBlacklist;
31 |
32 |
33 | private:
34 | QHash m_headers;
35 | QHash m_responses;
36 | bool isBlacklisted(QUrl url);
37 | QHash m_redirectMappings;
38 |
39 | private slots:
40 | void provideAuthentication(QNetworkReply *reply, QAuthenticator *authenticator);
41 | void finished(QNetworkReply *);
42 |
43 | signals:
44 | void requestCreated(QByteArray &url, QNetworkReply *reply);
45 | };
46 |
--------------------------------------------------------------------------------
/src/WebPageManager.h:
--------------------------------------------------------------------------------
1 | #ifndef _WEBPAGEMANAGER_H
2 | #define _WEBPAGEMANAGER_H
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | class WebPage;
11 | class NetworkCookieJar;
12 |
13 | class WebPageManager : public QObject {
14 | Q_OBJECT
15 |
16 | public:
17 | WebPageManager(QObject *parent = 0);
18 | void append(WebPage *value);
19 | QList pages() const;
20 | void setCurrentPage(WebPage *);
21 | WebPage *currentPage() const;
22 | WebPage *createPage(QObject *parent);
23 | void setIgnoreSslErrors(bool);
24 | bool ignoreSslErrors();
25 | void setTimeout(int);
26 | int getTimeout();
27 | void reset();
28 | NetworkCookieJar *cookieJar();
29 | bool isLoading() const;
30 | QDebug logger() const;
31 | void enableLogging();
32 | void replyFinished(QNetworkReply *reply);
33 |
34 | public slots:
35 | void emitLoadStarted();
36 | void setPageStatus(bool);
37 | void requestCreated(QByteArray &url, QNetworkReply *reply);
38 | void handleReplyFinished();
39 |
40 | signals:
41 | void pageFinished(bool);
42 | void loadStarted();
43 |
44 | private:
45 | void emitPageFinished();
46 | static void handleDebugMessage(QtMsgType type, const char *message);
47 |
48 | QList m_pages;
49 | WebPage *m_currentPage;
50 | bool m_ignoreSslErrors;
51 | NetworkCookieJar *m_cookieJar;
52 | QSet m_started;
53 | bool m_success;
54 | bool m_loggingEnabled;
55 | QFile *m_ignoredOutput;
56 | int m_timeout;
57 | };
58 |
59 | #endif // _WEBPAGEMANAGER_H
60 |
61 |
--------------------------------------------------------------------------------
/src/FrameFocus.cpp:
--------------------------------------------------------------------------------
1 | #include "FrameFocus.h"
2 | #include "SocketCommand.h"
3 | #include "WebPage.h"
4 | #include "WebPageManager.h"
5 |
6 | FrameFocus::FrameFocus(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
7 | }
8 |
9 | void FrameFocus::start() {
10 | findFrames();
11 | switch(arguments().length()) {
12 | case 1:
13 | focusId(arguments()[0]);
14 | break;
15 | case 2:
16 | focusIndex(arguments()[1].toInt());
17 | break;
18 | default:
19 | focusParent();
20 | }
21 | }
22 |
23 | void FrameFocus::findFrames() {
24 | frames = page()->currentFrame()->childFrames();
25 | }
26 |
27 | void FrameFocus::focusIndex(int index) {
28 | if (isFrameAtIndex(index)) {
29 | frames[index]->setFocus();
30 | success();
31 | } else {
32 | frameNotFound();
33 | }
34 | }
35 |
36 | bool FrameFocus::isFrameAtIndex(int index) {
37 | return 0 <= index && index < frames.length();
38 | }
39 |
40 | void FrameFocus::focusId(QString name) {
41 | for (int i = 0; i < frames.length(); i++) {
42 | if (frames[i]->frameName().compare(name) == 0) {
43 | frames[i]->setFocus();
44 | success();
45 | return;
46 | }
47 | }
48 |
49 | frameNotFound();
50 | }
51 |
52 | void FrameFocus::focusParent() {
53 | if (page()->currentFrame()->parentFrame() == 0) {
54 | emitFinished(false, QString("Already at parent frame."));
55 | } else {
56 | page()->currentFrame()->parentFrame()->setFocus();
57 | success();
58 | }
59 | }
60 |
61 | void FrameFocus::frameNotFound() {
62 | emitFinished(false, QString("Unable to locate frame. "));
63 | }
64 |
65 | void FrameFocus::success() {
66 | emitFinished(true);
67 | }
68 |
--------------------------------------------------------------------------------
/src/PageLoadingCommand.cpp:
--------------------------------------------------------------------------------
1 | #include "PageLoadingCommand.h"
2 | #include "SocketCommand.h"
3 | #include "WebPage.h"
4 | #include "WebPageManager.h"
5 |
6 | PageLoadingCommand::PageLoadingCommand(Command *command, WebPageManager *manager, QObject *parent) : Command(parent) {
7 | m_manager = manager;
8 | m_command = command;
9 | m_pageLoadingFromCommand = false;
10 | m_pageSuccess = true;
11 | m_pendingResponse = NULL;
12 | m_command->setParent(this);
13 | }
14 |
15 | void PageLoadingCommand::start() {
16 | m_manager->logger() << "Started" << m_command->toString();
17 | connect(m_command, SIGNAL(finished(Response *)), this, SLOT(commandFinished(Response *)));
18 | connect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
19 | connect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
20 | m_command->start();
21 | };
22 |
23 | void PageLoadingCommand::pendingLoadFinished(bool success) {
24 | m_pageSuccess = success;
25 | if (m_pageLoadingFromCommand) {
26 | m_pageLoadingFromCommand = false;
27 | if (m_pendingResponse) {
28 | m_manager->logger() << "Page load from command finished";
29 | if (m_pageSuccess) {
30 | emit finished(m_pendingResponse);
31 | } else {
32 | QString message = m_manager->currentPage()->failureString();
33 | emitFinished(false, message);
34 | }
35 | }
36 | }
37 | }
38 |
39 | void PageLoadingCommand::pageLoadingFromCommand() {
40 | m_manager->logger() << m_command->toString() << "started page load";
41 | m_pageLoadingFromCommand = true;
42 | }
43 |
44 | void PageLoadingCommand::commandFinished(Response *response) {
45 | disconnect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
46 | m_manager->logger() << "Finished" << m_command->toString() << "with response" << response->toString();
47 |
48 | if (m_pageLoadingFromCommand)
49 | m_pendingResponse = response;
50 | else
51 | emit finished(response);
52 | }
53 |
--------------------------------------------------------------------------------
/src/CommandParser.cpp:
--------------------------------------------------------------------------------
1 | #include "CommandParser.h"
2 | #include "CommandFactory.h"
3 | #include "SocketCommand.h"
4 |
5 | #include
6 |
7 | CommandParser::CommandParser(QIODevice *device, CommandFactory *commandFactory, QObject *parent) :
8 | QObject(parent) {
9 | m_device = device;
10 | m_expectingDataSize = -1;
11 | m_commandFactory = commandFactory;
12 | connect(m_device, SIGNAL(readyRead()), this, SLOT(checkNext()));
13 | }
14 |
15 | void CommandParser::checkNext() {
16 | if (m_expectingDataSize == -1) {
17 | if (m_device->canReadLine()) {
18 | readLine();
19 | checkNext();
20 | }
21 | } else {
22 | if (m_device->bytesAvailable() >= m_expectingDataSize) {
23 | readDataBlock();
24 | checkNext();
25 | }
26 | }
27 | }
28 |
29 | void CommandParser::readLine() {
30 | char buffer[128];
31 | qint64 lineLength = m_device->readLine(buffer, 128);
32 | if (lineLength != -1) {
33 | buffer[lineLength - 1] = 0;
34 | processNext(buffer);
35 | }
36 | }
37 |
38 | void CommandParser::readDataBlock() {
39 | char *buffer = new char[m_expectingDataSize + 1];
40 | m_device->read(buffer, m_expectingDataSize);
41 | buffer[m_expectingDataSize] = 0;
42 | processNext(buffer);
43 | m_expectingDataSize = -1;
44 | delete[] buffer;
45 | }
46 |
47 | void CommandParser::processNext(const char *data) {
48 | if (m_commandName.isNull()) {
49 | m_commandName = data;
50 | m_argumentsExpected = -1;
51 | } else {
52 | processArgument(data);
53 | }
54 | }
55 |
56 | void CommandParser::processArgument(const char *data) {
57 | if (m_argumentsExpected == -1) {
58 | m_argumentsExpected = QString(data).toInt();
59 | } else if (m_expectingDataSize == -1) {
60 | m_expectingDataSize = QString(data).toInt();
61 | } else {
62 | m_arguments.append(QString::fromUtf8(data));
63 | }
64 |
65 | if (m_arguments.length() == m_argumentsExpected) {
66 | Command *command = m_commandFactory->createCommand(m_commandName.toAscii().constData(), m_arguments);
67 | emit commandReady(command);
68 | reset();
69 | }
70 | }
71 |
72 | void CommandParser::reset() {
73 | m_commandName = QString();
74 | m_arguments.clear();
75 | m_argumentsExpected = -1;
76 | }
77 |
--------------------------------------------------------------------------------
/src/Connection.cpp:
--------------------------------------------------------------------------------
1 | #include "Connection.h"
2 | #include "WebPage.h"
3 | #include "WebPageManager.h"
4 | #include "CommandParser.h"
5 | #include "CommandFactory.h"
6 | #include "PageLoadingCommand.h"
7 | #include "TimeoutCommand.h"
8 | #include "SocketCommand.h"
9 |
10 | #include
11 |
12 | Connection::Connection(QTcpSocket *socket, WebPageManager *manager, QObject *parent) :
13 | QObject(parent) {
14 | m_socket = socket;
15 | m_manager = manager;
16 | m_commandFactory = new CommandFactory(m_manager, this);
17 | m_commandParser = new CommandParser(socket, m_commandFactory, this);
18 | m_pageSuccess = true;
19 | connect(m_socket, SIGNAL(readyRead()), m_commandParser, SLOT(checkNext()));
20 | connect(m_commandParser, SIGNAL(commandReady(Command *)), this, SLOT(commandReady(Command *)));
21 | connect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
22 | }
23 |
24 | void Connection::commandReady(Command *command) {
25 | m_manager->logger() << "Received" << command->toString();
26 | startCommand(command);
27 | }
28 |
29 | void Connection::startCommand(Command *command) {
30 | if (m_pageSuccess) {
31 | command = new TimeoutCommand(new PageLoadingCommand(command, m_manager, this), m_manager, this);
32 | connect(command, SIGNAL(finished(Response *)), this, SLOT(finishCommand(Response *)));
33 | command->start();
34 | } else {
35 | writePageLoadFailure();
36 | }
37 | }
38 |
39 | void Connection::pendingLoadFinished(bool success) {
40 | m_pageSuccess = m_pageSuccess && success;
41 | }
42 |
43 | void Connection::writePageLoadFailure() {
44 | m_pageSuccess = true;
45 | QString message = currentPage()->failureString();
46 | Response *response = new Response(false, message, this);
47 | writeResponse(response);
48 | delete response;
49 | }
50 |
51 | void Connection::finishCommand(Response *response) {
52 | m_pageSuccess = true;
53 | writeResponse(response);
54 | sender()->deleteLater();
55 | }
56 |
57 | void Connection::writeResponse(Response *response) {
58 | if (response->isSuccess())
59 | m_socket->write("ok\n");
60 | else
61 | m_socket->write("failure\n");
62 |
63 | m_manager->logger() << "Wrote response" << response->isSuccess() << response->message();
64 |
65 | QByteArray messageUtf8 = response->message();
66 | QString messageLength = QString::number(messageUtf8.size()) + "\n";
67 | m_socket->write(messageLength.toAscii());
68 | m_socket->write(messageUtf8);
69 | }
70 |
71 | WebPage *Connection::currentPage() {
72 | return m_manager->currentPage();
73 | }
74 |
--------------------------------------------------------------------------------
/src/TimeoutCommand.cpp:
--------------------------------------------------------------------------------
1 | #include "TimeoutCommand.h"
2 | #include "Command.h"
3 | #include "WebPageManager.h"
4 | #include "WebPage.h"
5 | #include
6 | #include
7 |
8 | TimeoutCommand::TimeoutCommand(Command *command, WebPageManager *manager, QObject *parent) : Command(parent) {
9 | m_command = command;
10 | m_manager = manager;
11 | m_timer = new QTimer(this);
12 | m_timer->setSingleShot(true);
13 | m_command->setParent(this);
14 | connect(m_timer, SIGNAL(timeout()), this, SLOT(commandTimeout()));
15 | connect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
16 | }
17 |
18 | void TimeoutCommand::start() {
19 | QApplication::processEvents();
20 | if (m_manager->isLoading()) {
21 | m_manager->logger() << this->toString() << "waiting for load to finish";
22 | connect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
23 | startTimeout();
24 | } else {
25 | startCommand();
26 | }
27 | }
28 |
29 | void TimeoutCommand::startCommand() {
30 | connect(m_command, SIGNAL(finished(Response *)), this, SLOT(commandFinished(Response *)));
31 | m_command->start();
32 | }
33 |
34 | void TimeoutCommand::startTimeout() {
35 | int timeout = m_manager->getTimeout();
36 | if (timeout > 0) {
37 | m_timer->start(timeout * 1000);
38 | }
39 | }
40 |
41 | void TimeoutCommand::pendingLoadFinished(bool success) {
42 | disconnect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
43 | if (success) {
44 | startCommand();
45 | } else {
46 | disconnect(m_timer, SIGNAL(timeout()), this, SLOT(commandTimeout()));
47 | disconnect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
48 | emitFinished(false, m_manager->currentPage()->failureString());
49 | }
50 | }
51 |
52 | void TimeoutCommand::pageLoadingFromCommand() {
53 | startTimeout();
54 | }
55 |
56 | void TimeoutCommand::commandTimeout() {
57 | disconnect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
58 | disconnect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
59 | disconnect(m_command, SIGNAL(finished(Response *)), this, SLOT(commandFinished(Response *)));
60 | m_manager->currentPage()->triggerAction(QWebPage::Stop);
61 | emit finished(new Response(false, QString("timeout"), this));
62 | }
63 |
64 | void TimeoutCommand::commandFinished(Response *response) {
65 | disconnect(m_timer, SIGNAL(timeout()), this, SLOT(commandTimeout()));
66 | disconnect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
67 | emit finished(response);
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/src/webkit_server.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = app
2 | TARGET = webkit_server
3 | DESTDIR = .
4 | HEADERS = \
5 | EnableLogging.h \
6 | Authenticate.h \
7 | SetConfirmAction.h \
8 | SetPromptAction.h \
9 | SetPromptText.h \
10 | ClearPromptText.h \
11 | JavascriptAlertMessages.h \
12 | JavascriptConfirmMessages.h \
13 | JavascriptPromptMessages.h \
14 | IgnoreSslErrors.h \
15 | ResizeWindow.h \
16 | CurrentUrl.h \
17 | ConsoleMessages.h \
18 | WebPage.h \
19 | Server.h \
20 | Connection.h \
21 | Command.h \
22 | SocketCommand.h \
23 | Visit.h \
24 | Find.h \
25 | Reset.h \
26 | Node.h \
27 | JavascriptInvocation.h \
28 | Evaluate.h \
29 | Execute.h \
30 | FrameFocus.h \
31 | Response.h \
32 | NetworkAccessManager.h \
33 | NetworkCookieJar.h \
34 | Header.h \
35 | Render.h \
36 | Body.h \
37 | Status.h \
38 | Headers.h \
39 | UnsupportedContentHandler.h \
40 | SetCookie.h \
41 | ClearCookies.h \
42 | GetCookies.h \
43 | CommandParser.h \
44 | CommandFactory.h \
45 | SetProxy.h \
46 | NullCommand.h \
47 | PageLoadingCommand.h \
48 | SetSkipImageLoading.h \
49 | WebPageManager.h \
50 | WindowFocus.h \
51 | GetWindowHandles.h \
52 | GetWindowHandle.h \
53 | GetTimeout.h \
54 | SetTimeout.h \
55 | TimeoutCommand.h \
56 | SetUrlBlacklist.h \
57 | NoOpReply.h \
58 | JsonSerializer.h
59 |
60 | SOURCES = \
61 | EnableLogging.cpp \
62 | Authenticate.cpp \
63 | SetConfirmAction.cpp \
64 | SetPromptAction.cpp \
65 | SetPromptText.cpp \
66 | ClearPromptText.cpp \
67 | JavascriptAlertMessages.cpp \
68 | JavascriptConfirmMessages.cpp \
69 | JavascriptPromptMessages.cpp \
70 | IgnoreSslErrors.cpp \
71 | ResizeWindow.cpp \
72 | CurrentUrl.cpp \
73 | ConsoleMessages.cpp \
74 | main.cpp \
75 | WebPage.cpp \
76 | Server.cpp \
77 | Connection.cpp \
78 | Command.cpp \
79 | SocketCommand.cpp \
80 | Visit.cpp \
81 | Find.cpp \
82 | Reset.cpp \
83 | Node.cpp \
84 | JavascriptInvocation.cpp \
85 | Evaluate.cpp \
86 | Execute.cpp \
87 | FrameFocus.cpp \
88 | Response.cpp \
89 | NetworkAccessManager.cpp \
90 | NetworkCookieJar.cpp \
91 | Header.cpp \
92 | Render.cpp \
93 | body.cpp \
94 | Status.cpp \
95 | Headers.cpp \
96 | UnsupportedContentHandler.cpp \
97 | SetCookie.cpp \
98 | ClearCookies.cpp \
99 | GetCookies.cpp \
100 | CommandParser.cpp \
101 | CommandFactory.cpp \
102 | SetProxy.cpp \
103 | NullCommand.cpp \
104 | PageLoadingCommand.cpp \
105 | SetTimeout.cpp \
106 | GetTimeout.cpp \
107 | SetSkipImageLoading.cpp \
108 | WebPageManager.cpp \
109 | WindowFocus.cpp \
110 | GetWindowHandles.cpp \
111 | GetWindowHandle.cpp \
112 | TimeoutCommand.cpp \
113 | SetUrlBlacklist.cpp \
114 | NoOpReply.cpp \
115 | JsonSerializer.cpp
116 |
117 | RESOURCES = webkit_server.qrc
118 | QT += network webkit
119 | CONFIG += console
120 | CONFIG -= app_bundle
121 |
122 |
--------------------------------------------------------------------------------
/src/JsonSerializer.cpp:
--------------------------------------------------------------------------------
1 | #include "JsonSerializer.h"
2 | #include
3 |
4 | JsonSerializer::JsonSerializer(QObject *parent) : QObject(parent) {
5 | }
6 |
7 | QByteArray JsonSerializer::serialize(const QVariant &object) {
8 | addVariant(object);
9 | return m_buffer;
10 | }
11 |
12 | void JsonSerializer::addVariant(const QVariant &object) {
13 | if (object.isValid()) {
14 | switch(object.type()) {
15 | case QMetaType::QString:
16 | {
17 | QString string = object.toString();
18 | addString(string);
19 | }
20 | break;
21 | case QMetaType::QVariantList:
22 | {
23 | QVariantList list = object.toList();
24 | addArray(list);
25 | }
26 | break;
27 | case QMetaType::Double:
28 | if (std::isinf(object.toDouble()))
29 | m_buffer.append("null");
30 | else
31 | m_buffer.append(object.toString());
32 | break;
33 | case QMetaType::QVariantMap:
34 | {
35 | QVariantMap map = object.toMap();
36 | addMap(map);
37 | break;
38 | }
39 | case QMetaType::Bool:
40 | {
41 | m_buffer.append(object.toString());
42 | break;
43 | }
44 | case QMetaType::Int:
45 | {
46 | m_buffer.append(object.toString());
47 | break;
48 | }
49 | default:
50 | m_buffer.append("null");
51 | }
52 | } else {
53 | m_buffer.append("null");
54 | }
55 | }
56 |
57 | void JsonSerializer::addString(const QString &string) {
58 | m_buffer.append("\"");
59 | m_buffer.append(sanitizeString(string));
60 | m_buffer.append("\"");
61 | }
62 |
63 | void JsonSerializer::addArray(const QVariantList &list) {
64 | m_buffer.append("[");
65 | for (int i = 0; i < list.length(); i++) {
66 | if (i > 0)
67 | m_buffer.append(",");
68 | addVariant(list[i]);
69 | }
70 | m_buffer.append("]");
71 | }
72 |
73 | void JsonSerializer::addMap(const QVariantMap &map) {
74 | m_buffer.append("{");
75 | QMapIterator iterator(map);
76 | while (iterator.hasNext()) {
77 | iterator.next();
78 | QString key = iterator.key();
79 | QVariant value = iterator.value();
80 | addString(key);
81 | m_buffer.append(":");
82 | addVariant(value);
83 | if (iterator.hasNext())
84 | m_buffer.append(",");
85 | }
86 | m_buffer.append("}");
87 | }
88 |
89 | QByteArray JsonSerializer::sanitizeString(QString str) {
90 | str.replace("\\", "\\\\");
91 | str.replace("\"", "\\\"");
92 | str.replace("\b", "\\b");
93 | str.replace("\f", "\\f");
94 | str.replace("\n", "\\n");
95 | str.replace("\r", "\\r");
96 | str.replace("\t", "\\t");
97 |
98 | QByteArray result;
99 | const ushort* unicode = str.utf16();
100 | unsigned int i = 0;
101 |
102 | while (unicode[i]) {
103 | if (unicode[i] > 31 && unicode[i] < 128) {
104 | result.append(unicode[i]);
105 | }
106 | else {
107 | QString hexCode = QString::number(unicode[i], 16).rightJustified(4, '0');
108 |
109 | result.append("\\u").append(hexCode);
110 | }
111 | ++i;
112 | }
113 |
114 | return result;
115 | }
116 |
117 |
--------------------------------------------------------------------------------
/src/WebPage.h:
--------------------------------------------------------------------------------
1 | #ifndef _WEBPAGE_H
2 | #define _WEBPAGE_H
3 | #include
4 |
5 | class WebPageManager;
6 | class NetworkAccessManager;
7 |
8 | class WebPage : public QWebPage {
9 | Q_OBJECT
10 |
11 | public:
12 | WebPage(WebPageManager *, QObject *parent = 0);
13 | QVariant invokeWebKitServerFunction(const char *name, const QStringList &arguments);
14 | QVariant invokeWebKitServerFunction(QString &name, const QStringList &arguments);
15 | QString failureString();
16 | QString userAgentForUrl(const QUrl &url ) const;
17 | void setUserAgent(QString userAgent);
18 | void setConfirmAction(QString action);
19 | void setPromptAction(QString action);
20 | void setPromptText(QString action);
21 | int getLastStatus();
22 | void setCustomNetworkAccessManager();
23 | bool render(const QString &fileName, const QSize &minimumSize);
24 | virtual bool extension (Extension extension, const ExtensionOption *option=0, ExtensionReturn *output=0);
25 | void setSkipImageLoading(bool skip);
26 | QVariantList consoleMessages();
27 | QVariantList alertMessages();
28 | QVariantList confirmMessages();
29 | QVariantList promptMessages();
30 | void resetWindowSize();
31 | QWebPage *createWindow(WebWindowType type);
32 | QString uuid();
33 | QString getWindowName();
34 | bool matchesWindowSelector(QString);
35 | void setFocus();
36 | NetworkAccessManager *networkAccessManager();
37 | bool unsupportedContentLoaded();
38 | void unsupportedContentFinishedReply(QNetworkReply *reply);
39 |
40 | public slots:
41 | bool shouldInterruptJavaScript();
42 | void injectJavascriptHelpers();
43 | void loadStarted();
44 | void loadFinished(bool);
45 | bool isLoading() const;
46 | const QList &pageHeaders();
47 | void frameCreated(QWebFrame *);
48 | void handleSslErrorsForReply(QNetworkReply *reply, const QList &);
49 | void handleUnsupportedContent(QNetworkReply *reply);
50 |
51 | signals:
52 | void pageFinished(bool);
53 | void requestCreated(QByteArray &url, QNetworkReply *reply);
54 | void replyFinished(QNetworkReply *reply);
55 |
56 | protected:
57 | virtual void javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID);
58 | virtual void javaScriptAlert(QWebFrame *frame, const QString &message);
59 | virtual bool javaScriptConfirm(QWebFrame *frame, const QString &message);
60 | virtual bool javaScriptPrompt(QWebFrame *frame, const QString &message, const QString &defaultValue, QString *result);
61 | virtual QString chooseFile(QWebFrame * parentFrame, const QString &suggestedFile);
62 | virtual bool supportsExtension(Extension extension) const;
63 |
64 | private:
65 | QString m_javascriptString;
66 | QString m_userAgent;
67 | bool m_loading;
68 | bool m_failed;
69 | QStringList getAttachedFileNames();
70 | void loadJavascript();
71 | void setUserStylesheet();
72 | bool m_confirm;
73 | bool m_prompt;
74 | QVariantList m_consoleMessages;
75 | QVariantList m_alertMessages;
76 | QVariantList m_confirmMessages;
77 | QString m_prompt_text;
78 | QVariantList m_promptMessages;
79 | QString m_uuid;
80 | WebPageManager *m_manager;
81 | QString m_errorPageMessage;
82 | bool m_unsupportedContentLoaded;
83 | };
84 |
85 | #endif //_WEBPAGE_H
86 |
87 |
--------------------------------------------------------------------------------
/src/NetworkCookieJar.cpp:
--------------------------------------------------------------------------------
1 | #include "NetworkCookieJar.h"
2 | #include "QtCore/qdatetime.h"
3 |
4 | NetworkCookieJar::NetworkCookieJar(QObject *parent)
5 | : QNetworkCookieJar(parent)
6 | { }
7 |
8 | QList NetworkCookieJar::getAllCookies() const
9 | {
10 | return allCookies();
11 | }
12 |
13 | void NetworkCookieJar::clearCookies()
14 | {
15 | setAllCookies(QList());
16 | }
17 |
18 | static inline bool isParentDomain(QString domain, QString reference)
19 | {
20 | if (!reference.startsWith(QLatin1Char('.')))
21 | return domain == reference;
22 |
23 | return domain.endsWith(reference) || domain == reference.mid(1);
24 | }
25 |
26 | void NetworkCookieJar::overwriteCookies(const QList& cookieList)
27 | {
28 | /* this function is basically a copy-and-paste of the original
29 | QNetworkCookieJar::setCookiesFromUrl with the domain and
30 | path validations removed */
31 |
32 | QString defaultPath(QLatin1Char('/'));
33 | QDateTime now = QDateTime::currentDateTime();
34 | QList newCookies = allCookies();
35 |
36 | foreach (QNetworkCookie cookie, cookieList) {
37 | bool isDeletion = (!cookie.isSessionCookie() &&
38 | cookie.expirationDate() < now);
39 |
40 | // validate the cookie & set the defaults if unset
41 | if (cookie.path().isEmpty())
42 | cookie.setPath(defaultPath);
43 |
44 | // don't do path checking. See http://bugreports.qt.nokia.com/browse/QTBUG-5815
45 | // else if (!isParentPath(pathAndFileName, cookie.path())) {
46 | // continue; // not accepted
47 | // }
48 |
49 | if (cookie.domain().isEmpty()) {
50 | continue;
51 | } else {
52 | // Ensure the domain starts with a dot if its field was not empty
53 | // in the HTTP header. There are some servers that forget the
54 | // leading dot and this is actually forbidden according to RFC 2109,
55 | // but all browsers accept it anyway so we do that as well.
56 | if (!cookie.domain().startsWith(QLatin1Char('.')))
57 | cookie.setDomain(QLatin1Char('.') + cookie.domain());
58 |
59 | QString domain = cookie.domain();
60 |
61 | // the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2
62 | // redundant; the "leading dot" rule has been relaxed anyway, see above
63 | // we remove the leading dot for this check
64 | /*
65 | if (QNetworkCookieJarPrivate::isEffectiveTLD(domain.remove(0, 1)))
66 | continue; // not accepted
67 | */
68 | }
69 |
70 | for (int i = 0; i < newCookies.size(); ++i) {
71 | // does this cookie already exist?
72 | const QNetworkCookie ¤t = newCookies.at(i);
73 | if (cookie.name() == current.name() &&
74 | cookie.domain() == current.domain() &&
75 | cookie.path() == current.path()) {
76 | // found a match
77 | newCookies.removeAt(i);
78 | break;
79 | }
80 | }
81 |
82 | // did not find a match
83 | if (!isDeletion) {
84 | int countForDomain = 0;
85 | for (int i = newCookies.size() - 1; i >= 0; --i) {
86 | // Start from the end and delete the oldest cookies to keep a maximum count of 50.
87 | const QNetworkCookie ¤t = newCookies.at(i);
88 | if (isParentDomain(cookie.domain(), current.domain())
89 | || isParentDomain(current.domain(), cookie.domain())) {
90 | if (countForDomain >= 49)
91 | newCookies.removeAt(i);
92 | else
93 | ++countForDomain;
94 | }
95 | }
96 |
97 | newCookies += cookie;
98 | }
99 | }
100 | setAllCookies(newCookies);
101 | }
102 |
--------------------------------------------------------------------------------
/src/WebPageManager.cpp:
--------------------------------------------------------------------------------
1 | #include "WebPageManager.h"
2 | #include "WebPage.h"
3 | #include "NetworkCookieJar.h"
4 |
5 | WebPageManager::WebPageManager(QObject *parent) : QObject(parent) {
6 | m_ignoreSslErrors = false;
7 | m_cookieJar = new NetworkCookieJar(this);
8 | m_success = true;
9 | m_loggingEnabled = false;
10 | m_ignoredOutput = new QFile(this);
11 | m_timeout = -1;
12 | createPage(this)->setFocus();
13 | }
14 |
15 | void WebPageManager::append(WebPage *value) {
16 | m_pages.append(value);
17 | }
18 |
19 | QList WebPageManager::pages() const {
20 | return m_pages;
21 | }
22 |
23 | void WebPageManager::setCurrentPage(WebPage *page) {
24 | m_currentPage = page;
25 | }
26 |
27 | WebPage *WebPageManager::currentPage() const {
28 | return m_currentPage;
29 | }
30 |
31 | WebPage *WebPageManager::createPage(QObject *parent) {
32 | WebPage *page = new WebPage(this, parent);
33 | connect(page, SIGNAL(loadStarted()),
34 | this, SLOT(emitLoadStarted()));
35 | connect(page, SIGNAL(pageFinished(bool)),
36 | this, SLOT(setPageStatus(bool)));
37 | connect(page, SIGNAL(requestCreated(QByteArray &, QNetworkReply *)),
38 | this, SLOT(requestCreated(QByteArray &, QNetworkReply *)));
39 | append(page);
40 | return page;
41 | }
42 |
43 | void WebPageManager::emitLoadStarted() {
44 | if (m_started.empty()) {
45 | logger() << "Load started";
46 | emit loadStarted();
47 | }
48 | m_started += qobject_cast(sender());
49 | }
50 |
51 | void WebPageManager::requestCreated(QByteArray &url, QNetworkReply *reply) {
52 | logger() << "Started request to" << url;
53 | if (reply->isFinished())
54 | replyFinished(reply);
55 | else {
56 | connect(reply, SIGNAL(finished()), SLOT(handleReplyFinished()));
57 | }
58 | }
59 |
60 | void WebPageManager::handleReplyFinished() {
61 | QNetworkReply *reply = qobject_cast(sender());
62 | disconnect(reply, SIGNAL(finished()), this, SLOT(handleReplyFinished()));
63 | replyFinished(reply);
64 | }
65 |
66 | void WebPageManager::replyFinished(QNetworkReply *reply) {
67 | int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
68 | logger() << "Received" << status << "from" << reply->url().toString();
69 | }
70 |
71 | void WebPageManager::setPageStatus(bool success) {
72 | logger() << "Page finished with" << success;
73 | m_started.remove(qobject_cast(sender()));
74 | m_success = success && m_success;
75 | if (m_started.empty()) {
76 | emitPageFinished();
77 | }
78 | }
79 |
80 | void WebPageManager::emitPageFinished() {
81 | logger() << "Load finished";
82 | emit pageFinished(m_success);
83 | m_success = true;
84 | }
85 |
86 | void WebPageManager::setIgnoreSslErrors(bool value) {
87 | m_ignoreSslErrors = value;
88 | }
89 |
90 | bool WebPageManager::ignoreSslErrors() {
91 | return m_ignoreSslErrors;
92 | }
93 |
94 | int WebPageManager::getTimeout() {
95 | return m_timeout;
96 | }
97 |
98 | void WebPageManager::setTimeout(int timeout) {
99 | m_timeout = timeout;
100 | }
101 |
102 | void WebPageManager::reset() {
103 | m_timeout = -1;
104 | m_cookieJar->clearCookies();
105 | m_pages.first()->deleteLater();
106 | m_pages.clear();
107 | createPage(this)->setFocus();
108 | }
109 |
110 | NetworkCookieJar *WebPageManager::cookieJar() {
111 | return m_cookieJar;
112 | }
113 |
114 | bool WebPageManager::isLoading() const {
115 | foreach(WebPage *page, pages()) {
116 | if (page->isLoading()) {
117 | return true;
118 | }
119 | }
120 | return false;
121 | }
122 |
123 | QDebug WebPageManager::logger() const {
124 | if (m_loggingEnabled)
125 | return qDebug();
126 | else
127 | return QDebug(m_ignoredOutput);
128 | }
129 |
130 | void WebPageManager::enableLogging() {
131 | m_loggingEnabled = true;
132 | }
133 |
--------------------------------------------------------------------------------
/src/NetworkAccessManager.cpp:
--------------------------------------------------------------------------------
1 | #include "NetworkAccessManager.h"
2 | #include "WebPage.h"
3 | #include
4 | #include
5 | #include "NoOpReply.h"
6 |
7 | NetworkAccessManager::NetworkAccessManager(QObject *parent):QNetworkAccessManager(parent) {
8 | connect(this, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(provideAuthentication(QNetworkReply*,QAuthenticator*)));
9 | connect(this, SIGNAL(finished(QNetworkReply *)), this, SLOT(finished(QNetworkReply *)));
10 | }
11 |
12 | QNetworkReply* NetworkAccessManager::createRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice * outgoingData = 0) {
13 | QNetworkRequest new_request(request);
14 | QByteArray url = new_request.url().toEncoded();
15 | if (this->isBlacklisted(new_request.url())) {
16 | return new NoOpReply(new_request, this);
17 | } else {
18 | if (operation != QNetworkAccessManager::PostOperation && operation != QNetworkAccessManager::PutOperation) {
19 | new_request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant());
20 | }
21 | QHashIterator item(m_headers);
22 | while (item.hasNext()) {
23 | item.next();
24 | new_request.setRawHeader(item.key().toAscii(), item.value().toAscii());
25 | }
26 | QNetworkReply *reply = QNetworkAccessManager::createRequest(operation, new_request, outgoingData);
27 | emit requestCreated(url, reply);
28 | return reply;
29 | }
30 | };
31 |
32 | void NetworkAccessManager::finished(QNetworkReply *reply) {
33 | QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
34 | if (redirectUrl.isValid())
35 | m_redirectMappings[reply->url().resolved(redirectUrl)] = reply->url();
36 | else {
37 | QUrl requestedUrl = reply->url();
38 | while (m_redirectMappings.contains(requestedUrl))
39 | requestedUrl = m_redirectMappings.take(requestedUrl);
40 | NetworkResponse response;
41 | response.statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
42 | response.headers = reply->rawHeaderPairs();
43 | m_responses[requestedUrl] = response;
44 | }
45 | }
46 |
47 | void NetworkAccessManager::addHeader(QString key, QString value) {
48 | m_headers.insert(key, value);
49 | }
50 |
51 | void NetworkAccessManager::resetHeaders() {
52 | m_headers.clear();
53 | }
54 |
55 | void NetworkAccessManager::setUserName(const QString &userName) {
56 | m_userName = userName;
57 | }
58 |
59 | void NetworkAccessManager::setPassword(const QString &password) {
60 | m_password = password;
61 | }
62 |
63 | void NetworkAccessManager::provideAuthentication(QNetworkReply *reply, QAuthenticator *authenticator) {
64 | Q_UNUSED(reply);
65 | if (m_userName != authenticator->user())
66 | authenticator->setUser(m_userName);
67 | if (m_password != authenticator->password())
68 | authenticator->setPassword(m_password);
69 | }
70 |
71 | int NetworkAccessManager::statusFor(QUrl url) {
72 | return m_responses[url].statusCode;
73 | }
74 |
75 | const QList &NetworkAccessManager::headersFor(QUrl url) {
76 | return m_responses[url].headers;
77 | }
78 |
79 | void NetworkAccessManager::setUrlBlacklist(QStringList urlBlacklist) {
80 | m_urlBlacklist.clear();
81 |
82 | QStringListIterator iter(urlBlacklist);
83 | while (iter.hasNext()) {
84 | m_urlBlacklist << QUrl(iter.next());
85 | }
86 | };
87 |
88 | bool NetworkAccessManager::isBlacklisted(QUrl url) {
89 | QListIterator iter(m_urlBlacklist);
90 |
91 | while (iter.hasNext()) {
92 | QUrl blacklisted = iter.next();
93 |
94 | if (blacklisted == url) {
95 | return true;
96 | } else if (blacklisted.path().isEmpty() && blacklisted.isParentOf(url)) {
97 | return true;
98 | }
99 | }
100 |
101 | return false;
102 | };
103 |
104 |
--------------------------------------------------------------------------------
/src/webkit_server.js:
--------------------------------------------------------------------------------
1 | window.WebKitServer = {
2 | nodes : {},
3 | nextIndex : 0,
4 | attachedFiles : [],
5 |
6 | invoke: function() {
7 | return this[WebKitServerInvocation.functionName].apply(this, WebKitServerInvocation.arguments);
8 | },
9 |
10 | find: function(selector) {
11 | return this.findRelativeTo(document, selector);
12 | },
13 |
14 | currentUrl: function() {
15 | return window.location.toString();
16 | },
17 |
18 | findWithin: function(index, selector) {
19 | return this.findRelativeTo(this.nodes[index], selector);
20 | },
21 |
22 | findRelativeTo: function(parent, selector) {
23 | var results = [],
24 | elements = parent.querySelectorAll(selector);
25 |
26 | for (var index = 0, length = elements.length; index < length; index++) {
27 | this.nodes[results.push(++this.nextIndex)] = elements[index];
28 | }
29 |
30 | return results.join(",");
31 | },
32 |
33 | isAttached: function(index) {
34 | return document.evaluate("ancestor-or-self::html", this.nodes[index], null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue != null;
35 | },
36 |
37 | text: function(index) {
38 | var node = this.nodes[index],
39 | type = (node.type || node.tagName).toLowerCase();
40 |
41 | if (type == "textarea") {
42 | return node.innerHTML;
43 | } else {
44 | return node.innerText;
45 | }
46 | },
47 |
48 | attribute: function(index, name) {
49 | var node = this.nodes[index];
50 |
51 | switch(name) {
52 | case "checked": return node.checked;
53 | case "disabled": return node.disabled;
54 | case "multiple": return node.multiple;
55 | default: return node.getAttribute(name);
56 | }
57 | },
58 |
59 | hasAttribtue: function(index, name) {
60 | return this.nodes[index].hasAttribute(name);
61 | },
62 |
63 | tagName: function(index) {
64 | return this.nodes[index].tagName.toLowerCase();
65 | },
66 |
67 | submit: function(index) {
68 | return this.nodes[index].submit();
69 | },
70 |
71 | mousedown: function(index) {
72 | var mousedownEvent = document.createEvent("MouseEvents");
73 | mousedownEvent.initMouseEvent("mousedown", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
74 | this.nodes[index].dispatchEvent(mousedownEvent);
75 | },
76 |
77 | mouseup: function(index) {
78 | var mouseupEvent = document.createEvent("MouseEvents");
79 | mouseupEvent.initMouseEvent("mouseup", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
80 | this.nodes[index].dispatchEvent(mouseupEvent);
81 | },
82 |
83 | click: function(index) {
84 | this.mousedown(index);
85 | this.focus(index);
86 | this.mouseup(index);
87 |
88 | var clickEvent = document.createEvent("MouseEvents");
89 | clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
90 | this.nodes[index].dispatchEvent(clickEvent);
91 | },
92 |
93 | trigger: function(index, eventName) {
94 | var eventObject = document.createEvent("HTMLEvents");
95 | eventObject.initEvent(eventName, true, true);
96 | this.nodes[index].dispatchEvent(eventObject);
97 | },
98 |
99 | keypress: function(index, altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) {
100 | var eventObject = document.createEvent("Events");
101 | eventObject.initEvent("keypress", true, true);
102 | eventObject.window = window;
103 | eventObject.altKey = altKey;
104 | eventObject.ctrlKey = ctrlKey;
105 | eventObject.shiftKey = shiftKey;
106 | eventObject.metaKey = metaKey;
107 | eventObject.keyCode = keyCode;
108 | eventObject.charCode = charCode;
109 | eventObject.which = keyCode;
110 | this.nodes[index].dispatchEvent(eventObject);
111 | },
112 |
113 | keyupdown: function(index, eventName, keyCode) {
114 | var eventObject = document.createEvent("HTMLEvents");
115 | eventObject.initEvent(eventName, true, true);
116 | eventObject.keyCode = keyCode;
117 | eventObject.which = keyCode;
118 | eventObject.charCode = 0;
119 | this.nodes[index].dispatchEvent(eventObject);
120 | },
121 |
122 | visible: function(index) {
123 | var element = this.nodes[index];
124 |
125 | while (element) {
126 | var style = element.ownerDocument.defaultView.getComputedStyle(element, null);
127 |
128 | if (style.getPropertyValue("display") == "none" || style.getPropertyValue("visibility") == "hidden") {
129 | return false;
130 | }
131 |
132 | element = element.parentElement;
133 | }
134 |
135 | return true;
136 | },
137 |
138 | selected: function(index) {
139 | return this.nodes[index].selected;
140 | },
141 |
142 | value: function(index) {
143 | return this.nodes[index].value;
144 | },
145 |
146 | getInnerHTML: function(index) {
147 | return this.nodes[index].innerHTML;
148 | },
149 |
150 | setInnerHTML: function(index, value) {
151 | this.nodes[index].innerHTML = value;
152 | return true;
153 | },
154 |
155 | characterToKeyCode: function(character) {
156 | var code = character.toUpperCase().charCodeAt(0);
157 | var specialKeys = {
158 | 96: 192, //`
159 | 45: 189, //-
160 | 61: 187, //=
161 | 91: 219, //[
162 | 93: 221, //]
163 | 92: 220, //\
164 | 59: 186, //;
165 | 39: 222, //'
166 | 44: 188, //,
167 | 46: 190, //.
168 | 47: 191, ///
169 | 127: 46, //delete
170 | 126: 192, //~
171 | 33: 49, //!
172 | 64: 50, //@
173 | 35: 51, //#
174 | 36: 52, //$
175 | 37: 53, //%
176 | 94: 54, //^
177 | 38: 55, //&
178 | 42: 56, //*
179 | 40: 57, //(
180 | 41: 48, //)
181 | 95: 189, //_
182 | 43: 187, //+
183 | 123: 219, //{
184 | 125: 221, //}
185 | 124: 220, //|
186 | 58: 186, //:
187 | 34: 222, //"
188 | 60: 188, //<
189 | 62: 190, //>
190 | 63: 191 //?
191 | };
192 |
193 | if (specialKeys[code]) {
194 | code = specialKeys[code];
195 | }
196 |
197 | return code;
198 | },
199 |
200 | set: function(index, value) {
201 | var node = this.nodes[index],
202 | type = (node.type || node.tagName).toLowerCase(),
203 | textTypes = ["email", "number", "password", "search", "tel", "text", "textarea", "url"];
204 |
205 | if (textTypes.indexOf(type) !== -1) {
206 | this.focus(index);
207 |
208 | node.value = "";
209 |
210 | var length = value.length,
211 | maxLength = this.attribute(index, "maxlength");
212 |
213 | if (maxLength && value.length > maxLength) {
214 | length = maxLength;
215 | }
216 |
217 | for (var offset = 0; offset < length; offset++) {
218 | node.value += value[offset];
219 |
220 | var keyCode = this.characterToKeyCode(value[strindex]);
221 | this.keyupdown(index, "keydown", keyCode);
222 | this.keypress(index, false, false, false, false, value.charCodeAt(strindex), value.charCodeAt(strindex));
223 | this.keyupdown(index, "keyup", keyCode);
224 | this.trigger(index, "input");
225 | }
226 |
227 | this.trigger(index, "change");
228 | } else if (type === "checkbox" || type === "radio") {
229 | if (node.checked != (value === "true")) {
230 | this.click(index);
231 | }
232 | } else if (type === "file") {
233 | this.attachedFiles = Array.prototype.slice.call(arguments, 1);
234 | this.click(index);
235 | } else {
236 | node.value = value;
237 | }
238 | },
239 |
240 | focus: function(index) {
241 | this.index[index].focus();
242 | },
243 |
244 | selectOption: function(index) {
245 | this.nodes[index].selected = true;
246 | this.trigger(index, "change");
247 | },
248 |
249 | unselectOption: function(index) {
250 | this.nodes[index].selected = false;
251 | this.trigger(index, "change");
252 | },
253 |
254 | centerPosition: function(element) {
255 | this.reflow(element);
256 |
257 | var rect = element.getBoundingClientRect(),
258 | position = {
259 | x: rect.width / 2,
260 | y: rect.height / 2
261 | };
262 |
263 | do {
264 | position.x += element.offsetLeft;
265 | position.y += element.offsetTop;
266 | } while ((element = element.offsetParent));
267 |
268 | position.x = Math.floor(position.x);
269 | position.y = Math.floor(position.y);
270 |
271 | return position;
272 | },
273 |
274 | reflow: function(element, force) {
275 | if (force || element.offsetWidth === 0) {
276 | var property,
277 | oldStyle = {},
278 | newStyle = {
279 | display : "block",
280 | position : "absolute",
281 | visibility : "hidden",
282 | };
283 |
284 | for (property in newStyle) {
285 | oldStyle[property] = element.style[property];
286 | element.style[property] = newStyle[property];
287 | }
288 |
289 | element.offsetWidth;
290 | element.offsetHeight;
291 |
292 | for (property in oldStyle) {
293 | element.style[property] = oldStyle[property];
294 | }
295 | }
296 | },
297 |
298 | dragTo: function(index, targetIndex) {
299 | var element = this.nodes[index],
300 | target = this.nodes[targetIndex],
301 | position = this.centerPosition(element),
302 | options = {
303 | clientX: position.x,
304 | clientY: position.y
305 | },
306 | mouseTrigger = function(eventName, options) {
307 | var eventObject = document.createEvent("MouseEvents");
308 | eventObject.initMouseEvent(eventName, true, true, window, 0, 0, 0, options.clientX || 0, options.clientY || 0, false, false, false, false, 0, null);
309 | element.dispatchEvent(eventObject);
310 | };
311 |
312 | mouseTrigger("mousedown", options);
313 |
314 | options.clientX += 1;
315 | options.clientY += 1;
316 |
317 | mouseTrigger("mousemove", options);
318 |
319 | position = this.centerPosition(target);
320 | options = {
321 | clientX: position.x,
322 | clientY: position.y
323 | };
324 |
325 | mouseTrigger("mousemove", options);
326 | mouseTrigger("mouseup", options);
327 | },
328 |
329 | equals: function(index, targetIndex) {
330 | return this.nodes[index] === this.nodes[targetIndex];
331 | }
332 | };
333 |
--------------------------------------------------------------------------------
/src/WebPage.cpp:
--------------------------------------------------------------------------------
1 | #include "WebPage.h"
2 | #include "WebPageManager.h"
3 | #include "JavascriptInvocation.h"
4 | #include "NetworkAccessManager.h"
5 | #include "NetworkCookieJar.h"
6 | #include "UnsupportedContentHandler.h"
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | WebPage::WebPage(WebPageManager *manager, QObject *parent) : QWebPage(parent) {
13 | m_loading = false;
14 | m_failed = false;
15 | m_manager = manager;
16 | m_uuid = QUuid::createUuid().toString();
17 | m_unsupportedContentLoaded = false;
18 |
19 | setForwardUnsupportedContent(true);
20 | loadJavascript();
21 | setUserStylesheet();
22 |
23 | m_confirm = true;
24 | m_prompt = false;
25 | m_prompt_text = QString();
26 | this->setCustomNetworkAccessManager();
27 |
28 | connect(this, SIGNAL(loadStarted()), this, SLOT(loadStarted()));
29 | connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
30 | connect(this, SIGNAL(frameCreated(QWebFrame *)),
31 | this, SLOT(frameCreated(QWebFrame *)));
32 | connect(this, SIGNAL(unsupportedContent(QNetworkReply*)),
33 | this, SLOT(handleUnsupportedContent(QNetworkReply*)));
34 | resetWindowSize();
35 |
36 | settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
37 | }
38 |
39 | void WebPage::resetWindowSize() {
40 | this->setViewportSize(QSize(1680, 1050));
41 | this->settings()->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, true);
42 | }
43 |
44 | void WebPage::setCustomNetworkAccessManager() {
45 | NetworkAccessManager *manager = new NetworkAccessManager(this);
46 | manager->setCookieJar(m_manager->cookieJar());
47 | this->setNetworkAccessManager(manager);
48 | connect(manager, SIGNAL(sslErrors(QNetworkReply *, QList)),
49 | this, SLOT(handleSslErrorsForReply(QNetworkReply *, QList)));
50 | connect(manager, SIGNAL(requestCreated(QByteArray &, QNetworkReply *)),
51 | SIGNAL(requestCreated(QByteArray &, QNetworkReply *)));
52 | }
53 |
54 | void WebPage::unsupportedContentFinishedReply(QNetworkReply *reply) {
55 | m_unsupportedContentLoaded = true;
56 | m_manager->replyFinished(reply);
57 | }
58 |
59 | void WebPage::loadJavascript() {
60 | QResource javascript(":/webkit_server.js");
61 | if (javascript.isCompressed()) {
62 | QByteArray uncompressedBytes(qUncompress(javascript.data(), javascript.size()));
63 | m_javascriptString = QString(uncompressedBytes);
64 | } else {
65 | char * javascriptString = new char[javascript.size() + 1];
66 | strcpy(javascriptString, (const char *)javascript.data());
67 | javascriptString[javascript.size()] = 0;
68 | m_javascriptString = javascriptString;
69 | }
70 | }
71 |
72 | void WebPage::setUserStylesheet() {
73 | QString data = QString("*, :before, :after { font-family: 'Arial' ! important; }").toUtf8().toBase64();
74 | QUrl url = QUrl(QString("data:text/css;charset=utf-8;base64,") + data);
75 | settings()->setUserStyleSheetUrl(url);
76 | }
77 |
78 | QString WebPage::userAgentForUrl(const QUrl &url ) const {
79 | if (!m_userAgent.isEmpty()) {
80 | return m_userAgent;
81 | } else {
82 | return QWebPage::userAgentForUrl(url);
83 | }
84 | }
85 |
86 | QVariantList WebPage::consoleMessages() {
87 | return m_consoleMessages;
88 | }
89 |
90 | QVariantList WebPage::alertMessages() {
91 | return m_alertMessages;
92 | }
93 |
94 | QVariantList WebPage::confirmMessages() {
95 | return m_confirmMessages;
96 | }
97 |
98 | QVariantList WebPage::promptMessages() {
99 | return m_promptMessages;
100 | }
101 |
102 | void WebPage::setUserAgent(QString userAgent) {
103 | m_userAgent = userAgent;
104 | }
105 |
106 | void WebPage::frameCreated(QWebFrame * frame) {
107 | connect(frame, SIGNAL(javaScriptWindowObjectCleared()),
108 | this, SLOT(injectJavascriptHelpers()));
109 | }
110 |
111 | void WebPage::injectJavascriptHelpers() {
112 | QWebFrame* frame = qobject_cast(QObject::sender());
113 | frame->evaluateJavaScript(m_javascriptString);
114 | }
115 |
116 | bool WebPage::shouldInterruptJavaScript() {
117 | return false;
118 | }
119 |
120 | QVariant WebPage::invokeWebKitServerFunction(const char *name, const QStringList &arguments) {
121 | QString qname(name);
122 | QString objectName("WebKitServerInvocation");
123 | JavascriptInvocation invocation(qname, arguments);
124 | currentFrame()->addToJavaScriptWindowObject(objectName, &invocation);
125 | QString javascript = QString("WebKitServer.invoke()");
126 | return currentFrame()->evaluateJavaScript(javascript);
127 | }
128 |
129 | QVariant WebPage::invokeWebKitServerFunction(QString &name, const QStringList &arguments) {
130 | return invokeWebKitServerFunction(name.toAscii().data(), arguments);
131 | }
132 |
133 | void WebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
134 | QVariantMap m;
135 | m["message"] = message;
136 | QString fullMessage = QString(message);
137 | if (!sourceID.isEmpty()) {
138 | fullMessage = sourceID + "|" + QString::number(lineNumber) + "|" + fullMessage;
139 | m["source"] = sourceID;
140 | m["line_number"] = lineNumber;
141 | }
142 | m_consoleMessages.append(m);
143 | m_manager->logger() << qPrintable(fullMessage);
144 | }
145 |
146 | void WebPage::javaScriptAlert(QWebFrame *frame, const QString &message) {
147 | Q_UNUSED(frame);
148 | m_alertMessages.append(message);
149 | m_manager->logger() << "ALERT:" << qPrintable(message);
150 | }
151 |
152 | bool WebPage::javaScriptConfirm(QWebFrame *frame, const QString &message) {
153 | Q_UNUSED(frame);
154 | m_confirmMessages.append(message);
155 | return m_confirm;
156 | }
157 |
158 | bool WebPage::javaScriptPrompt(QWebFrame *frame, const QString &message, const QString &defaultValue, QString *result) {
159 | Q_UNUSED(frame)
160 | m_promptMessages.append(message);
161 | if (m_prompt) {
162 | if (m_prompt_text.isNull()) {
163 | *result = defaultValue;
164 | } else {
165 | *result = m_prompt_text;
166 | }
167 | }
168 | return m_prompt;
169 | }
170 |
171 | void WebPage::loadStarted() {
172 | m_loading = true;
173 | m_errorPageMessage = QString();
174 | m_unsupportedContentLoaded = false;
175 | }
176 |
177 | void WebPage::loadFinished(bool success) {
178 | Q_UNUSED(success);
179 | m_loading = false;
180 | emit pageFinished(!m_failed);
181 | m_failed = false;
182 | }
183 |
184 | bool WebPage::isLoading() const {
185 | return m_loading;
186 | }
187 |
188 | QString WebPage::failureString() {
189 | QString message = QString("Unable to load URL: ") + currentFrame()->requestedUrl().toString();
190 | if (m_errorPageMessage.isEmpty())
191 | return message;
192 | else
193 | return message + m_errorPageMessage;
194 | }
195 |
196 | bool WebPage::render(const QString &fileName, const QSize &minimumSize) {
197 | QFileInfo fileInfo(fileName);
198 | QDir dir;
199 | dir.mkpath(fileInfo.absolutePath());
200 |
201 | QSize viewportSize = this->viewportSize();
202 | this->setViewportSize(minimumSize);
203 | QSize pageSize = this->mainFrame()->contentsSize();
204 | if (pageSize.isEmpty()) {
205 | return false;
206 | }
207 |
208 | QImage buffer(pageSize, QImage::Format_ARGB32);
209 | buffer.fill(qRgba(255, 255, 255, 0));
210 |
211 | QPainter p(&buffer);
212 | p.setRenderHint( QPainter::Antialiasing, true);
213 | p.setRenderHint( QPainter::TextAntialiasing, true);
214 | p.setRenderHint( QPainter::SmoothPixmapTransform, true);
215 |
216 | this->setViewportSize(pageSize);
217 | this->mainFrame()->render(&p);
218 | p.end();
219 | this->setViewportSize(viewportSize);
220 |
221 | return buffer.save(fileName);
222 | }
223 |
224 | QString WebPage::chooseFile(QWebFrame *parentFrame, const QString &suggestedFile) {
225 | Q_UNUSED(parentFrame);
226 | Q_UNUSED(suggestedFile);
227 |
228 | return getAttachedFileNames().first();
229 | }
230 |
231 | bool WebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) {
232 | if (extension == ChooseMultipleFilesExtension) {
233 | static_cast(output)->fileNames = getAttachedFileNames();
234 | return true;
235 | }
236 | else if (extension == QWebPage::ErrorPageExtension) {
237 | ErrorPageExtensionOption *errorOption = (ErrorPageExtensionOption*) option;
238 | m_errorPageMessage = " because of error loading " + errorOption->url.toString() + ": " + errorOption->errorString;
239 | m_failed = true;
240 | return false;
241 | }
242 | return false;
243 | }
244 |
245 | QStringList WebPage::getAttachedFileNames() {
246 | return currentFrame()->evaluateJavaScript(QString("WebKitServer.attachedFiles")).toStringList();
247 | }
248 |
249 | void WebPage::handleSslErrorsForReply(QNetworkReply *reply, const QList &errors) {
250 | if (m_manager->ignoreSslErrors())
251 | reply->ignoreSslErrors(errors);
252 | }
253 |
254 | void WebPage::setSkipImageLoading(bool skip) {
255 | settings()->setAttribute(QWebSettings::AutoLoadImages, !skip);
256 | }
257 |
258 | int WebPage::getLastStatus() {
259 | return networkAccessManager()->statusFor(currentFrame()->requestedUrl());
260 | }
261 |
262 | const QList &WebPage::pageHeaders() {
263 | return networkAccessManager()->headersFor(currentFrame()->requestedUrl());
264 | }
265 |
266 | NetworkAccessManager *WebPage::networkAccessManager() {
267 | return qobject_cast(QWebPage::networkAccessManager());
268 | }
269 |
270 | void WebPage::handleUnsupportedContent(QNetworkReply *reply) {
271 | QVariant contentMimeType = reply->header(QNetworkRequest::ContentTypeHeader);
272 | if(!contentMimeType.isNull()) {
273 | triggerAction(QWebPage::Stop);
274 | UnsupportedContentHandler *handler = new UnsupportedContentHandler(this, reply);
275 | if (reply->isFinished())
276 | handler->renderNonHtmlContent();
277 | else
278 | handler->waitForReplyToFinish();
279 | }
280 | }
281 |
282 | bool WebPage::unsupportedContentLoaded() {
283 | return m_unsupportedContentLoaded;
284 | }
285 |
286 | bool WebPage::supportsExtension(Extension extension) const {
287 | if (extension == ErrorPageExtension)
288 | return true;
289 | else if (extension == ChooseMultipleFilesExtension)
290 | return true;
291 | else
292 | return false;
293 | }
294 |
295 | QWebPage *WebPage::createWindow(WebWindowType type) {
296 | Q_UNUSED(type);
297 | return m_manager->createPage(this);
298 | }
299 |
300 | QString WebPage::uuid() {
301 | return m_uuid;
302 | }
303 |
304 | QString WebPage::getWindowName() {
305 | QVariant windowName = mainFrame()->evaluateJavaScript("window.name");
306 |
307 | if (windowName.isValid())
308 | return windowName.toString();
309 | else
310 | return "";
311 | }
312 |
313 | bool WebPage::matchesWindowSelector(QString selector) {
314 | return (selector == getWindowName() ||
315 | selector == mainFrame()->title() ||
316 | selector == mainFrame()->url().toString() ||
317 | selector == uuid());
318 | }
319 |
320 | void WebPage::setFocus() {
321 | m_manager->setCurrentPage(this);
322 | }
323 |
324 | void WebPage::setConfirmAction(QString action) {
325 | m_confirm = (action == "Yes");
326 | }
327 |
328 | void WebPage::setPromptAction(QString action) {
329 | m_prompt = (action == "Yes");
330 | }
331 |
332 | void WebPage::setPromptText(QString text) {
333 | m_prompt_text = text;
334 | }
335 |
336 |
--------------------------------------------------------------------------------