This is a thread for further discussion of The XOR-URLs RFC.
Please hold forth and opine here.
This is a thread for further discussion of The XOR-URLs RFC.
Please hold forth and opine here.
Currently thereâs some discussion around the use of :
for distinction of the typeTag
: Cannot fetch content with a XOR-URL which typeTag is greater than 65535 ¡ Issue #429 ¡ maidsafe/sn_browser ¡ GitHub
Essentially, itâs reserved in url schema for port numbers and so cannot be larger than 65535. Which is problematic.
There have been suggestions for alternative characters. !
, eg.
Thanks, @joshuef. I think I wanted to know what was envisioned with a possible âfallback mechanismâ in the âPrivate contentâ section:
At the same time, it may be considered to have either a fallback mechanism, or an additional bit encoded in the URL to realise if the XOR-URL is targeting a private or public content to act accordingly.
This is a very exciting rfc!!
RFC-0053 may need some modification to the bold part
#somesection?somekey=5 is the <fragment> and <query> parts which will be ignored by the resoler and simply returned back to the application for it to use it.
The URL spec says
No fragmentid part of a WWW URI (the hash sign and following) is sent with the request.
Maybe change to
#somesection?somekey=5 is the <fragment> and <query> parts which will not be sent with the request or received with the response data, but may be added to the response data by the client for the application to use.
My suggestion is to exclude fragments from the rfc completely, leave it to the app to use.
RFC 3986 Section 3.5 has useful claims about how fragments are meant to be used:
[fragments are] the primary form of client-side indirect referencing
âŚ
the identifying information within the fragment itself is dereferenced solely by the user
(also thereâs a typo resoler/resolver in the rfc)
In RFC-0053 why do both the querystring and fragment do the same thing, ie âto be used by the client app and not for retrieving the contentâ? Might be best to leave the fragment alone completely for apps to do with as they please.
Querystring is still useful to keep in the spec (see below about MD)
From RFC-0053
#somesection?somekey=5 is the and parts which will be ignored by the resoler and simply returned back to the application for it to use it.
The order of querystring and fragment is back to front (querystring should be second last, fragment should be last). See RFC 3986 Section 1.2.3, 3.4 and 3.5
The URI syntax is organized hierarchically, with components listed in order of decreasing significance from left to right.
âŚ
The query component is indicated by the first question mark (â?â) character and terminated by a number sign (â#â) character or by the end of the URI.
âŚ
A fragment identifier component is indicated by the presence of a number sign (â#â) character and terminated by the end of the URI.
Iâm dubious about the use of ports as a placeholder for MD types (which has been discussed by others in the github issue).
Introducing !
delimiter instead of :
will mean xor urls are broken in every existing url parser. I reckon itâs best to put the type value in the querystring as ?t=1234
A missing t
parameter means itâs immutable.
Then optional content version can be encoded into the querystring with v
, ie ?t=1234&v=1
; leaving out v
means the latest version is returned.
The querystring seems like the right place to encode metadata into xor-urls. It should not be encoded in the port. Or the host. Or the path. Or the fragment.
It may be encoded in the userinfo part of the url, eg type 1234 and version 1 could be safe://1234:1@<cid>/path/to/file?querysting#fragment
but I feel like this is abusing the intended userinfo semantics, depending how RFC 3986 Section 3.2 is interpreted:
[userinfo is a] means for distinguishing an authority based on a registered name or server address
Ultimately I reckon MD metadata belongs in the querystring. It might have collision issues if someone wants to use t
or v
keys in the querystring for their application data, but probably the fragment should be the canonical way for clients to manage data internally, leaving querystring only for request metadata.
Please do not break standard url parsers by introducing custom delimiters.
I missed the tag encoding problem.
I could argue that both the name and tag are equally important for locating an MD. If the tag is metadata, then so is the name. Both could be encoded into the cid
part I assume. (Version number too, or into the port part.)
Another option would be the top-level domain (TLD). TLDs canât start with a digit, so a SAFE URL could turn into: safe://<cid>.t12345
(for tag 12345).
Semantically I donât think the query string is suited for the tag. It follows the authority (userinfo, host and port) and path; reading from left to right it should narrow the scope. A query string is for querying, for passing parameters to the page. Web app developers (like with Vue) might have great trouble constantly re-encoding the tag type into the query string for every URI pointing to its own app.
I donât agree about their importance for locating an MD.
The xorname is the only data used to locate the section/group/vault for an MD (ie the route). This means the xorname is like host
in the url - the xorname is everything needed to route the request.
There are probably two main options for encoding type+version metadata into urls.
safe://<cid>/path?querystring#fragment
- immutable (no subdomain)
safe://1234.<cid>/path?querystring#fragment
- mutable with type 1234 (latest version)
safe://1.1234.<cid>/path?querystring#fragment
- mutable with type 1234 version 1
I donât think it should be encoded as the TLD, since type+version is lower in the hierarchy than the xorname (since theyâre not used at all for routing purposes).
Thereâs a loose hierarchy here, with version being a child of type, and type is a child of the xorname. But I think it sets up a false idea that MD under the same xorname are related when theyâre not. MD under the same xorname+type obviously are related by their version numbers, but the xorname has no meaningful relation to the various MD type values that have been created.
safe://<cid>/path#fragment
- immutable (no querystring)
safe://<cid>/path?t=1234#fragment
- mutable with type 1234 (latest version)
safe://<cid>/path?t=1234&v=1#fragment
- mutable with type 1234 version 1
I prefer querystring because itâs extendable and semantic. MD urls are literally querying a specific type and/or version of mutable data at a specific xorname.
Overall, existing urls have quite strong semantics and I think where possible xor-urls should try to match those and not repurpose fields for different purposes.
The difference is certainly not majorly significant in practice. If we need to have a custom xor-url parser in order to have meaningful semantics then so be it (this will be needed to some degree anyhow for the cid component). But Iâd like to see the design be maximally consistent with existing url wisdom where possible. The conceptual mapping isnât always perfect so itâs good to see discussion and ideas happening.
Yes, good point, itâs important to consider the impact on the end users. But I feel it doesnât make sense to model the design of xor-urls around implementations and libraries, it should be modelled on the existing design/purpose of urls.
Since all MD for the app will (presumably) have the same type it does map reasonably well onto the subdomain concept. But I still feel this is a query not a domain
I agree, but again I would argue that without the port (analogous to MD tag) there is no way to reach the service â in that sense I think host and port are equally important. Analogously, without either the name or tag you wonât get an MD.
Because I view it like this, I feel the query string isnât suited. Itâs too specific. It comes after the path. The path doesnât make sense without having specifief the MD first.
Touche.
Another reasonable option would be the first component in the path: safe://<cid>/1234
for tag 1234.
Looking at maidsafe/routing/src/messages/request.rs GetMData
Thereâs no way to specify which version is desired to be fetched. Is version history retained? Iâm not clear about accessing MD, can someone please clarify if only the latest version is available or if all versions are.
Only the latest version is available for now.
This is something we are debating internally with in the teams on and off. We are planning to bring this as a mainstream discussion in the upcoming weeks to explore possible approaches for a versioned datatype.
Right now the type tag is necessary component of the URL for fetching the data (it needs to be passed to the browser for grabbing MD).
Any webapps dealing with this would effectively be having to run their own fetch implementation instead of relying on baked in browser set fetch to retrieve XOR-URLs (which would negate the point of them, IMO).
On where should type/version live in the URLâŚ
Using the path I was initially against, to make it clear whatâs part of the URL and whatâs not as, the path could be used to fetching parts of RDF data eg., but, thatâs not necessarily precluded by using pathsâŚ
safe://dsaiudhasiuhiufhsiduhiusfgdsdsfs/t1234/v1/some/portion/of/the/RDFdata
Though weâre creating limitations (or if not, just confusion) about what paths could be reliably stored at a given XOR-URLâŚ
Subdomains is interesting, in the current plan we first attempt to resolve a XOR, and if fail, hit PNS.
So now it would be, if a XOR is hit with XOR-URL, we check for subdomains, if thereâs at least one, we resolve that typetag. if thereâs two⌠typetag and version. If not we move to PNS system.
This would more clearly retain the ability to utilise paths / fragments to further specify the data you might want from an MD (if it was RDF eg).
Another variation which avoids confusing version and tag with subNames or path, assuming thereâs a suitable separator we can use (here I use hyphen):
safe://dsaiudhasiuhiufhsiduhiusfgdsdsfs-t1234-v1
@bzee, I think this was just trying to mean that if the resolver supports to fetch and decrypt MD entries it may need to try first to decrypt them and if that fails then simply assume that entry is unencrypted, in priv MDs entries can be both encrypted but some unencrypted. Iâll be looking at applying some of the corrections made above by @mav so Iâll try to also enhance this paragraph as this bit is definitely not clear at all.
I think the confusion here has to do with the fact that the RFC is talking not just about the XOR-URL spec being proposed, but also how we can/want to support it with our resolver, i.e. our webFetch
and fetch
browser embedded functions.
E.g., if you are fetching a WebID with a fragment, I thought it would be desirable to have the fetch/webFetch to already take care of it and return the corresponding graph (in cases you have more than one foaf:Person
graph in the same WebID), but itâs also true an app may not want that and would prefer to obtain the complete WebID profile doc for it to process the fragment (or not ). This can probably be an option which can be passed in when invoking the resolver stating if the fragment shall be processed by the resolver, or as you suggested, simply have the resolver to not support fragment inspection/resolution.
When looking at how to encode the type tag I was having the same type of thoughts and point of view as @bzee, I donât think MD urls are literally querying a specific type and/or version of a MD in the sense that querying is supposed to be something targetting the client app or website, and nothing to do with the resolver or how to route the request, just like the fragment. So we thought that since the type tag is used by the vault to retrieve the service/content (as bzee says you cannot do it without a type tag), it fits quite well trying to make an analogy with port numbers.
I think along the same lines for the version, this is not defined yet how it will work, so we donât know if different versions of the âsameâ content would be store/hold by the same section/group, I presume it all depends how this will be implemented. And even if they are in the same section/group, providing the version is/will still be part of the routing/locating mechanism rather than something dealt by the client app.
Now, I have recently started to think about the need of a type tag number, simply considering not having type tags at all to route and locate any type of content. From a userâs perspective, why do I need a ânumberâ to locate a content on a network which holds immutable versionable data, for which I already have a hash of the content Iâm looking for? AFAIK, the idea behind the type tag was to be able to have the network (vaults) to act upon data in specific ways for predefined type tags, e.g. safecoin is typetag X so mutations/requests for such MDs can be treated in a special way. But what if we can do that in some other way and remove the type tag altogether? wouldnât that be a much cleaner CAS and URLs?
(Note I have no clear understanding yet if itâs possible to get rid of type tags but throwing it for consideration as well)⌠thinking out loud, what if some bits of the XOR address are actually the type tag, and what if we even expand the XOR name address space if we want to have 256 bits for it and add some more bits which are used for type tag? @ustulation / @nbaksalyar does this sounds too crazy/wrong?
I would be more inclined to this option rather than any of the other where querystring or fragment is used for any of the type tag or versioning. Iâm also thinking of the suggestion from @hunterlester Cannot fetch content with a XOR-URL which typeTag is greater than 65535 ¡ Issue #429 ¡ maidsafe/sn_browser ¡ GitHub, what if we propose an addition to the multiformat protocol where you can append some custom data and which we use to encode the type tag number. Iâll have to think about this more thoroughly though.
The use of the term website is not really ideal here (page was also used in an earlier post). I reckon this url scheme is closest to an api design, not a website or webpage. Querystrings are a way to refine the data returned from the specified endpoint. Querystrings are consumed by the endpoint, not by the client.
The host field in the url maps exactly in concept to the xor location of the data, which is used to route the request. Host/xorname is not used to refine data returned from the endpoint.
The type tag and / or version number maps almost exactly in concept to the querystring as a way to get the endpoint to refine the result from a larger set of data.
The point I want to make here is that type tag is not used for routing the request. This is my reason for wanting it not to be encoded as subdomain in the host field but instead as querystring. To my mind this is closer to the semantics of the current url rfc 3986. Type tag doesnât affect routing thus it doesnât belong in the host field.
In a similar vein, it might be good to also think toward the future when compute is on SAFE and how futureproofing that kind of feature might impact current URL design thinking. Itâs an unknown for now but that doesnât mean we canât at least consider keeping some options open for future uses.
I disagree (to an extent). Type/version is only used by the endpoint to filter the potential results at that xor address down to the correct data, ie itâs not used for routing (I think Iâm using a different definition of routing than you; I consider routing to stop when the request reaches the vault containing the data, operations internal to the vault such as picking the correct chunk off the disk are not routing). Type/version is not part of routing.
Anyway I think Iâve already said more than necessary on this topic considering the relatively small magnitude of the point. Please carefully consider what is âroutingâ, âlocationâ, âfilteringâ etc and apply those semantics consistently within the url encoding. As IPv6 and BIP70 has shown it can be very hard to change or extend once an existing standard is in use.
While I agree here, the is perhaps another way to consider it.
For instance when the address is routed only the upper âxâ number of bits is used. The rest are contained within the section/group. Not the number of bits will vary as the number of sections vary and how they split. But it will still only be a small portion of the address used for routing.
Now the tag when requesting a MD could be considered the lower 64 bits of a combined address.
It sounds like it just has to do with the fact there is no server, so we now have only the routing side of it, and the client side.
From my point of view the client side is everything that a traditional script would do on the client or server side, or even the web server process itself, this includes the query string used by a script and path which would be taken care by the web server process. Then the type tag or version is kinda in the middle/gray-area where traditionally has to be resolved before a server side script or webserver process deals with the request, which in my view/model is still part of the routing the request to the targetted content. So itâs a matter of where we draw the line I guess.
EDIT: however for the version, as I said before, I think it all depends how itâs implemented, if different versions are kept in the same section or not, then it would go on one side or the other.
Agreed, this is a very reasonable perspective. The traditional role of querystring maps onto fairly ambiguous territory when used in SAFE.
Stupid question
Xor urls - how are they defined by now� I saw a lot of discussion and this rfc
Sorry for not participating in this earlier and complaining now⌠But since the proposed z-base32 encoding is no standard encoding I wasnât able to simply just generate the string and try to see my uploaded data with the browserâŚ
Since this was kind of a bummer for me (and the z-base32 implementation for python that can simply installed with pip is python2 only for now) I thought it would ask why you want to use a non standard encoding which might cause trouble with other programming languages too�
The argument with easier readability doesnât count imho because we are talking about xor addresses which are hashes of data (at least for immutable dataâŚ?) which should result in kind of randomly distributed bits⌠So the characters should appear pretty much equally distributed (and with creating a new mutable data with the create new random it should be the same)
In addition to this I like the argument that base64 encoding is shorter (and nobody would type those links by hand anyway)
hey @riddim, not stupid questions at all!
The RFC is still on going so all comments / concerns / questions are very welcome!
Canât say I agree here, Iâm afraid.
z-base32 is case insensitive, which can be important when copy-pasting /passing around / normalizing urls to avoid issues (weâve had issues with base64, already). It also strives to remove characters that could be easily confused, which should make them just that bit more useable.
In addition to this I like the argument that base64 encoding is shorter (and nobody would type those links by hand anyway)
If no one would type them, what does it matter if they are longer?
If you do type them out for whatever reason, and one or two or three characters can be confused, thatâd be a huge pain (IMO).
That, at least ,is part of the reasoning for the choice of z-base32 (@bochaco maybe you can remember anye more ?)
The availability of parses might be something worth having a look at, certainly
Although as a developer you are able to use the SAFE APIs to decode the strings and retrieve the mutable data info if thatâs what youâre after. Or are you imagining other situations to be using the XOR-URLs?
Iâm not sure I follow.
You need to upload the data to the network and retrieve the given xor-url based on its location in the network. You cannot simply base32 some data and pass this link for the browser to decode / display data (Is that what youâre imagining?)
That was the reasoning about the choice of z-base32 so far @joshuef @riddim, for a URL having a case insensitive encoding seems a must to me.
Also, regarding different languages, you can take a look at the CID implementation for different languages if you donât want to use the functions exposed by the SAFE API: GitHub - multiformats/cid: Self-describing content-addressed identifiers for distributed systems, we are simply using the JS implementation of CID and multiformats, and whenever this is implemented in lower layers in Rust we will presumably also be using the available one GitHub - multiformats/rust-cid: CID in rust, once itâs in our SCL layer you shouldnât need any other package/lib but just use whatâs available in our API through the lang binding you are using.
@riddim, please take a look at the snippets and little description in the following post, thatâs how you can retrieve a XOR-URL (remember you need the experimental APIs enabled), this may help you in getting a sense of the current state of the proposal, this is part of https://safenetforum.org/t/release-safe-browser-v0-11-0/26792: