0

I have an Apache server that serves up binary files to an application (not a browser).

The application making the request wants the HTTP Content-MD5 header in HEX format. The default and only option within Apache is Base64. If I add "ContentDigest on" to my VirtualHost, I get this header in Base64.

So I wrote a perl script, md5digesthex.pl, that gives me exactly what I want: MD5 in HEX format but I'm struggling with the RewriteRule to get my server to send the result.

Here is my current Rewrite recipe:

RewriteEngine on
RewriteMap md5inhex prg:/www/download/md5digesthex.pl
RewriteCond %{REQUEST_URI} ^/download/(.*)
RewriteRule ^(.*) %{REQUEST_URI} [E=HASH:${md5inhex:$1}]
Header set Content-MD5 "%{HASH}e" env=HASH

The problem is that I can't seem to set the HASH environment variable based on the output of the md5inhex map function. It appears this behavior is not supported and I'm at a lost as to how to formulate this...

Kilo
  • 1,554
  • 13
  • 21

1 Answers1

1

I think the better question is, why are you redefining what the RFC already defines? If you're trying to overload the Content-MD5 header, chances are you should just be using a different header. If you're trying to adapt this to your program, it sounds to me like your program is doing the wrong thing and should be corrected.

EDIT: So I looked at this locally. Can you tell me what the output of md5digesthex.pl is? It should be a whitespace delimited pair of values, i.e.:

some/path/to/file somehash

It sounds like the key/value may not be matching up, because this WILL do what you want assuming ${md5inhex:$1} executes correctly. What you can try doing, for testing, is setting a dummy variable; i.e:

RewriteEngine on
RewriteMap md5inhex prg:/www/download/md5digesthex.pl
RewriteCond %{REQUEST_URI} ^/download/(.*)
RewriteRule ^(.*) %{REQUEST_URI} [E=HASH:${md5inhex:$1}]
Header set Content-MD5 "%{HASH}e" env=HASH

RewriteRule ^(.*)$ - [E=TEST_HASH:${md5inhex:somekey}]
Header set TestingHeader "%{TEST_HASH}e" env=TEST_HASH

You can use something like curl -I <server>/<path> to verify that its getting set. I can verify that using a correctly formatted RewriteMap, this WILL set your info correctly.

Andrew M.
  • 10,982
  • 2
  • 34
  • 29
  • very true. I guess I need to explain why I need to solve this? OK, it's a very large system. Some 4 or 5 back end systems that all use the same MD5 in hex format and the client is at some 30,000 locations. When you have a very large system such as this, you simply can not change the client and be done. This is a tactical approach until a more strategic architecture can be developed. We currently serve up binaries from a database application and the load is growing too high hence the reason to move to a web server. – Kilo Dec 24 '10 at 02:46
  • Ah, I gotcha. Don't you just wish you could have a talk to the people who developed that? -.- Anyways, I updated my answer to help you debug the issue; hope it helps! – Andrew M. Dec 24 '10 at 03:33
  • Yes, wish I was around to slap the original developers. Anyway, the output of the md5inhex is just a hex string. I pass it the name of a file, it computes the MD5 and returns the hex value i.e. 0xBADBEEF.... I've tested it on the command line and it works and a browser test prompts me to download the file but HTTP header never gets set. – Kilo Dec 24 '10 at 21:16
  • When you use the `prg:/path/to/filename`, it expects a key/value pair separated with whitespace. What it does right now is, it looks for a key calculated from `$1`, which would be the path that was matched. What you'll want to do is have the program output a pair (a constant key, and a calculated value), and use that key in `${md5inhex:somekey}`. – Andrew M. Dec 25 '10 at 01:51
  • I solved it. I overlooked the fact that the md5digesthex.pl had to be a long running app. So I change the perl code run inside a while() loop instead and I now get the desired results... Thanks for the help. – Kilo Dec 25 '10 at 04:52