﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
32982	Tighten up the check for status codes in HttpResponse	Abhyudai	nobody	"As of now, all values in between the range 100 and 600 are allowed. https://github.com/django/django/blob/main/django/http/response.py#L123

I'm quoting the relevant section for potential ease of discussion here.
{{{#!python
if not 100 <= self.status_code <= 599:
    raise ValueError('HTTP status code must be an integer from 100 to 599.')
}}}

Not all of them are valid, for example `111` is not a valid status code.  The list of valid status code can be seen here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

Using the [https://docs.python.org/3/library/http.html#http.HTTPStatus HTTPStatus] class from the `http` module should probably help us get around the problem.

{{{#!sh
>>> from http import HTTPStatus as status
>>> status(111)
Traceback (most recent call last):
  File ""<stdin>"", line 1, in <module>
  File ""/usr/lib/python3.8/enum.py"", line 339, in __call__
    return cls.__new__(cls, value)
  File ""/usr/lib/python3.8/enum.py"", line 663, in __new__
    raise ve_exc
ValueError: 111 is not a valid HTTPStatus
>>> status(100)
<HTTPStatus.CONTINUE: 100>
}}}

This will have a downside as to preventing a server that may probably be sending a custom status code in between `100` and `600`, which may raise an error in case this is allowed. For what it is worth, we already disallow values outside this range.

I think we can solve this issue, by introducing a method, something like `verfiy_status_code` which does the default verification and may be overridden in case someone wants to.

== Default implementation

{{{#!python
from http import HTTPStatus as status

class HttpResponseBase:
    def verify_status_code(self):
       if self.status is None:
           return 
       try:
           self.status_code = int(status)
       except (ValueError, TypeError):
           raise TypeError('HTTP status code must be an integer.')

       try:
           status(self.status)
       except ValueError as exc:
           raise
}}}

== Overriden implementation

{{{#!python
from django.http import HttpResponseBase

class CustomHttpResponse(HttpResponseBase):
    my_custom_codes = [111, 121]

    def verify_status_code(self):
        if self.status in self.my_custom_codes:
            return 
        super().verify_status_code()
}}}"	Cleanup/optimization	closed	HTTP handling	dev	Normal	wontfix	http, status code		Unreviewed	0	0	0	0	0	0
