Apache RewriteRule for removing tailing slash only at root - regex

I know there are many questions about Apache RewriteRules, especially for removing trailing slashes. I have looked at tons but I can't seem to find anyone trying to solve this problem.
I am using Magento, so the URL structure looks like this:
example.com/index.php
example.com/index.php/
example.com/index.php/page1/
Here is my ideal URL structure:
example.com
example.com/page1/
example.com/page2/
So basically I just want to strip the index.php AND make sure the naked domain does not have a trailing slash (example.com instead of example.com/). Also, I would like to NOT include the hardcoded domain name if possible so that the rewrite can be applied in different environments.
Here is my current Rewrite...
RewriteCond %{REQUEST_URI} ^/index\.php/?
RewriteRule ^index.php/(.*) /$1 [R=301,L]
This seems to work in all situations, except for:
example.com/index.php (doesn't work at all)
example.com/index.php/ (leaves the trailing slash)
I would appreciate any regex advice! Thank you.
UPDATE
Thanks to the answer below from #zx81 I have successfully stripped all URLs down to the root domain, but still can't remove the slash.
So here is the current URL: example.com/
And I can't remove the trailing slash!

Not able to test it live, but try this.
RewriteRule ^index\.php()/?(?:([^/]+)/)? $1$2 [R=301,L]
It should handle the one that doesn't work at all thanks to the empty capturing group 1 ().
In PCRE (Apache's regex flavor) this also strips the trailing slash, but Apache may decide to add it back.

Related

How to rewrite a space (%20) in .htaccess

I am trying to get some old URL's to redirect to the homepage. I tried it like below but it doesn't appear to work. Also tried some regex, but no results.
RewriteRule ^blog/%20article%20name(/?)$ / [R,L]
How is this to be done?
Converting my comment to answer so that solution is easy to find for future visitors.
To be able to match whitespace in URI, you can use perl property for whitespaces \s in your rule like this:
RewriteRule ^blog/\sarticle\sname/?$ / [R=302,NC,L]
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.

What does (|/)$ do with mod_rewrite?

I've seen examples in htaccess files using mod_rewrite where everything is done through one php file and different URLs are redirected back to index php.
RewriteRule ^registration(|/)$ /index.php
I'm curious as to what (|/)$ does/is. I've read a lot of stuff and can't seem to find any mention of the use of a vertical bar in mod_rewrite and if I remove this, the redirect still works fine.
The vertical bar stands for a logical OR, and lets you specify either a trailing slash after 'registration' or not.
I prefer using a '?' after the slash, making it optional:
RewriteRule ^registration/?$ /index.php

Redirect content of a folder to another with htaccess

I would like to restructure some folders on my website, specifically I am want to move what's contained inside "images/" to "images/gallery/", but I don't want to break previous links, so I thought of using htaccess.
I looked up several tutorials and even several questions here on stackoverflow, tried several times, but I can't get the rewrite rule to work.
This is what I have:
RewriteRule ^images/(.*) /images/gallery/$1 [R=301,NC,L]
But when I try to access anything inside /images/ (for example images/test.jpg) it stays into images/test.jpg and doesn't go to images/gallery/test.jpg. So it doesn't seem to have an effect.
Any clue on what I might possibly doing wrong?
Thank you!
Your rule at present will cause a redirect loop since /images/ is present in both source and target URLs and you're not even using anchor $:
You can tweak your regex like this:
RewriteRule ^images/([^/]+)$ /images/gallery/$1 [R=301,NC,L]
Now pattern will match /images/test.jpg but won't match redirected URL /images/gallery/test.jpg due to use of [^/]+ in pattern.
Make sure this rule is first after RewriteEngine On and there is no .htaccess in /images/ folder.
EDIT: If your original path has sub-directories also then use:
RewriteRule ^images/((?!gallery/).+)$ /images/gallery/$1 [R=301,NC,L]

httpd 2.4 ProxyPassMatch merge multiple slashes in regex

The current code I am using is
^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/puphpet/puphpet.com/web/$1
This works for proper URLs, ex http://puphpet.dev/app_dev.php/github-btn
If the URL has multiple slashes it's passing both slashes along, http://puphpet.dev/app_dev.php//github-btn
The multiple slashes are breaking my sites. I am aware that nginx has something that merges multiple slashes together, but have been unable to find something similar with httpd. I have tried multiple regexes for the match but they don't seem to be working as I'd expect.
For example, (.*\.php)(/)(.*) matches the above URL as
$1 /app_dev.php
$2 /
$3 /github-btn
So I would think passing $1$3 to the proxy would work, but alas it does not.
edit
After quite a bit of dancing around ProxyPassMatch's regex, I ended up with this:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
ProxyPassMatch /(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/puphpet/puphpet.com/web/$1
Which fixes the double slash in the URL by redirecting to a single URL. However, a completely new request isn't the most optimal solution, in my opinion. Transparently rewriting the URL for all further matches below it would be best.

Need more info with helicon isapi and regex rule

I am working on a helicon rule and tried various combinations but they didn't work
I want the following URL to be resolved.
It can be this
www.test.com/myownpages/
or
www.test.com/myownpages
www.test.com/myownpages/?value1=test2&value2=test2
it should be resolved to
$1/test.aspx [NC]
If anyone gives something after myownpages, it shouldn't work
www.test.com/myownpages/test (This shouldn't work)
It tried the below so far
RewriteRule ^(.*)(\/\myownpages\/)(.*)(\?)?(.+)?$ $1/test.aspx [NC]
I am not very familiar with these rewrite rules, but maybe I can help with the regex. As I read it, you want to match any string ending with "/myownpages", "/myownpages/", or "/myownpages/?anything" and capture the part before that.
I'd use
^(.*)/myownpages(/([?].+)?)?$
to get this. See it in action at RegExr. If you need to escape the forward slashes, it becomes.
^(.*)\/myownpages(\/([?].+)?)?$
Note that this will not preserve the values in the query string; it will rewrite www.test.com/myownpages/?value1=test2&value2=test2 to www.test.com/test.aspx.
In case you want rewrite (NOT redirect) from /myownpages --> /myownpages/test.aspx, try using:
RewriteEngine on
RewriteBase /
RewriteRule myownpages/?$ /myownpages/test.aspx [NC,QSA,L]
QSA-flag appends the query string to the source path automatically.