What libraries we need Lassi Kortela (07 Apr 2019 08:55 UTC)
Re: What libraries we need Peter Bex (07 Apr 2019 09:31 UTC)
URI/URL handling Lassi Kortela (07 Apr 2019 10:11 UTC)
Re: URI/URL handling Peter Bex (07 Apr 2019 10:56 UTC)
Re: URI/URL handling Lassi Kortela (07 Apr 2019 12:03 UTC)
Re: URI/URL handling Lassi Kortela (07 Apr 2019 12:46 UTC)
Re: URI/URL handling Peter Bex (07 Apr 2019 14:20 UTC)
Re: URI/URL handling Lassi Kortela (07 Apr 2019 15:06 UTC)
Re: URI/URL handling Peter Bex (07 Apr 2019 15:39 UTC)
Re: URI/URL handling Lassi Kortela (07 Apr 2019 15:52 UTC)
Re: URI/URL handling Peter Bex (07 Apr 2019 16:03 UTC)
Re: URI/URL handling Lassi Kortela (07 Apr 2019 16:30 UTC)
Re: URI/URL handling Arthur A. Gleckler (09 Apr 2019 21:06 UTC)
Re: What libraries we need Arthur A. Gleckler (09 Apr 2019 20:49 UTC)

Re: URI/URL handling Lassi Kortela 07 Apr 2019 15:06 UTC

> If you only have constructors, that's really tedious in use.

> So in uri-common that'd be
>
> (define base-uri (uri-reference "http://example.com/search"))
>
> and then, to construct the URI and hit the endpoint:
>
> (define (search/firstname uri name)
>    (update-uri base-uri
>       query: (alist-update 'firstname name (uri-query uri))))
>
> (define (search/lastname uri name)
>    (update-uri base-uri
>       query: (alist-update 'lastname name (uri-query uri))))
>
> (let* ((s base-uri)
>         (s (search/firstname s "peter"))
>         (s (search/lastname s "bex")))
>    (with-input-from-request s #f read-lines))
>
> I don't think it's necessary to have a mutable API, but an updating API
> would be very nice.

100% agree. We should definitely have an update API that returns new
URIs objects based on old ones.

Your API looks good to me. I.e. the keyword arguments (is that the right
term in Scheme?) are the same as the ones for the constructor, and you
only give the ones you want to change.

>> Great :D We should probably specify a conservative normalization form in
>> which differences like this don't matter...
>
> In uri-common, there's a SRFI-39 parameter you can set (fluidly or
> globally) which controls this.

Do you mean `(define form-urlencoded-separator (make-parameter ";&"))`?

> This is a bit ugly.  Unfortunately,
> when you update the common query object, the underlying query string
> in the generic object needs to get set, which means you need to know
> when you update what the separator character is.
>
> Otherwise, it'd make more sense to have uri->string accept the separator
> and other options.

OK, I'm trying to comprehend the situation in its full glory and it's
getting painful :D

Maybe we should store only the raw query string from the server.

And the separators ";&" would be given separately to each call of the
query parameter list getter. I.e.:

     (uri-raw-query-string u)       == "a%3Db;c=d&e=f"
     (uri-query/delimiters u ";&")  == (("a" . "b")
                                        ("c" . "d") ("e" . "f"))

And the accessor with the friendly name would just use the most
conservative delimiters:

     (uri-query u) == (uri-query/delimiters u ";&")

The constructor and update procedure "path:" arguments would use the
conservative delimiters to encode the path, and raise an error if those
delimiters appear in the user-supplied strings:

     (set! u (make-http-uri path: '("foo")))
     (update-uri u :path '("foo" "bar"))

     (update-uri u :path '("foo" "/" "bar"))
        ;; this would error because we cannot unambiguously encode slash

There would be a separate (string->uri ...) procedure for making a URI
from any raw string. Maybe it should have a less inviting name ;)

> I don't think you need to be able to dispatch on the query _string_,
> only on the parsed values.

That still seems quite specialized. But if we can parse the query
parameters into a canonical "safe" normal form then I don't see a
problem with dispatching on them.

> I don't really see the value in that.  foo//bar is not the same path
> as foo/bar.  A web server could issue a 301 redirect to "fix" such
> paths, which I think is a better level at which to fix it.

OK, you know much better than I do what the usual convention is. If
empty components are filtered out before the URL gets the dispatcher,
that is indeed even more robust.

>> In all parts of the API the boring, safe and ordinary way to do things
>> should be the obvious way to do it IMHO :)
>
> Agreed, but it should always be possible to recover such "losses" for
> cases where you want more precision.

Agreed.