|
Normalization of percent-encoding
Peter Bex
(16 Jun 2026 10:18 UTC)
|
|
Re: Normalization of percent-encoding D Guthrie (16 Jun 2026 12:26 UTC)
|
|
Re: Normalization of percent-encoding
Peter Bex
(16 Jun 2026 13:12 UTC)
|
|
Re: Normalization of percent-encoding
D Guthrie
(16 Jun 2026 14:50 UTC)
|
|
Re: Normalization of percent-encoding
Peter Bex
(17 Jun 2026 07:21 UTC)
|
Hi Peter, I'll reply inlineā¦
> On 16 Jun 2026, at 11:18, Peter Bex <xxxxxx@more-magic.net> wrote:
>
> Hi there,
>
> I saw the URI SRFI this morning and as the author of the CHICKEN
> uri-common and co-author of the uri-generic library I would like to at
> least point out that percent-encoding is a bit of a pitfall, especially
> when programmatically constructing or updating URIs, also when based
> on user input.
>
> For this reason, the uri-generic library deconstructs the path
> segments into list form. Any percent-encoded characters that cannot
> occur in a path segment are automatically decoded. So for example, the
> slash is encoded as %2F but in decoded path-segments-as-list form, the
> individual segments will contain the decoded slash. So a relative ref
> like "foo%2Fbar/qux" will read like '("foo/bar" "qux") when decoded.
I think that decoding problems most often arise if you're feeding in
arbitrary data into the setters with no restriction, which is why I parse
the input strings strictly according to the ABNF and raise errors on
failure. I think it is a good idea to have encoding and decoding of paths
from a high-level representation to the low-level one!
However, using a high-level representation like that internally which
makes slashes implicit, was for me unworkable when I was trying to achieve
compliance with the RFCs - the way in which path segment normalisation is
defined is a sort of stack procedure where there is special interpretation
of special dotted segments with respect to surrounding slashes. With a
representation like the above (where I tagged a path with being absolute
or relative to special-case a leading slash), I never figured out a way to
achieve exact compliance with the RFC's relative reference resolution or
the various normalisation test cases used by the other implementations.
I've come up with a test suite however so we might be able to give it
another shot and still come up with equivalent behaviour.
Of course, compliance with these RFCs and a measure of desired/normative
behaviour is very difficult to achieve because of the lack of test suites
and comprehensive examples for normalisation. I'd emphasise the Haskell
network-uri test suite had the most relevant test cases because it is
explicitly an implementation of RFC 3986, and the more obscure test
cases are based on correspondence on the W3C's mailing lists about edge
cases. You've probably seen the test cases at the end of the SRFI.
> And Unicode characters will also be decoded using the supplied encoding
> (UTF-8 by default).
>
> Note that all the "reserved" characters have a different meaning whether
> percent-encoded or not. See section 2.2 of RFC 2986.
>
> For this reason, we wrap the uri-generic library with the uri-common to
> make this easier for the user when dealing with "common" schemes like
> HTTP. This library fully decodes percent-encoded characters in path and
> query string (which is handled as an alist). This is a lossy process,
> as pointed out above, reserved characters have potentially different
> meaning whether encoded or decoded. However, in the vast majority of
> cases the programmer does not care and just wants to stuff a value into
> a path segment. It's nice not having to deal with the low-level nitty
> gritty of percent-encoding.
Well, the main reason I don't provide decoding procedures for all of an
URI's percent-encodings is because this seemed to largely be subsumed by
RFC 3987's conversions between IRIs and URIs (and vice versa), at least
for UTF-8.
We have the same set of reserved characters but this time we can decode
almost any other character in the universal character set as the character
proper. So `uri->iri' would let us decode (likely most of) an URI and
then still be able to use it to denote resources where IRIs are prevalent,
like RDF or JSON-LD. This is actually an interpretation of the
percent-encodings as UTF-8, and the behaviour is well-defined in RFC 3987
so we can probably rely on other implementations to interpret our IRIs and
URIs as we do. It works both ways so we can also encode an IRI as an URI.
For the conversion of IRIs to URIs, as far as I understand the current
approach for non-UTF-8 encodings is to represent them in the UCS after
normalising from that encoding:
https://www.rfc-editor.org/info/rfc3987/#section-3.1
For URIs alone, I'm not sure and I suspect this doesn't answer your
question.
I am not sure representing other character encodings than UTF-8 is so
useful, and I suspect it could be implemented in a separate library. I
could be missing something crucial here tohugh. For context, my own
interest in this is almost entirely for IRIs in the RDF world so I had no
need for scheme-specific interpretation, but I appreciate a lto of the
libraries out there put a lot more emphasis on web clients where there
may be a lot of scheme-specific decoding.
Thanks!
Duncan