Domains with special characters (punycode/umlaut)

In trellis configuration I am using a redirection-domain with special character (Umlaut) as unescaped unicode, e.g. ‘exämple.com’. During ansible playbook run I get an error during ACME script generation:

MODULE FAILURE
Traceback (most recent call last):
File "/tmp/ansible_FqcsT9/ansible_module_test_challenges.py", line 82, in <module>
main()
File "/tmp/ansible_FqcsT9/ansible_module_test_challenges.py", line 69, in main
status = get_status(host, path, file)
File "/tmp/ansible_FqcsT9/ansible_module_test_challenges.py", line 46, in get_status
conn.request('HEAD', '/{0}/{1}'.format(path, file))
File "/usr/lib/python2.7/httplib.py", line 1057, in request
self._send_request(method, url, body, headers)
File "/usr/lib/python2.7/httplib.py", line 1091, in _send_request
self.putrequest(method, url, **skips)
File "/usr/lib/python2.7/httplib.py", line 986, in putrequest
host_enc = host.encode("ascii")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 14:
ordinal not in range(128)
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 14: ordinal not in range(128)
failed: [host] (item=example-canonical-domain (got no special character)) => {"changed": false, "item": "example-canonical-domain (got no special character)", "module_stdout": "", "rc": 1}

So do I have to specify domains with special character (redirection or canonical) punycode-escaped?
Would it be a better idea to let ansible handle the punycode-escaping of unicode characters instead?

Edit: Interestingly, it works with a redirect umlaut domains of a wholly different site since the beginning (previous Trellis versions), just these new redirect umlaut domains cause the previously described issue.

Little confused by your last edit, but yeah Python’s urllib2 doesn’t handle non-ascii URLs like that. It’s technically not a valid URL anyway (according to spec).

So if punycode-escaped works, I’d suggest that. Otherwise we might be able to modify our module to encode these URLs properly? I’m not really sure what the exact solution is.

But it would go in https://github.com/partounian/trellis/blob/7d81e08d921768f5a0c39976be2105694db2ff0e/roles/letsencrypt/library/test_challenges.py#L45-L46

1 Like

This might work:

host = host.decode('UTF-8').encode('idna')

You could try modifying that file above with that before conn = HTTPConnection(host) and see if it works.

1 Like

Thanks. I added the line.
The playbook run now throws an error:

'dict object' has no attribute 'results'
fatal: [staging]: FAILED! => {}
$ ansible-playbook server.yml -e env=staging --tags=letsencrypt

Using request library which handles all these cases,
including python2 and python3 compatibility issues:

And many thanks for the support in freenode #python channel.