container-sync: Support HTTP proxy.
This commit is contained in:
@@ -10,6 +10,8 @@
|
|||||||
# This is a comma separated list of hosts allowed in the X-Container-Sync-To
|
# This is a comma separated list of hosts allowed in the X-Container-Sync-To
|
||||||
# field for containers.
|
# field for containers.
|
||||||
# allowed_sync_hosts = 127.0.0.1
|
# allowed_sync_hosts = 127.0.0.1
|
||||||
|
# If you need to use an HTTP Proxy, set it here; defaults to no proxy.
|
||||||
|
# sync_proxy = http://127.0.0.1:8888
|
||||||
# You can specify default log routing here if you want:
|
# You can specify default log routing here if you want:
|
||||||
# log_name = swift
|
# log_name = swift
|
||||||
# log_facility = LOG_LOCAL0
|
# log_facility = LOG_LOCAL0
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ class ClientException(Exception):
|
|||||||
return b and '%s: %s' % (a, b) or a
|
return b and '%s: %s' % (a, b) or a
|
||||||
|
|
||||||
|
|
||||||
def http_connection(url):
|
def http_connection(url, proxy=None):
|
||||||
"""
|
"""
|
||||||
Make an HTTPConnection or HTTPSConnection
|
Make an HTTPConnection or HTTPSConnection
|
||||||
|
|
||||||
@@ -145,14 +145,16 @@ def http_connection(url):
|
|||||||
:returns: tuple of (parsed url, connection object)
|
:returns: tuple of (parsed url, connection object)
|
||||||
:raises ClientException: Unable to handle protocol scheme
|
:raises ClientException: Unable to handle protocol scheme
|
||||||
"""
|
"""
|
||||||
parsed = urlparse(url)
|
parsed = urlparse(proxy or url)
|
||||||
if parsed.scheme == 'http':
|
if parsed.scheme == 'http':
|
||||||
conn = HTTPConnection(parsed.netloc)
|
conn = HTTPConnection(parsed.netloc)
|
||||||
elif parsed.scheme == 'https':
|
elif parsed.scheme == 'https':
|
||||||
conn = HTTPSConnection(parsed.netloc)
|
conn = HTTPSConnection(parsed.netloc)
|
||||||
else:
|
else:
|
||||||
raise ClientException('Cannot handle protocol scheme %s for url %s' %
|
raise ClientException('Cannot handle protocol scheme %s for url %s' %
|
||||||
(parsed.scheme, repr(url)))
|
(parsed.scheme, repr(proxy or url)))
|
||||||
|
if proxy:
|
||||||
|
parsed = urlparse(url)
|
||||||
return parsed, conn
|
return parsed, conn
|
||||||
|
|
||||||
|
|
||||||
@@ -567,7 +569,7 @@ def head_object(url, token, container, name, http_conn=None):
|
|||||||
|
|
||||||
def put_object(url, token=None, container=None, name=None, contents=None,
|
def put_object(url, token=None, container=None, name=None, contents=None,
|
||||||
content_length=None, etag=None, chunk_size=65536,
|
content_length=None, etag=None, chunk_size=65536,
|
||||||
content_type=None, headers=None, http_conn=None):
|
content_type=None, headers=None, http_conn=None, proxy=None):
|
||||||
"""
|
"""
|
||||||
Put an object
|
Put an object
|
||||||
|
|
||||||
@@ -590,12 +592,14 @@ def put_object(url, token=None, container=None, name=None, contents=None,
|
|||||||
if http_conn:
|
if http_conn:
|
||||||
parsed, conn = http_conn
|
parsed, conn = http_conn
|
||||||
else:
|
else:
|
||||||
parsed, conn = http_connection(url)
|
parsed, conn = http_connection(url, proxy=proxy)
|
||||||
path = parsed.path
|
path = parsed.path
|
||||||
if container:
|
if container:
|
||||||
path = '%s/%s' % (path.rstrip('/'), quote(container))
|
path = '%s/%s' % (path.rstrip('/'), quote(container))
|
||||||
if name:
|
if name:
|
||||||
path = '%s/%s' % (path.rstrip('/'), quote(name))
|
path = '%s/%s' % (path.rstrip('/'), quote(name))
|
||||||
|
if proxy:
|
||||||
|
path = parsed.scheme + '://' + parsed.netloc + path
|
||||||
if headers:
|
if headers:
|
||||||
headers = dict(headers)
|
headers = dict(headers)
|
||||||
else:
|
else:
|
||||||
@@ -606,6 +610,10 @@ def put_object(url, token=None, container=None, name=None, contents=None,
|
|||||||
headers['ETag'] = etag.strip('"')
|
headers['ETag'] = etag.strip('"')
|
||||||
if content_length is not None:
|
if content_length is not None:
|
||||||
headers['Content-Length'] = str(content_length)
|
headers['Content-Length'] = str(content_length)
|
||||||
|
else:
|
||||||
|
for n, v in headers.iteritems():
|
||||||
|
if n.lower() == 'content-length':
|
||||||
|
content_length = int(v)
|
||||||
if content_type is not None:
|
if content_type is not None:
|
||||||
headers['Content-Type'] = content_type
|
headers['Content-Type'] = content_type
|
||||||
if not contents:
|
if not contents:
|
||||||
@@ -672,7 +680,7 @@ def post_object(url, token, container, name, headers, http_conn=None):
|
|||||||
|
|
||||||
|
|
||||||
def delete_object(url, token=None, container=None, name=None, http_conn=None,
|
def delete_object(url, token=None, container=None, name=None, http_conn=None,
|
||||||
headers=None):
|
headers=None, proxy=None):
|
||||||
"""
|
"""
|
||||||
Delete object
|
Delete object
|
||||||
|
|
||||||
@@ -687,7 +695,7 @@ def delete_object(url, token=None, container=None, name=None, http_conn=None,
|
|||||||
if http_conn:
|
if http_conn:
|
||||||
parsed, conn = http_conn
|
parsed, conn = http_conn
|
||||||
else:
|
else:
|
||||||
parsed, conn = http_connection(url)
|
parsed, conn = http_connection(url, proxy=proxy)
|
||||||
path = parsed.path
|
path = parsed.path
|
||||||
if container:
|
if container:
|
||||||
path = '%s/%s' % (path.rstrip('/'), quote(container))
|
path = '%s/%s' % (path.rstrip('/'), quote(container))
|
||||||
@@ -699,6 +707,8 @@ def delete_object(url, token=None, container=None, name=None, http_conn=None,
|
|||||||
headers = {}
|
headers = {}
|
||||||
if token:
|
if token:
|
||||||
headers['X-Auth-Token'] = token
|
headers['X-Auth-Token'] = token
|
||||||
|
if proxy:
|
||||||
|
path = parsed.scheme + '://' + parsed.netloc + path
|
||||||
conn.request('DELETE', path, '', headers)
|
conn.request('DELETE', path, '', headers)
|
||||||
resp = conn.getresponse()
|
resp = conn.getresponse()
|
||||||
resp.read()
|
resp.read()
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ class ContainerSync(Daemon):
|
|||||||
self.allowed_sync_hosts = [h.strip()
|
self.allowed_sync_hosts = [h.strip()
|
||||||
for h in conf.get('allowed_sync_hosts', '127.0.0.1').split(',')
|
for h in conf.get('allowed_sync_hosts', '127.0.0.1').split(',')
|
||||||
if h.strip()]
|
if h.strip()]
|
||||||
|
self.proxy = conf.get('sync_proxy')
|
||||||
#: Number of containers with sync turned on that were successfully
|
#: Number of containers with sync turned on that were successfully
|
||||||
#: synced.
|
#: synced.
|
||||||
self.container_syncs = 0
|
self.container_syncs = 0
|
||||||
@@ -337,7 +338,8 @@ class ContainerSync(Daemon):
|
|||||||
try:
|
try:
|
||||||
client.delete_object(sync_to, name=row['name'],
|
client.delete_object(sync_to, name=row['name'],
|
||||||
headers={'X-Timestamp': row['created_at'],
|
headers={'X-Timestamp': row['created_at'],
|
||||||
'X-Container-Sync-Key': sync_key})
|
'X-Container-Sync-Key': sync_key},
|
||||||
|
proxy=self.proxy)
|
||||||
except client.ClientException, err:
|
except client.ClientException, err:
|
||||||
if err.http_status != 404:
|
if err.http_status != 404:
|
||||||
raise
|
raise
|
||||||
@@ -375,7 +377,8 @@ class ContainerSync(Daemon):
|
|||||||
headers['X-Container-Sync-Key'] = sync_key
|
headers['X-Container-Sync-Key'] = sync_key
|
||||||
client.put_object(sync_to, name=row['name'],
|
client.put_object(sync_to, name=row['name'],
|
||||||
headers=headers,
|
headers=headers,
|
||||||
contents=_Iter2FileLikeObject(body))
|
contents=_Iter2FileLikeObject(body),
|
||||||
|
proxy=self.proxy)
|
||||||
self.container_puts += 1
|
self.container_puts += 1
|
||||||
except client.ClientException, err:
|
except client.ClientException, err:
|
||||||
if err.http_status == 401:
|
if err.http_status == 401:
|
||||||
|
|||||||
Reference in New Issue
Block a user