Merge "Close all versioned_writes subrequests' app_iters"

This commit is contained in:
Jenkins 2017-06-30 18:44:44 +00:00 committed by Gerrit Code Review
commit fe3dcf5007
3 changed files with 24 additions and 20 deletions
swift/common
test/unit/common/middleware

@ -338,6 +338,7 @@ class VersionedWritesContext(WSGIContext):
lreq.environ['QUERY_STRING'] += '&reverse=on'
lresp = lreq.get_response(self.app)
if not is_success(lresp.status_int):
close_if_possible(lresp.app_iter)
if lresp.status_int == HTTP_NOT_FOUND:
raise ListingIterNotFound()
elif is_client_error(lresp.status_int):
@ -378,6 +379,7 @@ class VersionedWritesContext(WSGIContext):
if source_resp.content_length is None or \
source_resp.content_length > MAX_FILE_SIZE:
close_if_possible(source_resp.app_iter)
return HTTPRequestEntityTooLarge(request=req)
return source_resp
@ -391,7 +393,9 @@ class VersionedWritesContext(WSGIContext):
copy_header_subset(source_resp, put_req,
lambda k: k.lower() != 'x-timestamp')
put_req.environ['wsgi.input'] = FileLikeIter(source_resp.app_iter)
return put_req.get_response(self.app)
put_resp = put_req.get_response(self.app)
close_if_possible(source_resp.app_iter)
return put_resp
def _check_response_error(self, req, resp):
"""
@ -399,6 +403,7 @@ class VersionedWritesContext(WSGIContext):
"""
if is_success(resp.status_int):
return
close_if_possible(resp.app_iter)
if is_client_error(resp.status_int):
# missing container or bad permissions
raise HTTPPreconditionFailed(request=req)
@ -456,6 +461,7 @@ class VersionedWritesContext(WSGIContext):
put_resp = self._put_versioned_obj(req, put_path_info, get_resp)
self._check_response_error(req, put_resp)
close_if_possible(put_resp.app_iter)
def handle_obj_versions_put(self, req, versions_cont, api_version,
account_name, object_name):
@ -514,6 +520,7 @@ class VersionedWritesContext(WSGIContext):
marker_req.environ['swift.content_type_overridden'] = True
marker_resp = marker_req.get_response(self.app)
self._check_response_error(req, marker_resp)
close_if_possible(marker_resp.app_iter)
# successfully copied and created delete marker; safe to delete
return self.app
@ -527,6 +534,7 @@ class VersionedWritesContext(WSGIContext):
# if the version isn't there, keep trying with previous version
if get_resp.status_int == HTTP_NOT_FOUND:
close_if_possible(get_resp.app_iter)
return False
self._check_response_error(req, get_resp)
@ -537,6 +545,7 @@ class VersionedWritesContext(WSGIContext):
req, put_path_info, get_resp)
self._check_response_error(req, put_resp)
close_if_possible(put_resp.app_iter)
return get_path
def handle_obj_versions_delete_pop(self, req, versions_cont, api_version,
@ -582,6 +591,7 @@ class VersionedWritesContext(WSGIContext):
req.environ, path=req.path_info, method='HEAD',
headers=obj_head_headers, swift_source='VW')
hresp = head_req.get_response(self.app)
close_if_possible(hresp.app_iter)
if hresp.status_int != HTTP_NOT_FOUND:
self._check_response_error(req, hresp)
@ -606,6 +616,7 @@ class VersionedWritesContext(WSGIContext):
req.environ, path=restored_path, method='DELETE',
headers=auth_token_header, swift_source='VW')
del_resp = old_del_req.get_response(self.app)
close_if_possible(del_resp.app_iter)
if del_resp.status_int != HTTP_NOT_FOUND:
self._check_response_error(req, del_resp)
# else, well, it existed long enough to do the

@ -52,7 +52,7 @@ from six.moves import urllib
from swift.common.header_key_dict import HeaderKeyDict
from swift.common.utils import reiterate, split_path, Timestamp, pairs, \
close_if_possible
close_if_possible, closing_if_possible
from swift.common.exceptions import InvalidTimestamp
@ -308,7 +308,8 @@ def _resp_body_property():
if not self._body:
if not self._app_iter:
return ''
self._body = ''.join(self._app_iter)
with closing_if_possible(self._app_iter):
self._body = ''.join(self._app_iter)
self._app_iter = None
return self._body

@ -62,7 +62,10 @@ class VersionedWritesBaseTestCase(unittest.TestCase):
conf = {'allow_versioned_writes': 'true'}
self.vw = versioned_writes.filter_factory(conf)(self.app)
def call_app(self, req, app=None, expect_exception=False):
def tearDown(self):
self.assertEqual(self.app.unclosed_requests, {})
def call_app(self, req, app=None):
if app is None:
app = self.app
@ -84,24 +87,13 @@ class VersionedWritesBaseTestCase(unittest.TestCase):
headers[0] = h
body_iter = app(req.environ, start_response)
body = ''
caught_exc = None
try:
for chunk in body_iter:
body += chunk
except Exception as exc:
if expect_exception:
caught_exc = exc
else:
raise
with utils.closing_if_possible(body_iter):
body = b''.join(body_iter)
if expect_exception:
return status[0], headers[0], body, caught_exc
else:
return status[0], headers[0], body
return status[0], headers[0], body
def call_vw(self, req, **kwargs):
return self.call_app(req, app=self.vw, **kwargs)
def call_vw(self, req):
return self.call_app(req, app=self.vw)
def assertRequestEqual(self, req, other):
self.assertEqual(req.method, other.method)