Post by conandrum » Sat Nov 02, 2019 9:36 am

Using Opencart 3.0.3.2
I have developed a module for 2.3.0.2 & now converting it to 3.x. The module displays a list of products in the admin section of Opencart.
Each product has a button next to it which is meant as a toggle (enable/disable free shipping) to add/del free shipping to each product.

The button action is as follows:

Code: Select all

https://example.com/admin/index.php?route=extension/shipping/mymodule&user_token=W0nBWaeKPjpeHFSMb4QmCqmt3sW7hA6Z&product_id=422&active_tab=1&addfree
addfree is picked up in the controller by checking $this->request->get['addfree']
Some action is taken by the controller (database entry etc) and when the page is returned, the button action is changed to:

Code: Select all

https://example.com/admin/index.php?route=extension/shipping/mymodule&user_token=W0nBWaeKPjpeHFSMb4QmCqmt3sW7hA6Z&product_id=422&active_tab=1&delfree
So it toggles between add/del free shipping.

The problem is with caching:
In chrome when I click this toggle button, I can see that the response headers are:

Code: Select all

Cache-Control: max-age=900
Even if I disable caching from Dashboard Developer Settings, I still get the same as above.

My aim here is NOT to disable caching temporarily.
My goal is to disable caching completely whenever my module's URL is requested by the administrator who installed my module.

The only way I can get it to work as intended is by adding the following to my .htaccess file:

Code: Select all

     <ifModule mod_headers.c>
       Header set Cache-Control "no-cache, no-store, must-revalidate"
       Header set Pragma "no-cache"
       Header set Expires 0
     </ifModule>
The problem with using the above is obvious.
I only want to set these headers when it comes to my module.
I do not mind if my whole module has NO CACHING.

How do I achieve this with Opencart 3.x?

New member

Posts

Joined
Tue Jul 09, 2013 6:10 pm

Post by letxobnav » Sat Nov 02, 2019 10:06 am

that htaccess script is to prevent proxy and browser caching.
So leave that, why would you want browser caching in admin?

or if you must be selective, use php to set the headers in your script:

header("Cache-Control: no-cache, no-store, must-revalidate"); //browsers
header("Pragma: no-cache"); //HTTP 1.0 i.e. most proxies

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by conandrum » Sat Nov 02, 2019 11:02 am

Thank you letxobnav for replying so soon.
Until last week I never even installed 3.x. I am facing these issues because I want to convert my modules to 3.x. So I am very new to 3.x.

A.
You said: 'that htaccess script is to prevent proxy and browser caching. So leave that, why would you want browser caching in admin?'
Believe me I never expected to have browser caching in admin. I do not have browser caching in admin in 2.3.0.2 (where my module behaves properly). I was very surprised to have this problem in 3.x. Are you saying that you do not get browser caching in admin in your own 3.x installation?

B.
You said: 'or if you must be selective, use php to set the headers in your script:
header("Cache-Control: no-cache, no-store, must-revalidate"); //browsers
header("Pragma: no-cache"); //HTTP 1.0 i.e. most proxies'

My module does this when ready to send output to client:
$this->response->setOutput($this->load->view('extension/shipping/modularshipping', $data));
How would I go about setting these headers to go with my response?

Sorry, I have never had to do anything like this with previous OC versions.
I have no idea if what I am experiencing is normal until you answer A above. If it is normal then I will know how to build my modules from now on.
Seriously thanks for helping out.

New member

Posts

Joined
Tue Jul 09, 2013 6:10 pm

Post by conandrum » Sat Nov 02, 2019 11:59 am

CLARIFICATION:
I have the same module installed in a 2.3.0.2 installation and in a 3.0.3.2 installation. Both have virtually identical .htaccess files.
the URL is :

Code: Select all

https://example.com/admin/index.php?route=extension/shipping/mymodule&user_token=W0nBWaeKPjpeHFSMb4QmCqmt3sW7hA6Z&product_id=422&active_tab=1&addfree
The 3.x insists on loading my URL from disk cache with Cache-Control: max-age=900 as specified in the .htaccess

Code: Select all

ExpiresByType text/html                             "access plus 15 minutes"
The 2.3.0.2 loads the same URL with Cache-Control: no-store, no-cache, must-revalidate

I have no idea why this is happenning.
Any help appreciated.

New member

Posts

Joined
Tue Jul 09, 2013 6:10 pm

Post by letxobnav » Sat Nov 02, 2019 12:13 pm

OC has nothing to do with cache headers, the only place OC sets those is in the file download scripts, nowhere else.
Even the provided default htaccess file has no cache/expiration logic in it.
So for OC installations this is a pure htaccess/httpd.conf issue.

Somewhere in your new installation you are setting that max-age=900, default OC v3 has nothing to do with that.

but since installations differ and most have no idea about how the internet works (OC V3 development team included), I always advice to set cache headers in OC V3 via the framework for the response class.

This means that any output coming from that class in not proxy and/or browser cached as it should be.
This does not involve static assets like js, css, images, etc which should be cached via httpd.conf/htaccess settings

in system/framework.php you change:

Code: Select all

// Response
$response = new Response();
$response->addHeader('Content-Type: text/html; charset=utf-8');
$response->setCompression($config->get('config_compression'));
$registry->set('response', $response);
into:

Code: Select all

// Response
$response = new Response();
$response->addHeader('Content-Type: text/html; charset=utf-8');
$response->addHeader('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
$response->addHeader('Pragma: no-cache');
$response->setCompression($config->get('config_compression'));
$registry->set('response', $response);

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by letxobnav » Sat Nov 02, 2019 12:15 pm

You have to clear your browser cache because it will use what it has until it expires, and no, shift+F5 will not do.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by conandrum » Sat Nov 02, 2019 12:32 pm

letxobnav wrote:
Sat Nov 02, 2019 12:13 pm
OC has nothing to do with cache headers, the only place OC sets those is in the file download scripts, nowhere else.
Even the provided default htaccess file has no cache/expiration logic in it.
So for OC installations this is a pure htaccess/httpd.conf issue.
Somewhere in your new installation you are setting that max-age=900, default OC v3 has nothing to do with that.
Both in 3.x & 2.x installations I have this 900s for text/html.
Problem is that 3.x picks it up for all its responses, whereas 2.x does not.

letxobnav wrote:
Sat Nov 02, 2019 12:13 pm
I always advice to set cache headers in OC V3 via the framework for the response class.
This means that any output coming from that class in not proxy and/or browser cached as it should be.
Is this something that they changed in 3.x? Is this why I have this difference between the 2 versions?

letxobnav wrote:
Sat Nov 02, 2019 12:13 pm

Code: Select all

// Response
$response = new Response();
$response->addHeader('Content-Type: text/html; charset=utf-8');
$response->addHeader('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
$response->addHeader('Pragma: no-cache');
$response->setCompression($config->get('config_compression'));
$registry->set('response', $response);
So if I am to sell this module to customers, I have to advise them to make the above change to their installation.

New member

Posts

Joined
Tue Jul 09, 2013 6:10 pm

Post by conandrum » Sat Nov 02, 2019 12:38 pm

Are they basically allowing us to cache the 3.x responses using the ExpiresByType text/html directive in .htaccess?
I am guessing that this was not an option in 2.3 based on our discussion.?

New member

Posts

Joined
Tue Jul 09, 2013 6:10 pm

Post by letxobnav » Sat Nov 02, 2019 1:02 pm

Both in 3.x & 2.x installations I have this 900s for text/html.
Problem is that 3.x picks it up for all its responses, whereas 2.x does not.
Well, I guess your problem is with your httpd.conf or your htaccess file
The only thing that picks up headers are the recipients which in this case are the browsers.
The only one sending headers is your web server via httpd.conf, htaccess or scripts
Is this something that they changed in 3.x? Is this why I have this difference between the 2 versions?
nope, V2 also does not set cache-control headers except for file downloads
So if I am to sell this module to customers, I have to advise them to make the above change to their installation.
Nope, your customers should already have the right headers for browser caching, i.e. do not cache html! or their cart would not function properly
They either have that set in their httpd.conf or their htaccess.
If not, we will see them pop up in this forum as we have many times.

But many simply copy htaccess from the internet which has a default expires header set which then also applies to html or they specifically set html expires headers for 1 week in the future because it makes their pages load so fast, the problems start from there.
In other words, if your customers allow browser caching of their html output, they have more problems than your module.

These headers which are send along with the html output override any previously send cache control headers for html.
So if their installation is wrong on that, this will correct it.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by conandrum » Sat Nov 02, 2019 1:17 pm

Thanks for your help.

I followed your directions and modified the framework.php file.
I cleared my local cache in Chrome.
I set ExpiresActive off in .htaccess.

My URL does not load from disk anymore, but I cannot get any 'Cache-Control' !!!
Can you think of any reason why?

The response headers I get:
Connection: keep-alive, Keep-Alive
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Sat, 02 Nov 2019 05:11:08 GMT
Keep-Alive: timeout=5, max=100
Location: https://example.com/admin/index.php?rou ... tive_tab=1
Server: Apache
Set-Cookie: OCSESSID=104e728dafd3bfb5fe6179b597; path=/
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN

New member

Posts

Joined
Tue Jul 09, 2013 6:10 pm

Post by letxobnav » Sat Nov 02, 2019 1:30 pm

is https://example.com/admin/index.php?rou ... tive_tab=1
a page that is send to the browser?

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by letxobnav » Sat Nov 02, 2019 1:47 pm

these are normal response headers you should get in admin for html, same in the catalog actually

cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
content-encoding: gzip
content-length: 4224
content-type: text/html; charset=utf-8
date: Sat, 02 Nov 2019 05:42:13 GMT
expires: Sat, 02 Nov 2019 05:42:13 GMT
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
server: Apache
set-cookie: OCSESSID=4705515538d551262b843cb574; path=/; domain=xxxxxxxx.com.tw; secure; HttpOnly
status: 200
strict-transport-security: max-age=63072000; includeSubdomains; preload
vary: Accept-Encoding,User-Agent
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block

are you hosted?
if so, did you ask your host what they are setting in httpd.conf?

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by conandrum » Sun Nov 03, 2019 1:04 am

letxobnav wrote:
Sat Nov 02, 2019 1:47 pm
are you hosted?
if so, did you ask your host what they are setting in httpd.conf?
Sorry for the confusion. It is because I have both OC 2.x & 3.x open side-by-side and I am comparing the response headers from the same action.
First of all let me say that your solution is actually working 50%.
Secondly, I am on my own personally managed VPS. My apache2.conf & sites-available/example.com.conf has nothing special.
Thirdly, both 2.x & 3.x .htaccess file have 'ExpiresByType text/html "access plus 15 minutes"'

A.
So , with your modification enabled in framework.php, when I click my button...

Code: Select all

route=extension/shipping/modularshipping&token=NuGW9RJ0GvW5T8A27P9TgZmoRuEtR0dg&product_id=422&active_tab=1&addfree
...it does some things at the server and then redirects to the same URL without the parameter addfree (so that the action is not repeated by accident):

Code: Select all

route=extension/shipping/modularshipping&token=NuGW9RJ0GvW5T8A27P9TgZmoRuEtR0dg&active_tab=1
So in Chrome I have the above 2 URLS, the 1st with 302 status and the 2nd with 200 status.
In my previous post I said that I was not seeing any 'Cache-Control' headers.
This is true for the 3.x module, and the 1st URL with 302 status (this is why I said it is working 50%).
The 2.x module, 1st URL with 302 status, actually has 'Cache-Control: no-store, no-cache, must-revalidate'.
However, if I check the second URL (with status 200), which is the URL which the user will see, I get virtually the same response headers for both 2.x & 3.x modules (because of your solution).
There is still a problem with the headers in the redirection (302) in 3.x!!!

B.
with your modification disabled in framework.php, when I click my button...
2.x works as above.
3.x both 302 & 200 URLs pick up the headers from .htaccess and are loaded from 'disk cache' in Chrome.

Conclusion:
Both 2.x & 3.x are virtually identical but I can see a definite difference in how 2.x & 3.x handle headers.
I have no idea how 2.x adds 'Cache-Control: no-store, no-cache, must-revalidate' to its responses, thus avoiding the 'ExpiresByType text/html "access plus 15 minutes"' directive in its .htaccess. I have not made a modification to it in order to do so.
Contrast this with 3.x, where I have to make a modification to framework.php in order to avoid the same directive.

IMPORTANT: If you do not add a 'ExpiresByType text/html "access plus 15 minutes"' directive in .htaccess, you will not face these issues and you will not need to modify framework.php in order to bypass it.

Question:
In my 2.x I found custom 'Cache-Control' headers in the following files:

Code: Select all

\admin\controller\extension\payment\securetrading_ws.php
\admin\controller\journal3\import_export.php
\admin\controller\tool\upload.php
\catalog\controller\account\download.php
\catalog\controller\ebay\openbay.php
\catalog\model\extension\openbay\ebay_openbay.php
So I do not know why I am seeing 'Cache-Control' to the responses from 2.x. It should be behaving just like 3.x and I should be experiencing the same problems - but I am not! Do you know why?

New member

Posts

Joined
Tue Jul 09, 2013 6:10 pm

Guru Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

Post by conandrum » Sun Nov 03, 2019 8:39 am

ADD Creative wrote:
Sun Nov 03, 2019 8:21 am
See https://github.com/opencart/opencart/issues/7008 for an explanation.
I saw that, but did not immediately recognize a relation to my issue.
Are you sure this is related to my issue? Thanks for your input.

BTW, I have created a small extension module, which includes only a single button which does a redirect.
For the life of me, I cannot get the redirect to STOP BEING CACHED by the browser!!! Even manually adding headers before the redirection!

Can anybody suggest a solution to this?
Attached is the module (2 files, controller & twig), play with it.

Attachments


New member

Posts

Joined
Tue Jul 09, 2013 6:10 pm

Post by conandrum » Sun Nov 03, 2019 9:22 am

I have started a new thread which is more to the point here:
viewtopic.php?f=202&t=214613

New member

Posts

Joined
Tue Jul 09, 2013 6:10 pm

Post by ADD Creative » Mon Nov 04, 2019 12:49 am

My links explains why you see cache control headers in 2.x and not 3.x.

As to why your code functions definitely between versions . This, I believe down to the response class. As letxobnav explained here. viewtopic.php?f=202&t=214613#p768266

Looking at the code, headers are set on this line for response->output. https://github.com/opencart/opencart/bl ... e.php#L114

But for response->redirect no headers are set, other than the redirect header. After which exit() is called ending the PHP script. https://github.com/opencart/opencart/bl ... hp#L35-L38

So if you use response->redirect any header set by response->addHeader will not be used. As OpenCart 2.x uses PHP sessions as long as session_start() is cal before response->redirect (which it is) PHP will internally set the correct cache control headers, regardless of weather you set any headers or not.

If you don't want your web browser to cache redirects with version 3.x you have a few options, including.

1. Don't set the cache control header to have an age in your .htaccess for text/html. Set them to no cache.

2. Modify the response class redirect method to include the headers that have been set with addHeader.

3. Set the cache control headers with header() instead of response->addHeader().

www.add-creative.co.uk


Guru Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

Post by conandrum » Mon Nov 04, 2019 1:03 am

I want to thank you for your concise response.
Your quote below is absolutely on-the-money!
ADD Creative wrote:
Mon Nov 04, 2019 12:49 am
As OpenCart 2.x uses PHP sessions as long as session_start() is cal before response->redirect (which it is) PHP will internally set the correct cache control headers, regardless of weather you set any headers or not.
ADD Creative wrote:
Mon Nov 04, 2019 12:49 am
If you don't want your web browser to cache redirects with version 3.x you have a few options, including.
1. Don't set the cache control header to have an age in your .htaccess for text/html. Set them to no cache.
2. Modify the response class redirect method to include the headers that have been set with addHeader.
3. Set the cache control headers with header() instead of response->addHeader().
I will try to work with #3 above. I think it will work.
I hope other people will read your reply and learn something instead of repeating what we already know and trying to convince people that #1 is the only solution - that is beyond me!
Thanks again.

New member

Posts

Joined
Tue Jul 09, 2013 6:10 pm
Who is online

Users browsing this forum: No registered users and 80 guests