New submission from Samwyse:

When a URL is opened, the opener-director is responsible for locating the 
proper handler for the specified protocol. Frequently, an existing protocol 
handler will be subclassed and then added to the collection maintained by the 
director. When urlopen is called, the specified request is immediately handed 
off to the director's "open" method which finds the correct handler and invokes 
the protocol-specific XXX_open method. At least in the case of the HTTP 
protocols, if an error occurs then the director is called again to find and 
invoke a handler for the error; these handlers generally open a new connection 
after adding headers to avoid the error going forward. Finally, it is important 
to note that at the present time, the HTTP handlers in urllib2 are built using 
a class (infourl) that isn't prepared to deal with a persistent connection, so 
they always add a "Connection: close" header to the request.
    
Unfortunately, NTLM only certifies the current connection, meaning that a 
"Connection: keep-alive" header must be used to keep it open throughout the 
authentication process. Furthermore, because the opener director only provides 
a do_open method, there is no way to discover the type of connection without 
also opening it. This means that the HTTPNtlmAuthHandler cannot use the normal 
HTTPHandler and must therefore must hardcode the HTTPConnection class. If a 
custom class is required for whatever reason, the only way to cause it to be 
used is to monkey-patch the code. For an example, see 
http://code.google.com/p/python-ntlm/source/browse/trunk/python26/ntlm_examples/test_ntlmauth.py

This can be avoided if, instead of putting the instantiation of the desired 
HTTP connection class inline, the HTTPHandler classes used a class instance 
variable. Something like the following should work without breaking any 
existing code:

class HTTPHandler(AbstractHTTPHandler):

    _connection = httplib.HTTPConnection
    
    @property
    def connection(self):
        """Returns the class of connection being handled."""
        return self._connection

    def http_open(self, req):
        return self.do_open(_connection, req)

    http_request = AbstractHTTPHandler.do_request_

----------
components: Library (Lib)
messages: 182343
nosy: samwyse
priority: normal
severity: normal
status: open
title: unable to discover preferred HTTPConnection class
versions: 3rd party, Python 2.6, Python 2.7, Python 3.1, Python 3.2, Python 
3.3, Python 3.4, Python 3.5

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue17229>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to