I actually posted about this years ago, never got anywhere. Did more research, did testing, got something I thought worked and mostly did, but it seems to get bogged down in infinite loops under certain circumstances. I am at my wit's end. Anyone who can help me resolve this, you are my hero for life. :)
The Problem
I run a photo gallery and I changed my website structure a few years ago.
The Old Site
The old structure, an album had a form like this:
http://desktopscenes.com/Name Of Album (Year)/default.html
Individual photo slides were like this:
http://desktopscenes.com/Name Of Album (Year)/slides/Name Of Slide.html
And the actual slide was:
http://desktopscenes.com/Name Of Album (Year)/slides/Name Of Slide.jpg
The New Site
An album is like this:
http://desktopscenes.com/Name_Of_Album_-_Year/index.htm
A photo slide like this:
http://desktopscenes.com/Name_Of_Album_-_Year/slides/Name_Of_Slide.htm
And the photo:
http://desktopscenes.com/Name_Of_Album_-_Year/slides/Name_Of_Slide.jpg
So What I Need to Happen Is:
- Change all spaces to underscores.
- Change the year references from " (Year)" to "_-_Year".
- Change "html" to "htm".
- Not break anything else. :)
My Attempt
You'd think this would be fairly simple. And in fact I actually got this to work -- most of the time. The problem is that occasionally something sends a request and sends it into an infinite loop.
Here's my code.
RewriteEngine On
Rewritecond %{HTTP_HOST} ^(desktopscenes.com|www.desktopscenes.com)$ [nc]
RewriteRule ^(.*)\s(.*)$ $1_$2 [N,NE]
RewriteRule ^(.*)\((.*)$ $1-_$2 [N,NE]
RewriteRule ^(.*)\)(.*)html$ http://desktopscenes.com/$1$2htm [NE,R=301,L]
RewriteRule ^(.*)\)(.*)jpg$ http://desktopscenes.com/$1$2jpg [NE,R=301,L]
A Clue - Revised!
If 'proper' requests come in as they should, this works fine. I think the problem is if a request comes in that is incorrect. In particular, sometimes I get a request like this on the old site:
http://desktopscenes.com/Name Of Album (Year)/Name Of Slide.jpg
Notice the "slides" folder is missing. I am pretty sure this request created an infinite loop.
ETA: Looking through my logs I am now seeing this is much more common than I thought. I would love a way, if possible, to add the "slides/" folder back in if a request for a .jpg comes in without "slides/" in the URI.
In Closing
Thank you for listening and attempting to help me with this. It has literally been bothering me for years!
Addendum
I have also been changing apostrophes in the original names to dashes. But these are infrequent so they are less important.
Revised Code
This is what I have now
RewriteEngine On
Rewritecond %{HTTP_HOST} ^(desktopscenes.com|www.desktopscenes.com)$ [nc]
RewriteRule ^(Test.*)\s(.*)$ $1_$2 [N,NE]
RewriteRule ^(Test.*)\((.*)$ $1-_$2 [N,NE]
RewriteRule ^(Test.*)\)(.*)/slides/(.*)html$ http://desktopscenes.com/$1$2/slides/$3htm [NE,R=301,L]
RewriteRule ^(Test.*)\)(.*)/slides/(.*)jpg$ http://desktopscenes.com/$1$2/slides/$3jpg [NE,R=301,L]
This handles the case where I have album (year)/subalbum/slides.html or whatnot.
The "Test" is in there so I can test this on a dummy structure without blowing up the rest of the site.
I am still not sure how to handle requests of the form: http://desktopscenes.com/Name Of Album (Year)/Name Of Slide.jpb
That is no "slides". I am not sure what the regex is to NOT find a particular string, I guess I could look that up.
Another Update - Adding back "/slides/"
I don't need to search for "no slides". Since the ones that match "slides" have the "L" suffix they should stop processing once found. (Correct?)
So I was able to add this:
RewriteRule ^(Test.*)\)([^/]*)/(.*)jpg$ http://desktopscenes.com/$1$2/slides/$3jpg [NE,R=301,L]
Which actually adds the "/slides" back in if not present on a JPG request, which is great!
When I tried to do the same for HTML however:
RewriteRule ^(Test.*)\)([^/]*)/(.*)html$ http://desktopscenes.com/$1$2/slides/$3htm [NE,R=301,L]
It doesn't work. Any idea why?
default.html
toindex.htm
)? Presumably you already have a canonicalwww
to bare domain redirect at the top of your script? If so, your firstRewriteCond
would seem to be superfluous (but this would only apply to the firstRewriteRule
anyway). – MrWhite Sep 15 '15 at 21:38