Return 405 when attempting DELETE on /tasks
We currently return 404 NotFound when attempting to delete a task by hitting the resource /v2/tasks/{task_id}. However, as this resource exists and we do not allow DELETE on tasks, the correct response is 405 MethodNotAllowed. Implementing as per spec on http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html Fixes bug 1287951 Change-Id: Ia4a969e595b520dbc5f4e9a463d967681465ae6f
This commit is contained in:
parent
aabc62ad2c
commit
1367fa214d
@ -132,5 +132,9 @@ class API(wsgi.Router):
|
||||
controller=tasks_resource,
|
||||
action='get',
|
||||
conditions={'method': ['GET']})
|
||||
mapper.connect('/tasks/{task_id}',
|
||||
controller=tasks_resource,
|
||||
action='delete',
|
||||
conditions={'method': ['DELETE']})
|
||||
|
||||
super(API, self).__init__(mapper)
|
||||
|
@ -118,6 +118,14 @@ class TasksController(object):
|
||||
result = {'task': task, 'task_details': task_details}
|
||||
return result
|
||||
|
||||
def delete(self, req, task_id):
|
||||
msg = (_("This operation is currently not permitted on Glance Tasks. "
|
||||
"They are auto deleted after reaching the time based on "
|
||||
"their expires_at property."))
|
||||
raise webob.exc.HTTPMethodNotAllowed(explanation=msg,
|
||||
headers={'Allow': 'GET'},
|
||||
body_template='${explanation}')
|
||||
|
||||
|
||||
class RequestDeserializer(wsgi.JSONRequestDeserializer):
|
||||
_required_properties = ['type', 'input']
|
||||
|
@ -593,6 +593,8 @@ def translate_exception(req, e):
|
||||
if isinstance(e, webob.exc.HTTPError):
|
||||
e.explanation = gettextutils.translate(e.explanation, locale)
|
||||
e.detail = gettextutils.translate(e.detail, locale)
|
||||
if getattr(e, 'body_template', None):
|
||||
e.body_template = gettextutils.translate(e.body_template, locale)
|
||||
return e
|
||||
|
||||
|
||||
|
@ -129,4 +129,11 @@ class TestTasks(functional.FunctionalTest):
|
||||
self.assertEqual(1, len(tasks))
|
||||
self.assertEqual(tasks[0]['id'], task_id)
|
||||
|
||||
# Attempt to delete a task
|
||||
path = self._url('/v2/tasks/%s' % tasks[0]['id'])
|
||||
response = requests.delete(path, headers=self._headers())
|
||||
self.assertEqual(405, response.status_code)
|
||||
self.assertIsNotNone(response.headers.get('Allow'))
|
||||
self.assertEqual('GET', response.headers.get('Allow'))
|
||||
|
||||
self.stop_servers()
|
||||
|
@ -504,3 +504,40 @@ class TestTasksApi(base.ApiTest):
|
||||
actual_tasks = json.loads(content)['tasks']
|
||||
|
||||
self.assertEqual(0, len(actual_tasks))
|
||||
|
||||
def test_delete_task(self):
|
||||
# 0. POST /tasks
|
||||
# Create a new task with valid input and type
|
||||
task_data = _new_task_fixture()
|
||||
task_owner = 'tenant1'
|
||||
body_content = json.dumps(task_data)
|
||||
|
||||
path = "/v2/tasks"
|
||||
response, content = self.http.request(path, 'POST',
|
||||
headers=
|
||||
minimal_task_headers(task_owner),
|
||||
body=body_content)
|
||||
self.assertEqual(response.status, 201)
|
||||
|
||||
data = json.loads(content)
|
||||
task_id = data['id']
|
||||
|
||||
# 1. DELETE on /tasks/{task_id}
|
||||
# Attempt to delete a task
|
||||
path = "/v2/tasks/%s" % task_id
|
||||
response, content = self.http.request(path,
|
||||
'DELETE',
|
||||
headers=minimal_task_headers())
|
||||
self.assertEqual(response.status, 405)
|
||||
self.assertEqual('GET', response.webob_resp.headers.get('Allow'))
|
||||
self.assertEqual(('GET',), response.webob_resp.allow)
|
||||
self.assertEqual(('GET',), response.allow)
|
||||
|
||||
# 2. GET /tasks/{task_id}
|
||||
# Ensure that methods mentioned in the Allow header work
|
||||
path = "/v2/tasks/%s" % task_id
|
||||
response, content = self.http.request(path,
|
||||
'GET',
|
||||
headers=minimal_task_headers())
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertIsNotNone(content)
|
||||
|
@ -338,6 +338,13 @@ class TestTasksControllerPolicies(base.IsolatedUnitTest):
|
||||
self.assertRaises(webob.exc.HTTPForbidden, self.controller.create,
|
||||
request, task)
|
||||
|
||||
def test_delete(self):
|
||||
request = unit_test_utils.get_fake_request()
|
||||
self.assertRaises(webob.exc.HTTPMethodNotAllowed,
|
||||
self.controller.delete,
|
||||
request,
|
||||
'fake_id')
|
||||
|
||||
|
||||
class TestTasksDeserializer(test_utils.BaseTestCase):
|
||||
|
||||
|
@ -546,6 +546,17 @@ class Httplib2WebobResponse(object):
|
||||
def get(self, key):
|
||||
return self.webob_resp.headers[key]
|
||||
|
||||
@property
|
||||
def allow(self):
|
||||
return self.webob_resp.allow
|
||||
|
||||
@allow.setter
|
||||
def allow(self, allowed):
|
||||
if type(allowed) is not str:
|
||||
raise TypeError('Allow header should be a str')
|
||||
|
||||
self.webob_resp.allow = allowed
|
||||
|
||||
|
||||
class HttplibWsgiAdapter(object):
|
||||
def __init__(self, app):
|
||||
|
Loading…
Reference in New Issue
Block a user