Opened 15 years ago
Closed 12 years ago
#12747 closed New feature (fixed)
Custom HTTP status reason phrases are not supported
Reported by: | Gustavo Narea | Owned by: | gisle |
---|---|---|---|
Component: | HTTP handling | Version: | dev |
Severity: | Normal | Keywords: | http status, http status reason, http status reason phrase |
Cc: | akvadrako | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
At present, Django hard-codes the HTTP status reason phrases based on an integer that represents the HTTP status code, forcing the recommended phrases by the HTTP specification.
Note they are just the recommended/default phrases and developers should be allowed to override these phrases. For example, I may want to return the following and Django should allow me to do so:
403 Get out
Or,
200 Everything is fine
See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1
In order to support this, Django could have the following code in django.http:HttpResponse.__init__:
if isinstance(status, basestring): # The status is given as a real HTTP status header, so we should # tell the code and the reason apart for Django: (status_code, status_reason) = status.split(" ", 1) status_code = int(status_code) self.status_reason = status_reason or None else: # The status has been given the old way supported by Django, simply # the status code as an integer: status_code = status self.status_reason = None
And the following on django.core.handlers.wsgi:WSGIHandler.__call__():
if response.status_reason: status_text = "%s %s" % (response.status_code, response.status_reason) else: try: status_text = STATUS_CODE_TEXT[response.status_code] except KeyError: status_text = 'UNKNOWN STATUS CODE'
If any Django user wants to use this functionality before it gets implemented, they may use twod.wsgi: http://bitbucket.org/2degrees/twod.wsgi/
Attachments (3)
Change History (23)
comment:1 by , 15 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 15 years ago
Owner: | changed from | to
---|
comment:3 by , 15 years ago
Needs tests: | set |
---|
by , 15 years ago
Attachment: | 0001-Ticket-12747-Set-custom-status_text-message.patch added |
---|
by , 15 years ago
Attachment: | 0002-Test-that-the-custom-response-shows-up-on-the-WSGI-l.patch added |
---|
comment:4 by , 15 years ago
Needs tests: | unset |
---|
follow-up: 6 comment:5 by , 15 years ago
milestone: | 1.2 |
---|
1.2 is feature-frozen, moving this feature request off the milestone.
comment:6 by , 15 years ago
Replying to ubernostrum:
1.2 is feature-frozen, moving this feature request off the milestone.
This can hardly be a feature. It's a fix for partially broken HTTP support.
comment:7 by , 15 years ago
@Gustavo:
Is there any condition under which the existing implementation will raise an error or cause data loss in the absence of a custom status message?
Is there any standard that is violated by not allowing a custom status message?
The answer to both of these questions is No. Therefore, this isn't a bug fix. It's a feature request.
It may be an extremely useful new feature, but that doesn't change the fact that it is still a feature, and Django 1.2 is feature frozen.
comment:8 by , 14 years ago
Cc: | added |
---|
comment:9 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → New feature |
comment:10 by , 14 years ago
Easy pickings: | unset |
---|---|
Patch needs improvement: | set |
0002-Test-that-the-custom-response-shows-up-on-the-WSGI-l.patch fails to apply cleanly on to trunk
comment:12 by , 12 years ago
Patch needs improvement: | unset |
---|---|
Version: | 1.1 → master |
Just attached an updated patch. I choose to pass a tuple as the status argument, instead of a string that has to be parsed, which is always fragile.
comment:13 by , 12 years ago
I couldn't care less about this feature request, but the approach shown in the patch looks all right.
I don't have an opinion on using a string or a tuple or a new keyword argument to pass the status text.
The patch is out of date; otherwise, in the interest of crossing one ticket off the list, this is RFC.
follow-up: 15 comment:14 by , 12 years ago
Actually, since this isn't a particularly useful feature, and I don't expect anyone to ever need it, it'd be nice if it didn't have any overhead.
comment:15 by , 12 years ago
Hi, aaugustin.
Replying to aaugustin:
Actually, since this isn't a particularly useful feature, and I don't expect anyone to ever need it, it'd be nice if it didn't have any overhead.
What do you mean by "overhead"? I think a new keyword argument would be cleaner, but I'm happy to update update the patch in either direction. Which is the approach you prefer?
Thanks.
comment:16 by , 12 years ago
This is hackish, quickly written, and tested for only 10 minutes or so but I implemented custom status codes by monkeypatching the django.core.handlers.wsgi.STATUS_CODE_TEXT dict like:
import django.core.handlers.wsgi as wsgi class NextDict(dict): def __init__(self, *args, **kwargs): self._nextdict = {} super(NextDict, self).__init__(*args, **kwargs) def set_next(self, key, value): """ The next time this key is queried, return the passed value. After that, use the default. """ self._nextdict[key] = value def __getitem__(self, key): if key in self._nextdict: v = self._nextdict[key] del(self._nextdict[key]) return v return super(NextDict, self).__getitem__(key) wsgi.STATUS_CODE_TEXT = NextDict(wsgi.STATUS_CODE_TEXT)
And then when I want my response to have a custom message for it's status code:
class MyView(request): wsgi.STATUS_CODE_TEXT.set_next(200, "hello") return HttpResponse("hello again")
I googled for similar ideas and didn't find anyone doing this, so I thought it may give someone some ideas to develop this into a plugin or something. It wouldn't add overhead to the default (and reasonable) implementation, but would help some of us satisfy our requirements easily and without adding too much extra overhead...
comment:18 by , 12 years ago
For the API of my company we use this feature in a lot of places.
One of the use cases is:
We have a courses
resource, if the teacher tries to DELETE
a course with enrolled users, we return a 400 Cannot delete course with students
response.
comment:19 by , 12 years ago
I'd like to stop seeing pull requests about this.
If you want to do it, this is how: https://github.com/django/django/pull/1154
comment:20 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Test that the custom response shows up on the WSGI level as well