Fix Status-Line in HTTP response

There is a strict rule about constructing status line for HTTP:
'...Status-Line, consisting of the protocol version followed by a
numeric status code and its associated textual phrase, with each
element separated by SP characters'
(http://www.faqs.org/rfcs/rfc2616.html)

This patch ensures an associated textual phrase for a status code
is always written in the HTTP response.

Closes-Bug: #1496055
Change-Id: I68d4c41d0c04871eb032d23d7b16aa2bf2c0bb73
This commit is contained in:
Marian Horban 2015-09-14 13:43:36 -04:00
parent 7f9770892b
commit dbda82afd8
2 changed files with 39 additions and 3 deletions

View File

@ -30,6 +30,7 @@ from oslo_log import log as logging
from oslo_utils import excutils
import six
import webob.exc
from webob import util as woutil
from nova.i18n import _, _LE
from nova import safe_utils
@ -47,9 +48,24 @@ CONF.register_opts(exc_log_opts)
class ConvertedException(webob.exc.WSGIHTTPException):
def __init__(self, code=500, title="", explanation=""):
def __init__(self, code, title="", explanation=""):
self.code = code
self.title = title
# There is a strict rule about constructing status line for HTTP:
# '...Status-Line, consisting of the protocol version followed by a
# numeric status code and its associated textual phrase, with each
# element separated by SP characters'
# (http://www.faqs.org/rfcs/rfc2616.html)
# 'code' and 'title' can not be empty because they correspond
# to numeric status code and its associated text
if title:
self.title = title
else:
try:
self.title = woutil.status_reasons[self.code]
except KeyError:
msg = _LE("Improper or unknown HTTP status code used: %d")
LOG.error(msg, code)
self.title = woutil.status_generic_reasons[self.code // 100]
self.explanation = explanation
super(ConvertedException, self).__init__()

View File

@ -17,6 +17,7 @@
import inspect
import six
from webob.util import status_reasons
from nova import context
from nova import exception
@ -146,10 +147,29 @@ class NovaExceptionTestCase(test.NoDBTestCase):
self.assertEqual("some message %(somearg)s", exc.format_message())
class ConvertedExceptionTestCase(test.NoDBTestCase):
def test_instantiate(self):
exc = exception.ConvertedException(400, 'Bad Request', 'reason')
self.assertEqual(exc.code, 400)
self.assertEqual(exc.title, 'Bad Request')
self.assertEqual(exc.explanation, 'reason')
def test_instantiate_without_title_known_code(self):
exc = exception.ConvertedException(500)
self.assertEqual(exc.title, status_reasons[500])
def test_instantiate_without_title_unknown_code(self):
exc = exception.ConvertedException(499)
self.assertEqual(exc.title, 'Unknown Client Error')
def test_instantiate_bad_code(self):
self.assertRaises(KeyError, exception.ConvertedException, 10)
class ExceptionTestCase(test.NoDBTestCase):
@staticmethod
def _raise_exc(exc):
raise exc()
raise exc(500)
def test_exceptions_raise(self):
# NOTE(dprince): disable format errors since we are not passing kwargs