Merge "Wrap image data in iterator"
This commit is contained in:
@@ -5,6 +5,7 @@ OpenStack Client interface. Handles the REST calls and responses.
|
||||
import copy
|
||||
import logging
|
||||
import os
|
||||
import StringIO
|
||||
import urlparse
|
||||
|
||||
import httplib2
|
||||
@@ -25,6 +26,7 @@ from glanceclient import exc
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
USER_AGENT = 'python-glanceclient'
|
||||
CHUNKSIZE = 1024 * 64 # 64kB
|
||||
|
||||
|
||||
class HTTPClient(httplib2.Http):
|
||||
@@ -88,7 +90,12 @@ class HTTPClient(httplib2.Http):
|
||||
# Redirected. Reissue the request to the new location.
|
||||
return self._http_request(resp['location'], method, **kwargs)
|
||||
|
||||
return resp, body
|
||||
#NOTE(bcwaldon): body has been loaded to a string at this point,
|
||||
# but we want to move to a world where it can be read from a
|
||||
# socket-level cache. This is here until we can do that.
|
||||
body_iter = ResponseBodyIterator(StringIO.StringIO(body))
|
||||
|
||||
return resp, body_iter
|
||||
|
||||
def json_request(self, method, url, **kwargs):
|
||||
kwargs.setdefault('headers', {})
|
||||
@@ -97,7 +104,8 @@ class HTTPClient(httplib2.Http):
|
||||
if 'body' in kwargs:
|
||||
kwargs['body'] = json.dumps(kwargs['body'])
|
||||
|
||||
resp, body = self._http_request(url, method, **kwargs)
|
||||
resp, body_iter = self._http_request(url, method, **kwargs)
|
||||
body = ''.join([chunk for chunk in body_iter])
|
||||
|
||||
if body:
|
||||
try:
|
||||
@@ -115,3 +123,21 @@ class HTTPClient(httplib2.Http):
|
||||
kwargs['headers'].setdefault('Content-Type',
|
||||
'application/octet-stream')
|
||||
return self._http_request(url, method, **kwargs)
|
||||
|
||||
|
||||
class ResponseBodyIterator(object):
|
||||
"""A class that acts as an iterator over an HTTP response."""
|
||||
|
||||
def __init__(self, resp):
|
||||
self.resp = resp
|
||||
|
||||
def __iter__(self):
|
||||
while True:
|
||||
yield self.next()
|
||||
|
||||
def next(self):
|
||||
chunk = self.resp.read(CHUNKSIZE)
|
||||
if chunk:
|
||||
return chunk
|
||||
else:
|
||||
raise StopIteration()
|
||||
|
@@ -159,8 +159,9 @@ class ImageManager(base.Manager):
|
||||
if copy_from is not None:
|
||||
hdrs['x-glance-api-copy-from'] = copy_from
|
||||
|
||||
resp, body = self.api.raw_request(
|
||||
resp, body_iter = self.api.raw_request(
|
||||
'POST', '/v1/images', headers=hdrs, body=image_data)
|
||||
body = ''.join([c for c in body_iter])
|
||||
return Image(self, json.loads(body)['image'])
|
||||
|
||||
def update(self, image, **kwargs):
|
||||
@@ -199,6 +200,7 @@ class ImageManager(base.Manager):
|
||||
hdrs['x-glance-api-copy-from'] = copy_from
|
||||
|
||||
url = '/v1/images/%s' % base.getid(image)
|
||||
resp, body = self.api.raw_request(
|
||||
resp, body_iter = self.api.raw_request(
|
||||
'PUT', url, headers=hdrs, body=image_data)
|
||||
body = ''.join([c for c in body_iter])
|
||||
return Image(self, json.loads(body)['image'])
|
||||
|
@@ -131,7 +131,7 @@ class ImageManagerTest(unittest.TestCase):
|
||||
self.assertEqual(image.name, 'image-1')
|
||||
|
||||
def test_data(self):
|
||||
data = self.mgr.data('1')
|
||||
data = ''.join([b for b in self.mgr.data('1')])
|
||||
expect = [('GET', '/v1/images/1', {}, None)]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(data, 'XXX')
|
||||
@@ -256,7 +256,7 @@ class ImageTest(unittest.TestCase):
|
||||
|
||||
def test_data(self):
|
||||
image = self.mgr.get('1')
|
||||
data = image.data()
|
||||
data = ''.join([b for b in image.data()])
|
||||
expect = [
|
||||
('HEAD', '/v1/images/1', {}, None),
|
||||
('GET', '/v1/images/1', {}, None),
|
||||
|
Reference in New Issue
Block a user