~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/http/_urllib.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-04-26 10:41:48 UTC
  • mfrom: (2420.1.22 bzr.http.auth)
  • Revision ID: pqm@pqm.ubuntu.com-20070426104148-4l5wq2zemlzv0shg
http authentication and other integrated fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
from cStringIO import StringIO
 
18
import urllib
 
19
import urlparse
18
20
 
19
 
from bzrlib import (
20
 
    ui,
21
 
    errors,
22
 
    )
 
21
from bzrlib import errors
23
22
from bzrlib.trace import mutter
24
23
from bzrlib.transport import register_urlparse_netloc_protocol
25
24
from bzrlib.transport.http import HttpTransportBase
28
27
from bzrlib.transport.http._urllib2_wrappers import (
29
28
    Opener,
30
29
    Request,
 
30
    extract_authentication_uri,
 
31
    extract_credentials,
31
32
    )
32
33
 
33
34
 
45
46
 
46
47
    def __init__(self, base, from_transport=None):
47
48
        """Set the base path where files will be stored."""
48
 
        super(HttpTransport_urllib, self).__init__(base, from_transport)
49
49
        if from_transport is not None:
 
50
            super(HttpTransport_urllib, self).__init__(base, from_transport)
50
51
            self._connection = from_transport._connection
51
 
            self._user = from_transport._user
52
 
            self._password = from_transport._password
 
52
            self._auth = from_transport._auth
 
53
            self._proxy_auth = from_transport._proxy_auth
 
54
 
53
55
            self._opener = from_transport._opener
54
56
        else:
 
57
            # urllib2 will be confused if it find authentication
 
58
            # info in the urls. So we handle them separatly.
 
59
            # Note: we don't need to when cloning because it was
 
60
            # already done.
 
61
            clean_base, user, password = extract_credentials(base)
 
62
            super(HttpTransport_urllib, self).__init__(clean_base,
 
63
                                                       from_transport)
55
64
            self._connection = None
56
 
            self._user = None
57
 
            self._password = None
58
65
            self._opener = self._opener_class()
59
66
 
60
 
    def ask_password(self, request):
61
 
        """Ask for a password if none is already provided in the request"""
62
 
        # TODO: jam 20060915 There should be a test that asserts we ask 
63
 
        #       for a password at the right time.
64
 
        if request.password is None:
65
 
            # We can't predict realm, let's try None, we'll get a
66
 
            # 401 if we are wrong anyway
67
 
            realm = None
68
 
            host = request.get_host()
69
 
            password_manager = self._opener.password_manager
70
 
            # Query the password manager first
71
 
            user, password = password_manager.find_user_password(None, host)
72
 
            if user == request.user and password is not None:
73
 
                request.password = password
74
 
            else:
75
 
                # Ask the user if we MUST
76
 
                http_pass = 'HTTP %(user)s@%(host)s password'
77
 
                request.password = ui.ui_factory.get_password(prompt=http_pass,
78
 
                                                              user=request.user,
79
 
                                                              host=host)
80
 
                password_manager.add_password(None, host,
81
 
                                              request.user, request.password)
 
67
            authuri = extract_authentication_uri(self._real_abspath(self._path))
 
68
            self._auth = {'user': user, 'password': password,
 
69
                          'authuri': authuri}
 
70
            if user and password is not None: # '' is a valid password
 
71
                # Make the (user, password) available to urllib2
 
72
                # We default to a realm of None to catch them all.
 
73
                self._opener.password_manager.add_password(None, authuri,
 
74
                                                           user, password)
 
75
            self._proxy_auth = {}
82
76
 
83
77
    def _perform(self, request):
84
78
        """Send the request to the server and handles common errors.
88
82
        if self._connection is not None:
89
83
            # Give back shared info
90
84
            request.connection = self._connection
91
 
            if self._user is not None:
92
 
                request.user = self._user
93
 
                request.password = self._password
94
 
        elif request.user is not None:
95
 
            # We will issue our first request, time to ask for a
96
 
            # password if needed
97
 
            self.ask_password(request)
 
85
        # Ensure authentication info is provided
 
86
        request.auth = self._auth
 
87
        request.proxy_auth = self._proxy_auth
98
88
 
99
89
        mutter('%s: [%s]' % (request.method, request.get_full_url()))
100
90
        if self._debuglevel > 0:
101
91
            print 'perform: %s base: %s, url: %s' % (request.method, self.base,
102
92
                                                     request.get_full_url())
103
 
 
104
93
        response = self._opener.open(request)
105
94
        if self._connection is None:
106
95
            # Acquire connection when the first request is able
107
96
            # to connect to the server
108
97
            self._connection = request.connection
109
 
            self._user = request.user
110
 
            self._password = request.password
 
98
        # Always get auth parameters, they may change
 
99
        self._auth = request.auth
 
100
        self._proxy_auth = request.proxy_auth
111
101
 
112
102
        code = response.code
113
103
        if request.follow_redirections is False \