Support URLs in Gophermaps

Paths in Gophermaps that start with “URL:” should be interpreted as direct
URLs, rather than references to files or directories on the Gopher server
itself.

An excerpt from the standard document:
```

Links to URLs from a gopher directory shall be defined as follows:

 Type -- the appropriate character corresponding to the type of the
 document on the remote end; h if HTML.

 Path -- the full URL, preceeded by "URL:".  For instance:
         URL:http://www.complete.org/

 Host, Port -- pointing back to the gopher server that provided
 the directory for compatibility reasons.

 Name -- as usual for a Gopher directory entry.

```
Source: gopher://quux.org/0/Archives/Mailing Lists/gopher/gopher.2002-02?/MBOX-MESSAGE/34

An example of this in the wild can be seen at gopher://gopher.floodgap.com ,
at the bottom of the page.

Note that above link carries a fallback for clients that do not support it,
as described by the Bucktooth server software:
```
[...]  most people will want to add web links to their
gophers anyway. In 0.1-pr4 and up, this is supported in a protocol independent
fashion; simply specify any URL and an 'h' item type, like so:

hYour Web Link<TAB>URL:http://www.floodgap.com/

Note that the URL must be preceded by a literal "URL:" and that the itemtype
is h. Smart clients will automatically take the URL portion and use it, but
even if they do not, Bucktooth will generate an HTML page with a Refresh:
header and forward them on automatically.
```

Other clients supporting this standard include the OverbiteWX extension.
(Most likely, there will be others, but I haven’t tested them all.)
This commit is contained in:
Michael Steenbeek 2023-08-27 16:34:22 +02:00 committed by Felix Queißner
parent 659a144814
commit 10a9c4ccfa
1 changed files with 25 additions and 14 deletions

View File

@ -156,21 +156,32 @@ std::unique_ptr<QTextDocument> GophermapRenderer::render(const QByteArray &input
else
{
QString dst_url;
switch (items.size())
// If a resources link starts with “URL:”, it is a direct link (to HTTP or another protocol), rather than a file or directory on this server.
if (items.size() >= 2 && items.at(1).left(4) == "URL:")
{
case 0:
assert(false);
case 1:
assert(false);
case 2:
dst_url = root_url.resolved(QUrl(items.at(1))).toString();
break;
case 3:
dst_url = scheme + "://" + items.at(2) + "/" + QString(type) + items.at(1);
break;
default:
dst_url = scheme + "://" + items.at(2) + ":" + items.at(3) + "/" + QString(type) + items.at(1);
break;
auto item1 = QString(items.at(1));
item1.remove(0, 4);
dst_url = item1;
}
else
{
switch (items.size())
{
case 0:
assert(false);
case 1:
assert(false);
case 2:
dst_url = root_url.resolved(QUrl(items.at(1))).toString();
break;
case 3:
dst_url = scheme + "://" + items.at(2) + "/" + QString(type) + items.at(1);
break;
default:
dst_url = scheme + "://" + items.at(2) + ":" + items.at(3) + "/" + QString(type) + items.at(1);
break;
}
}
if (not QUrl(dst_url).isValid())