• [^] # Re: Fragment

    Posté par . En réponse à l’entrée du suivi Impossible de mettre un lien vers un salon matrix dans les liens d'une dépêche. Évalué à 3 (+0/-0).

    Non, allow_blank permet juste d'accepter une valeur vide, ce n'est pas passé à URI::regexp. Ça valide juste parce que la regexp n'est pas ancrée. Tu peux mettre n'importe quoi et ça passe, tant que y'a une URL quelque part.

    irb(main):010:0> URI.regexp(%w(http https)).match?("https://matrix.to/#/#copie-publique:codelutin.com")
    => true
    irb(main):011:0> URI.regexp(%w(http https)).match?("ziguigui+https://matrix.to/#/#copie-publique:codelutin.com")
    => true
    

    C'est un bug qui mériterait d'être corrigé.

    Par contre il est intéressant de constater que la RFC 3986 n'autorise pas de # dans le fragment (ce qui implique que l'URL de l'OP est invalide):

     segment = *pchar
     pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
     pct-encoded = "%" HEXDIG HEXDIG
     unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
     sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
     / "*" / "+" / "," / ";" / "="
    

    La regexp retournée par URI.regexp est d'ailleurs correcte en ce sens:

    (?:\#((?:[\-_.!~*'()a-zA-Z\d;\/?:@&=+,ドル\[\]]|%[a-fA-F\d]{2})*))? (?# 9: fragment)
    

    Pour rendre l'URL valide au sens de la RFC 3986 il faudrait donc encoder le #:

    irb(main):003:0> u = URI.parse("https://matrix.to/#/%23copie-publique:codelutin.com")
    => #<URI::HTTPS https://matrix.to/#/%23copie-publique:codelutin.com>
    

    Par ailleurs, python accepte l'URL telle quelle, avec les 2 # (j'imagine que c'est une déviation de la RFC qui est assez courante et elle ne cause pas d'ambiguité en soi):

    >>> urllib.parse.urlparse("https://matrix.to/#/#copie-publique:codelutin.com")
    ParseResult(scheme='https', netloc='matrix.to', path='/', params='', query='', fragment='/#copie-publique:codelutin.com')