Remove double slash at the begining of URL path - apache

Due to moving of a site, the old hoster created a redirect to the new location. However, there is a leading slash / in the redirection and the former hoster is not able/willing to fix it. So I end up with all the redirects coming in like this:
http://sub.domain.com//path/to/file.html
So I tried to remove the leading slash:
using mod_alias
RedirectMatch 301 ^//(.*)$ http://sub.domain.com/$1
using mod_rewrite
RewriteEngine on
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_URI} ^(.*?)(/{2,})(.*)$
RewriteRule . %1/%3 [R=301,L]
Neither works. The latter removes multiple slashes inside the path, but not at the beginning.
There are already questions regarding slash removing, but they don't solve this problem:
Issue In Removing Double Or More Slashes From URL By .htaccess
.htaccess - how to remove repeated characters from url?
Does Apache somehow treat this case differently?
How do I get rid of one of the leading slashes?

The Problem
The point is that Apache 2 do not include leading slashes in the Requested URI, so you can't do this:
RewriteRule ^/+(.*)$ /$1 [R=301,L]
or that:
RewriteCond %{REQUEST_URI} ^/+(.*)$
RewriteRule ^.*$ /%1 [R=301,L]
what workes grat for any other kind of redirects or rewrites.
The Solution
But what you can do is to use the the Apache request variable that usually looks something like this:
GET /some-page HTTP/1.1
With this in mind we can do the following:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,7}\s//+(.*)\sHTTP.*$
RewriteRule ^.*$ /%1 [R=301,L]
So all leading slashes will be reduced to the one that that we need.
I tested this positive on apache 2.4

This code work for me
RewriteEngine On
RewriteCond %{THE_REQUEST} \s/+(.*?)/{2,}([^\s]*)
RewriteRule ^ %1/%2 [R=301,L,NE]

The First / is Implied
Try this:
RewriteEngine on
RewriteRule ^/(.+) $1 [R=301,L,B,NE]
Why?
To match two slashes at the beginning of the path, in htaccess, we don't need to look for two slashes—just one—because the first slash is assumed. For instance, if you wanted to match example.com/pasta, your match rule would be ^pasta$, not ^/pasta (which would only match on example.com//pasta).
This is different from httpd.conf, where you would need to specify both slashes.
Confusing, but that's how it works.

Related

Add hyphen to clean URL with htaccess

I am following the single page approach for my website, all the GET requests were built like: index.php?ressource=product&identifier=5
To achieve clean URLs, I have found a generator which created this:
RewriteEngine On
RewriteCond %{HTTPS} !^on$ [NC]
RewriteRule . https://%{HTTP_HOST}/ [L] HTTPS_HOST ???
RewriteEngine On
RewriteRule ^([0-9a-zA-Z]+)/([0-9a-zA-Z]+)/([0-9a-zA-Z]+)$ ?ressource=$1&identifier=$2&action=$3 [L]
RewriteRule ^([0-9a-zA-Z]+)/([0-9a-zA-Z]+)$ ?ressource=$1&identifier=$2 [L]
#EOF
I have added the first three lines to force the user's client to go to my https site.
Now I also would like to have a hyphen within the identifier value, something like article/terms-of-service.
I did some research and I need to either use the NC, QSA or both flags, but whenever I add one of those flags I get the Server Error 500.
Okay, i have found the solution to add hyphen within the clean urls:
RewriteEngine On
RewriteRule ^([a-z]+)/([0-9a-üA-Ü\-]+)/([a-z]+)$ ?ressource=$1&identifier=$2&kwargs=$3 [L]
RewriteRule ^([a-z]+)/([0-9a-üA-Ü\-\%\s]+)$ ?ressource=$1&identifier=$2 [L]
RewriteRule ^([a-z]+)$ ?ressource=$1 [L]
the hyphen character had to be added to the regular expression

removing directory in apache mod_rewrite

I have a PHP site which replaces an ASP site, so the path structure is different.
In the URLs, I need to match http://apache.site/Cartv3/Details.asp & redirect to another location. What is the correct syntax to match that URL fragment?
I've already tried
RewriteCond %{REQUEST_URI} CartV3/results1.asp?Category=60
RewriteRule ^(.*)$ home-study/A-Levels/1/page-1 [R=301,L]
and
RewriteRule ^CartV3/Details\.asp?ProductID=1004 home-study/A-Levels/1/page-1 [R=301,L]
You meed to read more about mod_rewrite. Remember RewriteRule doesn't match query string. You attempt needs to be rewritten as:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^Category=60$ [NC]
RewriteRule ^CartV3/results1\.asp$ /home-study/A-Levels/1/page-1? [R=302,L,NC]
Once you verify it is working fine, replace R=302 to R=301. Avoid using R=301 (Permanent Redirect) while testing your mod_rewrite rules.
PS: ? after page-1 is a special mod_rewrite syntax to strip original query string. If you want to keep original query string in rewritten URL then take out ? in the end.
The problem here is that you are trying to match the query string, which has to be done by a separate RewriteCond. If you want the match specifically "Category=60", then you can add it as a Condition:
RewriteCond %{QUERY_STRING} Category=60
RewriteCond %{REQUEST_URI} /CartV3/results1.asp
RewriteRule .* home-study/A-Levels/1/page-1?
This will match http://example.com/CartV3/results1.asp?Category=60 and redirect. The ? at the end of the rule stops "?Category=60" being to the resulting URI.
If you don't care about the value in the query string, then you can remove the first condition.

.htaccess Rewrite Rule Possibility?

I'm having a little issue. One of my clients recently sent out an email blast to 6500 people, that included an invalid link to a PDF file.
The link was simply: http://theirsite.com/pdf/thepdf.pdf%20
So, I'd like to be able to do an htaccess rewrite for them to the valid http://theirsite.com/pdf/thepdf.pdf file
So far, everything I've tried does not work.
Here is what I've tried thus far:
RewriteRule ^(/pdf/thepdf.pdf[%20|\s]+)$ /pdf/thepdf.pdf [R=301,L]
RewriteRule /pdf/thepdf.pdf([%20|\s]+)$ /pdf/thepdf.pdf [R=301,L]
RewriteRule /pdf/thepdf.pdf%20 /pdf/thepdf.pdf [R=301,L]
RewriteRule /pdf/thepdf.pdf%20 /pdf/thepdf.pdf [R=301,L]
RewriteRule /pdf/thepdf.pdf /pdf/thepdf.pdf [R=301,L]
RewriteRule /pdf/thepdf.pdf(.+?) /pdf/thepdf.pdf [R=301,L]
Something to note here, if I click the original link, but remove the %20 and put in a space, the rewrite works.
Just does not work with the %20
Since this is .htaccess there should not be a mandatory forward slash at the beginning of the match rule. Try this:
RewriteEngine On
RewriteRule ^/?pdf/thepdf\.pdf\s+$ /pdf/thepdf.pdf [R=301,L]
Note:
I put a /? at the beginning of the match rule as this is good general practice to make the rule work in either a host config context or an .htaccess context. Since a / would be required if this rule was in host config.
You should escape the . before .pdf otherwise it will act as a wildcard match.
I added anchors (^ and $) at the beginning and the end of the match to make sure this matches the entire resource string
%20 is a URL encoded space, so you can use a lazy select (.+?) in your .htaccess file.
RewriteEngine On
RewriteBase /
RewriteRule /pdf/thepdf.pdf(.+?) /pdf/thepdf.pdf [L]
These rules should normally work.

How to use RewriteRule in Apache to redirect from /abc/ to /abc?

RewriteRule ^([^/\.]+)/$ $1 [R] redirects from website.com/abc/ to website.com/home/user/www/abc
How do I redirect to the correct location? (website.com/abc)
The first part of the RewriteRule is the matching part, the second the replacement expression. For full-url RewriteRules they should start with a ^/ (slash), because a path after http://exampl.com always starts with the root-slash. To redirect http://example.com/abc/ to http://example.com/abc (remove the trailing slash) you can do this:
RewriteEngine On
RewriteRule ^/([^/]+/$ /$1 [R]
It looks like the URL is already being rewritten to a filename and then you are rewriting the filename. This usually happens when the rewrite rule is being specified in an .htaccess file. The problem is due to the fact that by the time Apache reads the .htaccess file, it has already resolved all URLs to filenames. The standard solution to this is to supply a RewriteBase rule in your .htaccess. Try:
RewriteBase /
Above your RewriteRule for starters.
More documentation is here
You could try it with the additional L flag to avoid any further rules to be applied:
RewriteRule ^([^/\.]+)/$ /$1 [R,L]
But if nothing else works, try this:
RewriteCond %{THE_REQUEST} ^[A-Z]+\ (/[^/.?\ ]+)/[? ]
RewriteRule ^[^/.]+/$ %1 [R]

Apache mod_rewrite going berserk - redirecting where it shouldn't

I have a script that echoes a meta redirect to a page called account_management.php5, but for some reason it automatically redirects from there to index.php5. My .htaccess file handles a couple of redirects automatically, for example index.html|php5 to the domain root, and that's the only place I can see this problem originating, but I don't understand why. This is my .htaccess file:
RewriteEngine On
#remember to change this to aromaclear
RewriteCond %{HTTP_HOST} !^sinaesthesia\.co.uk$ [NC]
RewriteRule ^(.*)$ http://sinaesthesia.co.uk/$1 [R=301,L]
RewriteCond %{THE_REQUEST} ^GET\ .*/index\.(php5|html)\ HTTP
RewriteRule ^(.*)index\.(php5|html)$ /$1 [R=301,L]
#translate any .html ending into .php5
RewriteRule ^(.*)\.html$ /$1\.php5
#change / for ?
RewriteRule ^(.*)\.html/(.*)$ /$1\.html?$2
#strip .html from search res page
RewriteRule ^(.*)search/(.*)$ /$1search_results\.html/search=$2
#translate product details link from search res page
RewriteRule ^products/(.*)/(.*)/(.*)$ /product_details.php5?category=$1&title=$2&id=$3 [L]
#Translate products/psorisis/chamomile-skin-cream-P[x] to productview.php5?id=1
RewriteRule ^products/.*-P([0-9]+) /productview.php5?id=$1 [L]
Wrong:
RewriteRule ^(.*)\.html$ /$1\.php5
Right:
RewriteRule ^(.*)\.html$ /$1.php5
Righter:
RewriteRule ^(.*)\.html$ /$1.php5 [QSA]
This same mistake of escaping special chars in the second param of RewriteRule is happening in other rules too, I don't know if apache will handle it, but I know you don't need it because second param is not a regexp.
Never compare to %{THE_REQUEST}, thats a weird thing to do, you don't need that. Moreover, this condition is fine without it. Just put there:
RewriteRule ^(.*)index\.(php5|html)$ $1 [R=301,QSA,L]
Now look at it:
RewriteRule ^(.*)\.html/(.*)$ /$1.html?$2
First, you are still accepting that there are references to .html files, just after trying to translate all .html to .php5, there's something wrong here.
Moreover, you are defineing as QueryString something that was originally a file path, and are not even putting it in a key. It won't work, it need some more treatment.
#strip .html from search res page
RewriteRule ^(.*)search/(.*)$ /$1search_results.html/search=$2
Wasn't it supposed to strip the .html? Because it is actually putting a .html there. Maybe as it is not an [L] it get fixed in the next loop, but you could just get all fixed right here.
#translate product details link from search res page
RewriteRule ^products/(.*)/(.*)/(.*)$ /product_details.php5?category=$1&title=$2&id=$3 [L]
This one full of .* is potentially unstable, specially delimitating the end. You should do this:
RewriteRule ^products/([^/]*)/([^/]*)/([^/]*) /product_details.php5?category=$1&title=$2&id=$3 [L]
# or:
RewriteRule ^products/(.*?)/(.*?)/([^/]*) /product_details.php5?category=$1&title=$2&id=$3 [L]
The last one looks correct, except that you should strip the special character that may be faced as a range delimiter, the "-". I don't think it work after a *, but just to be sure and correct the syntax:
RewriteRule ^products/.*\-P([0-9]+) /productview.php5?id=$1 [L]
Add this just after RewriteEngine on
RewriteLogLevel 9
RewriteLog /tmp/rw.log
Then restart the webserver. It should help you debug the problem.
Edit: Sorry, I didn't notice the .htaccess above. This will only work from the main apache configuration file.