Opened 6 years ago

Closed 5 years ago

#13277 closed (wontfix)

HTTP 303 (See Other) Response

Reported by: therendus@… Owned by: nobody
Component: HTTP handling Version: master
Severity: Keywords: http response see other 303 redirection
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


Still not sure I've really looked everywhere but the fact that I can't find that string "303" in the relevant documentation, the ticket list or code files remains...

In short - there's a dire need for the 303 (See Other) http response object in ALL POST based pages in all web applications. If a page with a post request is not met with a 303 redirection - it's incompetently done (thence my rejection to believe such a exhaustive framework doesn't support that - apart from using the base HttpRequest object with all the fuss around that).

So in two words my suggestion is - a new httprequest derived object named smth. like HttpResponseSeeOther and another parameter for the redirect() shortcut to allow (and encourage!!!) the use of that response on all POST requests




Attachments (1)

http-303-redirect-backward-compatible.diff (3.4 KB) - added by Andreas Sommer <AndiDog@…> 5 years ago.
Proposed patch

Download all attachments as: .zip

Change History (9)

comment:1 Changed 6 years ago by therendus@…

  • Keywords redirection added
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

I see you're recommending the HttpResponseRedirect (302) for the aforementioned case but that's "wrong" and out of spec. It relies on common browser "misbehavior" to work around the issue.
The correct redirection (for preventing multiple posting and 'page expired' warnings) is code 303 !


comment:2 Changed 6 years ago by gabrielhurley

Words like "dire need" and "incompetent" aren't gonna get you anywhere. If you read the IETF docs on HTTP 302 and 303 available here:

You'll see they note that "most existing user agent implementations treat 302 as if it were a 303 response, performing a GET on the Location field-value regardless of the original request method. The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client." In practice, just about all current browsers treat 302s this way.

They also note that 303 is only valid in HTTP1.1, so servers serving HTTP1.0 cannot use it. Also, old browsers may not implement (or incorrectly implement) 303 and 307. While anything after IE4 and Netscape 4.7 support 303, IE5 and IE6 have bugs in their implementations.

Django provides the HttpResponseRedirect as a shortcut for 302s because 302 is the most commonly desired and used method. There's no reason you can't return a 303 response code using a regular HttpRequest object yourself.

If you want an HttpResponseSeeOther all you need to do is copy and paste the HttpResponseRedirect class and change the status_code value. If you post the patch here it may even get merged to trunk someday...

comment:3 Changed 6 years ago by russellm

  • Triage Stage changed from Unreviewed to Accepted

It says on the homepage that Django is for "Perfectionists with deadlines". That means we follow the spec whenever we can, but when the spec is completely at odds with reality, we follow reality.

Like Gabriel says, In this case, it doesn't matter what the official HTTP spec says - nobody follows it. Near on every browser in the world implements 302 incorrectly, and not every browser in the world implements 303 at all (or correctly). It simply isn't practical to be pure in this situation.

As far as not being implemented; 303 isn't alone. There are a bunch of HTTP response codes that Django doesn't currently implement. I'll accept this ticket on the basis that we should review and add a couple of commonly used status codes. 401 would be the top of my list; there's probably also a good argument for 307. Oh, and 418... just because :-)

comment:4 Changed 6 years ago by therendus@…

Words like "dire need" and "incompetent" aren't gonna get you anywhere.

Sorry, I suppose I should have explained in more details (though I thought both meanings would be clearer as they were indirectly addressed by the paragraphs to follow).
"Incompetent" - I was referring NOT to the framework (which is from my still short experience with it - perfectly designed and thought of (what I've seen so far)) BUT to the MANY, MANY, MANY pieces of BOTH freelance and commercial apps I've stumbled upon (mostly having to fix or patch them) without any PRG redirection at all or with a simple 301 one.

By "dire need" I meant that it's a necessity to use this mechanism in virtually all web applications (the pieces of web code that do "something") and I'm not so sure about testing 302 but other ways than 303 have been unreliable to my experience and 303 has been serving me perfectly.
I can't imagine making anything web without using 303.
I hope that solves the "dire need" mystery ;)

"They also note that 303 is only valid in HTTP1.1, so servers serving HTTP1.0 cannot use it. Also, old browsers may not implement (or incorrectly implement) 303 and 307. While anything after IE4 and Netscape 4.7 support 303, IE5 and IE6 have bugs in their implementations. "
About "non-spec" compliance and supporting "old" stuff - in CodeIgniter for eg. such "all browser and all server!!" compatibility code stamping have lead to overloaded code and necessary important features cut out! (like vital header control functionality that otherwise exists in php). Leading to the need to "patch" the framework as you are suggesting to me now.

You shouldn't be advising me to patch the framework to have it compliant with modern (AND ONGOING) standards and browsers.
You should be advising and thinking of patching it to keep THE BACKWARD compliance!

At least that's how I understand the lonely path of perfectionism... ;)

And another point (you really need to want to in order to apprehend it's importance instead of just dumping it out as "not concerning you")...
Following the 3-rd party software incompatibilities is the middle league (not following it is the small one). But what would distinguish a true leader (of technology) would be the team that MAKES them (or in this case would just assert them).
For eg. why do you think IE is still torturing (instead of dying the shameful death it deserves years ago) the well-trained multitude of the web developers ?
Because they put up with it by striving to bring all seb solutions to a common denominator with IE (on the expence of cut down features, more efforts and messy patched code).
It all comes down to the fact that those that hold the casting vote - don't care enough to "bring balance to the force" as and where needed. In this case - the very experienced developers of this so popular (with a great potential for more and further popularity) framework.
I've seen this policy exercised in other frameworks too but I still think this is the wrong way.
Take for eg. the python 'depricated' mechanism. What would have happened if it tried to keep consistency with V 1.0 ?! It is true that python is a lot smaller and easy to "advance" community than the web itself but if leverage holding parties like yourselves don't make at least a symbolic move onward who will it (the web) have to rely upon ? Browser developing companies ? Microsoft ?! ... All quality browser developers react very quick to web tendencies and technologies (let alone such a simple issue). So are you saying that devs (and yourself) should put this idea behind just to keep compliant with the piece of software of the least quality (increasing overall incompatibility that way and stalling "perfection")?...

I know - a lot of talking just to avoid using a parameter to the httprequest, but that's not the point and I hope you see that clearly ;)

So you see I still stand by my qualifiers "incompetent" and "dire need".

"...aren't gonna get you anywhere."
Well I was driven off of trying to contribute to CodeIgniter because I was getting mostly rejective or none responses for issues I'm still certain I had serious grounds for bringing up or just plain bugs.
At least I got a response here :) (and well substantiated in this, though I still disagree with it) - two for a day. Really impressed ;)

"all you need to do is copy and paste the HttpResponseRedirect? "
was gonna do...

"If you post the patch here it may even get merged to trunk someday... "
I thought I might get a response like that so I thought of that myself. However it might take time for me (using it) to get familiar with the overall philosophy of the framework to know which solution style will be best (as it would require modification in several places) and the needed testing...

For dealing with all the issues here I suggest (although that's already a feature request) that stuff like complying with old or rare protocols and stuff like that and supporting broken web clients or other broken technologies be put in an external 'deprecated' mod(s) for inclusion on request only.
That is - the standard compliant behavior should be in the core of an app and then patches should be "added" if so much needed - not be part of the foundation.
Especially for one (app) that holds a key position and role in this process like a framework - the very thing that teaches and asserts development style and habits which on their turn are the hanger for the rest of the event chain to global perfectionism :)
Devs need to know what they should use (also as now the majority are not using it at all - hats off for your documentation bringing the post redirection to the attention), and only then they should know about how compliant it actually is. You wouldn't teach a freshman designer that Alpha(opacity=50) is the css property for element opacity, now would you? That apart of the fact that they would need to know that too for still some time...
Needless to say such an endeavor would only make a diff if undertaken on a larger scale but that's a no argument to "not be the first or only one taking this step"...

And another point regarding
"They also note that 303 is only valid in HTTP1.1, so servers serving HTTP1.0 cannot use it. Also, old browsers may not implement (or incorrectly implement) 303 and 307. While anything after IE4 and Netscape 4.7..."
I wonder how many "new" apps are meant for or developed on such platforms ? (perhaps a real statistics poll would be in place here)
I also wonder what if wanted (in the light of that direction of thinking) to use django with python 2.2 (on a 10 year old server while striving to make IE4 users happy).
How should I address you with this urge of mine then ? :) What would you answer me then to that ? And isn't the situation with this issue approximately the same ?

Best regards and appreciating the swift response

P.S. Btw this ticket tracker could use a "quote" tag ;)

comment:5 Changed 6 years ago by gabrielhurley

Gonna keep it short after that massive reply... but a couple quick notes:

  • Sadly, the fact is that enterprise customers are the driving force in many software markets, not the developers, manufacturers, or users. Massive corporate and governmental institutions have both the power to make or break software projects and also have a huge amount of inertia and legacy systems to deal with. Ignoring compatibility issues to push forward simply isn't an option for an "enterprise-grade framework".
  • The 1.2 release is trying to get out the door ASAP and the devs are all working very hard on that, so tread lightly for now... others have already been chastised for being off-topic, distracting, or "difficult".
  • You might want to read some of the recent threads on Django-Developers; there's been a lot of talk about why Django is so focused on stability and backwards-compatibility. It's informative.
  • There's no quote feature on Trac 'cuz discussion is supposed to take place on the Django-Developers mailing list. This thread's probably gotten too long already...

If I have a minute sometime I'll write a patch for this ticket, but as mentioned above getting it merged to trunk (let alone into a release) is gonna be a while.

comment:6 Changed 6 years ago by anonymous

"Gonna keep it short"
will try that myself (already spared a pronoun ;) (not that there's need to drag on this discussion ...)

"Sadly, the fact is that enterprise customers are the driving force..."
Surely you're right - I've had my shares of clientele I've had to dissuade on all kind of issues in their preliminary requirement list. With/for some I've managed it - with some I've failed...
Apparently there are powerful factors on stage. Acknowledging them is the first important step toward engaging an issue. But while majority of people just stop there and reconcile with that - this is never the only possible response and attitude. People throughout history that have actually achieved world-scale changes and made a difference - knew that :) Apparently that's one in a million individual ;)

"The 1.2 release is trying to get out the door ASAP"
I couldn't figure how to check the issue status (and I bet I'll have others to come) on a newer version. I'd never had brought it up if I'd seen situation was changing in a newer version (that's the only goal I had posting it and knowing how important it is - I never actually wanted to "get myself anywhere" with anything ;) )
Also at that point I didn't actually know you've addressed the issue even with an out of spec technique. As I didn't find 303 anywhere in the code I assumed that issue was just left behind. As I said it was a bit hard to believe but I'd seen that same situation with another extreme popular and otherwise well made (the aforementioned) framework - it just doesn't say or do anything special for this most common web coding pattern. Although it allows the return code to be specified in its redirect() shortcut. So I was mostly hoping to manage to suggest that little but so important improvement in this very shotcut. Especially considering that while the redirect function should accept a parameter stating that you want to do RPG - it could still return 302 in the behind (say for eg. if a special _COMPATIBILITY = True setting is configured) and in future versions this would just be dropped while all code would continue working well and on specs ! Something that wouldn't happen now and is indirectly the actual reason for current "incompatible situation". Once again if non of the parties involved doesn't "force" anything - nothing is going to change as long as all sides try to comply to each-other and make themselves compatible.
Also those "enterprise" customers are even more distant to the actual technology and technically less competent (the higher they stand) than the small web project owners. And they don't care which http code they use to make big $$$. However if they face a top of the line framework (which they would very much want to use) telling them that 303 is "goooood" - they will update their requirements too. You would know - all web clients demand web 2.0 architecture or table-less design having moderate idea what that is and very little why! - making them wanting something just because it's fashionable even if their case actually requires a totally different (or old school) approach. ...The point being that those "big shot" clients while having a great impact are essentially followers ! Given there's something to follow... If there isn't - things come down to that "inertia" you talk about. And while there's no doubt the process is a bit ungainly one thing is beyond argument (and way overlooked :) - it has to start somewhere.

"You might want to read some of the recent threads..."
Will do and I'm sure there are reasonable considerations for the framework policy and architecture.
However as I do and say to all my clients and projects (actually spending half the time and efforts convincing them on certain strategy) - the right way is to make the actual foundation as generalized as possible (as an OS core). Then all fancy features be built on top of that and compatibility issues be patched on the final stage - thus preserving the overall system robustness.
The point being - policy and strategy/architecture are different things and one can serve the other in different (better and worse) ways.
"This thread's probably gotten too long already... "
I realize that :) But just wanted to make my points complete - then maybe the ticket (being consistent and self contained enough) could serve as a reference in a discussion...

"...but as mentioned above getting it merged to trunk (let alone into a release) is gonna be a while..."
If you hadn't yet you might go check a certain very nice feature of CodeIgniter (I realize this is to be discussed elsewhere - here it's just a remark) - the ability to override the framework core functionality by just replacing a specially named replacement substitute file of one of it's libraries. You can even inherit a core library and just override the methods you want - then your derived class will be used through the whole framework even by core code.
I couldn't find anything related to 'patching' or 'overriding' in the django docs - also it's file structure shows that's not easily achievable at the same level...
Perhaps what I wanted could be easily achieved with "custom commands" but haven't explored that direction yet. Anyway just thought you might be interested in that technique used quite successfully in CodeIgniter.


Changed 5 years ago by Andreas Sommer <AndiDog@…>

Proposed patch

comment:7 Changed 5 years ago by Andreas Sommer <AndiDog@…>

  • Has patch set
  • Summary changed from HTTP 303 (See Other) Response to Proposed patch
  • Version changed from 1.1 to SVN

I attached a patch for this problem. It introduces settings.REDIRECT_303_BACKWARD_COMPATIBILITY, which defaults to True. That settings defines whether the HttpResponseSeeOtherRedirect.status_code property returns 303 (probably not compatible with HTTP/1.0 clients) or 302 (backward compatible).

Tell me how you like that approach.

comment:8 Changed 5 years ago by lukeplant

  • Resolution set to wontfix
  • Status changed from new to closed
  • Summary changed from Proposed patch to HTTP 303 (See Other) Response

As Gabriel explained, you can already make your own HttpResponse subclass that does this. There is very little advantage in adding this to core unless we also change use of 302 to 303. However, that would break lots of tests, with zero practical advantage AFAICS. So I'm closing WONTFIX.

Note: See TracTickets for help on using tickets.
Back to Top