User tests: Successful: Unsuccessful:
The menu item Users > Logout recently introduced highlights an old time latent problem related to the cache.
Basically, while JApplicationWeb::respond() respects the fact that the page can be cachable or not, JApplicationWeb::redirect() totally ignores that fact.
As a result, redirections can be cached causing weird bugs.
One of them, is the inability to execute the log-out a second time. That is, you can login, then logout, login again, but from here to the cache expiration you won't be able to logout furthermore.
We didn't noticed this up to now, because the "Logout button" submits a form, and a POST request is never cached. The new "Logout menu item" is a GET request instead, which on the contrary can be cached.
Cache problem are tricky to reproduce and debug, due to the different way the various cache layers work and react to different inputs, (such as a simple URL request vs a page refresh). For that reason I'll explain how to reproduce the problem step by step.
I've verified this problem with Google Chrome. In my tests, Mozilla Firefox is not affected. I haven't tested further browsers.
Since the logout button is not affected, the problem can be observed through the Logout menu item, so prepare it. New menu item > Type = Users - Logout. Save and close.
To test this, you need to activate a cache layer between the web server and the client.
While a proxy should be fine for this purpose, I've used Apache module mod_expires instead, which is a common environment in many hosting providers. It's easy con configure and from the browser's point of view, it has a predictable behaviour.
mod_expires configuration follows:
1- Ensure that Apache mod_expires is enabled.
a2enmod expires
service apache2 restart
2- Set up the cache in the .htaccess.
ExpiresActive On
ExpiresDefault "now plus 1 hour"
This sets a one hour cache to all resources, such as images, js, css. php would be affected as well, but note that Joomla, while generating its HTML output, overrides this general settings by turning off any cache through appropriate HTTP response headers (see JApplicationWeb::respond()).
Open the "Network" console in Google Chrome, and browse any page of the Joomla website.
It's headers contains all the necessary anti-cache elements:
Cache-Control: no-cache
Pragma: no-cache
Expires: (a date in the far past)
See screenshot n.1.
So far, so good.
Now, login and logout using the "Logout menu item". The logout is successful, but note the absence of the necessary anti-cache elements. Also note the "Expires" date in the future.
See screenshot n.2.
The page can now be cached. We will have big problems soon.
Login again. Now there is no way to Logout by the "Logout menu item". By pressing the Logout menu item we get the page from the cache, and no PHP code is executed server-side.
See screenshot n.3.
The PR proposed simply uniforms the way that JApplicationWeb::respond() and JApplicationWeb::redirect() handle the cache-related headers.
See screenshot n.4.
After applying the PR, the redirect contains all the necessary anti-cache elements.
Status | New | ⇒ | Pending |
Labels |
Added:
?
|
Category | ⇒ | Libraries |
I see that there are a lot of errors, but I don't understand the cause.
The tests are validating the sent headers. You're making changes that add additional headers, so the expected return no longer matches the actual return.
yes that is correct. That way the version will be correctly set when it is
merged and you dont have to redo this if it is not released n 3.6.4
On 23 October 2016 at 17:41, Demis Palma ツ notifications@github.com wrote:
@demis-palma commented on this pull request.
In libraries/joomla/application/web.php
#12504:@@ -592,6 +574,43 @@ public function allowCache($allow = null)
return $this->response->cachable;
}+
- /**
- * Set all the necessary cache-related headers, based on the current value of $this->response->cachable,
- * which in turn can be set by the components controllers, in case of need, with JApplicationWeb::allowCache()
- *
- * @return void
- *
- * @since 3.6.4
I don't understand the suggestion.
Should I replace "@since https://github.com/since 3.6.4" with "@since
https://github.com/since DEPLOY_VERSION"?—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#12504, or mute the thread
https://github.com/notifications/unsubscribe-auth/ABPH8SJI-qOBEUlICBlVudGvsoezjnUrks5q244lgaJpZM4KduQ4
.
Brian Teeman
Co-founder Joomla! and OpenSourceMatters Inc.
https://brian.teeman.net/ http://brian.teeman.net/
Ok, I used the placeholder __DEPLOY_VERSION__
and I modified the tests according with the modifications.
In my test environment, all the tests are successful now, while on travis there are still 2 failures. I don't understand why.
In addition, the tests are not satisfactory yet.
The problem is that the method to be tested and the method that runs the test, they both run gmdate() function independently. It's highly probable that they runs during the same second, and the test completes successfully, but chances are that the second call to gmdate() falls into the following second, causing the test failure.
Since the function gmdate('D, d M Y H:i:s') . ' GMT' is called several time along the code, I would suggest to call it once for all and set a constant, a singleton, or a global variable, indicating uniquely the time of the main HTTP request, so that everyone can access it and be sure to get back a consistent value.
How to proceed?
Tests OK. To me the PR is complete for the moment.
I've found that 2 months later, this same patch has been proposed (and merged in 2 days) here: #13516
The reasons to keep a patch dormant for 4 months and counting, are beyond my understanding, but it's a pity that someone has to waste his time reinventing something that was already there, waiting to be merged.
Status | Pending | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2017-03-07 12:28:20 |
Closed_By | ⇒ | zero-24 |
Category | Libraries | ⇒ | Libraries Unit Tests |
you have a lot of unit tests failing here