Add a function to convert a domain name to punycode.
This commit is contained in:
parent
a721084f6e
commit
041bd63864
@ -101,5 +101,21 @@ def idna(domain):
|
|||||||
domain_parts.append(label)
|
domain_parts.append(label)
|
||||||
return '.'.join(domain_parts)
|
return '.'.join(domain_parts)
|
||||||
|
|
||||||
|
def punycode(domain):
|
||||||
|
domain_parts = []
|
||||||
|
for label in domain.split('.'):
|
||||||
|
try:
|
||||||
|
label = encodings.idna.nameprep(label)
|
||||||
|
encodings.idna.ToASCII(label)
|
||||||
|
except UnicodeError:
|
||||||
|
raise StringprepError
|
||||||
|
|
||||||
|
for char in label:
|
||||||
|
if char in ILLEGAL_CHARS:
|
||||||
|
raise StringprepError
|
||||||
|
|
||||||
|
domain_parts.append(label)
|
||||||
|
return b'.'.join(domain_parts)
|
||||||
|
|
||||||
logging.getLogger(__name__).warning('Using slower stringprep, consider '
|
logging.getLogger(__name__).warning('Using slower stringprep, consider '
|
||||||
'compiling the faster cython/libidn one.')
|
'compiling the faster cython/libidn one.')
|
||||||
|
@ -19,7 +19,8 @@ from libc.stdlib cimport free
|
|||||||
# Those are Cython declarations for the C function we’ll be using.
|
# Those are Cython declarations for the C function we’ll be using.
|
||||||
|
|
||||||
cdef extern from "stringprep.h" nogil:
|
cdef extern from "stringprep.h" nogil:
|
||||||
int stringprep_profile(const char* in_, char** out, const char* profile, int flags)
|
int stringprep_profile(const char* in_, char** out, const char* profile,
|
||||||
|
int flags)
|
||||||
|
|
||||||
cdef extern from "idna.h" nogil:
|
cdef extern from "idna.h" nogil:
|
||||||
int idna_to_ascii_8z(const char* in_, char** out, int flags)
|
int idna_to_ascii_8z(const char* in_, char** out, int flags)
|
||||||
@ -40,16 +41,19 @@ cdef str _stringprep(str in_, const char* profile):
|
|||||||
free(out)
|
free(out)
|
||||||
return unicode_out
|
return unicode_out
|
||||||
|
|
||||||
|
|
||||||
def nodeprep(str node):
|
def nodeprep(str node):
|
||||||
"""The nodeprep profile of stringprep used to validate the local, or
|
"""The nodeprep profile of stringprep used to validate the local, or
|
||||||
username, portion of a JID."""
|
username, portion of a JID."""
|
||||||
return _stringprep(node, 'Nodeprep')
|
return _stringprep(node, 'Nodeprep')
|
||||||
|
|
||||||
|
|
||||||
def resourceprep(str resource):
|
def resourceprep(str resource):
|
||||||
"""The resourceprep profile of stringprep, which is used to validate the
|
"""The resourceprep profile of stringprep, which is used to validate the
|
||||||
resource portion of a JID."""
|
resource portion of a JID."""
|
||||||
return _stringprep(resource, 'Resourceprep')
|
return _stringprep(resource, 'Resourceprep')
|
||||||
|
|
||||||
|
|
||||||
def idna(str domain):
|
def idna(str domain):
|
||||||
"""The idna conversion functions, which are used to validate the domain
|
"""The idna conversion functions, which are used to validate the domain
|
||||||
portion of a JID."""
|
portion of a JID."""
|
||||||
@ -69,3 +73,17 @@ def idna(str domain):
|
|||||||
unicode_domain = utf8_domain.decode('utf-8')
|
unicode_domain = utf8_domain.decode('utf-8')
|
||||||
free(utf8_domain)
|
free(utf8_domain)
|
||||||
return unicode_domain
|
return unicode_domain
|
||||||
|
|
||||||
|
|
||||||
|
def punycode(str domain):
|
||||||
|
"""Converts a domain name to its punycode representation."""
|
||||||
|
|
||||||
|
cdef char* ascii_domain
|
||||||
|
cdef bytes bytes_domain
|
||||||
|
|
||||||
|
ret = idna_to_ascii_8z(domain.encode('utf-8'), &ascii_domain, 0)
|
||||||
|
if ret != 0:
|
||||||
|
raise StringprepError(ret)
|
||||||
|
bytes_domain = ascii_domain
|
||||||
|
free(ascii_domain)
|
||||||
|
return bytes_domain
|
||||||
|
Loading…
Reference in New Issue
Block a user