Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

hopefully someone can help me with this as it's driving me crazy.

I want to be able to accept URLs containing a calculation such as:

http://www.calcatraz.com/api/calc/3*3.txt

And rewrite them it this format:

http://www.calcatraz.com/calculator/api.php?a=calc&c=3*3&f=.txt

The above case works fine when I use this rewrite rule:

<IfModule mod_rewrite.c>
  Options +FollowSymLinks
  Options +Indexes
  RewriteEngine On
  RewriteRule ^api/calc/(.+)(\.(txt|sci))?$ calculator/api.php?a=calc&c=$1&f=$2 [L]
</IfModule>    

But it breaks down for URLs containing special characters, which will be URL encoded. For example 3/3 would be requested using:

http://www.calcatraz.com/api/calc/3%2F3.txt

I'd like this to rewrite, as before, to:

http://www.calcatraz.com/calculator/api.php?a=calc&c=3%2F3&f=.txt

But it doesn't - I just get an object not found error. I've played around with the 'B' flag and some others, but if they are the correct thing to use, I haven't been using them correctly!

Any pointers greatly appreciated!

share|improve this question
    
Based on the 404, I suspect the slash is a problem - does it work with %2A for an encoded *? –  Shane Madden Jul 29 '11 at 21:27
1  
It 's a know problem -- try use double encoding (encode /, and then encode result of it) -- yes, it does not look very nice .. but it works (in PHP script you will have to run single decoding routine). AT least give it a try. –  LazyOne Jul 29 '11 at 23:26
    
@Shane Yeah, %2A works, it does seem to be the slash that's causing the problems. –  Calcatraz Jul 29 '11 at 23:59
    
@LazyOne - the double encoding works in the way you describe. Perhaps it's the best we can do...? –  Calcatraz Jul 30 '11 at 0:04
    
@Calcatraz As to my knowledge -- yes. But wait a day or two -- maybe somebody else has better solution. –  LazyOne Jul 30 '11 at 0:22
add comment

1 Answer

up vote 0 down vote accepted

Why even bother with a complex rewrite? PHP can handle it much easier. I was bored so I put up a simple working example.

By default Apache httpd decodes %2f (a slash) before processing the request. This has nothing to do with mod_rewrite. I have no idea why it is enabled by default. Place the following in the appropriate VirtualHost definition. Sorry, it does not work in an .htaccess file.

AllowEncodedSlashes On

.htaccess

RewriteEngine On
RewriteRule /api/calc/.* api.php

api.php

<?php

define('STRIP_URI', '/api/calc/');
define('REGEX_URI', '/^(?P<calc>.+)(?P<ext>\.(txt|sci))?$/U');

$clean_request_uri = rawurldecode(str_replace(STRIP_URI, '', $_SERVER['REQUEST_URI']));

$math = array();
preg_match(REGEX_URI, $clean_request_uri, $math);

echo $math['calc'] . "<br/>";
echo $math['ext'] . "<br/>";

Updated to fully address encoding issue.
Updated again with work-around for Apache url decoding.

share|improve this answer
    
I like the simplicity of this approach. Unfortunately it doesn't solve the problem. The rewrite rule will match a slash '/', or a double-urlencoded slash '%252f', but not a single-urlencoded slash '%2f'. If the url contains a %2f it won't redirect to api.php at all. I was trying to pass calculations in as human-readable form as possible, but so far it looks like the double encoding will be necessary. (Note, while single encoding works it fails for other chars such as '?'). Thanks for the post! –  Calcatraz Jul 30 '11 at 9:15
    
As you pointed out, my original suggestion was on the right track, but ultimately flawed. Try the improved one and let me know what you think. –  h0tw1r3 Jul 30 '11 at 15:24
    
Thanks for taking the time to code the example. It works exactly as I want it to on the stack exchange sandbox - it nicely handles %2f in urls, converting it correctly to '/' in the php code. But... (sorry there had to be one!).. when I run the same example code on my local server (Apache 2.2.17 with xampp), it doesn't work. The .htaccess redirect works for most calculations, but not when %2f is in there. If so, it doesn't redirect to the php script at all. So it seems like it's a mod_rewrite issue. The best solution still seems to be double-encode (or switch to nginx)! Any ideas? –  Calcatraz Jul 30 '11 at 21:51
    
Added a work-around note. –  h0tw1r3 Jul 30 '11 at 23:29
    
Brilliant! AllowEncodedSlashes On solves it perfectly. You're a legend h0tw1r3! Thanks for all your help :) –  Calcatraz Jul 31 '11 at 2:18
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.