15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
from cStringIO import StringIO
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
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
53
55
self._opener = from_transport._opener
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
61
clean_base, user, password = extract_credentials(base)
62
super(HttpTransport_urllib, self).__init__(clean_base,
55
64
self._connection = None
58
65
self._opener = self._opener_class()
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
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
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,
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,
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,
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
97
self.ask_password(request)
85
# Ensure authentication info is provided
86
request.auth = self._auth
87
request.proxy_auth = self._proxy_auth
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())
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
112
102
code = response.code
113
103
if request.follow_redirections is False \