Re: Re: generate an etag header that apache can subsequentlyuse, how?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jochem,

in your post I see:
Last-Modified: Fri, 22 Jun 2007 19:20:30 GMT

and:

-rw-r--r-- 1 apache apache 11924 Jun 22 21:20 foo.jpg

Those two look like they're 2 hours off from eachother! Perhaps Apache does some magic on the unix timestamp first?

Just a thought there.
- Tul

Jochem Maas wrote:
hi Tul,

thanks for the feedback ... can I borrow your brain for a little longer? ....

M. Sokolewicz wrote:
hey Jochem,
as far as I can see, this should work for you:
<?php
$stats = stat('/dev/shm/file');
$etag = sprintf('"%x-%x-%x"', $stats['ino'], $stats['size'],
$stats['mtime']); // lowercase hexadecimal numbers separated by dashes
header('Etag: '.$etag);
?>

this is what I thought - actually I originally used dechex() - which gave the
same output as sprintf("%x", ...) ... which is not surprising.

sidenote: I'm actually only using the modification time in the etag right now.
I figure this keeps it a little faster - there is next to no chance to
that the filemtime will change and the file will be the same and using the inode
info is silly because moving the files locally (for whatever reason) shouldn't affect
whether a 304 can be given (imho). the fact that this may result in many files with
identical Etags maybe incorrect but I don't see the problem as the URL (and therefore
the local file) is going to be different.

BIG BUT: apache is not generating the same hexadecimal value for the filemtime of a
given file as I get from the various attempts with php

for a given file I get:

apache Etag		: 8e6bbb80
mtime via stat() 	: 1182540030
mtime via filemtime()	: 1182540030
sprintf("%x") Etag	: 467c20fe
dechex() Etag		: 467c20fe

the http headers for the URL of the file in question are:

Date: Fri, 22 Jun 2007 23:00:13 GMT
Server: Apache
Last-Modified: Fri, 22 Jun 2007 19:20:30 GMT
Etag: "8e6bbb80"
Accept-Ranges: bytes
Content-Length: 11924
Content-Type: image/jpeg
X-lori-time-2: 1182553213537

an 'ls -l' on the file in question gives (name of file changed to protect the innocent):

-rw-r--r-- 1 apache apache 11924 Jun 22 21:20 foo.jpg

I swear it's the same file but apache is generating the hexadecimal representation of the
filemtime differently than a 'straight' dec2hex conversion (ala dechex() and sprintf())

doing a hexdec() on the apache generated Etag shows that this is not a question
of mtimes being slightly off (for some reason):

hexdec("8e6bbb80") = 2389425024

I'm stumped, the comments for etag_ulong_to_hex() in the apache source even states:

	"Generate the human-readable hex representation of an unsigned long
	 (basically a faster version of 'sprintf("%lx")')"

I'm rather wary of the 'basically' it smells fishy to me ... rather like saying I'm basically
a women - sure there is a resemblance, but bit of investigation will show plenty of differences.

I have been checking with static image files (ones that go no where near a resampling script)
and the same problem occurs.




my desk is covered in hair :-/

PS - completely offtrack but what's "X-lori-time-2" - I've noticed since not long ago,
I have no idea what it is or what purpose it serves, and seemingly nor do the search engines.

Assuming your apache is configured to use the inode, modification time
and filesize in its etag.

The function you attached simply converts integers of type long to
hexadecimal strings. It is not the actual function creating the etag
itself.

....

I'd like to be able to generate an Etag header in php that matches
what Apache generates, I ended up in the apache source code here:

http://svn.apache.org/viewvc/httpd/httpd/branches/2.0.x/modules/http/http_protocol.c?view=markup



....

static char *etag_ulong_to_hex(char *next, unsigned long u)
{
    int printing = 0;
    int shift = sizeof(unsigned long) * 8 - 4;
    do {
        unsigned long next_digit = ((u >> shift) & (unsigned long)0xf);
        if (next_digit) {
            *next++ = HEX_DIGITS[next_digit];
            printing = 1;
        }
        else if (printing) {
            *next++ = HEX_DIGITS[next_digit];
        }
        shift -= 4;
    } while (shift);
    *next++ = HEX_DIGITS[u & (unsigned long)0xf];
    return next;
}


....

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux