Edgewall Software
Modify

Opened 11 years ago

Closed 7 years ago

#5862 closed defect (fixed)

Bad response header - browser cache is not invalidated for some browsers

Reported by: Licho Owned by: Christian Boos
Priority: normal Milestone: 0.12.3
Component: web frontend Version: devel
Severity: minor Keywords: verify opera
Cc:
Release Notes:

Improved compatibility with old proxies by also setting the Expires header for dynamic content

API Changes:

Description

I tested this with latest Opera. It fails to redownload trac sites, you have to manually refresh it.

Trac should tell opera to not use cache.

Attachments (0)

Change History (22)

comment:1 Changed 11 years ago by Emmanuel Blot

Milestone: 0.11
Version: devel

comment:2 Changed 11 years ago by Dave.Wilson@…

With the latest development version of Trac I also have a similar issue. For example… if I have a new ticket and attempt to resolve it, add a comment or some other action I have to hit refresh (even after hitting "Submit change") before the changes are visible on the ticket. This only happens with the newest Firefox so far - IE 6 doesn't do it.

comment:3 Changed 11 years ago by sonic_and_tails2000@…

I would also like to follow-up this issue on Opera and on devel v11-r6216. As of version 9.24, Opera seems to be not updating the changes properly. Not really a major issue but it can get quite annoying.

comment:4 Changed 11 years ago by Christian Boos

Keywords: verify added
Milestone: 0.11.1

comment:5 Changed 10 years ago by anonymous

I've encountered this behavior with Trac 0.11 + Apache 2.2. It affected both browsers used - Firefox 2.0.14 and IE 7.

I've changed all headers generated trac/web/api.py to prevent browser caching. I went through trac/web/api.py, found there 3 places where trac generates an http header and replaced all existed cache control options with following:

self.send_header('Pragma', 'no-cache') self.send_header('Cache-control', 'no-cache') self.send_header('Expires', 'Fri, 01 Jan 1999 00:00:00 GMT')

Apparently it solved the issue.

I didn't have an opportunity to investigate it deeper. However, the issue seems to be affected by authentication method used. With SSPI authentication it was similar to described by Dave.Wilson: I had to refresh page after a modification in order to see changes. Happened on both IE and Firefox (despite Firefox seems can't use SSPI and uses Basic instead). When I changed authentication to Basic I've been regularly seeing "logged in as" showing another user (e.g. Firefox shows a user logged on in IE or even from another machine). I've surely checked caching on Apache and to my best knowledge it is disabled there. The latter case make me think it isn't exactly a browser issue. Anyway the fix above have solved both issues.

comment:6 Changed 10 years ago by Christian Boos

Milestone: 0.11-retriage
Resolution: wontfix
Status: newclosed

I figure this problem has vanished.

If not, please reopen and give a concrete example that we could try to reproduce.

comment:7 Changed 10 years ago by anonymous

Resolution: wontfix
Status: closedreopened

Trac version: 0.11.4 Opera: 9.64 OS: Windows Vista

Exactly the same error as specified above. The cache is not invalidated, resulting in many annoying problems.

comment:8 Changed 10 years ago by anonymous

As an extension to my previous post: it works fine in IE and Firefox. The authentication method is Basic.

comment:9 Changed 9 years ago by Christian Boos

Keywords: opera added
Milestone: 1.0
Priority: normallow
Severity: normalminor

I still don't see exactly what the problem is.

Keeping the ticket around to remind me/someone to test more thoroughly Trac with Opera (I never noticed such an issue so far, but I only use Opera very seldom).

comment:10 Changed 9 years ago by anonymous

Trac 0.11.5, Apache2, CentOS, python 2.4

Problem on all browsers (IE7, FF3.5.4pre, Chrome2) - cant get the page to refresh even after hitting Ctrl+f5. Happens when I add a component (doesnt show up) or delete an existing component.

comment:11 in reply to:  10 Changed 9 years ago by Remy Blank

Replying to anonymous:

Happens when I add a component (doesnt show up) or delete an existing component.

That's not the same issue. You should make your trac.ini writable for the web server (or tracd).

comment:12 Changed 9 years ago by igloo@…

We had this problem for people behind a proxy. We think the problem may be that the proxy only understands HTTP 1.0, and thus not cache-control headers, but we may be wrong. This patch fixed it for us:

diff -ur orig/trac/web/api.py patch/trac/web/api.py
--- orig/trac/web/api.py    2010-01-28 12:11:08.000000000 +0000
+++ patch/trac/web/api.py   2010-01-28 12:12:43.000000000 +0000
@@ -351,6 +351,7 @@
     def send(self, content, content_type='text/html', status=200):
         self.send_response(status)
         self.send_header('Cache-Control', 'must-revalidate')
+        self.send_header('Expires', 'Fri, 01 Jan 1999 00:00:00 GMT')
         self.send_header('Content-Type', content_type + ';charset=utf-8')
         self.send_header('Content-Length', len(content))
         self.end_headers()

The other two places that a cache-control header is given, an expires header is already given.

comment:13 Changed 9 years ago by igloo@…

(that patch is made relative to the Debian trac 0.11.6-2 package)

comment:14 Changed 9 years ago by Christian Boos

Milestone: 1.0unscheduled

Milestone 1.0 deleted

comment:15 in reply to:  12 Changed 8 years ago by Alex

Trac 0.12.2 - Chrome, Firefox, IE8 - Win 7 - TracAccountManager 0.3dev-r10113 - LoginModule (acct_mgr.web_ui) enabled - Apache/fcgid:

Once logged in, users would have to manually refresh every page which they had previously visited anonymously in order for Trac to serve a non-cached/logged-in header. Applied igloo's patch above and issue was immediately resolved.

Thanks!

comment:16 Changed 7 years ago by bergamot

Trac 0.12 Firefox 5 - Win 7, Apache/2.2.3 Same for me. Microsoft proxy in between, so this might be the culprit. Patch makes the problem go away.

comment:17 Changed 7 years ago by Christian Boos

Milestone: unscheduled0.12.3
Owner: changed from Jonas Borgström to Christian Boos
Priority: lownormal
Status: reopenednew

Looks like a low risk change, 0.12.3?

comment:18 in reply to:  17 ; Changed 7 years ago by Remy Blank

Replying to cboos:

Looks like a low risk change, 0.12.3?

Won't this disable caching altogether (for send() only)? RFC:2616#sec-14 has the following to say about the Cache-Control: must-revalidate header:

When the must-revalidate directive is present in a response received by a cache, that cache MUST NOT use the entry after it becomes stale to respond to a subsequent request without first revalidating it with the origin server. (I.e., the cache MUST do an end-to-end revalidation every time, if, based solely on the origin server's Expires or max-age value, the cached response is stale.)

So with the Expires: header in the past, a revalidation will take place on every request. Is this what we want?

comment:19 in reply to:  18 ; Changed 7 years ago by Christian Boos

Replying to rblank:

So with the Expires: header in the past, a revalidation will take place on every request. Is this what we want?

Unless I'm mistaken, yes, that's exactly what we want: we don't want the client to keep using a cached version of dynamic content without trying to revalidate it first. When this revalidation happens, if the content has not changed, the ETag mechanism and check_modified() will prevent the request to complete (304) and the client will then be able to use its cached content.

comment:20 in reply to:  19 ; Changed 7 years ago by Remy Blank

Replying to cboos:

When this revalidation happens, if the content has not changed, the ETag mechanism and check_modified() will prevent the request to complete (304) and the client will then be able to use its cached content.

AFAICT, we only ever return a 304 when using req.send_file() or when calling req.check_modified() explicitly (currently for attachments and changesets). That means we will always re-send the content. But you are probably right, that's exactly what we want for dynamic content. A quick check shows that Drupal uses the same Cache-Control: and Expires: headers.

One question though: could it be that some code that currently uses req.send() doesn't want the Expires: header? If not, I'm ok with the change.

comment:21 in reply to:  20 Changed 7 years ago by Christian Boos

Replying to rblank:

One question though: could it be that some code that currently uses req.send() doesn't want the Expires: header? If not, I'm ok with the change.

Perhaps if we would dynamically generate CSS from templates, as we sometimes discuss? But even there, we would probably first generate a file and then send that file. So no, I can't think about one, for now.

comment:22 in reply to:  12 Changed 7 years ago by Christian Boos

Component: generalweb frontend
Release Notes: modified (diff)
Resolution: fixed
Status: newclosed

Replying to igloo@…:

We had this problem for people behind a proxy. We think the problem may be that the proxy only understands HTTP 1.0, and thus not cache-control headers, but we may be wrong. This patch fixed it for us

Thanks for identifying the problem and providing a patch!

Applied in r10775.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Christian Boos.
The resolution will be deleted.
to The owner will be changed from Christian Boos to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.