Need help on complicated RewriteCond + RewriteRule

Folks,
I am struggling with my Apache rewrite rules. Any help will be appreciated?

=====
What I need?
I want to redirect all requests to the following URL pattern

[B]http://mydomain.com/cms/themes/currenttheme/thumb.php?src=http://mydomain.com/cms/media/imagefile.jpg&h=400&w=590&zc=1[/B]

TO

[B]http://mydomain.com/cms/themes/currenttheme/cache/imagefile-400-590-1.jpg[/B]

ONLY IF the file http://mydomain.com/cms/themes/currenttheme/cache/imagefile-400-590-1.jpg EXISTS.

I tried parametrizing imagefile, jpg, h, w, zc but no avail :frowning: Please help.

This is the current redirect script that I was able to write influenced by many examples which is obviously not working.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} thumb\\.php
RewriteCond %{QUERY_STRING} src=http:\\/\\/.*\\..*\\/.*\\/.*\\/(.*)\\.(png|jpe?g)&h=([0-9]+)&w=([0-9]+)&zc=([0-9]+)
RewriteCond %{DOCUMENT_ROOT}/cms/themes/currenttheme/cache/%1-%3-%4-%5.%2 -f
RewriteRule ^.* /cms/themes/currenttheme/cache/%1-%3-%4-%5.%2 [L]
</IfModule>

Any help will be highly appreciated :slight_smile:

The URL seem to be shortened in the message thread. Please hover your mouse for copy URL in browser to see the actual URL.

ds,

A few things about your URI and <IfModule> blocks:

URI: Including the protocol in the query string is illegal (at least unless it’s encoded) per Tim Berners-Lee’s techno-geek treatise on Uniform Resource Identifiers (URI): Generic Syntax. That said, I’m surprised that your FROM URIs (query strings) work at all.

Second, using the <IfModule> in the .htaccess file is an abuse of the server as explained in my Standard Rant #4:

[rant #4][indent]The definition of an idiot is someone who repeatedly does the same thing expecting a different result. Asking Apache to confirm the existence of ANY module with an <IfModule> … </IfModule> wrapper is the same thing in the webmaster world. DON’T BE AN IDIOT! If you don’t know whether a module is enabled, run the test ONCE then REMOVE the wrapper as it is EXTREMELY wasteful of Apache’s resources (and should NEVER be allowed on a shared server).[/indent][/rant 4]

Now that those two items are out of my system …

Okay, I don’t believe that I’d go through the cms/themes/currenttheme/cache to get to an image but that’s your choice:

Assuming that you actually receive the request, create a RewriteCond statement to fetch the h, w and zc values as well as the imagefile and file’s extension (jpg) as you’ll need those twice.

Create a second RewriteCond statement to see if the {REQUEST_FILENAME} of the cms/{crap}/%1-%3-%4-%5.%2 exists (!f)

Create a RewriteRule to redirect from ^cms/themes/currenttheme/thumb\.php$ to cms/{crap}/%1-%3-%4-%5.%2 [R=301,L]

Notes: cms/{crap} is your path, %1 is the imagefile name, %2 is the imagefile name extension, %3 is the h(eight), %4 is the w(idth) and %5 is the … er, zc? As for the R=301, presumably you do NOT want to display the redirection so this is just for testing that you get redirected to the correct URI - remove after verification.

Additionally, remove the <IfModule> wrapper and the RewriteBase directive (it does nothing unless you’re undoing mod_alias redirections so it’s only slowing your server).

Your attempt was fraught with some serious misconceptions about mod_rewrite but you displayed some really good thought processes so I’m sure you’ll get through the pseudo code from above - if you have any problems, I’d be honored to assist you through them.

Regards,

DK

Thank you dk.

Let me see if I can translate your pseudo code to script :slight_smile: Not very hopeful as I am not a RegEx expert, but would like to give it a try first.

Btw, I removed the IfModule statements from my htacces.

cheers

ds,

GOOD! You learn most when you give it a try! I was hoping to see your attempt at the mod_rewrite code but, when needed, I’ll be around (or PM me to let me know you’ve updated this thread so I’ll know to return quicker).

Regards,

DK

No success dk. I ended up something like this without any success. It does look dumb but I wanted to publicly admit that I don’t understand rewriterules lol.

RewriteEngine On
RewriteCond %{QUERY_STRING} src=\/(.*)\.(png|jpe?g)&h=([0-9]+)&w=([0-9]+)&zc=([0-9]+)
RewriteCond %{REQUEST_FILENAME} /cms/themes/currenttheme/cache/%1-%3-%4-%5.%2 !f
RewriteRule ^/cms/themes/currenttheme/cache/%1-%3-%4-%5.%2 [R=301,L]

Would be great if you can spend a couple of minutes to rewrite it properly.

Thanks

Second attempt after running through your mod_rewrite article… Still no luck! Am I anywhere closer?

RewriteEngine On
RewriteCond ^\/(.*)\.(png|jpe?g)&h=([0-9]+)&w=([0-9]+)&zc=([0-9]+)$
RewriteCond %{REQUEST_FILENAME} /cms/themes/currenttheme/cache/%1-%3-%4-%5.%2 !f
RewriteRule ^/cms/themes/currenttheme/cache/%1-%3-%4-%5.%2$ [L]

D$,

It looks like you’re trying to make the regex too complicated but I have an appointment and will need to spend a few minutes on this - be back in a few hours.

Regards,

DK

D$,

Okay, that’s a bit complicated but quite do-able:

Your code has problems:


[COLOR="#FF0000"]<IfModule mod_rewrite.c>
# DELETE as it's an abuse of the server[/COLOR]
RewriteEngine On
[COLOR="#FF0000"]RewriteBase /
# DELETE as you're not using any mod_alias Redirect[/COLOR]
[COLOR="#FF0000"]RewriteCond %{SCRIPT_FILENAME} thumb\\.php
# This belongs in the RewriteRule's regex[/COLOR]
[COLOR="#FF0000"]RewriteCond %{QUERY_STRING} src=http:\\/\\/.*\\..*\\/.*\\/.*\\/(.*)\\.(png|jpe?g)&h=([0-9]+)&w=([0-9]+)&zc=([0-9]+)
# The query string will NEVER contain a URL, merely anything after the reserved ? character[/COLOR]
[COLOR="#FF0000"]RewriteCond %{DOCUMENT_ROOT}/cms/themes/currenttheme/cache/%1-%3-%4-%5.%2 -f
# You're on the right track in using the % series[/COLOR]
RewriteRule [COLOR="#FF0000"]^.*[/COLOR] /cms/themes/currenttheme/cache/%1-%3-%4-%5.%2 [L]
[COLOR="#FF0000"]# That's your thumb\\.php[/COLOR]
[COLOR="#FF0000"]</IfModule>
# Ditto the above[/COLOR]

On to your other attempts (then on to my “solution”). BTW, please use the [noparse]

...

[/noparse] wrapper for your code.

RewriteEngine On
[COLOR="#FF0000"]RewriteCond %{QUERY_STRING} src=\\/(.*)\\.(png|jpe?g)&h=([0-9]+)&w=([0-9]+)&zc=([0-9]+)
# src has been changed in your link to remove the http://?
# I would not have used (.*) but src=.*/([^.]) so you throw away the path while capturing the filename and
# your / does not need escaped (with the \\) as it's included in the "catch all"[/COLOR]
RewriteCond %{REQUEST_FILENAME} [COLOR="#0000FF"]%{DOCUMENT_ROOT}[/COLOR]/cms/themes/currenttheme/cache/%1-%3-%4-%5.%2 !f
[COLOR="#0000FF"]# Here's where your {DOCUMENT_ROOT} was correct[/COLOR]
RewriteRule .? /cms/themes/currenttheme/cache/%1-%3-%4-%5.%2 [R=301,L]
[COLOR="#0000FF"]# Missing regex - or did I delete it in the copy process?[/color]

VERY much closer but still no cigar!

RewriteEngine On
RewriteCond ^\\/(.*)\\.(png|jpe?g)&h=([0-9]+)&w=([0-9]+)&zc=([0-9]+)$
RewriteCond %{REQUEST_FILENAME} /cms/themes/currenttheme/cache/%1-%3-%4-%5.%2 !f
RewriteRule ^/cms/themes/currenttheme/cache/%1-%3-%4-%5.%2$ [L]

Same problems as above.

My attempt:

# .htaccess in DocumentRoot
# Create a RewriteCond statement to fetch the h, w and zc values as well as the imagefile and file's extension (jpg) as you'll need those twice.
# Note: src=http://mydomain.com/cms/media/imagefile.jpg&h=400&w=590&zc=1 is now
# assumed to be src=cms/media/imagefile.jpg&h=400&w=590&zc=1
RewriteCond %{QUERY_STRING} [^.]+/([a-z]+)\\.(png|jpg)&h=([0-9]+)&w=([0-9]+)&zc=([0-9]+)$

# Create a second RewriteCond statement to see if the {REQUEST_FILENAME} of the cms/{crap}/%1-%3-%4-%5.%2 exists (!f)
RewriteCond %{DOCUMENT_ROOT}/cms/themes/currenttheme/cache/%1-3-%4-%5.%2

# Create a RewriteRule to redirect from ^cms/themes/currenttheme/thumb\\.php$ to cms/{crap}/%1-%3-%4-%5.%2 [R=301,L]
RewriteRule ^cms/themes/currenttheme/thumb\\.php$ cms/themes/currenttheme/cache/%1-3-%4-%5.%2 [L]
# Note: USE [R=301,L] to verify the redirection then remove the 'R=301,' for production use.

# Notes: cms/{crap} is your path, %1 is the imagefile name, %2 is the imagefile name extension, %3 is the h(eight), %4 is the w(idth) and %5 is the zc

Regards,

DK

D$,

For all the %3 above, you’re correct (in your PM) that the -3- in my coding example should have been -%3-.

That said, I still believe that you may not use ‘http://’ in your query string:
[quote=“Uniform Resource Identifiers (URI): Generic Syntax
linked above”]
2.2. Reserved Characters

Many URI include components consisting of or delimited by, certain
special characters. These characters are called “reserved”, since
their usage within the URI component is limited to their reserved
purpose. If the data for a URI component would conflict with the
reserved purpose, then the conflicting data must be escaped before
forming the URI.

  reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
                "$" | ","

The “reserved” syntax class above refers to those characters that are
allowed within a URI, but which may not be allowed within a
particular component of the generic URI syntax; they are used as
delimiters of the components described in Section 3.

{snip}

2.4.1. Escaped Encoding

An escaped octet is encoded as a character triplet, consisting of the
percent character “%” followed by the two hexadecimal digits
representing the octet code. For example, “%20” is the escaped
encoding for the US-ASCII space character.

  escaped     = "%" hex hex
  hex         = digit | "A" | "B" | "C" | "D" | "E" | "F" |
                        "a" | "b" | "c" | "d" | "e" | "f"

{snip}

3.4. Query Component

The query component is a string of information to be interpreted by
the resource.

  query         = *uric

Within a query component, the characters “;”, “/”, “?”, “:”, “@”,
“&”, “=”, “+”, “,”, and “$” are reserved.
[/quote]

Please note that I provided code which assumed that you actually read the Berners-Lee treatise on URI Syntax and removed the offending http:// from your query string.

That said, what I got from your PM’s link was the image of the mangoes both with and without the http://.

Regards,

DK

@DK, thanks for you advice on query/http params in the URL. I totally rewrote my code to avoid all such calls and definitely there’s significant performance gain.

The rewrite rule is not required now. However, should I need one like this in the future, I am more or less still clueless lol.

cheers and thanks for your help.

DS,

I’m glad to have been of some (minor) help. I believe that you’ve learned a few things (<IfModule> wrappers do NOT belong in an .htaccess file is the most important) and hope that you’ll keep mod_rewrite in mind for other tasks.

Regards,

DK