If a module sends out a message and then Drupal redirects to a page that be cached, the message shown on that page is cached too.
Steps to reproduce (example):
[as an admin]
- activate the contact module and set things up so that the contact form is available to anonymous users
- activate caching in normal mode
- make sure your default page in site configuration is a node (not "node", but "node/1", "node/23", etc.)
[as anonymous user (ex. using another browser and not logging in)]
- visit the contact form and send a message
- you are now redirected to the default page, where a confirmation message appears ("Your message ave been sent")
- reload the page with the browser's reload button
- you shouldn't see now the message, but you see it again
- visit the site as another anonymous user (use another browser, or another PC)
- you'll see the message even if you're another anonymous user
After, you've followed these steps, you can go back to administration and update the node you defined as default page: you'll see that the message disappears from the anonymous user view. So, caching works as expected, only it shouldn't cache messages with nodes.
For the contact form, the issue is just a little more than a visual annoyance; but if you use Simplenews and allow anonymous users to subscribe, the latest subscription confirmation (with the e-mail address of the subscriber) remains visible to al anonymous visitors of the default page (ugly!).
http://drupal.org/node/150852 shows that the issue dates at least back to 5.1
This happens to me on Apache 2, PHP 5.2.2, MySQL 5.0.24
| Comment | File | Size | Author |
|---|---|---|---|
| #36 | cache-anon.patch | 1.98 KB | catch |
| #28 | pgsc_HEAD.patch | 1.82 KB | gábor hojtsy |
| #25 | x.patch | 768 bytes | chx |
| #24 | bootstrap-fix-page-cache-168909-24.patch | 677 bytes | cburschka |
| #15 | pgsc_3.patch.txt | 1.76 KB | gábor hojtsy |
Comments
Comment #1
flevour commentedAlas, after following your instructions carefully, I can't reproduce this bug.
Even with aggressive caching turned on things work smoothly (reloading home page makes message disappear).
It looks like a browser+server+other_unguessable_variables issue to me. Since things work as expected in the vast majority of the cases, I'd look into some $_SESSION handling issues (?). You may try to var_dump($_SESSION) at the end of each page load and see what goes? But this wouldn't explain the cross-browser part of the issue...
I am running PHP 5.2.1 and Apache 2.2.3 Multi-Processing Module (MPM) (in ubuntu).
Unreproducible bugs are weird, anyway.
Comment #2
Pinolo@www.drupalitalia.org commentedI have 2 sites on the same Drupal installation. Both have a very basic setup. One shows the problem, the other doesn't. I have also verified this is not theme (template.php) related, since I was able to reproduce the bug with the stock Garland. I have also verified the settings.php files and they're identical, except for the db connection line.
The core is an unpatched 5.2 checked out from CVS, modules are all from the 5 branch of contrib.
Modules enabled for the installation WITH issue
Core (opt)
Color
Comment
Contact
Help
Locale
Menu
Upload
Mail
Mime Mail
Simplenews
Other
FCKeditor
Views
Views
Views RSS
Views Th. Wiz
Views UI
Modules enabled for the installation WITHOUT issue
CCK
Content Templates
Content
Content Copy
Date
Fieldgroup
Image
Option Widgets
Text
Core (opt)
Comment
Contact
Locale
Menu
Path
Taxonomy
Upload
Other
BUEditor
Taxonomy Context
TinyMCE
Views
Views
Views RSS
Views Th. Wiz
Views UI
Comment #3
coreyp_1 commentedI can confirm the bug. My forum post can be found here.
In my post, I mention that I cannot reproduce the bug on my localhost (possibly because it cannot send e-mails), but I can reliably re-create it on my web host.
This would seemingly be a critical bug, because cache is, in essence, broken.
It may only be manifesting itself when the front page is a node, rather than a module-generated pages.
Comment #4
kndrI've got this bug in clean instalation of Drupal 6.0-rc4. Here is an issue http://drupal.org/node/219652
Comment #5
catchhttp://drupal.org/node/219652 was duplicate. See also this forum report: http://drupal.org/node/205521
Moving to 6.x - bugs get fixed in the development release then back ported.
Comment #6
chx commentedComment #7
kndr#6 works for me in Drupal 6.0-rc4. Great! I've just also tested it on Drupal 5.x with Simplenews and it works too. Very good news!
Comment #8
chx commentedThen it's RTBC.
Comment #9
moshe weitzman commented@chx - can you explain whats wrong with the current code that it causes thus bug? your new code looks good but i am missing the "why".
Comment #10
chx commentedI suspect some php goof here , we basically used ob_get_contents as our gatekeeper which apparently fails. I instead pass a flag "yes i did start ob!" and then recounting messages is not needed at all. Even the request method is not absolutely necessary but I left it in as a sneaky hacky way to stop page set cache for whatever reason.
Comment #11
gábor hojtsypage_get_cache() already checks for uid and the GET method, so this looks like some code duplication there. (If not for micro optimized speed, to avoid a function call, then I don't see why to do it). Even if the page was cached, page_get_cache() should return FALSE under these conditions with uid != 0 or !GET.
Comment #12
gábor hojtsyHere is an updated patch with some phpdoc improvements as well. Please test.
Comment #13
kndr#12 works good in my Drupal 6.x and 5.x instalations .
Comment #14
chx commentedHm, I left in the user uid checking because you might get logged in during the page run and I left in the request method caching as I stated above so that there is a sneaky way of disabling page set cache just in case. Not a terrible code duplication, I say.
Comment #15
gábor hojtsyIndeed, the user might have been logged in since the request started. OK, brought these two conditionals back. Thanks kndr for retesting. Committed the attached one. RTBC for 7.x as well.
Comment #16
cburschkaHow would you sneakily disable it - by setting REQUEST_METHOD to something other than GET manually?
Also, is your complaint with #12 that the status gets stored statically and checked only once?
Comment #17
cburschkaCross-post.
Comment #18
chx commentedExactly, by setting REQUEST_METHOD. It is a hack, but how often do we need page_set_cache disabled? Extremely rarely so we do not need a full fledged API to disable it but leaving a catdoor open is good.
Comment #19
kndrOuch! Did you check cache_page table? There is no records, no cached pages! Sorry. I did not check this. It looks that cache is turned off by this patch. Am I wrong?
Comment #20
cburschkaDo you mean {cache_page}? I will test to see if I can reproduce this.
Comment #21
cburschkaReproduced, alas. Page cache mode is set to normal, I am browsing as an anonymous user, and try as I might I cannot get {cache_page} to gain any records.
Edit: Aggressive caching with minimum lifetime of one day makes no difference either. I will add some debugging output to trace this issue...
Comment #22
cburschkaOdd. Adding a var_dump call to the function has produced bool(true) at the start and end of the page (expected), and also I now have a record in {cache_page}.
I hate it when this happens. Trying to remove the var_dump again to see if this really does it. If it does, I am stumped.
Edit: s/page_cache/cache_page
Comment #23
cburschkaWell, good news (good?) and bad news:
1.) {cache_page} is indeed only filled with the following code:
2.) {cache_page} will contain "test". Nothing else.
Perhaps we're inadvertently closing the output buffer somewhere before output is actually started?
Edit: s/page_cache/cache_page
Edit2:
Might this do it?
Or this?
I got this weird suspicion we may be starting the buffer twice.
Comment #24
cburschkaI've solved the problem by using !$status as in the second of the three code blocks above. page cache now works as advertised.
I don't know the policy here. Do we have to roll-back and re-roll the complete patch, or is it enough to tack on this new fix in a separate patch?
Here it is, anyway.
Comment #25
chx commentedComment #26
catchlooks like a cross post to me.
Comment #27
cburschka(This is a cross-post too, but luckily I got the email alert and can keep the status updated in this form...)
I guess either of these fixes work. Just to be safe, however, why not check the $status as well (as mine does)? If we're already paranoid about ob and setting our own flag, we might as well prevent ourselves from starting ob more than once by actually using the flag there.
Comment #28
gábor hojtsychx's patch was more in line with what we would do. The $status_only flag is just a parameter to ask for the status recorded statically from the beginning of the page request, so no need to go into the other parts of the function, and waste our time there (additionally to causing bugs by opening new output buffers). Arancaytar, thanks for the analysis, but I think chx's patch is better this time.
Committed his patch to 6.x and attaching a combined patch which was rolled against HEAD. This one is to be committed to 7.x.
Comment #29
catchNever got applied to D7 by the looks of things (and still applies).
Comment #30
Drupalr commentedmy post below has been fixed. my problem was not related to caching. FYI, it was due to debug output from a hook in using multiping:
http://drupal.org/node/245554
++++++++
Does this problem manifest as messages such as
appearing in a box (green) above the node??
I'm seeing this in a clean install of 6.2 with caching enabled.
Comment #31
michelleAny chance of getting this applied to 5.x as well?
Michelle
Comment #32
scriptnews commentedHi
this issue has not been responded to as far as I could find.
The only fast way to stop this appearing for me was commenting out / hacking the template.
Pretty poor solution, but it does the job.
Seems that V6 is just not ready for "simple" public use.
Cheers
Roland
Comment #33
litwol commentedI've implemented javascript side messages setting and getting in my js_theming project.
This approach could be leveraged to solve the problem we are having. i dont know how the end result will be reached but this could be the first step to invoke messages through javascript rather than printing them via php.
more information at: http://drupal.org/project/js_theming
Comment #34
catchStill applies to 7.x with offset.
Comment #35
damien tournoud commentedProbably doesn't apply anymore now that #231190: Page Cache doesn't work with HEAD requests gone in.
Comment #36
catchVery true. This is a straight re-roll of #28.
Comment #37
damien tournoud commentedI suggest the following plan: this can go in for D7 as is, but we'll need a test for it.
Comment #38
catchIMO we shouldn't hold up small yet critical/out of sync bug fixes due to tests getting written - at least not until core has zero known test failures. Testing uptake is going to be slow until we can demonstrate that failed tests are down to people's own code rather than a buggy testing framework or buggy tests themselves.
For now I've opened a new issue for the tests at #284271: Tests for drupal_set_messages are cached for anonymous users and marked this back to needs review. Others may disagree of course, so feel free to change it back if I've not won you over ;)
Comment #39
damien tournoud commentedFine by me.
Comment #40
lilou commentedPatch #36 still applies.
Comment #42
lilou commentedSee: #335122: Test clean HEAD after every commit and http://pastebin.ca/1258476
Comment #43
catchAll tests have been passing for months, so we need one for this issue now!
Comment #44
dave reidTest along with alternate solution provided in #54238: page cache might show messages.
Comment #45
c960657 commentedSomething roughly similar to the latest patch was committed to HEAD a few days ago as part of #201122: Drupal should support disabling anonymous sessions. Does that fix this issue?
Comment #46
dave reidHmm...I'm not sure it does. I'll have to run the tests from #54238: page cache might show messages to see if they actually did fix it.
Comment #47
dave reidMessages are still in fact cached for anonymous users on HEAD.
Comment #48
chx commentedtagging
Comment #49
damien tournoud commentedThat should not happen anymore in D7. Does it apply to D6?
Comment #50
gpk commentedSetting version + status since it should be OK for D7 (certainly I've not seen any problems).
Comment #51
dariogcode commentedI had same problem, but i fixed checking my user table and I found that mysql client change uid = 0 (anonymous) to 11 (or something). I change to 0 again and it work like a charm.
Comment #52
roald commentedI'm having this issue in Drupal 6.19 with pagecache turned on. Has the issue been fixed and then re-entered at a later version?
Roald
Comment #53
dpearcefl commentedIs this still an active issue?
Comment #54
damienmckennaDemoting this due to inactivity for over a year.