diff options
| author | Felix (xq) Queißner <git@mq32.de> | 2020-06-22 21:10:04 +0200 |
|---|---|---|
| committer | Felix (xq) Queißner <git@mq32.de> | 2020-06-22 21:10:04 +0200 |
| commit | 75ec461eeaa851cb5c53f4cfffc434e3e529ed1d (patch) | |
| tree | 3944737340718ca3675381aa06636045d397e780 /src/protocols/gopherclient.cpp | |
| parent | 8dbfb0890560fd1cd698d06fa05ac868c4db8576 (diff) | |
Restructures the project source and cleans up a bit
Diffstat (limited to 'src/protocols/gopherclient.cpp')
| -rw-r--r-- | src/protocols/gopherclient.cpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/protocols/gopherclient.cpp b/src/protocols/gopherclient.cpp new file mode 100644 index 0000000..63c35ca --- /dev/null +++ b/src/protocols/gopherclient.cpp @@ -0,0 +1,109 @@ +#include "gopherclient.hpp" +#include "ioutil.hpp" + +GopherClient::GopherClient(QObject *parent) : ProtocolHandler(parent) +{ + connect(&socket, &QTcpSocket::connected, this, &GopherClient::on_connected); + connect(&socket, &QTcpSocket::readyRead, this, &GopherClient::on_readRead); + connect(&socket, &QTcpSocket::disconnected, this, &GopherClient::on_finished); + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) + connect(&socket, &QTcpSocket::errorOccurred, this, &GopherClient::on_socketError); +#else + connect(&socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &GopherClient::on_socketError); +#endif +} + +GopherClient::~GopherClient() +{ + +} + +bool GopherClient::supportsScheme(const QString &scheme) const +{ + return (scheme == "gopher"); +} + +bool GopherClient::startRequest(const QUrl &url, RequestOptions options) +{ + Q_UNUSED(options) + + if(isInProgress()) + return false; + + if(url.scheme() != "gopher") + return false; + + // Second char on the URL path denotes the Gopher type + // See https://tools.ietf.org/html/rfc4266 + QString type = url.path().mid(1, 1); + + mime = "application/octet-stream"; + if(type == "") mime = "text/gophermap"; + else if(type == "0") mime = "text/plain"; + else if(type == "1") mime = "text/gophermap"; + else if(type == "g") mime = "image/gif"; + else if(type == "I") mime = "image/unknown"; + else if(type == "h") mime = "text/html"; + else if(type == "s") mime = "audio/unknown"; + + is_processing_binary = (type == "5") or (type == "9") or (type == "I") or (type == "g"); + + this->requested_url = url; + this->was_cancelled = false; + socket.connectToHost(url.host(), url.port(70)); + + return true; +} + +bool GopherClient::isInProgress() const +{ + return socket.isOpen(); +} + +bool GopherClient::cancelRequest() +{ + was_cancelled = true; + socket.close(); + body.clear(); + return true; +} + +void GopherClient::on_connected() +{ + auto blob = (requested_url.path().mid(2) + "\r\n").toUtf8(); + + IoUtil::writeAll(socket, blob); +} + +void GopherClient::on_readRead() +{ + body.append(socket.readAll()); + + if(not is_processing_binary) { + // Strip the "lone dot" from gopher data + if(int index = body.indexOf("\r\n.\r\n"); index >= 0) { + body.resize(index + 2); + socket.close(); + } + } + + if(not was_cancelled) { + emit this->requestProgress(body.size()); + } +} + +void GopherClient::on_finished() +{ + if(not was_cancelled) + { + emit this->requestComplete(this->body, mime); + was_cancelled = true; + } + body.clear(); +} + +void GopherClient::on_socketError(QAbstractSocket::SocketError error_code) +{ + this->emitNetworkError(error_code, socket.errorString()); +} |
