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?

Community
  • 1
  • 1
algal
  • 27,584
  • 13
  • 78
  • 80

1 Answers1

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.

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
  • So `myscheme:` is a *syntactically* valid URL, and `-resourceSpecifier` lets you grab the ``, and this is enough for a simple URL adapter protocol. Hurray! However, `` 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. – algal Dec 29 '13 at 05:11
  • 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. – Mike Abdullah Dec 29 '13 at 10:14
  • Oh, and strictly speaking it's more accurate to say `myscheme:` is a syntactically valid *URI*, rather than a *URL* as such (I think!) – Mike Abdullah Dec 29 '13 at 10:15
  • If `` is a URL, then it promises lookup-from-location behavior. If `myscheme:` promises to perform a transformation on whatever is retrieved from ``, then `myscheme:` 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. :) – algal Dec 30 '13 at 18:16