Suivi — Dépêches Impossible de mettre un lien vers un salon matrix dans les liens d'une dépêche

#2047 Posté par  (site web personnel) . État de l’entrée : ouverte. Assigné à Adrien Dorsaz. Licence CC By‑SA.
Étiquettes : aucune
1
31
déc.
2022

Exemple avec https://matrix.to/#/#copie-publique:codelutin.com pour la dépêche https://linuxfr.org/news/copie-publique-des-entreprises-s-allient-pour-financer-les-communs-numeriques

  • # Fragment

    Posté par  . Évalué à 2 (+0/-0).

    J'imagine que le problème c'est le '#' ?

    • [^] # Re: Fragment

      Posté par  . Évalué à 3 (+0/-0).

      Bon je n'étais pas loin, le problème c'est que la validation des liens considère que l'URL "https://matrix.to/#/#copie-publique:codelutin.com" n'est pas valide car elle contient deux fois le caractère #.

      • [^] # Re: Fragment

        Posté par  . Évalué à 3 (+0/-0). Dernière modification le 05 janvier 2023 à 23:27.

        Les liens dans les dépèches et dans les bookmarks sont validés comme suit et refuse l'URL matrix.to:

        validates :url, http_url: { protocols: PROTOCOLS, message: "L'adresse n'est pas valide" },

        Le site web personnel de l'utilisateur est validé comme suit et accepte l'URL matrix.to:

        validates_format_of :homesite, message: "L’adresse du site Web personnel n’est pas valide", with: URI::regexp(%w(http https)), allow_blank: true

        Les bookmarks utilisent le même procédé pour indiquer que l'URL est mauvaise si la validation échoue:

        flash.now[:alert] = "Votre lien semble invalide. Le confimez‑vous ?" unless @bookmark.link =~ /\A#{URI::regexp(['http', 'https'])}\z/

        Ça vaudrait peut-être la peine d'uniformiser tout ça. :-)

        A priori ce http_url vient de app/validators/http_url_validator.rb, qui utilise URI.parse mais échoue:

        irb(main):001:0> URI.parse("https://matrix.to/#/#copie-publique:codelutin.com")
        URI::InvalidURIError: bad URI(is not URI?): https://matrix.to/#/#copie-publique:codelutin.com
            from /usr/lib/ruby/2.3.0/uri/rfc3986_parser.rb:67:in `split'
            from /usr/lib/ruby/2.3.0/uri/rfc3986_parser.rb:73:in `parse'
            from /usr/lib/ruby/2.3.0/uri/common.rb:227:in `parse'
            from (irb):1
            from /usr/bin/irb:11:in `<main>'
        

        Donc ruby n'est pas capable de parser une URI que sa regexp considère comme valide…

        • [^] # Re: Fragment

          Posté par  (site web personnel, Mastodon) . Évalué à 2 (+0/-0).

          Donc ruby n'est pas capable de parser une URI que sa regexp considère comme valide…

          Je pense que le paramètre allow_blank fait toute la différence. Ce n'est pas le cas par défaut, où juste /#/ est vu comme aussi vide de sens que // à cet emplacement.

          “It is seldom that liberty of any kind is lost all at once.” ― David Hume

          • [^] # Re: Fragment

            Posté par  . É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')
            
            • [^] # Re: Fragment

              Posté par  . Évalué à 3 (+0/-0). Dernière modification le 06 janvier 2023 à 01:32.

              Voir aussi ce bug report pour matrix.to: Switch to valid URL syntax #17

              Correctif pour l'incohérence de validation: Fix validating the URL of user home sites #355

              Faut pas laisser >trim dormir.

              • [^] # Re: Fragment

                Posté par  (site web personnel) . Évalué à 3 (+0/-0).

                Merci pour la MR. Il faudrait changer le message affiché par contre pour retirer "URL", qui ne parle qu'aux gens techniques. On a uniformisé avec "adresse" quand c'est pour les visiteurs.

              • [^] # Re: Fragment

                Posté par  (site web personnel, Mastodon) . Évalué à 3 (+0/-0). Dernière modification le 06 janvier 2023 à 18:22.

                Faut pas laisser >trim dormir.

                Et >oumph non plus pour gérer les déploiements :)


                Merci pour l’analyse, je conclurai donc que l’entrée de suivi ne sera pas corrigée: si Matrix a décidé de ne pas suivre le standard des URLs, ce n’est pas à LinuxFr à s’adapter.

                Comme le lien peut être mis dans le texte de la dépêche, je propose de ne pas tordre le validateur.


                Si je suis bien la discussion du côté de Matrix, des utilisateurs ont proposé des solutions techniquement juste, mais les mainteneurs n’ont pas réagi depuis 2017 et ont écarté certaines propositions juste parce qu’elles ne sont pas esthétiques.

                Dans cette discussion, le second commentaire parle d’une autre forme de liens pour Matrix, les « compact URL » peuvent aussi aider à contourner ce problème.

                • [^] # Re: Fragment

                  Posté par  (site web personnel) . Évalué à 4 (+0/-0).

                  J'ai rajouté le lien %-codé sur la dépêche https://linuxfr.org/news/copie-publique-des-entreprises-s-allient-pour-financer-les-communs-numeriques
                  J'étais persuadé que ça ne marchait pas… Donc soit j'ai un mauvais souvenir, soit il y avait un souci quand j'ai testé à l'époque… En tout cas on a un contournement (pas super sympa pour le lectorat qui doit apprendre à %-coder des URL) fonctionnel.

                  • [^] # Re: Fragment

                    Posté par  (site web personnel, Mastodon) . Évalué à 2 (+0/-0).

                    Ah oui, il y a la possibilité d'encoder le dièse en pourcent pour garder des liens valides.

                    J'ai proposé un merge request ici pour faire ça automatiquement: https://github.com/linuxfrorg/linuxfr.org/pull/356

                    J'ai renommé le validateur de http_url vers uri simplement, parce qu'il est encore généraliste et pourrait être utilisé pour d'autres styles d'URI (comme mailto:, xmpp:…).

                    J'ai appris que Rails permet de définir des méthodes before_validation qui permettent de modifier les paramètres reçus dans le modèle avant de faire passer les validateurs.

                    J'en ai profité pour fusionner le code existant déjà dupliqué entre link et bookmark en plus d'ajouter l'encodage automatique des dièses.

                    Il faudra adapter le code de Mastodon quand on aura fusionné cette MR.

                    • [^] # Re: Fragment

                      Posté par  . Évalué à 3 (+0/-0).

                      Je propose de d'abord merger les deux PR qui utilisent le validateur http_url avant de changer le nom.

              • [^] # Re: Fragment

                Posté par  (site web personnel) . Évalué à 3 (+0/-0).

                Au passage on devrait valider les URL xmpp aussi, mais ça va poser souci.

                Par exemple:

                | mail me at xxxx at xxxx |
                |  xxx@xxxxx              |
                | mon_pseudo_habituel @xx |
                

                Il faudrait aussi convertir les 4976 champs vides en NULL probablement.

                Sans parler de ceux en https://… ou sans '@' (45 de plus).

                Et 3 en erreur sur le username qui contient ` ou â ou é.

                Reste 721 entrées (non préfixées par xmpp: en base), qui sont valides selon URI.parse (avec ou sans le xmpp:).

                Plus des questions annexes :

                • peut-on / doit-on / veut-on valider les adresses XMPP non pas comme RFC-valides, mais comme fonctionnelles ? (genre comme on valide les adresses de courriel à la création du compte). Mais ça veut dire envoyer de l'XMPP dessus, gérer les acceptations, les erreurs, blabla, probablement pas mal de taf.
                • restreindre ou fournir une restriction possible sur les adresses XMPP ? Visiblement certaines sont corrompues volontairement pour éviter le spam, alors même que les adresses ne sont visibles que pour les accès avec un compte.
                • [^] # Re: Fragment

                  Posté par  (site web personnel, Mastodon) . Évalué à 2 (+0/-0).

                  Première réponse annexe : non…
                  Seconde réponse annexe : oui…
                  Accessoirement, je pense qu'il ne faut pas préfixer par xmpp

                  “It is seldom that liberty of any kind is lost all at once.” ― David Hume

            • [^] # Re: Fragment

              Posté par  (site web personnel, Mastodon) . Évalué à 2 (+0/-0).

              Bien vu pour l'ancrage. Et pour l'encodage du #.

              De ce que je comprends de la réponse de Python, le premier croisillon est bien vu comme marqueur d'ancre (fragment) et le second avec la barre (slash) qui précède font partie de l'ancre : ce n'est pas une déviation courante mais un laxisme qui se justifie dans son contexte (la commande ne valide pas par rapport au RFC mais découpe en composants au mieux)
              Ça montre que l'encodage de caractère devrait se faire pour les deux croisillons pour éviter toute ambigüité…

              “It is seldom that liberty of any kind is lost all at once.” ― David Hume

              • [^] # Re: Fragment

                Posté par  . Évalué à 2 (+0/-0).

                Non, le premier "croisillon" correspond bien au séparateur du fragment et est géré comme tel par matrix.to. Ils justifient même cette entorse au RFC par le fait que le fragment n'est pas envoyé au serveur.

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.