diff --git a/swift/account/server.py b/swift/account/server.py
index 757fa6d904..ef469b0a60 100644
--- a/swift/account/server.py
+++ b/swift/account/server.py
@@ -23,21 +23,20 @@ from gettext import gettext as _
from eventlet import Timeout
import swift.common.db
-from swift.account.utils import account_listing_response, \
- account_listing_content_type
+from swift.account.utils import account_listing_response
from swift.common.db import AccountBroker, DatabaseConnectionError
-from swift.common.request_helpers import get_param
+from swift.common.request_helpers import get_param, get_listing_content_type
from swift.common.utils import get_logger, hash_path, public, \
normalize_timestamp, storage_directory, config_true_value, \
validate_device_partition, json, timing_stats, replication
from swift.common.constraints import ACCOUNT_LISTING_LIMIT, \
- check_mount, check_float, check_utf8, FORMAT2CONTENT_TYPE
+ check_mount, check_float, check_utf8
from swift.common.db_replicator import ReplicatorRpc
from swift.common.swob import HTTPAccepted, HTTPBadRequest, \
HTTPCreated, HTTPForbidden, HTTPInternalServerError, \
HTTPMethodNotAllowed, HTTPNoContent, HTTPNotFound, \
HTTPPreconditionFailed, HTTPConflict, Request, \
- HTTPInsufficientStorage, HTTPNotAcceptable, HTTPException
+ HTTPInsufficientStorage, HTTPException
DATADIR = 'accounts'
@@ -181,14 +180,7 @@ class AccountController(object):
except ValueError, err:
return HTTPBadRequest(body=str(err), content_type='text/plain',
request=req)
- query_format = get_param(req, 'format')
- if query_format:
- req.accept = FORMAT2CONTENT_TYPE.get(
- query_format.lower(), FORMAT2CONTENT_TYPE['plain'])
- out_content_type = req.accept.best_match(
- ['text/plain', 'application/json', 'application/xml', 'text/xml'])
- if not out_content_type:
- return HTTPNotAcceptable(request=req)
+ out_content_type = get_listing_content_type(req)
if self.mount_check and not check_mount(self.root, drive):
return HTTPInsufficientStorage(drive=drive, request=req)
broker = self._get_account_broker(drive, part, account,
@@ -234,9 +226,7 @@ class AccountController(object):
ACCOUNT_LISTING_LIMIT)
marker = get_param(req, 'marker', '')
end_marker = get_param(req, 'end_marker')
- out_content_type, error = account_listing_content_type(req)
- if error:
- return error
+ out_content_type = get_listing_content_type(req)
if self.mount_check and not check_mount(self.root, drive):
return HTTPInsufficientStorage(drive=drive, request=req)
diff --git a/swift/account/utils.py b/swift/account/utils.py
index e4c3b053b8..5565b46166 100644
--- a/swift/account/utils.py
+++ b/swift/account/utils.py
@@ -16,9 +16,7 @@
import time
from xml.sax import saxutils
-from swift.common.constraints import FORMAT2CONTENT_TYPE
-from swift.common.swob import HTTPOk, HTTPNoContent, HTTPNotAcceptable
-from swift.common.request_helpers import get_param
+from swift.common.swob import HTTPOk, HTTPNoContent
from swift.common.utils import json, normalize_timestamp
@@ -43,25 +41,6 @@ class FakeAccountBroker(object):
return {}
-def account_listing_content_type(req):
- """
- Figure out the content type of an account-listing response.
-
- Returns a 2-tuple: (content_type, error). Only one of them will be set;
- the other will be None.
- """
- query_format = get_param(req, 'format')
- if query_format:
- req.accept = FORMAT2CONTENT_TYPE.get(query_format.lower(),
- FORMAT2CONTENT_TYPE['plain'])
- content_type = req.accept.best_match(
- ['text/plain', 'application/json', 'application/xml', 'text/xml'])
- if not content_type:
- return (None, HTTPNotAcceptable(request=req))
- else:
- return (content_type, None)
-
-
def account_listing_response(account, req, response_content_type, broker=None,
limit='', marker='', end_marker='', prefix='',
delimiter=''):
diff --git a/swift/common/request_helpers.py b/swift/common/request_helpers.py
index 5dd8b940fa..283a7be98a 100644
--- a/swift/common/request_helpers.py
+++ b/swift/common/request_helpers.py
@@ -20,8 +20,8 @@ Why not swift.common.utils, you ask? Because this way we can import things
from swob in here without creating circular imports.
"""
-
-from swift.common.swob import HTTPBadRequest
+from swift.common.constraints import FORMAT2CONTENT_TYPE
+from swift.common.swob import HTTPBadRequest, HTTPNotAcceptable
def get_param(req, name, default=None):
@@ -45,3 +45,25 @@ def get_param(req, name, default=None):
request=req, content_type='text/plain',
body='"%s" parameter not valid UTF-8' % name)
return value
+
+
+def get_listing_content_type(req):
+ """
+ Determine the content type to use for an account or container listing
+ response.
+
+ :param req: request object
+ :returns: content type as a string (e.g. text/plain, application/json)
+ :raises: HTTPNotAcceptable if the requested content type is not acceptable
+ :raises: HTTPBadRequest if the 'format' query param is provided and
+ not valid UTF-8
+ """
+ query_format = get_param(req, 'format')
+ if query_format:
+ req.accept = FORMAT2CONTENT_TYPE.get(
+ query_format.lower(), FORMAT2CONTENT_TYPE['plain'])
+ out_content_type = req.accept.best_match(
+ ['text/plain', 'application/json', 'application/xml', 'text/xml'])
+ if not out_content_type:
+ raise HTTPNotAcceptable(request=req)
+ return out_content_type
diff --git a/swift/container/server.py b/swift/container/server.py
index 0da4a0c4d3..c2f75d8fae 100644
--- a/swift/container/server.py
+++ b/swift/container/server.py
@@ -26,13 +26,13 @@ from eventlet import Timeout
import swift.common.db
from swift.common.db import ContainerBroker
-from swift.common.request_helpers import get_param
+from swift.common.request_helpers import get_param, get_listing_content_type
from swift.common.utils import get_logger, hash_path, public, \
normalize_timestamp, storage_directory, validate_sync_to, \
config_true_value, validate_device_partition, json, timing_stats, \
replication, parse_content_type
from swift.common.constraints import CONTAINER_LISTING_LIMIT, \
- check_mount, check_float, check_utf8, FORMAT2CONTENT_TYPE
+ check_mount, check_float, check_utf8
from swift.common.bufferedhttp import http_connect
from swift.common.exceptions import ConnectionTimeout
from swift.common.db_replicator import ReplicatorRpc
@@ -40,7 +40,7 @@ from swift.common.http import HTTP_NOT_FOUND, is_success
from swift.common.swob import HTTPAccepted, HTTPBadRequest, HTTPConflict, \
HTTPCreated, HTTPInternalServerError, HTTPNoContent, HTTPNotFound, \
HTTPPreconditionFailed, HTTPMethodNotAllowed, Request, Response, \
- HTTPInsufficientStorage, HTTPNotAcceptable, HTTPException, HeaderKeyDict
+ HTTPInsufficientStorage, HTTPException, HeaderKeyDict
DATADIR = 'containers'
@@ -300,14 +300,7 @@ class ContainerController(object):
except ValueError, err:
return HTTPBadRequest(body=str(err), content_type='text/plain',
request=req)
- query_format = get_param(req, 'format')
- if query_format:
- req.accept = FORMAT2CONTENT_TYPE.get(
- query_format.lower(), FORMAT2CONTENT_TYPE['plain'])
- out_content_type = req.accept.best_match(
- ['text/plain', 'application/json', 'application/xml', 'text/xml'])
- if not out_content_type:
- return HTTPNotAcceptable(request=req)
+ out_content_type = get_listing_content_type(req)
if self.mount_check and not check_mount(self.root, drive):
return HTTPInsufficientStorage(drive=drive, request=req)
broker = self._get_container_broker(drive, part, account, container,
@@ -388,14 +381,7 @@ class ContainerController(object):
return HTTPPreconditionFailed(
request=req,
body='Maximum limit is %d' % CONTAINER_LISTING_LIMIT)
- query_format = get_param(req, 'format')
- if query_format:
- req.accept = FORMAT2CONTENT_TYPE.get(query_format.lower(),
- FORMAT2CONTENT_TYPE['plain'])
- out_content_type = req.accept.best_match(
- ['text/plain', 'application/json', 'application/xml', 'text/xml'])
- if not out_content_type:
- return HTTPNotAcceptable(request=req)
+ out_content_type = get_listing_content_type(req)
if self.mount_check and not check_mount(self.root, drive):
return HTTPInsufficientStorage(drive=drive, request=req)
broker = self._get_container_broker(drive, part, account, container,
diff --git a/swift/proxy/controllers/account.py b/swift/proxy/controllers/account.py
index 04af4d1cd9..d0cffddc4f 100644
--- a/swift/proxy/controllers/account.py
+++ b/swift/proxy/controllers/account.py
@@ -27,8 +27,8 @@
from gettext import gettext as _
from urllib import unquote
-from swift.account.utils import account_listing_response, \
- account_listing_content_type
+from swift.account.utils import account_listing_response
+from swift.common.request_helpers import get_listing_content_type
from swift.common.utils import public
from swift.common.constraints import check_metadata, MAX_ACCOUNT_NAME_LENGTH
from swift.common.http import HTTP_NOT_FOUND
@@ -60,11 +60,8 @@ class AccountController(Controller):
req, _('Account'), self.app.account_ring, partition,
req.path_info.rstrip('/'))
if resp.status_int == HTTP_NOT_FOUND and self.app.account_autocreate:
- content_type, error = account_listing_content_type(req)
- if error:
- return error
resp = account_listing_response(self.account_name, req,
- content_type)
+ get_listing_content_type(req))
if not req.environ.get('swift_owner', False):
for key in self.app.swift_owner_headers:
if key in resp.headers:
diff --git a/swift/proxy/server.py b/swift/proxy/server.py
index 4601a72a9e..15814d5b9c 100644
--- a/swift/proxy/server.py
+++ b/swift/proxy/server.py
@@ -42,7 +42,7 @@ from swift.proxy.controllers import AccountController, ObjectController, \
ContainerController
from swift.common.swob import HTTPBadRequest, HTTPForbidden, \
HTTPMethodNotAllowed, HTTPNotFound, HTTPPreconditionFailed, \
- HTTPServerError, Request
+ HTTPServerError, HTTPException, Request
class Application(object):
@@ -293,6 +293,8 @@ class Application(object):
# method the client actually sent.
req.environ['swift.orig_req_method'] = req.method
return handler(req)
+ except HTTPException as error_response:
+ return error_response
except (Exception, Timeout):
self.logger.exception(_('ERROR Unhandled exception in request'))
return HTTPServerError(request=req)
diff --git a/test/unit/account/test_server.py b/test/unit/account/test_server.py
index 8f2afb22f3..94a7094c99 100644
--- a/test/unit/account/test_server.py
+++ b/test/unit/account/test_server.py
@@ -129,7 +129,7 @@ class TestAccountController(unittest.TestCase):
def test_HEAD_not_found(self):
# Test the case in which account does not exist (can be recreated)
req = Request.blank('/sda1/p/a', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 404)
self.assertTrue('X-Account-Status' not in resp.headers)
@@ -156,7 +156,7 @@ class TestAccountController(unittest.TestCase):
'HTTP_X_TIMESTAMP': '0'})
self.controller.PUT(req)
req = Request.blank('/sda1/p/a', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assertEquals(resp.headers['x-account-container-count'], '0')
self.assertEquals(resp.headers['x-account-object-count'], '0')
@@ -181,7 +181,7 @@ class TestAccountController(unittest.TestCase):
'X-Timestamp': normalize_timestamp(0)})
self.controller.PUT(req)
req = Request.blank('/sda1/p/a', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assertEquals(resp.headers['x-account-container-count'], '2')
self.assertEquals(resp.headers['x-account-object-count'], '0')
@@ -202,7 +202,7 @@ class TestAccountController(unittest.TestCase):
self.controller.PUT(req)
req = Request.blank('/sda1/p/a', environ={'REQUEST_METHOD': 'HEAD',
'HTTP_X_TIMESTAMP': '5'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assertEquals(resp.headers['x-account-container-count'], '2')
self.assertEquals(resp.headers['x-account-object-count'], '4')
@@ -211,20 +211,20 @@ class TestAccountController(unittest.TestCase):
def test_HEAD_invalid_partition(self):
req = Request.blank('/sda1/./a', environ={'REQUEST_METHOD': 'HEAD',
'HTTP_X_TIMESTAMP': '1'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 400)
def test_HEAD_invalid_content_type(self):
req = Request.blank('/sda1/p/a', environ={'REQUEST_METHOD': 'HEAD'},
headers={'Accept': 'application/plain'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 406)
def test_HEAD_insufficient_storage(self):
self.controller = AccountController({'devices': self.testdir})
req = Request.blank('/sda-null/p/a', environ={'REQUEST_METHOD': 'HEAD',
'HTTP_X_TIMESTAMP': '1'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 507)
def test_HEAD_invalid_format(self):
@@ -349,7 +349,7 @@ class TestAccountController(unittest.TestCase):
resp = self.controller.POST(req)
self.assertEquals(resp.status_int, 204)
req = Request.blank('/sda1/p/a', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assertEquals(resp.headers.get('x-account-meta-test'), 'Value')
# Update metadata header
@@ -359,7 +359,7 @@ class TestAccountController(unittest.TestCase):
resp = self.controller.POST(req)
self.assertEquals(resp.status_int, 204)
req = Request.blank('/sda1/p/a', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assertEquals(resp.headers.get('x-account-meta-test'), 'New Value')
# Send old update to metadata header
@@ -369,7 +369,7 @@ class TestAccountController(unittest.TestCase):
resp = self.controller.POST(req)
self.assertEquals(resp.status_int, 204)
req = Request.blank('/sda1/p/a', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assertEquals(resp.headers.get('x-account-meta-test'), 'New Value')
# Remove metadata header (by setting it to empty)
@@ -379,7 +379,7 @@ class TestAccountController(unittest.TestCase):
resp = self.controller.POST(req)
self.assertEquals(resp.status_int, 204)
req = Request.blank('/sda1/p/a', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assert_('x-account-meta-test' not in resp.headers)
@@ -974,14 +974,14 @@ class TestAccountController(unittest.TestCase):
self.controller.PUT(req)
req = Request.blank('/sda1/p/a', environ={'REQUEST_METHOD': 'GET'})
req.accept = 'application/xml*'
- resp = self.controller.GET(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 406)
def test_GET_delimiter_too_long(self):
req = Request.blank('/sda1/p/a?delimiter=xx',
environ={'REQUEST_METHOD': 'GET',
'HTTP_X_TIMESTAMP': '0'})
- resp = self.controller.GET(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 412)
def test_GET_prefix_delimiter_plain(self):
@@ -1306,22 +1306,22 @@ class TestAccountController(unittest.TestCase):
env = {'REQUEST_METHOD': 'HEAD'}
req = Request.blank('/sda1/p/a?format=xml', environ=env)
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/xml')
req = Request.blank('/sda1/p/a?format=json', environ=env)
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/json')
self.assertEquals(resp.charset, 'utf-8')
req = Request.blank('/sda1/p/a', environ=env)
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'text/plain')
self.assertEquals(resp.charset, 'utf-8')
req = Request.blank(
'/sda1/p/a', headers={'Accept': 'application/json'}, environ=env)
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/json')
self.assertEquals(resp.charset, 'utf-8')
diff --git a/test/unit/container/test_server.py b/test/unit/container/test_server.py
index 6a3b8b1b10..75d1e74564 100644
--- a/test/unit/container/test_server.py
+++ b/test/unit/container/test_server.py
@@ -64,9 +64,9 @@ class TestContainerController(unittest.TestCase):
# Ensure no acl by default
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'PUT'},
headers={'X-Timestamp': '0'})
- self.controller.PUT(req)
+ req.get_response(self.controller)
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'HEAD'})
- response = self.controller.HEAD(req)
+ response = req.get_response(self.controller)
self.assert_(response.status.startswith('204'))
self.assert_('x-container-read' not in response.headers)
self.assert_('x-container-write' not in response.headers)
@@ -74,9 +74,9 @@ class TestContainerController(unittest.TestCase):
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'POST'},
headers={'X-Timestamp': '1', 'X-Container-Read': '.r:*',
'X-Container-Write': 'account:user'})
- self.controller.POST(req)
+ resp = req.get_response(self.controller)
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'HEAD'})
- response = self.controller.HEAD(req)
+ response = req.get_response(self.controller)
self.assert_(response.status.startswith('204'))
self.assertEquals(response.headers.get('x-container-read'), '.r:*')
self.assertEquals(response.headers.get('x-container-write'),
@@ -85,9 +85,9 @@ class TestContainerController(unittest.TestCase):
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'POST'},
headers={'X-Timestamp': '3', 'X-Container-Read': '',
'X-Container-Write': ''})
- self.controller.POST(req)
+ resp = req.get_response(self.controller)
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'HEAD'})
- response = self.controller.HEAD(req)
+ response = req.get_response(self.controller)
self.assert_(response.status.startswith('204'))
self.assert_('x-container-read' not in response.headers)
self.assert_('x-container-write' not in response.headers)
@@ -95,9 +95,9 @@ class TestContainerController(unittest.TestCase):
req = Request.blank('/sda1/p/a/c2', environ={'REQUEST_METHOD': 'PUT'},
headers={'X-Timestamp': '4', 'X-Container-Read': '.r:*',
'X-Container-Write': 'account:user'})
- self.controller.PUT(req)
+ resp = req.get_response(self.controller)
req = Request.blank('/sda1/p/a/c2', environ={'REQUEST_METHOD': 'HEAD'})
- response = self.controller.HEAD(req)
+ response = req.get_response(self.controller)
self.assert_(response.status.startswith('204'))
self.assertEquals(response.headers.get('x-container-read'), '.r:*')
self.assertEquals(response.headers.get('x-container-write'),
@@ -106,28 +106,31 @@ class TestContainerController(unittest.TestCase):
def test_HEAD(self):
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'PUT',
'HTTP_X_TIMESTAMP': '0'})
- self.controller.PUT(req)
- response = self.controller.HEAD(req)
+ req.get_response(self.controller)
+ req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'HEAD',
+ 'HTTP_X_TIMESTAMP': '0'})
+ response = req.get_response(self.controller)
self.assert_(response.status.startswith('204'))
self.assertEquals(int(response.headers['x-container-bytes-used']), 0)
self.assertEquals(int(response.headers['x-container-object-count']), 0)
req2 = Request.blank('/sda1/p/a/c/o', environ={
+ 'REQUEST_METHOD': 'PUT',
'HTTP_X_TIMESTAMP': '1', 'HTTP_X_SIZE': 42,
'HTTP_X_CONTENT_TYPE': 'text/plain', 'HTTP_X_ETAG': 'x'})
- self.controller.PUT(req2)
- response = self.controller.HEAD(req)
+ req2.get_response(self.controller)
+ response = req.get_response(self.controller)
self.assertEquals(int(response.headers['x-container-bytes-used']), 42)
self.assertEquals(int(response.headers['x-container-object-count']), 1)
def test_HEAD_not_found(self):
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 404)
def test_HEAD_invalid_partition(self):
req = Request.blank('/sda1/./a/c', environ={'REQUEST_METHOD': 'HEAD',
'HTTP_X_TIMESTAMP': '1'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 400)
def test_HEAD_insufficient_storage(self):
@@ -135,13 +138,13 @@ class TestContainerController(unittest.TestCase):
{'devices': self.testdir})
req = Request.blank('/sda-null/p/a/c', environ={'REQUEST_METHOD': 'HEAD',
'HTTP_X_TIMESTAMP': '1'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 507)
def test_HEAD_invalid_content_type(self):
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'HEAD'},
headers={'Accept': 'application/plain'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 406)
def test_HEAD_invalid_format(self):
@@ -258,7 +261,7 @@ class TestContainerController(unittest.TestCase):
resp = self.controller.POST(req)
self.assertEquals(resp.status_int, 204)
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assertEquals(resp.headers.get('x-container-meta-test'), 'Value')
# Update metadata header
@@ -268,7 +271,7 @@ class TestContainerController(unittest.TestCase):
resp = self.controller.POST(req)
self.assertEquals(resp.status_int, 204)
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assertEquals(resp.headers.get('x-container-meta-test'),
'New Value')
@@ -279,7 +282,7 @@ class TestContainerController(unittest.TestCase):
resp = self.controller.POST(req)
self.assertEquals(resp.status_int, 204)
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assertEquals(resp.headers.get('x-container-meta-test'),
'New Value')
@@ -290,14 +293,14 @@ class TestContainerController(unittest.TestCase):
resp = self.controller.POST(req)
self.assertEquals(resp.status_int, 204)
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'HEAD'})
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 204)
self.assert_('x-container-meta-test' not in resp.headers)
def test_POST_invalid_partition(self):
req = Request.blank('/sda1/./a/c', environ={'REQUEST_METHOD': 'POST',
'HTTP_X_TIMESTAMP': '1'})
- resp = self.controller.POST(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 400)
def test_POST_timestamp_not_float(self):
@@ -306,7 +309,7 @@ class TestContainerController(unittest.TestCase):
self.controller.PUT(req)
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'POST'},
headers={'X-Timestamp': 'not-float'})
- resp = self.controller.POST(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 400)
def test_POST_insufficient_storage(self):
@@ -314,7 +317,7 @@ class TestContainerController(unittest.TestCase):
{'devices': self.testdir})
req = Request.blank('/sda-null/p/a/c', environ={'REQUEST_METHOD': 'POST',
'HTTP_X_TIMESTAMP': '1'})
- resp = self.controller.POST(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 507)
def test_POST_invalid_container_sync_to(self):
@@ -323,22 +326,22 @@ class TestContainerController(unittest.TestCase):
req = Request.blank('/sda-null/p/a/c', environ={'REQUEST_METHOD': 'POST',
'HTTP_X_TIMESTAMP': '1'},
headers={'x-container-sync-to': '192.168.0.1'})
- resp = self.controller.POST(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 400)
def test_POST_after_DELETE_not_found(self):
req = Request.blank('/sda1/p/a/c',
environ={'REQUEST_METHOD': 'PUT'},
headers={'X-Timestamp': '1'})
- self.controller.PUT(req)
+ resp = req.get_response(self.controller)
req = Request.blank('/sda1/p/a/c',
environ={'REQUEST_METHOD': 'DELETE'},
headers={'X-Timestamp': '2'})
- self.controller.DELETE(req)
+ resp = req.get_response(self.controller)
req = Request.blank('/sda1/p/a/c/',
environ={'REQUEST_METHOD': 'POST'},
headers={'X-Timestamp': '3'})
- resp = self.controller.POST(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 404)
def test_DELETE_obj_not_found(self):
@@ -392,7 +395,7 @@ class TestContainerController(unittest.TestCase):
with save_globals():
new_connect = fake_http_connect(200, count=123)
swift.container.server.http_connect = new_connect
- resp = self.controller.PUT(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 201)
def test_PUT_account_update(self):
@@ -758,7 +761,9 @@ class TestContainerController(unittest.TestCase):
self.assertEquals(simplejson.loads(resp.body), json_body)
self.assertEquals(resp.charset, 'utf-8')
- resp = self.controller.HEAD(req)
+ req = Request.blank('/sda1/p/a/jsonc?format=json',
+ environ={'REQUEST_METHOD': 'HEAD'})
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/json')
for accept in ('application/json', 'application/json;q=1.0,*/*;q=0.9',
@@ -766,13 +771,16 @@ class TestContainerController(unittest.TestCase):
req = Request.blank('/sda1/p/a/jsonc',
environ={'REQUEST_METHOD': 'GET'})
req.accept = accept
- resp = self.controller.GET(req)
+ resp = req.get_response(self.controller)
self.assertEquals(simplejson.loads(resp.body), json_body,
'Invalid body for Accept: %s' % accept)
self.assertEquals(resp.content_type, 'application/json',
'Invalid content_type for Accept: %s' % accept)
- resp = self.controller.HEAD(req)
+ req = Request.blank('/sda1/p/a/jsonc',
+ environ={'REQUEST_METHOD': 'HEAD'})
+ req.accept = accept
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/json',
'Invalid content_type for Accept: %s' % accept)
@@ -804,7 +812,9 @@ class TestContainerController(unittest.TestCase):
self.assertEquals(resp.body, plain_body)
self.assertEquals(resp.charset, 'utf-8')
- resp = self.controller.HEAD(req)
+ req = Request.blank('/sda1/p/a/plainc',
+ environ={'REQUEST_METHOD': 'HEAD'})
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'text/plain')
for accept in ('', 'text/plain', 'application/xml;q=0.8,*/*;q=0.9',
@@ -819,7 +829,10 @@ class TestContainerController(unittest.TestCase):
self.assertEquals(resp.content_type, 'text/plain',
'Invalid content_type for Accept: %s' % accept)
- resp = self.controller.HEAD(req)
+ req = Request.blank('/sda1/p/a/plainc',
+ environ={'REQUEST_METHOD': 'GET'})
+ req.accept = accept
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'text/plain',
'Invalid content_type for Accept: %s' % accept)
@@ -915,7 +928,9 @@ class TestContainerController(unittest.TestCase):
self.assertEquals(resp.body, xml_body)
self.assertEquals(resp.charset, 'utf-8')
- resp = self.controller.HEAD(req)
+ req = Request.blank('/sda1/p/a/xmlc?format=xml',
+ environ={'REQUEST_METHOD': 'HEAD'})
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/xml')
for xml_accept in ('application/xml', 'application/xml;q=1.0,*/*;q=0.9',
@@ -929,7 +944,10 @@ class TestContainerController(unittest.TestCase):
self.assertEquals(resp.content_type, 'application/xml',
'Invalid content_type for Accept: %s' % xml_accept)
- resp = self.controller.HEAD(req)
+ req = Request.blank('/sda1/p/a/xmlc',
+ environ={'REQUEST_METHOD': 'HEAD'})
+ req.accept = xml_accept
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/xml',
'Invalid content_type for Accept: %s' % xml_accept)
@@ -944,13 +962,13 @@ class TestContainerController(unittest.TestCase):
# make a container
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'PUT',
'HTTP_X_TIMESTAMP': '0'})
- resp = self.controller.PUT(req)
+ resp = req.get_response(self.controller)
# fill the container
for i in range(3):
req = Request.blank('/sda1/p/a/c/%s' % i, environ={'REQUEST_METHOD': 'PUT',
'HTTP_X_TIMESTAMP': '1', 'HTTP_X_CONTENT_TYPE': 'text/plain',
'HTTP_X_ETAG': 'x', 'HTTP_X_SIZE': 0})
- resp = self.controller.PUT(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 201)
# test limit with marker
req = Request.blank('/sda1/p/a/c?limit=2&marker=1', environ={'REQUEST_METHOD': 'GET'})
@@ -962,7 +980,7 @@ class TestContainerController(unittest.TestCase):
snowman = u'\u2603'
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'PUT',
'HTTP_X_TIMESTAMP': '0'})
- resp = self.controller.PUT(req)
+ resp = req.get_response(self.controller)
for i, ctype in enumerate((snowman.encode('utf-8'),
'text/plain; charset="utf-8"')):
req = Request.blank('/sda1/p/a/c/%s' % i, environ={
@@ -986,17 +1004,17 @@ class TestContainerController(unittest.TestCase):
'X-Object-Count': '0',
'X-Bytes-Used': '0',
'X-Timestamp': normalize_timestamp(0)})
- self.controller.PUT(req)
+ req.get_response(self.controller)
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'GET'})
req.accept = 'application/xml*'
- resp = self.controller.GET(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 406)
def test_GET_limit(self):
# make a container
req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'PUT',
'HTTP_X_TIMESTAMP': '0'})
- resp = self.controller.PUT(req)
+ resp = req.get_response(self.controller)
# fill the container
for i in range(3):
req = Request.blank('/sda1/p/a/c/%s' % i,
@@ -1006,11 +1024,11 @@ class TestContainerController(unittest.TestCase):
'HTTP_X_CONTENT_TYPE': 'text/plain',
'HTTP_X_ETAG': 'x',
'HTTP_X_SIZE': 0})
- resp = self.controller.PUT(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 201)
# test limit
req = Request.blank('/sda1/p/a/c?limit=2', environ={'REQUEST_METHOD': 'GET'})
- resp = self.controller.GET(req)
+ resp = req.get_response(self.controller)
result = resp.body.split()
self.assertEquals(result, ['0', '1'])
@@ -1026,17 +1044,17 @@ class TestContainerController(unittest.TestCase):
'HTTP_X_CONTENT_TYPE': 'text/plain',
'HTTP_X_ETAG': 'x',
'HTTP_X_SIZE': 0})
- resp = self.controller.PUT(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 201)
req = Request.blank('/sda1/p/a/c?prefix=a', environ={'REQUEST_METHOD': 'GET'})
- resp = self.controller.GET(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.body.split(), ['a1', 'a2', 'a3'])
def test_GET_delimiter_too_long(self):
req = Request.blank('/sda1/p/a/c?delimiter=xx',
environ={'REQUEST_METHOD': 'GET',
'HTTP_X_TIMESTAMP': '0'})
- resp = self.controller.GET(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 412)
def test_GET_delimiter(self):
@@ -1049,11 +1067,11 @@ class TestContainerController(unittest.TestCase):
'REQUEST_METHOD': 'PUT', 'HTTP_X_TIMESTAMP': '1',
'HTTP_X_CONTENT_TYPE': 'text/plain', 'HTTP_X_ETAG': 'x',
'HTTP_X_SIZE': 0})
- resp = self.controller.PUT(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.status_int, 201)
req = Request.blank('/sda1/p/a/c?prefix=US-&delimiter=-&format=json',
environ={'REQUEST_METHOD': 'GET'})
- resp = self.controller.GET(req)
+ resp = req.get_response(self.controller)
self.assertEquals(simplejson.loads(resp.body),
[{"subdir": "US-OK-"},
{"subdir": "US-TX-"},
@@ -1324,29 +1342,29 @@ class TestContainerController(unittest.TestCase):
env = {'REQUEST_METHOD': 'HEAD'}
req = Request.blank('/sda1/p/a/o?format=xml', environ=env)
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/xml')
self.assertEquals(resp.charset, 'utf-8')
req = Request.blank('/sda1/p/a/o?format=json', environ=env)
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/json')
self.assertEquals(resp.charset, 'utf-8')
req = Request.blank('/sda1/p/a/o', environ=env)
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'text/plain')
self.assertEquals(resp.charset, 'utf-8')
req = Request.blank(
'/sda1/p/a/o', headers={'Accept': 'application/json'}, environ=env)
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/json')
self.assertEquals(resp.charset, 'utf-8')
req = Request.blank(
'/sda1/p/a/o', headers={'Accept': 'application/xml'}, environ=env)
- resp = self.controller.HEAD(req)
+ resp = req.get_response(self.controller)
self.assertEquals(resp.content_type, 'application/xml')
self.assertEquals(resp.charset, 'utf-8')
diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py
index c3202a9059..1d913d2f9c 100644
--- a/test/unit/proxy/test_server.py
+++ b/test/unit/proxy/test_server.py
@@ -5725,7 +5725,6 @@ class TestAccountController(unittest.TestCase):
req.content_length = 0
resp = controller.OPTIONS(req)
self.assertEquals(200, resp.status_int)
- print resp.headers['Allow']
for verb in 'OPTIONS GET POST PUT DELETE HEAD'.split():
self.assertTrue(
verb in resp.headers['Allow'])
@@ -6093,20 +6092,20 @@ class TestAccountControllerFakeGetResponse(unittest.TestCase):
have to match the responses for empty accounts that really exist.
"""
def setUp(self):
- self.app = proxy_server.Application(None, FakeMemcache(),
+ conf = {'account_autocreate': 'yes'}
+ self.app = proxy_server.Application(conf, FakeMemcache(),
account_ring=FakeRing(),
container_ring=FakeRing(),
object_ring=FakeRing)
self.app.memcache = FakeMemcacheReturnsNone()
- self.controller = proxy_server.AccountController(self.app, 'acc')
- self.controller.app.account_autocreate = True
def test_GET_autocreate_accept_json(self):
with save_globals():
- set_http_connect(404) # however many backends we ask, they all 404
- req = Request.blank('/a', headers={'Accept': 'application/json'})
-
- resp = self.controller.GET(req)
+ set_http_connect(*([404] * 100)) # nonexistent: all backends 404
+ req = Request.blank('/v1/a', headers={'Accept': 'application/json'},
+ environ={'REQUEST_METHOD': 'GET',
+ 'PATH_INFO': '/v1/a'})
+ resp = req.get_response(self.app)
self.assertEqual(200, resp.status_int)
self.assertEqual('application/json; charset=utf-8',
resp.headers['Content-Type'])
@@ -6114,10 +6113,12 @@ class TestAccountControllerFakeGetResponse(unittest.TestCase):
def test_GET_autocreate_format_json(self):
with save_globals():
- set_http_connect(404) # however many backends we ask, they all 404
- req = Request.blank('/a?format=json')
-
- resp = self.controller.GET(req)
+ set_http_connect(*([404] * 100)) # nonexistent: all backends 404
+ req = Request.blank('/v1/a?format=json',
+ environ={'REQUEST_METHOD': 'GET',
+ 'PATH_INFO': '/v1/a',
+ 'QUERY_STRING': 'format=json'})
+ resp = req.get_response(self.app)
self.assertEqual(200, resp.status_int)
self.assertEqual('application/json; charset=utf-8',
resp.headers['Content-Type'])
@@ -6125,30 +6126,54 @@ class TestAccountControllerFakeGetResponse(unittest.TestCase):
def test_GET_autocreate_accept_xml(self):
with save_globals():
- set_http_connect(404) # however many backends we ask, they all 404
- req = Request.blank('/a', headers={"Accept": "text/xml"})
+ set_http_connect(*([404] * 100)) # nonexistent: all backends 404
+ req = Request.blank('/v1/a', headers={"Accept": "text/xml"},
+ environ={'REQUEST_METHOD': 'GET',
+ 'PATH_INFO': '/v1/a'})
- resp = self.controller.GET(req)
+ resp = req.get_response(self.app)
self.assertEqual(200, resp.status_int)
+
self.assertEqual('text/xml; charset=utf-8',
resp.headers['Content-Type'])
empty_xml_listing = ('\n'
- '\n')
+ '\n')
self.assertEqual(empty_xml_listing, resp.body)
def test_GET_autocreate_format_xml(self):
with save_globals():
- set_http_connect(404) # however many backends we ask, they all 404
- req = Request.blank('/a?format=xml')
-
- resp = self.controller.GET(req)
+ set_http_connect(*([404] * 100)) # nonexistent: all backends 404
+ req = Request.blank('/v1/a?format=xml',
+ environ={'REQUEST_METHOD': 'GET',
+ 'PATH_INFO': '/v1/a',
+ 'QUERY_STRING': 'format=xml'})
+ resp = req.get_response(self.app)
self.assertEqual(200, resp.status_int)
self.assertEqual('application/xml; charset=utf-8',
resp.headers['Content-Type'])
empty_xml_listing = ('\n'
- '\n')
+ '\n')
self.assertEqual(empty_xml_listing, resp.body)
+ def test_GET_autocreate_accept_unknown(self):
+ with save_globals():
+ set_http_connect(*([404] * 100)) # nonexistent: all backends 404
+ req = Request.blank('/v1/a', headers={"Accept": "mystery/meat"},
+ environ={'REQUEST_METHOD': 'GET',
+ 'PATH_INFO': '/v1/a'})
+ resp = req.get_response(self.app)
+ self.assertEqual(406, resp.status_int)
+
+ def test_GET_autocreate_format_invalid_utf8(self):
+ with save_globals():
+ set_http_connect(*([404] * 100)) # nonexistent: all backends 404
+ req = Request.blank('/v1/a?format=\xff\xfe',
+ environ={'REQUEST_METHOD': 'GET',
+ 'PATH_INFO': '/v1/a',
+ 'QUERY_STRING': 'format=\xff\xfe'})
+ resp = req.get_response(self.app)
+ self.assertEqual(400, resp.status_int)
+
class FakeObjectController(object):