Commit 86871639 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Distinguish quoted from unquoted request headers

Introduce the "headers_to_quote" and "header_prefices" properties
in RequestManager class. Modify the class so that only matching
API-specific header values are encoded and quoted.
parent 021535d0
......@@ -142,6 +142,7 @@ class RequestManager(Logged):
self.headers = dict(headers)
self.method, self.data = method, data
self.scheme, self.netloc = self._connection_info(url, path, params)
self._headers_to_quote, self._header_prefices = [], []
def dump_log(self):
plog = ('\t[%s]' % self) if self.LOG_PID else ''
......@@ -161,9 +162,14 @@ class RequestManager(Logged):
sendlog.info('data size: 0%s' % plog)
def _encode_headers(self):
headers = dict(self.headers)
headers = dict()
for k, v in self.headers.items():
headers[k] = quote('' if v is None else '%s' % v)
key = k.lower()
val = '' if v is None else '%s' % (
v.encode('utf-8') if isinstance(v, unicode) else v)
quotable = any([key in self._headers_to_quote, ] +
[key.startswith(p) for p in self._header_prefices])
headers[k] = quote(val) if quotable else val
self.headers = headers
def perform(self, conn):
......@@ -193,6 +199,24 @@ class RequestManager(Logged):
recvlog.debug(logmsg)
raise ClientError('HTTPResponse takes too long - kamaki timeout')
@property
def headers_to_quote(self):
return self._headers_to_quote
@headers_to_quote.setter
def headers_to_quote(self, header_keys):
self._headers_to_quote += [k.lower() for k in header_keys]
self._headers_to_quote = list(set(self._headers_to_quote))
@property
def header_prefices(self):
return self._header_prefices
@header_prefices.setter
def header_prefices(self, header_key_prefices):
self._header_prefices += [p.lower() for p in header_key_prefices]
self._header_prefices = list(set(self._header_prefices))
class ResponseManager(Logged):
"""Manage the http request and handle the response data, headers, etc."""
......@@ -373,6 +397,8 @@ class Client(Logged):
self.token = token
self.headers, self.params = dict(), dict()
self.poolsize = None
self.request_headers_to_quote = []
self.request_header_prefices_to_quote = []
self.response_headers = []
self.response_header_prefices = []
......@@ -489,6 +515,8 @@ class Client(Logged):
req = RequestManager(
method, self.base_url, path,
data=data, headers=headers, params=params)
req.headers_to_quote = self.request_headers_to_quote
req.header_prefices = self.request_header_prefices_to_quote
# req.log()
r = ResponseManager(
req,
......
......@@ -31,7 +31,7 @@
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from kamaki.clients import Client, ClientError
from kamaki.clients import Client, ClientError, quote
from kamaki.clients.utils import path4url
......@@ -57,7 +57,12 @@ class ImageClient(Client):
def __init__(self, base_url, token):
super(ImageClient, self).__init__(base_url, token)
self.response_header_prefices = ['X-Image-', ]
self.request_headers_to_quote = ['X-Image-Meta-Name', ]
self.request_header_prefices_to_quote = ['X-Image-Meta-Property-', ]
self.response_headers = [
'X-Image-Meta-Name', 'X-Image-Meta-Location',
'X-Image-Meta-Description']
self.response_header_prefices = ['X-Image-Meta-Property-', ]
def list_public(self, detail=False, filters={}, order=''):
"""
......@@ -121,6 +126,14 @@ class ImageClient(Client):
location = location if (
isinstance(location, str) or isinstance(location, unicode)) else (
'pithos://%s' % '/'.join(location))
prefix = 'pithos://'
if location.startswith(prefix):
lvalues = (location[len(prefix):]).split('/')
location = '%s%s' % (prefix, '/'.join([
quote(s.encode('utf-8')) for s in lvalues]))
else:
lvalues = location.split('/')
location = '.'.join([quote(s.encode('utf-8')) for s in lvalues])
self.set_header('X-Image-Meta-Location', location)
async_headers = {}
......
......@@ -104,6 +104,8 @@ class PithosClient(PithosRestClient):
def __init__(self, base_url, token, account=None, container=None):
super(PithosClient, self).__init__(base_url, token, account, container)
# All kamaki-set headers are quoted
self.request_header_prefices_to_quote = ['', ]
def create_container(
self,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment