[ Vincent Bernat ] > OoO Pendant le journal télévisé du lundi 21 janvier 2008, vers 20:40, > Eric Evans <[EMAIL PROTECTED]> disait: > > [ Vincent Bernat ] > >> Proxy support using http_proxy environment variable seems broken. Boto > >> seems to wait http_proxy as "proxy:port", while the form of this > >> variable is usually "http://proxy:port". Since it splits on ":", it > >> gets a 3-tuple instead of a 2-tuple. > >> > >> Moreover, this variable can be empty. In this case, we get an > >> exception because Boto tries to access to > >> os.environ['http_proxy'].split(':')[1]. > > > I've submitted a bug upstream[1] and included the attached patch. > > > If you have the opportunity to try out the patch, please update the bug > > report and let me know if there are any problems. > > Hi Éric ! > > I will try to complete your patch for a more complete > support. http_proxy can also be of the form of > http://user:[EMAIL PROTECTED]:port. In this case, your patch does not > work. Maybe there is some code in urllib to correctly parse such a > variable.
Hi Vincent, There are some parsing functions in urllib and urlparse but none of them seemed to provide for a very clean solution. The attached patch should correctly parse urls with or without a username/password pair as well as setting up the appropriate header for proxy basic auth. Again, I don't have a ready means of testing this. I've made sure that it's parsing the url and setting the instance attributes correctly, and that it doesn't effect normal usage of boto. If you could apply the patch and let me know how it works for you, it would be appreciated. Thanks again, -- Eric Evans [EMAIL PROTECTED]
Index: boto/connection.py
===================================================================
--- boto.orig/connection.py 2008-01-21 10:58:59.000000000 -0600
+++ boto/connection.py 2008-01-29 15:05:43.000000000 -0600
@@ -55,9 +55,13 @@
class AWSAuthConnection:
def __init__(self, server, aws_access_key_id=None,
aws_secret_access_key=None, is_secure=True, port=None,
- proxy=None, proxy_port=None, debug=False,
- https_connection_factory=None):
+ proxy=None, proxy_port=None, proxy_user=None,
+ proxy_pass=None, debug=False, https_connection_factory=None):
self.is_secure = is_secure
+ self.proxy = proxy
+ self.proxy_port = proxy_port
+ self.proxy_user = proxy_user
+ self.proxy_pass = proxy_pass
# define exceptions from httplib that we want to catch and retry
self.http_exceptions = (httplib.HTTPException, socket.error,
socket.gaierror)
# define values in socket exceptions we don't want to catch
@@ -90,29 +94,31 @@
if os.environ.has_key('AWS_SECRET_ACCESS_KEY'):
self.aws_secret_access_key =
os.environ['AWS_SECRET_ACCESS_KEY']
- self.proxy = proxy
#This lowercase environment var is the same as used in urllib
- if os.environ.has_key('http_proxy'):
- proxy_port_pair = os.environ['http_proxy'].split(':')
- self.proxy = proxy_port_pair[0]
+ if os.environ.has_key('http_proxy') and not self.proxy:
+ pattern = re.compile(
+ '(?:http://)?' \
+ '(?:(?P<user>\w+):(?P<pass>\w+)@)?' \
+ '(?P<host>[\w\-\.]+)' \
+ '(?::(?P<port>\d+))?'
+ )
+ match = pattern.match(os.environ['http_proxy'])
+ if match:
+ self.proxy = match.group('host')
+ self.proxy_port = match.group('port')
+ self.proxy_user = match.group('user')
+ self.proxy_pass = match.group('pass')
+
+ if not self.proxy_port and self.proxy:
+ print "http_proxy environment variable does not specify " \
+ "a port, using default"
+ self.proxy_port = self.port
+
self.use_proxy = (self.proxy != None)
if (self.use_proxy and self.is_secure):
raise AWSConnectionError("Unable to provide secure connection
through proxy")
- if proxy_port:
- self.proxy_port = proxy_port
- else:
- if os.environ.has_key('http_proxy'):
- proxy_port_pair = os.environ['http_proxy'].split(':')[1]
- if len(proxy_port_pair) != 2:
- print "http_proxy env var does not specify port, using
default"
- self.proxy_port = self.port
- else:
- self.proxy_port = proxy_port_pair[1]
- else:
- self.proxy_port = None
-
self.make_http_connection()
self._last_rs = None
@@ -143,7 +149,11 @@
def prefix_proxy_to_path(self, path):
path = self.protocol + '://' + self.server + path
return path
-
+
+ def get_proxy_auth_header(self):
+ auth = base64.encodestring(self.proxy_user+':'+self.proxy_pass)
+ return {'Proxy-Authorization': 'Basic %s' % auth}
+
def make_request(self, method, path, headers=None, data='', metadata=None):
if headers == None:
headers = {}
@@ -151,11 +161,13 @@
metadata = {}
if not headers.has_key('Content-Length'):
headers['Content-Length'] = len(data)
+ if self.use_proxy:
+ path = self.prefix_proxy_to_path(path)
+ if self.proxy_user and self.proxy_pass:
+ headers.update(self.get_proxy_auth_header())
final_headers = boto.utils.merge_meta(headers, metadata);
# add auth header
self.add_aws_auth_header(final_headers, method, path)
- if self.use_proxy:
- path = self.prefix_proxy_to_path(path)
try:
self.connection.request(method, path, data, final_headers)
return self.connection.getresponse()
signature.asc
Description: Digital signature

