This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author samwyse
Recipients samwyse
Date 2013-02-18.21:21:11
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1361222471.81.0.536204108906.issue17229@psf.upfronthosting.co.za>
In-reply-to
Content
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_
History
Date User Action Args
2013-02-18 21:21:11samwysesetrecipients: + samwyse
2013-02-18 21:21:11samwysesetmessageid: <1361222471.81.0.536204108906.issue17229@psf.upfronthosting.co.za>
2013-02-18 21:21:11samwyselinkissue17229 messages
2013-02-18 21:21:11samwysecreate