Skip to content

Canonicalization of query strings, or pp_hum prints same string but compare/equal says they are different? #128

Description

@edwintorok

I got 2 URIs in 2 different files (url1 was created by Uri.to_string on url2), I load them and Uri.compare and Uri.equal considers them distinct even after running it through Uri.canonicalize.
This is confusing because when I use Uri.pp_hum it prints identical strings.
If I recreate the query parameter of the uri in a my_canonicalize function then they are considered equal.

I found this when trying to put a Uri.t into a Set, is this expected?

#use "topfind";;
#require "uri";;

let () =
  let url1 = Uri.of_string "https://example.com/?redirect=http://example.com/foobar" in
  let url2 = Uri.of_string "https://example.com/?redirect=http%3A%2F%2Fexample.com%2Ffoobar" in
  Format.printf "url1: %a@,url2: %a@." Uri.pp_hum url1 Uri.pp_hum url2;
  Format.printf "compare: %d@." @@ Uri.compare (Uri.canonicalize url1) (Uri.canonicalize url2);
  let my_canonicalize u = let u = Uri.canonicalize u in Uri.with_query u (Uri.query u) in
  Format.printf "compare with my_canonicalize: %d@." @@ Uri.compare (my_canonicalize url1) (my_canonicalize url2);;
url1: https://example.com/?redirect=http://example.com/foobar
url2: https://example.com/?redirect=http://example.com/foobar
compare: 1
compare with my_canonicalize: 0

P.S. dune is awesome for debugging issues like this, I just did opam source uri, added some debug print statements in Uri.compare until I drilled down to where it considered them different.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions