Refactor how we pick listings' content type.
There were a few different places where we had some repeated code to figure out what format an account or container listing response should be in (text, JSON, or XML). Now that's been pulled into a single function. As part of this, you can now raise HTTPException subclasses in proxy controllers instead of laboriously plumbing error responses all the way back up to swift.proxy.server.Application.handle_request(). This lets us avoid certain ugly patterns, like the one where a method returns a tuple of (x, y, z, error) and the caller has to see if it got (value, value, value, None) or (None, None, None, errorvalue). Now we can just raise the error. Change-Id: I316873df289160d526487ad116f6fbb9a575e3de
This commit is contained in:
parent
5f4e7cd2ff
commit
a4f371439b
@ -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)
|
||||
|
@ -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=''):
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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')
|
||||
|
||||
|
@ -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')
|
||||
|
||||
|
@ -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 = ('<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||
'<account name="acc">\n</account>')
|
||||
'<account name="a">\n</account>')
|
||||
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 = ('<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||
'<account name="acc">\n</account>')
|
||||
'<account name="a">\n</account>')
|
||||
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):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user