1
# Copyright (C) 2006, 2007, 2008 Canonical Ltd
1
# Copyright (C) 2006-2010 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
80
81
self.filesock = filesock
81
82
self._report_activity = report_activity
84
def report_activity(self, size, direction):
85
if self._report_activity:
86
self._report_activity(size, direction)
84
88
def read(self, size=1):
85
89
s = self.filesock.read(size)
86
self._report_activity(len(s), 'read')
90
self.report_activity(len(s), 'read')
89
93
def readline(self):
93
97
# don't *need* the size parameter we'll stay with readline(self)
95
99
s = self.filesock.readline()
96
self._report_activity(len(s), 'read')
100
self.report_activity(len(s), 'read')
99
103
def __getattr__(self, name):
107
111
self._report_activity = report_activity
113
def report_activity(self, size, direction):
114
if self._report_activity:
115
self._report_activity(size, direction)
109
117
def sendall(self, s, *args):
110
118
self.sock.sendall(s, *args)
111
self._report_activity(len(s), 'write')
119
self.report_activity(len(s), 'write')
113
121
def recv(self, *args):
114
122
s = self.sock.recv(*args)
115
self._report_activity(len(s), 'read')
123
self.report_activity(len(s), 'read')
118
126
def makefile(self, mode='r', bufsize=-1):
219
227
# we want to warn. But not below a given thresold.
220
228
_range_warning_thresold = 1024 * 1024
223
report_activity=None):
230
def __init__(self, report_activity=None):
224
231
self._response = None
225
232
self._report_activity = report_activity
226
233
self._ranges_received_whole_file = None
361
368
def set_proxy(self, proxy, type):
362
369
"""Set the proxy and remember the proxied host."""
363
self.proxied_host = self.get_host()
370
host, port = urllib.splitport(self.get_host())
372
# We need to set the default port ourselves way before it gets set
373
# in the HTTP[S]Connection object at build time.
374
if self.type == 'https':
375
conn_class = HTTPSConnection
377
conn_class = HTTPConnection
378
port = conn_class.default_port
379
self.proxied_host = '%s:%s' % (host, port)
364
380
urllib2.Request.set_proxy(self, proxy, type)
381
# When urllib2 makes a https request with our wrapper code and a proxy,
382
# it sets Host to the https proxy, not the host we want to talk to.
383
# I'm fairly sure this is our fault, but what is the cause is an open
384
# question. -- Robert Collins May 8 2010.
385
self.add_unredirected_header('Host', self.proxied_host)
367
388
class _ConnectRequest(Request):
695
716
connect = _ConnectRequest(request)
696
717
response = self.parent.open(connect)
697
718
if response.code != 200:
698
raise ConnectionError("Can't connect to %s via proxy %s" % (
719
raise errors.ConnectionError("Can't connect to %s via proxy %s" % (
699
720
connect.proxied_host, self.host))
701
722
connection.cleanup_pipe()
852
873
print 'Will unbind %s_open for %r' % (type, proxy)
853
874
delattr(self, '%s_open' % type)
876
def bind_scheme_request(proxy, scheme):
879
scheme_request = scheme + '_request'
880
if self._debuglevel >= 3:
881
print 'Will bind %s for %r' % (scheme_request, proxy)
882
setattr(self, scheme_request,
883
lambda request: self.set_proxy(request, scheme))
855
884
# We are interested only by the http[s] proxies
856
885
http_proxy = self.get_proxy_env_var('http')
886
bind_scheme_request(http_proxy, 'http')
857
887
https_proxy = self.get_proxy_env_var('https')
859
if http_proxy is not None:
860
if self._debuglevel >= 3:
861
print 'Will bind http_request for %r' % http_proxy
862
setattr(self, 'http_request',
863
lambda request: self.set_proxy(request, 'http'))
865
if https_proxy is not None:
866
if self._debuglevel >= 3:
867
print 'Will bind http_request for %r' % https_proxy
868
setattr(self, 'https_request',
869
lambda request: self.set_proxy(request, 'https'))
888
bind_scheme_request(https_proxy, 'https')
871
890
def get_proxy_env_var(self, name, default_to='all'):
872
891
"""Get a proxy env var.
1052
1071
auth = self.get_auth(request)
1053
1072
auth['modified'] = False
1073
# Put some common info in auth if the caller didn't
1074
if auth.get('path', None) is None:
1076
host, port, path) = urlutils.parse_url(request.get_full_url())
1077
self.update_auth(auth, 'protocol', protocol)
1078
self.update_auth(auth, 'host', host)
1079
self.update_auth(auth, 'port', port)
1080
self.update_auth(auth, 'path', path)
1054
1081
# FIXME: the auth handler should be selected at a single place instead
1055
1082
# of letting all handlers try to match all headers, but the current
1056
1083
# design doesn't allow a simple implementation.
1152
1179
and then during dialog with the server).
1154
1181
auth_conf = config.AuthenticationConfig()
1156
password = auth['password']
1182
user = auth.get('user', None)
1183
password = auth.get('password', None)
1157
1184
realm = auth['realm']
1159
1186
if user is None:
1293
1320
# Put useful info into auth
1294
1321
self.update_auth(auth, 'scheme', scheme)
1295
1322
self.update_auth(auth, 'realm', realm)
1296
if auth['user'] is None or auth['password'] is None:
1323
if (auth.get('user', None) is None
1324
or auth.get('password', None) is None):
1297
1325
user, password = self.get_user_password(auth)
1298
1326
self.update_auth(auth, 'user', user)
1299
1327
self.update_auth(auth, 'password', password)
1358
1386
# Put useful info into auth
1359
1387
self.update_auth(auth, 'scheme', scheme)
1360
1388
self.update_auth(auth, 'realm', realm)
1361
if auth['user'] is None or auth['password'] is None:
1389
if auth.get('user', None) is None or auth.get('password', None) is None:
1362
1390
user, password = self.get_user_password(auth)
1363
1391
self.update_auth(auth, 'user', user)
1364
1392
self.update_auth(auth, 'password', password)