aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelix (xq) Queißner <git@mq32.de>2020-06-17 01:29:30 +0200
committerFelix (xq) Queißner <git@mq32.de>2020-06-17 01:29:30 +0200
commit5b14fc424462a5d3a5a509bd177c04e9cba2ce17 (patch)
treead5e9b685be26d22d570ba4788a9b01a65ceb531 /src
parent03253a724b6fdb3f511510d10c3e62615e305cf2 (diff)
downloadkristall-5b14fc424462a5d3a5a509bd177c04e9cba2ce17.tar.gz
Makes gemini protocol handler a bit more robust.Makes style preview a file in about: instead of hardcoding it. Starts to implement the options menu for redirection configuration.
Diffstat (limited to 'src')
-rw-r--r--src/about/style-preview.gemini21
-rw-r--r--src/about/updates.gemini1
-rw-r--r--src/browsertab.cpp11
-rw-r--r--src/browsertab.hpp2
-rw-r--r--src/browsertab.ui7
-rw-r--r--src/builtins.qrc1
-rw-r--r--src/geminiclient.cpp41
-rw-r--r--src/kristall.pro2
-rw-r--r--src/searchbar.cpp26
-rw-r--r--src/searchbar.hpp19
-rw-r--r--src/settingsdialog.cpp35
-rw-r--r--src/settingsdialog.ui24
12 files changed, 156 insertions, 34 deletions
diff --git a/src/about/style-preview.gemini b/src/about/style-preview.gemini
new file mode 100644
index 0000000..295c1da
--- /dev/null
+++ b/src/about/style-preview.gemini
@@ -0,0 +1,21 @@
+# H1 Header
+## H2 Header
+### H3 Header
+Plain text document here.
+* List A
+* List B
+=> rela-link Same-Site Link
+=> //foreign.host/ Foreign Site Link
+=> https://foreign.host/ Cross-Protocol Link
+> Multi-lined
+> block quotes
+```
+ ▄▄▄ ██▀███ ▄▄▄█████▓
+ ▒████▄ ▓██ ▒ ██▒▓ ██▒ ▓▒
+ ▒██ ▀█▄ ▓██ ░▄█ ▒▒ ▓██░ ▒░
+ ░██▄▄▄▄██ ▒██▀▀█▄ ░ ▓██▓ ░
+ ▓█ ▓██▒░██▓ ▒██▒ ▒██▒ ░
+ ▒▒ ▓▒█░░ ▒▓ ░▒▓░ ▒ ░░
+ ▒ ▒▒ ░ ░▒ ░ ▒░ ░
+ ░ ▒ ░░ ░ ░
+ ░ ░ ░
diff --git a/src/about/updates.gemini b/src/about/updates.gemini
index 5a1711a..7f4bae5 100644
--- a/src/about/updates.gemini
+++ b/src/about/updates.gemini
@@ -8,6 +8,7 @@
* Fixed bug: Gopher end-of-file marker is now better detected.
* Adds support for server certificate handling for gemini://
* Reworked internal network structure. Makes room for future improvements
+* Pressing escape now resets search bar to current location
## 0.2
* Implement Ctrl+D/*Add to favourites* menu item
diff --git a/src/browsertab.cpp b/src/browsertab.cpp
index 4e5f25c..09bb56c 100644
--- a/src/browsertab.cpp
+++ b/src/browsertab.cpp
@@ -59,6 +59,8 @@ BrowserTab::BrowserTab(MainWindow *mainWindow) : QWidget(nullptr),
this->ui->text_browser->setVisible(true);
this->ui->text_browser->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(this->ui->url_bar, &SearchBar::escapePressed, this, &BrowserTab::on_url_bar_escapePressed);
}
BrowserTab::~BrowserTab()
@@ -156,7 +158,7 @@ void BrowserTab::focusUrlBar()
void BrowserTab::on_url_bar_returnPressed()
{
- QUrl url{this->ui->url_bar->text()};
+ QUrl url { this->ui->url_bar->text().trimmed() };
if (url.scheme().isEmpty())
{
@@ -166,6 +168,11 @@ void BrowserTab::on_url_bar_returnPressed()
this->navigateTo(url, PushImmediate);
}
+void BrowserTab::on_url_bar_escapePressed()
+{
+ this->ui->url_bar->setText(this->current_location.toString(QUrl::FullyEncoded));
+}
+
void BrowserTab::on_refresh_button_clicked()
{
reloadPage();
@@ -443,8 +450,6 @@ void BrowserTab::on_redirected(const QUrl &uri, bool is_permanent)
}
}
- // TODO: Implement cross-protocol redirections
- // TODO: Implement cross-host redirection
if (this->startRequest(uri))
{
redirection_count += 1;
diff --git a/src/browsertab.hpp b/src/browsertab.hpp
index 2cd6d4b..506584d 100644
--- a/src/browsertab.hpp
+++ b/src/browsertab.hpp
@@ -62,6 +62,8 @@ signals:
private slots:
void on_url_bar_returnPressed();
+ void on_url_bar_escapePressed();
+
void on_refresh_button_clicked();
void on_linkHovered(const QString &url);
diff --git a/src/browsertab.ui b/src/browsertab.ui
index 46ff31f..6819707 100644
--- a/src/browsertab.ui
+++ b/src/browsertab.ui
@@ -115,7 +115,7 @@
</widget>
</item>
<item>
- <widget class="QLineEdit" name="url_bar">
+ <widget class="SearchBar" name="url_bar">
<property name="placeholderText">
<string>gemini://</string>
</property>
@@ -231,6 +231,11 @@ p, li { white-space: pre-wrap; }
<extends>QGraphicsView</extends>
<header location="global">interactiveview.hpp</header>
</customwidget>
+ <customwidget>
+ <class>SearchBar</class>
+ <extends>QLineEdit</extends>
+ <header>searchbar.hpp</header>
+ </customwidget>
</customwidgets>
<resources>
<include location="icons.qrc"/>
diff --git a/src/builtins.qrc b/src/builtins.qrc
index 41b5965..9d51375 100644
--- a/src/builtins.qrc
+++ b/src/builtins.qrc
@@ -17,5 +17,6 @@
<file>error_page/Unauthorized.gemini</file>
<file>error_page/UnknownError.gemini</file>
<file>error_page/UntrustedHost.gemini</file>
+ <file>about/style-preview.gemini</file>
</qresource>
</RCC>
diff --git a/src/geminiclient.cpp b/src/geminiclient.cpp
index a21eea4..80f5742 100644
--- a/src/geminiclient.cpp
+++ b/src/geminiclient.cpp
@@ -9,6 +9,9 @@ GeminiClient::GeminiClient() : ProtocolHandler(nullptr)
connect(&socket, &QSslSocket::encrypted, this, &GeminiClient::socketEncrypted);
connect(&socket, &QSslSocket::readyRead, this, &GeminiClient::socketReadyRead);
connect(&socket, &QSslSocket::disconnected, this, &GeminiClient::socketDisconnected);
+ connect(&socket, &QSslSocket::stateChanged, [](QSslSocket::SocketState state) {
+ qDebug() << "Socket state changed to " << state;
+ });
connect(&socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), this, &GeminiClient::sslErrors);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
@@ -33,8 +36,12 @@ bool GeminiClient::startRequest(const QUrl &url)
if(url.scheme() != "gemini")
return false;
- if(socket.isOpen())
- return false;
+ if(socket.state() != QTcpSocket::UnconnectedState) {
+ socket.disconnectFromHost();
+ socket.close();
+ if(not socket.waitForDisconnected(1500))
+ return false;
+ }
QSslConfiguration ssl_config;
ssl_config.setProtocol(QSsl::TlsV1_2);
@@ -61,16 +68,24 @@ bool GeminiClient::startRequest(const QUrl &url)
bool GeminiClient::isInProgress() const
{
- return socket.isOpen();
+ return (socket.state() != QTcpSocket::UnconnectedState);
}
bool GeminiClient::cancelRequest()
{
- this->is_receiving_body = false;
- this->socket.close();
- this->buffer.clear();
- this->body.clear();
- return true;
+ if(isInProgress())
+ {
+ this->is_receiving_body = false;
+ this->socket.disconnectFromHost();
+ this->socket.close();
+ this->buffer.clear();
+ this->body.clear();
+ return this->socket.waitForDisconnected(250);
+ }
+ else
+ {
+ return true;
+ }
}
bool GeminiClient::enableClientCertificate(const CryptoIdentity &ident)
@@ -130,6 +145,11 @@ void GeminiClient::socketReadyRead()
emit networkError(ProtocolViolation, "Line is too short for valid protocol");
return;
}
+ if(buffer.size() >= 1200)
+ {
+ emit networkError(ProtocolViolation, "response too large!");
+ socket.close();
+ }
if(buffer[buffer.size() - 1] != '\r') {
socket.close();
qDebug() << buffer;
@@ -246,6 +266,11 @@ void GeminiClient::socketReadyRead()
assert(false and "unreachable");
}
}
+ if((buffer.size() + response.size()) >= 1200)
+ {
+ emit networkError(ProtocolViolation, "META too large!");
+ socket.close();
+ }
buffer.append(response);
}
}
diff --git a/src/kristall.pro b/src/kristall.pro
index 4084fce..fa0ee15 100644
--- a/src/kristall.pro
+++ b/src/kristall.pro
@@ -70,6 +70,7 @@ SOURCES += \
plaintextrenderer.cpp \
protocolhandler.cpp \
protocolsetup.cpp \
+ searchbar.cpp \
settingsdialog.cpp \
ssltrust.cpp \
tabbrowsinghistory.cpp \
@@ -104,6 +105,7 @@ HEADERS += \
plaintextrenderer.hpp \
protocolhandler.hpp \
protocolsetup.hpp \
+ searchbar.hpp \
settingsdialog.hpp \
ssltrust.hpp \
tabbrowsinghistory.hpp \
diff --git a/src/searchbar.cpp b/src/searchbar.cpp
new file mode 100644
index 0000000..4d8ea3a
--- /dev/null
+++ b/src/searchbar.cpp
@@ -0,0 +1,26 @@
+#include "searchbar.hpp"
+
+#include <QKeyEvent>
+
+SearchBar::SearchBar(QWidget *parent) : QLineEdit(parent)
+{
+
+}
+
+void SearchBar::keyPressEvent(QKeyEvent *event)
+{
+ if(event->key() == Qt::Key_Escape) {
+ emit this->escapePressed();
+ } else {
+ QLineEdit::keyPressEvent(event);
+ }
+}
+
+void SearchBar::keyReleaseEvent(QKeyEvent *event)
+{
+ if(event->key() == Qt::Key_Escape) {
+ // Eat the event
+ } else {
+ QLineEdit::keyReleaseEvent(event);
+ }
+}
diff --git a/src/searchbar.hpp b/src/searchbar.hpp
new file mode 100644
index 0000000..e03331f
--- /dev/null
+++ b/src/searchbar.hpp
@@ -0,0 +1,19 @@
+#ifndef SEARCHBAR_HPP
+#define SEARCHBAR_HPP
+
+#include <QLineEdit>
+
+class SearchBar : public QLineEdit
+{
+ Q_OBJECT
+public:
+ explicit SearchBar(QWidget *parent = nullptr);
+
+signals:
+ void escapePressed();
+public:
+ void keyPressEvent(QKeyEvent *event) override;
+ void keyReleaseEvent(QKeyEvent *event) override;
+};
+
+#endif // SEARCHBAR_HPP
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 7ef05fb..838d17c 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -102,6 +102,13 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
&QItemSelectionModel::currentChanged,
this,
&SettingsDialog::on_trusted_server_selection);
+
+ this->ui->redirection_mode->clear();
+ this->ui->redirection_mode->addItem("Ask for cross-scheme or cross-host redirection");
+ this->ui->redirection_mode->addItem("Ask for cross-scheme redirection");
+ this->ui->redirection_mode->addItem("Ask for cross-host redirection");
+ this->ui->redirection_mode->addItem("Ask for all redirection");
+ this->ui->redirection_mode->addItem("Silently redirect everything");
}
SettingsDialog::~SettingsDialog()
@@ -241,28 +248,11 @@ void SettingsDialog::setSslTrust(const SslTrust &trust)
void SettingsDialog::reloadStylePreview()
{
- auto const document = R"gemini(# H1 Header
-## H2 Header
-### H3 Header
-Plain text document here.
-* List A
-* List B
-=> rela-link Same-Site Link
-=> //foreign.host/ Foreign Site Link
-=> https://foreign.host/ Cross-Protocol Link
-> Multi-lined
-> block quotes
-```
- ▄▄▄ ██▀███ ▄▄▄█████▓
- ▒████▄ ▓██ ▒ ██▒▓ ██▒ ▓▒
- ▒██ ▀█▄ ▓██ ░▄█ ▒▒ ▓██░ ▒░
- ░██▄▄▄▄██ ▒██▀▀█▄ ░ ▓██▓ ░
- ▓█ ▓██▒░██▓ ▒██▒ ▒██▒ ░
- ▒▒ ▓▒█░░ ▒▓ ░▒▓░ ▒ ░░
- ▒ ▒▒ ░ ░▒ ░ ▒░ ░
- ░ ▒ ░░ ░ ░
- ░ ░ ░
-)gemini";
+ QFile document_src { ":/about/style-preview.gemini" };
+ bool ok = document_src.open(QFile::ReadOnly);
+ assert(ok and "failed to find style-preview.gemini!");
+
+ auto const document = document_src.readAll();
QString host = this->ui->preview_url->text();
if(host.length() == 0)
@@ -335,6 +325,7 @@ void SettingsDialog::updateColor(QColor &input)
void SettingsDialog::on_trusted_server_selection(const QModelIndex &current, const QModelIndex &previous)
{
+ Q_UNUSED(previous);
if(auto host = this->current_trust.trusted_hosts.get(current); host) {
this->ui->trust_revoke_selected->setEnabled(true);
} else {
diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui
index 5671001..b8665c2 100644
--- a/src/settingsdialog.ui
+++ b/src/settingsdialog.ui
@@ -241,6 +241,30 @@
</item>
</layout>
</item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_26">
+ <property name="text">
+ <string>Max. Number of Redirections</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QSpinBox" name="max_redirects">
+ <property name="value">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QComboBox" name="redirection_mode"/>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_27">
+ <property name="text">
+ <string>Redirection Handling</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="style_tab">