More specific protocol handlers

Sailfish seems to have some support for associating applications to a protocol handlers by creating a desktop file with a MimeType=x-scheme-handler/<protocol>.

One particular trend I’m seeing is to register the application to support the “http” and “https” protocol, while the applications are in fact not a web browser, but only act as a replacement for a single website. Examples for such applications include Fernschreiber, which can only really handle “https://telegram.me/*” URLs and MicroTube, which can only really handle “https://youtube.com/*” URLs.

Use cases

As an user, this is annoying, since everytime I click on a link within an application, such as “https://example.com”, a system dialog shows up, asking I’d like to open the link in Browser, Fernschreiber or MicroTube, while in fact, only the browser can handle this link. As an user, this is annoying, since this is a common occurrence which the system should handle itself.

As an application developer, I would like to indicate somehow that my application can only handle URLs that match a given scheme, host and/or path. When I want to create a link to content within my application, I would like to use the widely supported http protocol, such that people that have not installed my application can view them within the web browser, but I would like that people who open such an have installed my application.

Alternative options

An commonly used alternative is to have your application register a custom scheme handler, such as “example-app”. When an user opens a link to a webpage which the author of the application controls, such as “app.example.org”. The given webpage could then try to detect if the operating system supports the “example-app” custom scheme. If so, display the user a link they can press with that custom scheme to open the application". Otherwise, show a fallback webpage.

This approach has the following downsides:

  1. Requiring the app developer to be the owner of the domain. This could be problematic for third party clients of a website. And Sailfish OS has a lot of third-party clients.
  2. The user is first taken to the web browser and then has to commit an extra action by clicking a button on the webpage.
  3. Detecting if a protocol handler is supported on an operating system is non-standardized and is done by exploiting behaviours of specific browser implementations, which can break in the future. (see for example https://gist.github.com/kfatehi/f2f521c654bab106fdf9)

How other operating systems solve this

Android uses Intent Filters. Applications can declare that they support an Intent such as “android.action.VIEW” for certain MIME-types or certain URLs, or certain schemes, or certain schemes and hosts, … or certain schemes, hosts, ports, path (regexes) and mimeTypes. The exact documentation can be found here, while a more general documentation about Intent Filters can be found here.

What would I suggest

If there was a FreeDesktop standard for this, that would be the best to support. As far as I’m aware, there isn’t.

My proposal would be to extend the desktop entry standard by adding a new group, such as "X-Sailfish URL Handler ", and adding new fields such as “X-Sailfish-scheme”, “X-Sailfish-host”, “X-Sailfish-port”, “x-Sailfish-Path”. Following the Android implementation, if the host is set, the scheme must also be set. If the port is set, the host and scheme must also be set. If the path is set, the host and scheme must also be set.

All fields are a semicolon separated list. The path could allow simple wildcards, such as bash allows for shell globbing

Some examples:

[Desktop Entry]
Name=Foo App
Exec=harbour-foo
Icon=harbour-foo

[X-Sailfish URL Handler example1]
X-Sailfish-scheme=http;https;
X-Sailfish-host=foo.example.org;bar.example.org;
Exec=harbour-foo
X-Maemo-Service=org.example.bar
X-Maemo-Object-Path=/org/example/bar/App
X-Maemo-Method=org.example.bar.App.openUri

This example would match on “http://foo.example.org”, “https://foo.example.lorg”, “http://bar.example.org”, “https://bar.example.org”.

[Desktop Entry]
Name=Foo App
Exec=harbour-foo
Icon=harbour-foo

[X-Sailfish URL Handler example2foo]
X-Sailfish-scheme=http;
X-Sailfish-host=foo.example.org;
Exec=harbour-foo
X-Maemo-Service=org.example.bar
X-Maemo-Object-Path=/org/example/bar/App
X-Maemo-Method=org.example.bar.App.openFoo

[X-Sailfish URL Handler example2bar]
X-Sailfish-scheme=https;
X-Sailfish-host=bar.example.org;
X-Sailfish-path=/a/b/*
Exec=harbour-foo
X-Maemo-Service=org.example.bar
X-Maemo-Object-Path=/org/example/bar/App
X-Maemo-Method=org.example.bar.App.openBar

This example would match “http://foo.example.org” and “https://bar.example.org/a/b/baz”, but not “http://bar.example.org” and not “https://bar.example.org/a/c/baz”.

This isn’t a finalized proposal by any means, it is more to give a rough. Feel free to reply on what you think about this feature request.

12 Likes

We can have a declarative way to describe what mime types the app can handle, as you described in your proposal.

Then the app can use DBus to actually handle incoming requests. This will be similar to how android’s intent system works.

1 Like

It seems like @Mister_Magister has started on implementing a (different) solution for this problem in libcontentaction: https://git.sailfishos.org/mer-core/libcontentaction/merge_requests/18

Putting it into his normal application repository for every user to replace a system lib without consent. Well, that’s… an unfortunate decision.

It seems that MisterMagister’s implementation was merged: Sailfish Community News, 11th March!

For more inspiration of how more advanced schemes could be impemented, you could look atUbuntu Touch’s(or UBPorts’) URL handler system:

It works with JSON files. An example taken from the Telegram application TELEports:

[
    {
        "protocol": "teleports"
    },
    {
        "protocol": "https",
        "domain-suffix": "t.me"
    },
    {
        "protocol": "https",
        "domain-suffix": "telegram.me"
    },
    {
        "protocol": "https",
        "domain-suffix": "telegram.dog"
    },
    {
        "protocol": "tg"
    }
]

I’ve not found the complete specification/description of what is supported in these JSON files yet.