One link doesn't work after rewrite?

Hi,

This rewriting script almost works perfectly.


# don't rewrite images or scripts 
RewriteRule ^(images|scripts)/ - [L]
# the rs query variable is never numeric
RewriteRule ^([a-z_-]+)\\.html /sub_folder/landing_page.php?rs=$1

So using [noparse]http://www.example.com/sub_folder/web.htm[/noparse] navigates to [noparse]http://www.example.com/sub_folder/landing_page.php?rs=web[/noparse]

However, one of the links on the [noparse]http://www.example.com/sub_folder/landing_page.php?rs=web[/noparse] page, specfically

<a href='skills_front_end.html'>Front End Skills</a>

does not work, in that it stays on the landing page and does not navigate.

I have renamed [noparse]skills_front_end.html to front_end.html[/noparse] but no luck. Other similar links on this page work fine?

Any idea of what is happening?

Warm regards,
Steve

Steve,

This rewriting script almost works perfectly.

YGBSM


# This has NO bearing on your stated problem - and makes almost no sense anyway (the L should be PT for passthrough)
# don't rewrite images or scripts
RewriteRule ^(images|scripts)/ - [L]

# the rs query variable is never numeric
RewriteRule ^([a-z_-]+)\\.html /sub_folder/landing_page.php?rs=$1

No Last flag? Oh, well, don’t forget that you can test your mod_rewrite using the R=301 flag (then remove it for your production server).

YGBSM? Yes, your URI, [noparse]http://www.example.com/sub_folder/web.htm[/noparse] CANNOT redirect to [noparse]http://www.example.com/sub_folder/landing_page.php?rs=web[/noparse] with your above code (“sub_folder” does not match “^”) OR … just what directory is your .htaccess located?

Of course not! Your link is a relative link which is to the sub_folder/skills_front_end.html. Wait! My error! Because you’re changing directory level, I must ask whether you have told your sub_folder scripts they’re one level lower in your website (<base> directive or absolute links in the scripts) or believe they’re in the root directory!

Now that I’m thoroughly confused, please specify directory levels and any code within the scripts which acknowledge directory level changes.

It may help you to checkout the “Relative Links Are Missing!” section of my signature’s tutorial for more information about the directory level changes.

Regards,

DK

In the past few times you have suggested to write out your rewriting objectives so here goes:

  • eliminate the ugly php extension and parameters.
  • handle the text not numeric parameter values
  • rewrite a really long and ugly folder name where in the about examples subfolder is really long and not properly descriptive.
  • do not screw up <a href> links or images.

Thanks for your help!
Steve

Steve,

[aside]Editing a quote is not passed along with the Reply With Quote making embedded comment responses difficult.[/aside]

No, the Last flag simply tells mod_rewrite that, if it’s matched the conditions of a RewriteRule and redirected, simply start the next pass immediately rather than go through the remaining mod_rewrite code. Your concern that images and scripts directory files not be affected is already handled by the ^{letters, hyphens and underscores}.html$ - no match on subdirectories nor on files without an .html extension.

The R=301 flag will tell the browser to display the redirection (it also tells SE’s that the redirection is permanent so don’t leave it if you’re trying to hide the real link). That’s very helpful because it allows you to see the resultant URI and that can help you decide whether your problem is with the mod_rewrite code or the code of the target script.

If all files are located in the subfolder, you can remove any reference to the subfolder in your .htaccess (which is also in the subfolder). Just don’t use absolute redirections without the subfolder being referenced, too. If you’re not changing directory level with your mod_rewrite, the “missing support files” problem doesn’t rear its ugly head so your other files are fine as is. It was simply my kneejerk reaction to what appeared to be a common problem (you didn’t need the /sub_folder/ in the /sub_folder/landing_page.php?rs=$1 redirection).

My apologies for “going off” on you over the “missing support files” problem. I’m just too used to directory level changes being the cause.

Regards,

DK

Duly noted.

Thanks, I’ve since done more reading at apache.org and your description fits well! Thanks.

Yes I tried this and now get it why this is a good thing to help you understand the rewriting that has been performed.

Yah, I’m still working on getting this right as I still have the one link that doesn’t work, so for now I’ve disabled the rewriting until I get a chance to get to it tomorrow.

No problem, I’ll head that warning to check this when multiple directory levels are present.

Thank you :slight_smile:

Hello,

Well I’m beginning to think that the problem may be how this particular server is configured. Please correct me if I’m wrong but having a directory structure of:

 /SiteFolder/sub_folder/files.php

with the .htaccess file in the sub_folder and doing this simple rewrite (I show the <FilesMatch> directive in case it is causing problems):


#force download of pdf
<FilesMatch "\\.(?i:doc|odf|pdf|rtf|txt)$">
  Header set Content-Disposition attachment
</FilesMatch>
# Rewrite 
RewriteEngine on
# rewrite the non-numeric text parameter to the single atom in the RegEx
RewriteRule ^rate/([A-Za-z0-9_]+)/ $rate.php?rs=$1 [L]

This should mean that if I use [noparse]www.asite.com/sub_folder/rate/buttons[/noparse] that my $1 atom is ‘buttons’ and the RegEx replacement is the balance of the URL.

When I try this url then I get a 404 error that reports:


[B]Not Found[/B]

[COLOR=#000000][FONT=Times New Roman]The requested URL /var/www/SiteFolder/sub_folder/rate.php was not found on this server.[/FONT][/COLOR]

Any ideas as this should not be difficult!

And for completeness here is the virtual host that I’ve just altered the names for this post but it is structured this exact way.


<VirtualHost *:80>
    DocumentRoot /var/www/ASite
    ServerName www.asite.com
<Directory "/var/www/ASite">
    Order Deny,Allow
    allow from all
    Options Includes FollowSymLinks 
</Directory>
<Directory "/var/www/ASite/Ice_Rink">
    Order Deny,Allow
    allow from all
    Options Includes FollowSymLinks 
</Directory>
</VirtualHost>

Routes to this server come from a front-end Apache server. Here is the config


<VirtualHost *:80>
    ServerName www.asite.com
    ProxyPreserveHost On
    ProxyPass / http://172.16.4.15/
    ProxyPassReverse / http://172.16.4.15/
    <Proxy http://172.16.4.15> 
       Allow from 172.16.4.15
   </Proxy>
</VirtualHost>

Hi Steve,

Ah, with the understanding you’ve gained, you’re becoming an expert, too! :tup:

SiteFolder is your DocumentRoot and you’re dealing with sub_folder and its files where the .htaccess is in the subfolder. Did I get that correct?

You may want to remove your IP addresses from the post above.

Finally, you may want to add an optional / to the regex on the RewriteRule (because you’re in a sub_folder of the DocumentRoot. I recall reading that subdirectories are handled slightly differently than the DocumentRoot (which Apache 2 assumes a leading / and will not match it in the URI). Making it optional will test whether the / is required for the subdirectory or not. Sorry, I (almost) always code my mod_rewrite in the DocumentRoot so this had slipped my (porous) mind.

Feedback, if you please, especially on the optional leading / (RewriteRule [1]/?[/COLOR]rate/([A-Za-z0-9_]+)/ $rate.php?rs=$1 [L]).

Regards,

DK


  1. COLOR=“#0000FF↩︎

Thank you… wouldn’t say this yet but working on it.

yes this is correct :slight_smile:

I fudged these as to not reveal the real IPs but thanks for pointing it out if I had not done this!

This may well be… I’m going to read up on it … for now I will not need to (see below)

I got rid of the trailing / as your recommended. It is now working for all but one different link. Here are the things I needed to do:

  1. set the <base> tag on the landing page; where all the links are located
  2. remove the [L] flag on the first rewrite rule as it was not getting to the new rewrite rules/conditions I put
  3. needed to move the _ character to the front of the character class!!!

So here is the code


RewriteEngine on
RewriteRule ^rate/([_A-Za-z0-9]+)$ rate.php?rs=$1

# DOES THIS CODE LOOK FAMILIAR ;)
# Test php first - gives preference in case you have both
# then test for the .html extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([_a-zA-Z0-9]+)$ $1.php [L]


RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([_a-zA-Z0-9]+)$ $1.html [L]

This works now; however there is one .html file that does not work if the .html file is not included. It is in the same directory as all the other .php files reside, so in other words it does not traverse directories. the file is web_portfolio.html and any time I do I get a 404 error. It should match just like the extensionless .php files do but it needs the .html extension?

This is now liveable, as I can use [noparse]http://www.asite.com/sub_folder/rate/buttons[/noparse] and it works. I’d just like to know why with the


RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([_a-zA-Z0-9]+)$ $1.php [L]


RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([_a-zA-Z0-9]+)$ $1.html [L]

testing if it is a php file first. It should say nope and then move on to the .html test, but it does not :frowning:

Thanks again for you support on this one!

Warm regards,
Steve


  1. COLOR=#0000FF ↩︎

Hi Steve,

Well, you’re certainly working on it … and being quite successful. I just hope others are gaining from this thread, too.

Specificity:

  1. set the <base> tag on the landing page; where all the links are located
  2. remove the [L] flag on the first rewrite rule as it was not getting to the new rewrite rules/conditions I put
  3. needed to move the _ character to the front of the character class!!!

Okay, #1 is the best solution to the “missing support files” problem.

#2 doesn’t look correct as the Last flag simply tells Apache to terminate that pass through the mod_rewrite code and start the next pass with the new URI. Therefore, if there was a problem with your test URI (which was …?), then the earlier code would have been the problem to examine.

#3 is not correct … but no harm so no foul! The only requirement within a character range definition is to keep ranges together (i.e., a-z and A-Z and 0-9 should not have anything else inserted in the middle) and only the few characters which would upset the regex expression must be escaped.

Okay, no harm, no foul.


RewriteEngine on
RewriteRule ^rate/([_A-Za-z0-9]+)$ rate.php?rs=$1

# DOES THIS CODE LOOK FAMILIAR ;)  :tup:
# Test php first - gives preference in case you have both
# then test for the .html extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([_a-zA-Z0-9]+)$ $1.php [L]
# Add R=301 flag to view this redirection
# If URI.html is a file, this is the only shortstop which could interfere
# ... except the case where web_portfolio is also a directory where !-d would be the exclusion

RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([_a-zA-Z0-9]+)$ $1.html [L]
# Add R=301 flag to view this redirection

As you said, it works EXCEPT for web_portfolio (an .html file). The obvious question is whether web_portfolio.php exists? Then, does web_portfolio exist as a directory? When troubleshooting a redirection problem (like this), use of the R=301 flag can identify the redirection which has resulted so you are saved from looking at the mod_rewrite log file (a painful, albeit invaluable experience)

Okay, okay, I wasn’t trying to be insulting as those are the only possibilities I can think of that could hijack your URI. I KNOW you’re smarter than that (as you know, too)!

Regards,

DK