Opened 14 years ago
Closed 12 years ago
#9453 closed defect (fixed)
[PATCH] The session does not get saved with `req.send()`
Reported by: | Jun Omae | Owned by: | Jun Omae |
---|---|---|---|
Priority: | normal | Milestone: | 1.0 |
Component: | general | Version: | 0.11 |
Severity: | normal | Keywords: | |
Cc: | leho@…, Thijs Triemstra, osimons | Branch: | |
Release Notes: |
When modified, the session is now always saved regardless of the way the response is sent (except for |
||
API Changes: | |||
Internal Changes: |
Description (last modified by )
When the session is modified and the response is sent with req.send()
, the session does not get saved.
The patch adds self.session.save()
to check_modified
, send
and send_file
, excluding send_error
.
Trac 0.12 and Trac 0.11-stable have the same issue.
-
trac/web/api.py
diff --git a/trac/web/api.py b/trac/web/api.py index df6d9ac..b3becbd 100644
a b class Request(object): 341 341 if (not inm or inm != etag): 342 342 self.send_header('ETag', etag) 343 343 else: 344 self.session.save() 344 345 self.send_response(304) 345 346 self.send_header('Content-Length', 0) 346 347 self.end_headers() … … class Request(object): 402 403 self.send(data, content_type, status) 403 404 404 405 def send(self, content, content_type='text/html', status=200): 406 self.session.save() 405 407 self.send_response(status) 406 408 self.send_header('Cache-Control', 'must-revalidate') 407 409 self.send_header('Content-Type', content_type + ';charset=utf-8') … … class Request(object): 477 479 mtime = datetime.fromtimestamp(stat.st_mtime, localtz) 478 480 last_modified = http_date(mtime) 479 481 if last_modified == self.get_header('If-Modified-Since'): 482 self.session.save() 480 483 self.send_response(304) 481 484 self.send_header('Content-Length', 0) 482 485 self.end_headers() … … class Request(object): 486 489 mimetype = mimetypes.guess_type(path)[0] or \ 487 490 'application/octet-stream' 488 491 492 self.session.save() 489 493 self.send_response(200) 490 494 self.send_header('Content-Type', mimetype) 491 495 self.send_header('Content-Length', stat.st_size)
Attachments (0)
Change History (17)
comment:1 by , 14 years ago
Milestone: | → 0.13 |
---|
comment:2 by , 14 years ago
Replying to cboos:
As one is supposed to raise
RequestDone
after a send, what about simply:…
Yes, that makes sense as a general solution as plugins may implement similar logic too - like I've done for bitten:source:trunk/bitten/master.py (see BuildMaster._send_response()
currently at line 139).
comment:3 by , 14 years ago
Cc: | added |
---|
comment:5 by , 14 years ago
Owner: | set to |
---|
comment:6 by , 14 years ago
Cc: | added |
---|
follow-up: 8 comment:7 by , 14 years ago
Jun, for what kind of requests do we need to save the session after a send()
?
follow-up: 9 comment:8 by , 14 years ago
Replying to cboos:
Jun, for what kind of requests do we need to save the session after a
send()
?
Well…, when Request.redirect()
is called, the method saves a session before raising RequestDone
. In the other methods which raises RequestDone
(e.g. send()
), the methods don't save it. I thought that the other methods should save it.
Your patch is simple and generic. In this case, I think that the saving a session in Request.redirect
should be removed cause it saves a session, twice.
-
trac/web/api.py
diff --git a/trac/web/api.py b/trac/web/api.py index f461a2c..b0dcdef 100644
a b class Request(object): 446 446 for listener in self.redirect_listeners: 447 447 listener(self, url, permanent) 448 448 449 self.session.save() # has to be done before the redirect is sent450 451 449 if permanent: 452 450 status = 301 # 'Moved Permanently' 453 451 elif self.method == 'POST': -
trac/web/main.py
diff --git a/trac/web/main.py b/trac/web/main.py index 4449717..1cfac67 100644
a b class RequestDispatcher(Component): 204 204 205 205 output = chrome.render_template(req, template, data, 206 206 content_type) 207 # Give the session a chance to persist changes208 req.session.save()209 207 req.send(output, content_type or 'text/html') 210 208 else: 211 209 self._post_process_request(req) 212 210 except RequestDone: 211 # Give the session a chance to persist changes after a send() 212 req.session.save() 213 213 raise 214 214 except: 215 215 # post-process the request in case of errors
comment:9 by , 14 years ago
Replying to jomae:
Your patch is simple and generic. In this case, I think that the saving a session in
Request.redirect
should be removed cause it saves a session, twice.
#!diff...
And this patch is tested.
comment:10 by , 13 years ago
Cc: | added |
---|
comment:12 by , 13 years ago
Version: | 0.12 → 0.11 |
---|
According to the initial description the issue persisted since 0.11 at least already.
comment:13 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:14 by , 13 years ago
Owner: | changed from | to
---|
comment:15 by , 12 years ago
comment:16 by , 12 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
The initial approach was better, as doing the session.save()
at the level of the RequestDone
exception handler means that the request has been fully sent. The client might already have sent another query which gets processed (by another thread or process) before the save is complete (like the error in ticket:10779#comment:59).
comment:17 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
Fixed in [11236] by saving the session in send_response()
instead of after sending the content.
As one is supposed to raise
RequestDone
after a send, what about simply:trac/web/main.py
(untested)