Custom URL scheme as adapter on existing URL schemes
Asked Answered
D

1

1

Is there a clean and spec-conformant way to define a custom URL scheme that acts as an adapter on the resource returned by another URL?

I have already defined a custom URL protocol which returns a decrypted representation of a local file. So, for instance, in my code,

decrypted-file:///path/to/file

transparently decrypts the file you would get from file:///path/to/file. However, this only works for local files. No fun! I am hoping that the URL specification allows a clean way that I could generalize this by defining a new URL scheme as a kind of adapter on existing URLs.

For example, could I instead define a custom URL scheme decrypted: that could be used as an adapter that prefixes another absolute URL that retrieved a resource? Then I could just do

decrypted:file:///path/to/file

or decrypted:http://server/path/to/file or decrypted:ftp://server/path/to/file or whatever. This would make my decrypted: protocol composable with all existing URL schemes that do file retrieval.

Java does something similar with the jar: URL scheme but from my reading of RFC 3986 it seems like this Java technology violates the URL spec. The embedded URL is not properly byte-encoded, so any /, ?, or # delimiters in the embedded URL should officially be treated as segment delimiters in the embedding URL (even if that's not what JarURLConnection does). I want to stay within the specs.

Is there a nice and correct way to do this? Or is the only option to byte-encode the entire embedded URL (i.e., decrypted:file%3A%2F%2F%2Fpath%2Fto%2Ffile, which is not so nice)?

Is what I'm suggesting (URL adapters) done anywhere else? Or is there a deeper reason why this is misguided?

Diageotropism answered 27/12, 2013 at 20:32 Comment(0)
G
0

There's no built-in adaptor in Cocoa, but writing your own using NSURLProtocol is pretty straightforward for most uses. Given an arbitrary URL, encoding it like so seems simplest:

myscheme:<originalurl>

For example:

myscheme:http://example.com/path

At its simplest, NSURL only actually cares if the string you pass in is a valid URI, which the above is. Yes, there is then extra URL support layered on top, based around RFC 1808 etc. but that's not essential.

All that's required to be a valid URI is a colon to indicate the scheme, and no invalid characters (basically, ASCII without spaces).

You can then use the -resourceSpecifier method to retrieve the original URL and work with that.

Grice answered 28/12, 2013 at 12:24 Comment(4)
So myscheme:<originalurl> is a syntactically valid URL, and -resourceSpecifier lets you grab the <originalurl>, and this is enough for a simple URL adapter protocol. Hurray! However, <originalurl> does not match any well-defined semantic component of the outer URL but instead matches its hierarchical-part plus query component plus fragment components. So simple prefixing like this would not work if, for instance, I also wanted to add a query component to the outer URL, since the inner URL's query component would count as belonging to the outer URL. Phew.Diageotropism
Yep, it's only if you want to start adding in additional parameters have you got to worry about some form of encoding. KSURLQuery might prove handy for that.Grice
Oh, and strictly speaking it's more accurate to say myscheme:<originalurl> is a syntactically valid URI, rather than a URL as such (I think!)Grice
If <originalurl> is a URL, then it promises lookup-from-location behavior. If myscheme: promises to perform a transformation on whatever is retrieved from <originalurl>, then myscheme:<originalurl> can also promise lookup-from-location behavior so it is also a URL. At least, that's my thinking. But I'm not sure if URLs are under-used as an access DSL, or if this is all just nuts. :)Diageotropism

© 2022 - 2024 — McMap. All rights reserved.