Skip to content

Loading…

Feature/url blacklist #1

Merged
merged 2 commits into from

2 participants

View
5 lib/capybara/driver/webkit/browser.rb
@@ -14,6 +14,7 @@ def initialize(options = {})
$stdout
@ignore_ssl_errors = options[:ignore_ssl_errors]
@skip_image_loading = options[:skip_image_loading]
+ @blacklist_file = options[:blacklist_file]
start_server
connect
end
@@ -177,6 +178,10 @@ def server_pipe_and_pid(server_path)
cmdline = [server_path]
cmdline << "--ignore-ssl-errors" if @ignore_ssl_errors
cmdline << "--skip-image-loading" if @skip_image_loading
+ if @blacklist_file
+ cmdline << "--blacklist-file"
+ cmdline << @blacklist_file
+ end
pipe = IO.popen(cmdline.join(" "))
[pipe, pipe.pid]
end
View
72 spec/browser_spec.rb
@@ -8,7 +8,9 @@
describe Capybara::Driver::Webkit::Browser do
+ let(:blacklist_file) { File.join(File.dirname(__FILE__), 'support/test_blacklist.txt') }
let(:browser) { Capybara::Driver::Webkit::Browser.new }
+ let(:browser_with_blacklist) { Capybara::Driver::Webkit::Browser.new(blacklist_file: blacklist_file)}
let(:browser_ignore_ssl_err) {
Capybara::Driver::Webkit::Browser.new(:ignore_ssl_errors => true)
}
@@ -158,6 +160,76 @@
end
end
+ context "uses the url blacklist" do
+ before(:each) do
+ # set up minimal HTTP server
+ @host = "127.0.0.1"
+ @server = TCPServer.new(@host, 0)
+ @port = @server.addr[1]
+
+ @server_thread = Thread.new(@server) do |serv|
+ while conn = serv.accept do
+ # read request
+ request = []
+ until (line = conn.readline.strip).empty?
+ request << line
+ end
+
+ request = request.join("\n")
+ content = if request =~ %r{GET /frame}
+ "<p>Inner</p>"
+ else
+ <<-HTML
+ <iframe src="http://example.com/path" id="frame1"></iframe>
+ <iframe src="http://example.org/path/to/file" id="frame2"></iframe>
+ <iframe src="/frame" id="frame3"></iframe>
+ HTML
+ end
+
+ html = <<-HTML
+ <html>
+ <head>
+ </head>
+ <body>
+ #{content}
+ </body>
+ </html>
+ HTML
+ conn.write "HTTP/1.1 200 OK\r\n"
+ conn.write "Content-Type: text/html\r\n"
+ conn.write "Content-Length: %i\r\n" % html.size
+ conn.write "\r\n"
+ conn.write html
+ conn.write("\r\n\r\n")
+ conn.close
+ end
+ end
+ end
+
+ after(:each) do
+ @server_thread.kill
+ @server.close
+ end
+
+ it "should not fetch urls blocked by host" do
+ browser_with_blacklist.visit("http://#{@host}:#{@port}")
+ browser_with_blacklist.frame_focus('frame1')
+ browser_with_blacklist.find('//body').should be_empty
+ end
+
+ it "should not fetch urls blocked by full paths" do
+ browser_with_blacklist.visit("http://#{@host}:#{@port}")
+ browser_with_blacklist.frame_focus('frame2')
+ browser_with_blacklist.find('//body').should be_empty
+ end
+
+ it "should not block non-blacklisted urls" do
+ browser_with_blacklist.visit("http://#{@host}:#{@port}")
+ browser_with_blacklist.frame_focus('frame3')
+ browser_with_blacklist.find('//p').should_not be_empty
+ end
+ end
+
context "timeout on long requests" do
before(:each) do
# set up minimal HTTPS server
View
2 spec/support/test_blacklist.txt
@@ -0,0 +1,2 @@
+http://example.org/path/to/file
+http://example.com
View
49 src/NetworkAccessManager.cpp
@@ -8,18 +8,51 @@ NetworkAccessManager::NetworkAccessManager(QObject *parent):QNetworkAccessManage
QNetworkReply* NetworkAccessManager::createRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice * outgoingData = 0) {
QNetworkRequest new_request(request);
- if (operation != QNetworkAccessManager::PostOperation && operation != QNetworkAccessManager::PutOperation) {
- new_request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant());
- }
- QHashIterator<QString, QString> item(m_headers);
- while (item.hasNext()) {
- item.next();
- new_request.setRawHeader(item.key().toAscii(), item.value().toAscii());
+
+ if (this->isBlacklisted(new_request.url())) {
+ return this->noOpRequest();
+ } else {
+ if (operation != QNetworkAccessManager::PostOperation && operation != QNetworkAccessManager::PutOperation) {
+ new_request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant());
+ }
+ QHashIterator<QString, QString> item(m_headers);
+ while (item.hasNext()) {
+ item.next();
+ new_request.setRawHeader(item.key().toAscii(), item.value().toAscii());
+ }
+ return QNetworkAccessManager::createRequest(operation, new_request, outgoingData);
}
- return QNetworkAccessManager::createRequest(operation, new_request, outgoingData);
};
void NetworkAccessManager::addHeader(QString key, QString value) {
m_headers.insert(key, value);
};
+void NetworkAccessManager::setUrlBlacklist(QStringList urlBlacklist) {
+ m_urlBlacklist.clear();
+
+ QStringListIterator iter(urlBlacklist);
+ while (iter.hasNext()) {
+ m_urlBlacklist << QUrl(iter.next());
+ }
+};
+
+bool NetworkAccessManager::isBlacklisted(QUrl url) {
+ QListIterator<QUrl> iter(m_urlBlacklist);
+
+ while (iter.hasNext()) {
+ QUrl blacklisted = iter.next();
+
+ if (blacklisted == url) {
+ return true;
+ } else if (blacklisted.path().isEmpty() && blacklisted.isParentOf(url)) {
+ return true;
+ }
+ }
+
+ return false;
+};
+
+QNetworkReply* NetworkAccessManager::noOpRequest() {
+ return QNetworkAccessManager::createRequest(QNetworkAccessManager::GetOperation, QNetworkRequest(QUrl()));
+};
View
7 src/NetworkAccessManager.h
@@ -1,6 +1,7 @@
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
+#include <QStringList>
class NetworkAccessManager : public QNetworkAccessManager {
@@ -9,10 +10,14 @@ class NetworkAccessManager : public QNetworkAccessManager {
public:
NetworkAccessManager(QObject *parent = 0);
void addHeader(QString key, QString value);
+ void setUrlBlacklist(QStringList blacklist);
protected:
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice * outgoingData);
private:
+ bool isBlacklisted(QUrl url);
+ QNetworkReply* noOpRequest();
QHash<QString, QString> m_headers;
-};
+ QList<QUrl> m_urlBlacklist;
+};
View
3 src/Server.cpp
@@ -4,11 +4,12 @@
#include <QTcpServer>
-Server::Server(QObject *parent, bool ignoreSslErrors, bool skipImageLoading) : QObject(parent) {
+Server::Server(QObject *parent, bool ignoreSslErrors, bool skipImageLoading, QStringList urlBlacklist) : QObject(parent) {
m_tcp_server = new QTcpServer(this);
m_page = new WebPage(this);
m_page->setIgnoreSslErrors(ignoreSslErrors);
m_page->setSkipImageLoading(skipImageLoading);
+ m_page->setUrlBlacklist(urlBlacklist);
}
bool Server::start() {
View
2 src/Server.h
@@ -7,7 +7,7 @@ class Server : public QObject {
Q_OBJECT
public:
- Server(QObject *parent, bool ignoreSslErrors, bool skipImageLoading);
+ Server(QObject *parent, bool ignoreSslErrors, bool skipImageLoading, QStringList urlBlackList);
bool start();
quint16 server_port() const;
View
5 src/WebPage.cpp
@@ -219,6 +219,11 @@ void WebPage::setIgnoreSslErrors(bool ignore) {
m_ignoreSslErrors = ignore;
}
+void WebPage::setUrlBlacklist(QStringList blacklist) {
+ NetworkAccessManager* networkAccessManager = qobject_cast<NetworkAccessManager*>(this->networkAccessManager());
+ networkAccessManager->setUrlBlacklist(blacklist);
+}
+
bool WebPage::ignoreSslErrors() {
return m_ignoreSslErrors;
}
View
1 src/WebPage.h
@@ -18,6 +18,7 @@ class WebPage : public QWebPage {
void setIgnoreSslErrors(bool ignore);
void setSkipImageLoading(bool skip);
void setTimeout(int timeout);
+ void setUrlBlacklist(QStringList blacklist);
int getTimeout();
bool ignoreSslErrors();
QString consoleMessages();
View
32 src/main.cpp
@@ -5,6 +5,31 @@
#include <unistd.h>
#endif
+static int readBlackList(QStringList args, QStringList & blacklist) {
+ int returnCode = 1;
+
+ if (args.contains("--blacklist-file")) {
+ int fileNameIndex = args.indexOf("--blacklist-file") + 1;
+ if (fileNameIndex < args.size()) {
+ QString fileName = args.at(fileNameIndex);
+ QFile file(fileName);
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream in(&file);
+ QString line = in.readLine();
+ while (!line.isNull()) {
+ blacklist << line;
+ line = in.readLine();
+ }
+ } else {
+ std::cerr << "Unable to read blacklist file at " << qPrintable(fileName) << std::endl;
+ returnCode = 0;
+ }
+ }
+ }
+
+ return returnCode;
+}
+
int main(int argc, char **argv) {
#ifdef Q_OS_UNIX
if (setpgid(0, 0) < 0) {
@@ -22,7 +47,12 @@ int main(int argc, char **argv) {
bool ignoreSslErrors = args.contains("--ignore-ssl-errors");
bool skipImageLoading = args.contains("--skip-image-loading");
- Server server(0, ignoreSslErrors, skipImageLoading);
+ QStringList blacklist;
+ if (!readBlackList(args, blacklist)) {
+ return 1;
+ }
+
+ Server server(0, ignoreSslErrors, skipImageLoading, blacklist);
if (server.start()) {
std::cout << "Capybara-webkit server started, listening on port: " << server.server_port() << std::endl;
Something went wrong with that request. Please try again.