Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #3881 -- skip saving session when response status is 500

Saving session data is somewhat likely to lead into error when the
status code is 500. It is guaranteed to lead into error if the reason
for the 500 code is query error on PostgreSQL.
  • Loading branch information...
commit aeda55e6bffc3cfbf53698af398a19c1a0f02d46 1 parent bebbbb7
@akaariai akaariai authored
View
16 django/contrib/sessions/middleware.py
@@ -33,11 +33,13 @@ def process_response(self, request, response):
expires_time = time.time() + max_age
expires = cookie_date(expires_time)
# Save the session data and refresh the client cookie.
- request.session.save()
- response.set_cookie(settings.SESSION_COOKIE_NAME,
- request.session.session_key, max_age=max_age,
- expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
- path=settings.SESSION_COOKIE_PATH,
- secure=settings.SESSION_COOKIE_SECURE or None,
- httponly=settings.SESSION_COOKIE_HTTPONLY or None)
+ # Skip session save for 500 responses, refs #3881.
+ if response.status_code != 500:
+ request.session.save()
+ response.set_cookie(settings.SESSION_COOKIE_NAME,
+ request.session.session_key, max_age=max_age,
+ expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
+ path=settings.SESSION_COOKIE_PATH,
+ secure=settings.SESSION_COOKIE_SECURE or None,
+ httponly=settings.SESSION_COOKIE_HTTPONLY or None)
return response
View
16 django/contrib/sessions/tests.py
@@ -409,6 +409,22 @@ def test_no_httponly_session_cookie(self):
self.assertNotIn('httponly',
str(response.cookies[settings.SESSION_COOKIE_NAME]))
+ def test_session_save_on_500(self):
+ request = RequestFactory().get('/')
+ response = HttpResponse('Horrible error')
+ response.status_code = 500
+ middleware = SessionMiddleware()
+
+ # Simulate a request the modifies the session
+ middleware.process_request(request)
+ request.session['hello'] = 'world'
+
+ # Handle the response through the middleware
+ response = middleware.process_response(request, response)
+
+ # Check that the value wasn't saved above.
+ self.assertNotIn('hello', request.session.load())
+
class CookieSessionTests(SessionTestsMixin, TestCase):
View
6 docs/releases/1.5.txt
@@ -177,6 +177,12 @@ autocommit behavior was never restored. This bug is now fixed in 1.5. While
this is only a bug fix, it is worth checking your applications behavior if
you are using PostgreSQL together with the autocommit option.
+Session not saved on 500 responses
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django's session middleware will skip saving the session data if the
+response's status code is 500.
+
Miscellaneous
~~~~~~~~~~~~~
View
3  docs/topics/http/sessions.txt
@@ -423,6 +423,9 @@ cookie will be sent on every request.
Similarly, the ``expires`` part of a session cookie is updated each time the
session cookie is sent.
+.. versionchanged:: 1.5
+ The session is not saved if the response's status code is 500.
+
Browser-length sessions vs. persistent sessions
===============================================
Please sign in to comment.
Something went wrong with that request. Please try again.