"""HTTP with chunked transfer encoding for urllib. This module provides the handlers HTTPHandler and HTTPSHandler that are suitable to be used as openers for urllib. These handlers differ from the standard counterparts in that they allow the data to be sent using chunked transfer encoding to the HTTP server. **Note**: This module might be useful independently of python-icat. It is included here because python-icat uses it internally, but it is not considered to be part of the API. Changes in this module are not considered API changes of python-icat. It may even be removed from future versions of the python-icat distribution without further notice. This version of the module requires Python 3.5 with the `patch for Issue 12319`_ being applied. .. _patch for Issue 12319: https://bugs.python.org/file39447/issue12319_6.patch """ from urllib2 import URLError, HTTPHandler, HTTPSHandler class HTTPHandlerMixin: """Internal helper class. This is designed as a mixin class to modify either HTTPHandler or HTTPSHandler accordingly. It overrides do_request_() inherited from AbstractHTTPHandler. """ def do_request_(self, request): # The original method from AbstractHTTPHandler sets some # defaults that are unsuitable for our use case. In # particular it tries to enforce Content-length to be set (and # fails doing so if data is not a string), while for chunked # transfer encoding Content-length must not be set. host = request.host if not host: raise URLError('no host given') if request.data is not None: if not request.has_header('Content-type'): request.add_unredirected_header( 'Content-type', 'application/x-www-form-urlencoded') sel_host = host if request.has_proxy(): scheme, sel = splittype(request.selector) sel_host, sel_path = splithost(sel) if not request.has_header('Host'): request.add_unredirected_header('Host', sel_host) for name, value in self.parent.addheaders: name = name.capitalize() if not request.has_header(name): request.add_unredirected_header(name, value) return request class HTTPHandler(HTTPHandlerMixin, HTTPHandler): http_request = HTTPHandlerMixin.do_request_ class HTTPSHandler(HTTPHandlerMixin, HTTPSHandler): https_request = HTTPHandlerMixin.do_request_