Quelle est la bonne façon de valider un xmpp jid? La syntaxe est décrite here:, mais je ne le comprends pas vraiment. En outre, cela semble assez compliqué, donc utiliser une bibliothèque pour le faire semblerait une bonne idée. J'utilise actuellement xmpppy, mais je n'arrive pas à trouver comment valider un jid avec celui-ci. Toute aide appréciée!Valider un jid XMPP avec python?
8
A
Répondre
20
Tout d'abord, la meilleure référence actuelle pour les JID est RFC 6122.
Je voulais simplement vous donner l'expression régulière ici, mais nous avons eu un peu emporté et mis en œuvre toutes les spécifications:
import re
import sys
import socket
import encodings.idna
import stringprep
# These characters aren't allowed in domain names that are used
# in XMPP
BAD_DOMAIN_ASCII = "".join([chr(c) for c in range(0,0x2d) +
[0x2e, 0x2f] +
range(0x3a,0x41) +
range(0x5b,0x61) +
range(0x7b, 0x80)])
# check bi-directional character validity
def bidi(chars):
RandAL = map(stringprep.in_table_d1, chars)
for c in RandAL:
if c:
# There is a RandAL char in the string. Must perform further
# tests:
# 1) The characters in section 5.8 MUST be prohibited.
# This is table C.8, which was already checked
# 2) If a string contains any RandALCat character, the string
# MUST NOT contain any LCat character.
if filter(stringprep.in_table_d2, chars):
raise UnicodeError("Violation of BIDI requirement 2")
# 3) If a string contains any RandALCat character, a
# RandALCat character MUST be the first character of the
# string, and a RandALCat character MUST be the last
# character of the string.
if not RandAL[0] or not RandAL[-1]:
raise UnicodeError("Violation of BIDI requirement 3")
def nodeprep(u):
chars = list(unicode(u))
i = 0
while i < len(chars):
c = chars[i]
# map to nothing
if stringprep.in_table_b1(c):
del chars[i]
else:
# case fold
chars[i] = stringprep.map_table_b2(c)
i += 1
# NFKC
chars = stringprep.unicodedata.normalize("NFKC", "".join(chars))
for c in chars:
if (stringprep.in_table_c11(c) or
stringprep.in_table_c12(c) or
stringprep.in_table_c21(c) or
stringprep.in_table_c22(c) or
stringprep.in_table_c3(c) or
stringprep.in_table_c4(c) or
stringprep.in_table_c5(c) or
stringprep.in_table_c6(c) or
stringprep.in_table_c7(c) or
stringprep.in_table_c8(c) or
stringprep.in_table_c9(c) or
c in "\"&'/:<>@"):
raise UnicodeError("Invalid node character")
bidi(chars)
return chars
def resourceprep(res):
chars = list(unicode(res))
i = 0
while i < len(chars):
c = chars[i]
# map to nothing
if stringprep.in_table_b1(c):
del chars[i]
else:
i += 1
# NFKC
chars = stringprep.unicodedata.normalize("NFKC", "".join(chars))
for c in chars:
if (stringprep.in_table_c12(c) or
stringprep.in_table_c21(c) or
stringprep.in_table_c22(c) or
stringprep.in_table_c3(c) or
stringprep.in_table_c4(c) or
stringprep.in_table_c5(c) or
stringprep.in_table_c6(c) or
stringprep.in_table_c7(c) or
stringprep.in_table_c8(c) or
stringprep.in_table_c9(c)):
raise UnicodeError("Invalid node character")
bidi(chars)
return chars
def parse_jid(jid):
# first pass
m = re.match("^(?:([^\"&'/:<>@]{1,1023})@)?([^/@]{1,1023})(?:/(.{1,1023}))?$", jid)
if not m:
return False
(node, domain, resource) = m.groups()
try:
# ipv4 address?
socket.inet_pton(socket.AF_INET, domain)
except socket.error:
# ipv6 address?
try:
socket.inet_pton(socket.AF_INET6, domain)
except socket.error:
# domain name
dom = []
for label in domain.split("."):
try:
label = encodings.idna.nameprep(unicode(label))
encodings.idna.ToASCII(label)
except UnicodeError:
return False
# UseSTD3ASCIIRules is set, but Python's nameprep doesn't enforce it.
# a) Verify the absence of non-LDH ASCII code points; that is, the
for c in label:
if c in BAD_DOMAIN_ASCII:
return False
# Verify the absence of leading and trailing hyphen-minus
if label[0] == '-' or label[-1] == "-":
return False
dom.append(label)
domain = ".".join(dom)
try:
if node is not None:
node = nodeprep(node)
if resource is not None:
resource = resourceprep(resource)
except UnicodeError:
return False
return node, domain, resource
if __name__ == "__main__":
results = parse_jid(sys.argv[1])
if not results:
print "FAIL"
else:
print results
Oui, cela est beaucoup de travail. Il y a de bonnes raisons pour tout cela, mais nous espérons pouvoir le simplifier un peu plus tard si le groupe de travail précis porte ses fruits.
Questions connexes
- 1. Envoyer un message xmpp à l'aide d'une bibliothèque python
- 2. Simple client XMPP en continu fonctionnant en python
- 3. Composant xmpp: envoyer uniquement le message si jid est en ligne
- 4. Valider un nom en Python
- 5. Bibliothèque de serveurs Python XMPP
- 6. Meilleure bibliothèque client python XMPP/Jabber?
- 7. python: valider ticket Kerberos
- 8. démarreur XMPP - avec java
- 9. Starter XMPP - avec Java
- 10. Un à plusieurs chat avec XMPP
- 11. Stratégie de nommage JID pour une armée de bot?
- 12. Bibliothèque client Python Jabber/XMPP pour Twisted
- 13. google apspot xmpp envoyer échouer. est ce bug?
- 14. Python2.6 xmpp Erreur Jabber
- 15. Quelle est l'expression régulière pour valider jabber id?
- 16. appspot xmpp parler avec jabber.org
- 17. Comment créer MUC et envoyer des messages à MUC existant en utilisant Python et XMPP
- 18. valider la réponse correcte avec des boucles en python
- 19. Quand utiliser un ESB? messagerie avec Email/XMPP/SMS
- 20. Un bot de chat Facebook maintenant possible avec XMPP?
- 21. jeu multijoueur peer-to-peer avec xmpp
- 22. erreur lors de l'installation de xmpp python lib dans ubuntu
- 23. Authentification XMPP SASL sur Ejabberd avec PHP
- 24. Problème iCHAT avec XMPP DIGEST-MD5 connexion
- 25. Comment puis-je obtenir le nom d'utilisateur d'un utilisateur gtalk utilisant XMPP avec google appengine?
- 26. Comment valider xml sur un fichier DTD en Python
- 27. valider xml avec un fichier xml arbitraire
- 28. Comment valider un fichier html avec C#?
- 29. Valider l'en-tête de l'email en Python
- 30. Bibliothèque Python pour valider les données Excel
Désolé pour la demande tardive; J'allais l'implémenter comme vous l'avez fait, mais je me demande si l'itération sur les points de code est correcte pour stringprep. Dans le [RFC] stringprep (https://tools.ietf.org/html/rfc3454), ils parlent de caractères, ce qui n'est pas forcément équivalent aux codes (pensez à combiner des signes diacritiques). Ou ai-je oublié quelque chose à propos de la terminologie Unicode? –
La RFC stringprep a été écrite avant que l'IETF dispose d'une vue nuancée sur Unicode qui était nécessaire pour résoudre le problème. Lorsque le RFC dit "caractère", cela signifie "codepoint" dans la plupart des endroits. Nous essayons de résoudre ce problème dans le groupe de travail [précis] (http://tools.ietf.org/wg/precis/charters). –
Dans l'intérêt d'aider quelqu'un d'autre (comme moi!) À essayer d'utiliser ce code dans Python 3, deux changements sont nécessaires: les 'range()' s doivent être transmis à ['itertools.chain()'] (http://stackoverflow.com/a/14099894) au lieu de concaténer avec + (et la liste one doit aussi être 'range()'), et les appels 'unicode()' doivent être supprimés. – Kromey