Forum Moderators: phranque

Message Too Old, No Replies

Apache2 mod rewrite rule for changing file extentions

         

Cyber_Dog

4:24 pm on Aug 27, 2007 (gmt 0)

10+ Year Member



I want to make a mod_rewrite rule that performs the following, but I'm failing to get the logic in order:

1) Does [filename] end in .XYZ?
2) Does [filename].ABC exist?
3) If yes, redirect [filename].XYZ to [filename].ABC. If no, do nothing.

I could just do a blunt redirect with:
RewriteRule ^(.+)\.XYZ$ $1.ABC [R=301,L]
...which works, but I don't like the idea of doing a redirect to another non-existent file, so I'd like to check if it actually exists first.

I know I can accomplish 1) with:
RewriteCond %{REQUEST_FILENAME} ^(.+)\.XYZ$

and I know I can check for files existing with:
RewriteCond %{REQUEST_FILENAME} -f

The problem is, since the filename is dynamic, and we're not checking for the actual requested file, I don't know how to do a RewriteCond -f against the potential new filename.

jdMorgan

10:26 pm on Aug 27, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It only "comes together" and makes sense when all the steps are present. Remember that RewriteConds and RewriteRules can back-reference the request string parts that match each other's and their own patterns. In this case, we extract the "filename" without the filetype in the RewriteRule, and pass it to the RewriteCond as $1 to be used as part of the filepath to be checked.

# If requested .XYZ-filetype resource exists as a .ABC file
RewriteCond %{DOCUMENT_ROOT}/[b]$1[/b].ABC -f
# externally redirect to same-named resource having filetype .ABC
RewriteRule ^([.]+)\.XYZ$ http://www.example.com/$1.ABC [R=301,L]

Also remember that RewriteRule patterns are evaluated before the rule's associated RewriteConds are processed. This behaviour (which some have interpreted as a "mistake" or have ascribed to obscure "legacy support causes") is actually an important part of mod_rewrite's functionality and capabilities.

Because we're only using/retaining *part* of the URL-path for 'exists' testing, we can't use REQUEST_FILENAME. Instead, it is necessary to manually 'construct' the desired new filepath for that requested URL-path, by prepending DOCUMENT_ROOT and adding the replacement filetype to the end.

Jim

Cyber_Dog

11:06 pm on Aug 28, 2007 (gmt 0)

10+ Year Member



That appears to have worked perfectly. Very informative too, thanks very much!

g1smd

11:40 pm on Aug 28, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Did you really want a redirect or did you want a rewrite?

Which URL should the user ultimately see in their browser? the one they requested (content comes from elsewhere via the rewrite), or a new URL (after the browser has been redirected to it)?

Cyber_Dog

2:19 pm on Aug 29, 2007 (gmt 0)

10+ Year Member



a redirect