Last active
May 26, 2022 20:46
-
-
Save jasco/b633467545abf242ca0673630a10ddb6 to your computer and use it in GitHub Desktop.
Apache Use Stored MD5 as ETAG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
$| = 1; # Turn off I/O buffering | |
sub sanitize { | |
my $fname = $_[0]; | |
$fname =~ s#[^-_a-zA-Z0-9./]*##g; | |
$fname =~ s#/\.\.+/##g; | |
$fname =~ s%/+$%%; | |
return $fname; | |
} | |
while (<STDIN>) { | |
local $/ = undef; # slurp mode. Makes chomp ineffective. | |
# Remove whitespace. Input has a newline. | |
$_ =~ s/^\s+|\s+$//g; | |
# Verify that input appears sane or reject | |
if (sanitize($_) ne $_) { | |
print "\n"; | |
next; | |
} | |
my $fname = $_ . '.md5'; | |
open(my $fh, $fname) or print "\n" and next; | |
binmode $fh; | |
my $content = <$fh>; | |
close $fh; | |
# Remove any extraneous whitespace | |
$content =~ s/\s//sg; | |
# Verify that content is no longer than an md5 string. | |
if (length($content) > 32) { | |
print "\n"; | |
next; | |
} | |
print $content . "\n"; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<VirtualHost *:443> | |
# .... | |
# This looks for a static file *.md5 along side the requested | |
# file and, if found, returns the .md5 file contents as the etag. | |
# On request, the if-none-match value is compared with the | |
# value from the .md5 file contents. | |
# | |
# 1. Does not handle multiple etags in an array. | |
# 2. Uses a separator of | in check condition, which is actually | |
# a valid etag character. Should use a control character to | |
# avoid possible conflict. | |
# 3. Not tested but likely not compatible with etags that include | |
# embedded newlines. | |
# 4. In VirtualHost context, REQUEST_FILENAME is REQUEST_URI. | |
# This likely means must assume completely unsanitized. | |
# | |
# Reference https://serverfault.com/a/693079/425597 for use | |
# of RewriteMap with RewriteCond | |
RewriteMap getmd5 "prg:/opt/bin/get_etag.pl" | |
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.md5 -s | |
RewriteRule / - [E=ETAG:"${getmd5:%{DOCUMENT_ROOT}%{REQUEST_FILENAME}}"] | |
Header always set ETag %{ETAG}e env=ETAG | |
RewriteMap getmd5 "prg:/opt/bin/get_etag.pl" | |
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.md5 -s | |
RewriteCond "%{HTTP:If-None-Match}|${getmd5:%{DOCUMENT_ROOT}%{REQUEST_FILENAME}}" ^(?:W/)?"([^|]+)"\|\1$ | |
RewriteRule ^(.*)$ $1 [R=304,L] | |
</VirtualHost> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment