#32982: Tighten up the check for status codes in HttpResponse
-------------------------------------+-------------------------------------
               Reporter:  Abhyudai   |          Owner:  nobody
                   Type:  Bug        |         Status:  new
              Component:  HTTP       |        Version:  dev
  handling                           |
               Severity:  Normal     |       Keywords:  http, status code
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 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()
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/32982>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/053.acd93fb2f8d34aee1dcb23fbe0a2dd6d%40djangoproject.com.

Reply via email to