◐ Shell
clean mode source ↗

Issue 7708: test_xmlrpc fails with non-ascii path

Another buildbot failure (repeated on AMD64 Ubuntu wide).


test_xmlrpc
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 59299)
Traceback (most recent call last):
  File "/home/buildbot/cpython-ucs4-nonascii-€/3.x.pitrou-ubuntu-wide/build/Lib/xmlrpc/server.py", line 474, in do_POST
    size_remaining = int(self.headers["content-length"])
ValueError: invalid literal for int() with base 10: 'I am broken'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/buildbot/cpython-ucs4-nonascii-€/3.x.pitrou-ubuntu-wide/build/Lib/socketserver.py", line 282, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/home/buildbot/cpython-ucs4-nonascii-€/3.x.pitrou-ubuntu-wide/build/Lib/socketserver.py", line 308, in process_request
    self.finish_request(request, client_address)
  File "/home/buildbot/cpython-ucs4-nonascii-€/3.x.pitrou-ubuntu-wide/build/Lib/socketserver.py", line 321, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/home/buildbot/cpython-ucs4-nonascii-€/3.x.pitrou-ubuntu-wide/build/Lib/socketserver.py", line 637, in __init__
    self.handle()
  File "/home/buildbot/cpython-ucs4-nonascii-€/3.x.pitrou-ubuntu-wide/build/Lib/http/server.py", line 360, in handle
    self.handle_one_request()
  File "/home/buildbot/cpython-ucs4-nonascii-€/3.x.pitrou-ubuntu-wide/build/Lib/http/server.py", line 348, in handle_one_request
    method()
  File "/home/buildbot/cpython-ucs4-nonascii-€/3.x.pitrou-ubuntu-wide/build/Lib/xmlrpc/server.py", line 502, in do_POST
    self.send_header("X-traceback", traceback.format_exc())
  File "/home/buildbot/cpython-ucs4-nonascii-€/3.x.pitrou-ubuntu-wide/build/Lib/http/server.py", line 418, in send_header
    self.wfile.write(("%s: %s\r\n" % (keyword, value)).encode('ASCII', 'strict'))
UnicodeEncodeError: 'ascii' codec can't encode character '\u20ac' in position 93: ordinal not in range(128)
SimpleXMLRPCRequestHandler.do_POST() writes the traceback in the HTTP header "X-traceback". But an HTTP header value is ASCII only, whereas a traceback can contain any character (eg. an non-ASCII character from a directory name for this issue).

A simple fix would be to use the ASCII charset with the backslashreplace error handler. Attached patch uses:

   trace = str(trace.encode('ASCII', 'backslashreplace'), 'ASCII')

Is there an easier method to escape non-ASCII characters without double conversion (unicode->bytes and bytes->unicode)?