Forum Moderators: phranque

Message Too Old, No Replies

htaccess last-modified usage

htaccess last-modified

         

sneskid

5:27 am on Nov 30, 2006 (gmt 0)

10+ Year Member



Sorry for these noob questions, it's tricky to find quality info on google about htaccess.

I'm somewhat new to htaccess. I realized a few months back it's crucial to good web design, and it would be wreckless not learning about it. Right now I'm aiming for cache control.

To my understanding: if a user agent it smart enough to request the last-modified header (or Etag), and there's a match, it won't d/l the file again. If htaccess is the one to provide that info, then a PHP script (if such was the file in question) won't even have to run. Right?

This is important to me because I've noticed a bare PHP script eats up 7 megs or ram. Sure php can do headers, but 7 megs is a huge overhead for something so simple.

How should I use last-modified on files with htaccess, as well as Etag if you happen to know.

Is it a good idea to put the last-mod header in a <files> tag?
ex:
<files something.htm>
Header set last-modified "Sun Jul 18 00:32:50 EDT 2004"
</files>

I can always modify the date with a php/perl script when it changes. But is there a way for htaccess check the real file mod-date?

Is these proper syntax?
<files something.htm *.html *.php whatever.pl start*end.p*p>
Would that last one require a regular expression?

Also what's the difference in using "Header set/unset/append"?
I'm pretty sure I understand them, but a proper explanation would be nice.

Thanks.

phranque

7:54 am on Nov 30, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



you should be aware that .htaccess is intended for directory level control.
you can do things more efficiently using server directives in the config file.
just make sure directory level is the reason you are using htaccess.


To my understanding: if a user agent it smart enough to request the last-modified header (or Etag), and there's a match, it won't d/l the file again. If htaccess is the one to provide that info, then a PHP script (if such was the file in question) won't even have to run. Right?
...snippage..
Is it a good idea to put the last-mod header in a <files> tag?
ex:
<files something.htm>
Header set last-modified "Sun Jul 18 00:32:50 EDT 2004"
</files>

I can always modify the date with a php/perl script when it changes. But is there a way for htaccess check the real file mod-date?


i'm not sure how the the requesting client could see the header for the "real file" without it being served by the script, unless you are actually cacheing the resulting documents.
the "Header set" directive will only be applied after the content handler and output filters do their thing, so you are still loading the script before you "get there".
see for details:
[httpd.apache.org...]


Is these proper syntax?
<files something.htm *.html *.php whatever.pl start*end.p*p>
Would that last one require a regular expression?

your wildcarding looks correct here.

jdMorgan

2:41 pm on Nov 30, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Be aware that <Files> takes as its argument a single filename, not a list. I'm not sure if you meant that list notation literally or not...

<FilesMatch> can be used to construct a list using regular-expressions notation.

Back up a bit and take a look at this problem from a higher level. If you implement this solution, you will have to manually update that Last-Modified date now and forever. The potential for error is large, and it's also a maintenance headache - You will never be able to take a vacation/holiday without serving a stale file for the duration.

I'd suggest a caching solution -- either using Squid or a 'manual' approach.

A manual approach involves modifying the script to write its output to a static file, and then serving that static file. When a request arrives, you can use mod_rewrite to check for the existence of that static file. If it exists, serve it. If not, run the script again to re-create it, then serve it.

How you manage the expiration of the static file depends on your needs; You can delete the static file manually to force a regeneration -- which is again a maintenance headache. Or you can set up a cron job to delete it every so many minutes or hours. How you set up cron jobs varies by host, but look in your control panel first.

An example of the mod_rewrite code for use in /.htaccess would be:


# If static html page exists
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
# rewrite php file requests to it
RewriteRule ^(php-file)\.php$ /$1.html [L]

Anyway, before digging into implementation details for one particular method, I suggest taking an overview of what your current and future needs will be, and finding a high-level solution that will scale well with your needs (and let you get away for a holiday).

Jim

jd01

5:43 pm on Nov 30, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I think you are better off using php. Servers do not usually set last-mod. headers on php (or other dynamic) pages, so you will need to specify they be set if you are using a rewrite for friendly URLs even if the original request is for an .html page. (I know it's why I started using php =)

You can set the 'last-mod' to the filemtime() of the script and use that, combined with the 'page' requested, to generate your ETag.

This should give you the ability to keep the .php page in the server cache, while cutting down the times it executes --- make sure you exit() if there is a 304.

Personally, I use php for almost everything. One of the cool 'biproducts' of setting your .html headers with .php is you can set a blanket 'long-cache' on the files your server sends a 'header' tag with and cache graphics, css, and other files for a longer period of time, freeing additional resources normally used to process requests for 'nothing' files.

If you are trying to give the appearance of truly 'static' you may want to look into setting 'content length' also.

Justin

Edited: Can't type/communicate in English very well yet today --- It's the only language I speak, so it could be a long day. --- I'll stop editing soon Jim.

(IOW: Adjusted wording so people could read the post AND it would make a little sense.)

sneskid

7:08 pm on Nov 30, 2006 (gmt 0)

10+ Year Member



Thanks a lot guys.

I have several implementation ideas (ones that will let me have a vacation).

I guess it's time to stop doing research and start putting what i've learned to practice.

cduke250

1:12 pm on Dec 4, 2006 (gmt 0)

10+ Year Member



There is a really good article about using mod_headers and mod_expires, and filesmatch+files in htaccess files at the askapache blog.

mod_headers is what you are currently using, though I don't understand why you need a last-modified header.. apache generates that header automatically unless its something dynamic like php.. then use something in the code to do this.. like for php:


@header ('Cache-Control: private, pre-check=0, post-check=0, max-age=1080');
@header ('Expires: ' . gmstrftime("%a, %d %b %Y %H:%M:%S GMT", time() + 1080)); //60*3
@header ('Last-Modified: ' . gmstrftime("%a, %d %b %Y %H:%M:%S GMT", time() - 20)); //60*60*3


# MONTH
<FilesMatch "\.(flv夙if夸pg夸peg如ng夷co存wf)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
# WEEK
<FilesMatch "\.(js圭ss如df宇xt)$">
Header set Cache-Control "max-age=604800"
</FilesMatch>
# DAY
<FilesMatch "\.(html多tm)$">
Header set Cache-Control "max-age=43200"
</FilesMatch>
# DONT CACHE
<FilesMatch "\.(pl如hp圭gi存pl)$">
Header set Cache-Control "max-age=0"
</FilesMatch>

It talks about using the FileETag directive


FileETag INode MTime Size
FileETag -INode
FileETag MTime Size
FileETag All

And the Files and FilesMatch directives:

Using the Files Directive

<Files ~ "\.(htm¦html¦css¦js¦php)$">
AddDefaultCharset UTF-8
DefaultLanguage en-US
</Files>

Using the FilesMatch Directive (preferred)

<FilesMatch "\.(htm¦html¦css¦js¦php)$">
AddDefaultCharset UTF-8
DefaultLanguage en-US
</FilesMatch>