Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Describe matrix: URI scheme #3608

Merged
merged 4 commits into from
Dec 31, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelogs/appendices/newsfragments/3608.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Describe the `matrix:` URI scheme as per [MSC2312](https://github.com/matrix-org/matrix-doc/pull/2312).
158 changes: 133 additions & 25 deletions content/appendices.md
Original file line number Diff line number Diff line change
Expand Up @@ -656,24 +656,136 @@ homeserver to look up the alias.
Room aliases MUST NOT exceed 255 bytes (including the `#` sigil and the
domain).

#### matrix.to navigation
#### URIs

There are two major kinds of referring to a resource in Matrix: matrix.to
and `matrix:` URI. The specification currently defines both as active/valid
ways to refer to entities/resources.

Rooms, users, and aliases may be represented as a URI. This URI can
be used to reference particular objects in a given context, such as mentioning
a user in a message or linking someone to a particular point in the room's
history (a permalink).

##### Matrix URI scheme

{{% added-in v="1.2" %}}

The Matrix URI scheme is defined as follows (`[]` enclose optional parts, `{}`
enclose variables):
```
matrix:[//{authority}/]{type}/{id without sigil}[/{type}/{id without sigil}...][?{query}][#{fragment}]
```

As a schema, this can be represented as:

```
MatrixURI = "matrix:" hier-part [ "?" query ] [ "#" fragment ]
hier-part = [ "//" authority "/" ] path
path = entity-descriptor ["/" entity-descriptor]
entity-descriptor = nonid-segment / type-qualifier id-without-sigil
nonid-segment = segment-nz ; as defined in RFC 3986
type-qualifier = segment-nz "/" ; as defined in RFC 3986
id-without-sigil = string ; as defined in Matrix identifier spec above
query = query-element *( "&" query-item )
query-item = action / routing / custom-query-item
action = "action=" ( "join" / "chat" )
routing = "via=” authority
custom-query-item = custom-item-name "=" custom-item-value
custom-item-name = 1*unreserved ; reverse-DNS name
custom-item-value =
turt2live marked this conversation as resolved.
Show resolved Hide resolved
```

Note that this format is deliberately following [RFC 3986](https://tools.ietf.org/html/rfc3986)
to ensure maximum compatibility with existing tooling. The scheme name (`matrix`) is
registered alongside other schemes by the IANA [here](https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml).

Currently, the `authority` and `fragment` are unused by this specification,
though are reserved for future use. Matrix does not have a central authority which
could reasonably fill the `authority` role. `nonid-segment` in the schema is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some explanation of what the nonid-segment could possibly be(come) would help. I'm not getting a sense of understanding what it is while reading this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MSC doesn't appear to have much more information, sorry.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't really define it beyond "a segment to specify a resource that is not supposed to have an id", which is pretty tautological and not any clearer. The idea was that some resources don't need an id but could benefit from having a URI - as a contrived example, some kind of a cloak-room/homepage for a space.

In any case, this PR is meant for purely technical purposes so not a good place to introduce new wording; and as Travis said, the original MSC doesn't have anything to build on, anyway.

additionally reserved for future use.

The `type` denotes the kind of entity which is described by `id without sigil`.
Specifically, the following mappings are used:

* `r` for room aliases.
* `u` for users.
* `roomid` for room IDs (note the distinction from room aliases).
* `e` for events, when after a room reference (`r` or `roomid`).

{{% boxes/note %}}
This namespacing is in place pending a `matrix://` (or similar) URI
scheme. This is **not** meant to be interpreted as an available web
service - see below for more details.
During development of this URI format, types of `user`, `room`, and `event`
were used: these MUST NOT be produced any further, though implementations might
wish to consider handling them as `u`, `r`, and `e` respectively.

`roomid` was otherwise unchanged.
{{% /boxes/note %}}

Rooms, users, aliases, and groups may be represented as a "matrix.to"
URI. This URI can be used to reference particular objects in a given
context, such as mentioning a user in a message or linking someone to a
particular point in the room's history (a permalink).
The `id without sigil` is simply the identifier for the entity without the defined
sigil. For example, `!room:example.org` becomes `room:example.org` (`!` is the sigil
for room IDs). The sigils are described under the
[Common Identifier Format](#common-identifier-format).

The `query` is optional and helps clients with processing the URI's intent. In
this specification are the following:

* `action` - Helps provide intent for what the client should do specifically with
the URI. Lack of an `action` simply indicates that the URI is identifying a resource
and has no suggested action associated with it - clients could treat this as
navigating the user to an informational page, for example.
* `action=join` - Describes an intent for the client to join the room described
by the URI and thus is only valid on URIs which are referring to a room (it
has no meaning and is ignored otherwise). The client should prompt for confirmation
prior to joining the room, if the user isn't already part of the room.
* `action=chat` - Describes an intent for the client to start/open a DM with
the user described by the URI and thus is only valid on URIs which are referring
to a user (it has no meaning and is ignored otherwise). Clients supporting a
form of Canonical DMs should reuse existing DMs instead of creating new ones
if available. The client should prompt for confirmation prior to creating the
DM, if the user isn't being redirected to an existing canonical DM.
* `via` - Can be used to denote which servers (authorities) to attempt to resolve
turt2live marked this conversation as resolved.
Show resolved Hide resolved
the resource through, or take `action` through. An example of using `via` for
routing Room IDs is described [below](#routing), and is encouraged for use in
Matrix URIs referring to a room ID. Matrix URIs can additionally use this `via`
parameter for non-public federation resolution of identifiers (i.e.: listing a
server which might have information about the given user) while a more comprehensive
way is being worked out, such as one proposed by [MSC3020](https://github.com/matrix-org/matrix-doc/pull/3020).
turt2live marked this conversation as resolved.
Show resolved Hide resolved

Custom query parameters can be specified using the
[Common Namespaced Identifier format](#common-namespaced-identifier-grammar) and
appropriately encoding their values. Specifically, "percent encoding" and encoding
of the `&` are required. Where custom parameters conflict with specified ones,
clients should prefer the specified parameters. Clients should strive to maintain
consistency across custom parameters as users might be using multiple different
clients across multiple different authors. Useful and mission-aligned custom
parameters should be proposed to be included in this specification.

Examples of common URIs are:

<!-- Author's note: These examples should be consistent with the matrix.to counterparts. -->
* Link to `#somewhere:example.org`: `matrix:r/somewhere:example.org`
* Link to `!somewhere:example.org`: `matrix:roomid/somewhere:example.org?via=elsewhere.ca`
* Link to `$event` in `#somewhere:example.org`: `matrix:r/somewhere:example.org/e/event`
* Link to `$event` in `!somewhere:example.org`: `matrix:roomid/somewhere:example.org/e/event?via=elsewhere.ca`
* Link to chat with `@alice:example.org`: `matrix:u/alice:example.org?action=chat`

A suggested client implementation algorithm is available in the
[original MSC](https://github.com/matrix-org/matrix-doc/blob/main/proposals/2312-matrix-uri.md#recommended-implementation).

##### matrix.to navigation

{{% boxes/note %}}
This namespacing existed prior to a `matrix:` scheme. This is **not**
meant to be interpreted as an available web service - see below for more
details.
{{% /boxes/note %}}

A matrix.to URI has the following format, based upon the specification
defined in RFC 3986:
defined in [RFC 3986](https://tools.ietf.org/html/rfc3986):

> <https://matrix.to/#/>&lt;identifier&gt;/&lt;extra
> parameter&gt;?&lt;additional arguments&gt;
```
https://matrix.to/#/<identifier>/<extra parameter>?<additional arguments>
```

The identifier may be a room ID, room alias, user ID, or group ID. The
extra parameter is only used in the case of permalinks where an event ID
Expand All @@ -694,13 +806,12 @@ The components of the matrix.to URI (`<identifier>` and

Examples of matrix.to URIs are:

- Room alias: `https://matrix.to/#/%23somewhere%3Aexample.org`
- Room: `https://matrix.to/#/!somewhere%3Aexample.org`
- Permalink by room:
`https://matrix.to/#/!somewhere%3Aexample.org/%24event%3Aexample.org`
- Permalink by room alias:
`https://matrix.to/#/%23somewhere:example.org/%24event%3Aexample.org`
- User: `https://matrix.to/#/%40alice%3Aexample.org`
<!-- Author's note: These examples should be consistent with the matrix scheme counterparts. -->
* Link to `#somewhere:example.org`: `https://matrix.to/#/%23somewhere%3Aexample.org`
* Link to `!somewhere:example.org`: `https://matrix.to/#/!somewhere%3Aexample.org?via=elsewhere.ca`
* Link to `$event` in `#somewhere:example.org`: `https://matrix.to/#/%23somewhere:example.org/%24event%3Aexample.org`
* Link to `$event` in `!somewhere:example.org`: `https://matrix.to/#/!somewhere%3Aexample.org/%24event%3Aexample.org?via=elsewhere.ca`
* Link to `@alice:example.org`: `https://matrix.to/#/%40alice%3Aexample.org`

{{% boxes/note %}}
Historically, clients have not produced URIs which are fully encoded.
Expand Down Expand Up @@ -730,20 +841,17 @@ may not be encoded).

Room IDs are not routable on their own as there is no reliable domain to
send requests to. This is partially mitigated with the addition of a
`via` argument on a matrix.to URI, however the problem of routability is
`via` argument on a URI, however the problem of routability is
still present. Clients should do their best to route Room IDs to where
they need to go, however they should also be aware of [issue
\#1579](https://github.com/matrix-org/matrix-doc/issues/1579).

A room (or room permalink) which isn't using a room alias should supply
at least one server using `via` in the `<additional arguments>`, like
so:
`https://matrix.to/#/!somewhere%3Aexample.org?via=example.org&via=alt.example.org`.
The parameter can be supplied multiple times to specify multiple servers
to try.
at least one server using `via` in the URI's query string. Multiple servers
can be specified by including multuple `via` parameters.

The values of `via` are intended to be passed along as the `server_name`
parameters on the Client Server `/join` API.
parameters on the [Client Server `/join/{roomIdOrAlias}` API](/client-server-api/#post_matrixclientv3joinroomidoralias).

When generating room links and permalinks, the application should pick
servers which have a high probability of being in the room in the
Expand Down