HTTP Headers For Cache Control

Please bear with me. I know the topic of cache control via .httaccess has been discussed at length already on this site. The problem is that I’ve browsed through several threads on this and other forums and they all assume prior knowledge I happen to lack. I’ve read several tutorials and they all cover the topic in the same broad brush strokes.

I need the basics. What language/s are HTTP headers written in? PRECISELY how are HTTP header to be formatted? Where do they go?

I’ve figured out that my server (Hosmonster) has an .httaccess file in my public_html folder. Here it is:

# Use PHP5 Single php.ini as default
AddHandler application/x-httpd-php5s .php

RewriteEngine on
RewriteCond %{HTTP_HOST} ^drumdr\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.drumdr\.com$
RewriteRule ^hand\-drum\.html$ "http\:\/\/drumdr\.com\/hand\-drums\.html" [R=301,L]


# Start CloudFlare:drumdr.com rewrite. Do not Edit 
RewriteEngine On 
RewriteCond %{HTTP_HOST} ^drumdr.com 
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L] 
# End CloudFlare rewrite. 

I don’t understand any of this, but I would guess this is a PHP script. Am I wrong?

Any help would be appreciated.

HTTP headers aren’t written in any language as such, but they do follow a format which is defined as part of the HTTP specification. They are plain text key-value pairs, written in the format:

Header-Name: value

and sent before the body (content) of a HTTP request.

No, this is a format specific to configuration files for the Apache web server software. You can set options in this file that instruct Apache to send various kinds of headers.

For example:

<IfModule mod_expires.c>
    ExpiresByType image/jpeg    "access plus 1 month"
</IfModule>

The enclosing IfModule tags check if the necessary Apache module is loaded (to prevent errors) and the line in-between says that all JPG images should be cached for a month. This would result in header like this being sent:

Expires: Tue, 13 Jan 2015 12:51:00 GMT
1 Like

Thank you fretburner.

So, because my server is Apache based, the key-value format would not be appropriate? I should familiarize myself with Apache’s requirements?

Perhaps not by coincidence, my site is image-intensive, so I would want to do something very similar to your example, though I would also want to include other image formats for logo, background, etc.

For other image formats try this:

RewriteEngine On
# compress all text and html:
AddOutputFilterByType DEFLATE text/html text/plain text/xml
# Or, compress certain file types by extension:
<FilesMatch "\.(js|css)$">
    SetOutputFilter DEFLATE
</FilesMatch>

<IfModule mod_expires.c>
ExpiresActive On
<FilesMatch "\.(gif|jpg|png|ico)$">
    ExpiresDefault "access plus 10 years"
    FileETag none
</FilesMatch>

<FilesMatch "\.(js|css)$">
    ExpiresDefault "access plus 7 days"
    FileETag none
</FilesMatch>
</IfModule>

I use an Apache server and the following free tools to try and squeeze the last few milliseconds from rendering:

They both have detailed explanations of “How your site could be improved”.

Another way you could squeeze a bit more is to lose the if checking every HTTP request

<IfModule mod_expires.c>
ExpiresActive On
<FilesMatch "\.(gif|jpg|png|ico)$">
    ExpiresDefault "access plus 10 years"
    FileETag none
</FilesMatch>

<FilesMatch "\.(js|css)$">
    ExpiresDefault "access plus 7 days"
    FileETag none
</FilesMatch>
</IfModule>

Such checks have a place when it’s unknown whether or not where it’s being used has the module or not, but surely you know whether or not you do, no?

1 Like

I appreciate your attempt to help. As with other examples I’ve come across, this is of no use to me, since I lack the knowledge you assume.

I’ve begun to read Apache’s documentation in the hope of gaining some understanding. In the meantime, I copied and pasted your snippet into my .htaccess file just to see what would happen. Nothing.

I appreciate your attempt to help. As with other examples I’ve come across, this is of no use to me, since I lack the knowledge you assume.

I’ve begun to read Apache’s documentation in the hope of gaining some understanding. In the meantime, I copied and pasted your snippet into my .htaccess file just to see what would happen. Nothing.

It means that once you know that the code works you can delete the first and last lines (the ifmodule wrapper around the code that tests if the module is installed). If the module is installed now it will be installed every time someone accesses it.

2 Likes

Please show the contents of your .htaccess file. I believe the statement order may have a bearing on the outcome.

Please also explain in detail what you mean by “Nothing.”

I mentioned in post #4 about using http://tools.pingdom.com/fpt/ to optimise you site.

Just checked the link

**recommendations for your site:**
Combine external JavaScript
Leverage browser caching
Minimize DNS lookups
Remove query strings from static resources
Serve static content from a cookieless domain
Specify a cache validator	
Minimize redirects
Specify a Vary: Accept-Encoding header

Perf. grade: 78/100
Load time: 1.17s
Requests: 51
page Size: 535.2kB

There are detailed explanations regarding each recommendation so it looks like you are going to be busy over the coming holidays :slight_smile:

Thanks felgall. The problem is that you too seem to assume I have some understanding. I do not.

But, as I mentioned, I’ve begun to read Apache’s documentation and am beginning to think that I need to to activate mod_headers and/or mod_expires, which seems relevant to your observation.

John,

Please find the exact contents on my original post. I’ve tried pasting the example snippets at the beginning and at the end of the original.

I clear my browser’s cache (This may or may not make a difference. I don’t know!) then use several of the online tools to check response headers before and after. No change. That’s what I mean by “Nothing”.

As I mention to felgall, at this point I’m leaning towards activating mod_headers and/or mod_expires, but I have a lot of reading still to do.

I seem to have made a bit of progress. I’ve added the following code to my .htaccess file:

<ifModule mod_headers.c>
ExpiresActive On
 
# Expires after 1 month
<filesMatch ".(gif|png|jpg|jpeg|ico|pdf|js|htm|html|txt)$">
Header set Cache-Control "max-age=2592000"
</filesMatch>
 
# Expires after 1 day
<filesMatch ".(css)$">
Header set Cache-Control "max-age=86400"
</filesMatch>
</ifModule>

When I use an online tool to check the response header, I get something like:

SERVER RESPONSE: HTTP/1.1 200 OK
Date:
Mon, 29 Dec 2014 22:54:24 GMT
Content-Type:
text/html
Connection:
keep-alive
Set-Cookie:
__cfduid=de8fa6f062922d507d0c7677af25251a01419893664; expires=Tue, 29-Dec-15 22:54:24 GMT; path=/; domain=.drumdr.com; HttpOnly
Last-Modified:
Sat, 22 Nov 2014 01:48:01 GMT
Vary:
Accept-Encoding
Cache-Control:
max-age=2592000
Server:
cloudflare-nginx
CF-RAY:
1a09944ba06c0f27-IAD

So it seems that I’m at least setting some kind of cache control, but when I check my site with Google’s PageSpeed Insights the indication is that this has had no effect. The suggestion offered is exactly the same as before.

Still scratching my head.

I think the problem is that you are seeing the cached Cloudflare results.

No changes on your Hostmonster site will make any differences until you delete pages on your Cloudflare site. Once they are gone Cloudflare will obtain the latest version from your Hostmonster site and continue to display the latest result.

Even if your Hostmonster site goes down you will still be able to see your cached Cloudflare web pages.

Thanks for the suggestion John. This actually occurred to me and wondered if there’s a way to make sure that the very latest version of my site is being accessed.

Of course, I’m not sure if you’re referring to the results from the PageSpeed Insights or the header checking tools. I can tell you that with the current version of my .htaccess file PageSpeed Insights registers no change whatsoever, whereas the header checkers will reflect changes immediately.

By the way, along the way I’ve determined that, according to their Help Techs, HM uses CentOs rather than Ubuntu and is an XAMP installation rather than NGINX. I know all these detail make a difference somewhere along the way, I just haven’t figured it all out yet.

In my common footer I have the version no displayed. I don’t think a remark in your header will show but note what is currently displayed and see if you can make some changes which do show.

You were right John, and it only took a click to to purge Cloudflare’s cache. Pagespeed Insights now acknowledges my efforts, but I still have a lot to learn and a lot of fine tuning to do.

The more I learn the more complicated things get. For example, I mentioned that my server uses an XAMPP installation, but the reverse proxy server (Cloudflare) goes with NGINX. Does this explain why the snippets suggested had no effect?

Thank you all.

1 Like

I used to use Cloudflare when running on a slow server (a Godaddy Shared Hosting Scheme).

Normally your host server .htaccess files filter requests from routers and forward the relevant web page and content to the users’s browser.

As far as I know, Cloudflare only saves web pages and the relevant content on their numerous servers which are scattered around the globe.

When a user requests a webpage (URL - Uniform Resource Locator) the nearest Cloudflare server first checks if it has a copy of your web page. If it does not have a copy of your web page then it requests a copy from your server and duplicates your web page on various Cloudflare servers before sending a copy of your web page and content to the user.

Any future user requests bypass your server (and your server .htaccess file) completely!

The specific location of a user’s requests is used and the web page is delivered from the nearest Cloudflare server. eg The Brits’ are supplied web page copies from Europe, Yanks get copies from USA, Aussies get copies from Australia, etc. Each request gets the nearest Cloudflare copy and minimizes the distance that the web page has to travel.

Any changes uploaded to your web server do not take effect until Cloudflares’s copies are purged. Then the URL cycle starts again.

Does this explain why the snippets suggested had no effect?

Maybe someone else can supply a more lucid explanation.

This seems to explain why the suggested snippets had no effect on Google’s PageSpeed Insights but not why they had no effect on the header checking. Remember, once I added the snippet I currently have in the .htaccess file, the header checking tools recognized it even before I purged CloudFlare’s cache.

I was under the impression that .htaccess was accessed on EVERY request, with the implication that it was not cacheable.

I just initiated a live chat with HM’s Help, so I should be able to get a couple of answers. Will get back on this.

So it turns out that .htaccess is NOT cacheable (https://support.cloudflare.com/hc/en-us/articles/200172516-Which-file-extensions-does-CloudFlare-cache-for-static-content-), though I bet there are exceptions. Who knows what effects things like redirects and such have on the whole process.

The more I learn the more complicated it gets.

1 Like

So I’ve managed to implement some cache control sufficiently to satisfy PageSpeed Insights and other performance monitoring tools. I still don’t understand much of what’s involved in cache control (I don’t know why the snippet suggested had no effect, for example [though I have ideas]), but I though I’d spell out some of the key points I HAVE figured out. Some of you may find it useful.

  1. Apache is probably the most widely used web server software, but not all web servers use Apache. Those that do use different versions (releases). The first thing to do is figure out exactly what software your web server is using.

  2. Read the documentation for the specific release of the web server software that applies to you. I found Apache’s documentation to be quite succinct and digestable. Most anyone should be able to get a least a tentative handle on it in a reasonable amount of time.

  3. According to Apache “You should avoid using .htaccess files completely if you have access to httpd main server config file.” The main reason for this is improved performance. I have a shared server account and had no choice but to use the .htaccess file.

  4. If you have no access to the main server configuration file, you’ll need find out (through their documentation or by asking them) what modules have been enabled. You’ll want to know what AllowOverride has been set to.

  5. You’ll want at least a basic understanding of what goes on with your server’s reverse proxy, if applicable.

I hope this is helpful to anyone having problems similar to those I’ve had. I hope those who know more than I will point out where I’ve erred and fill any major gaps.

jcmcobra