httpd 2.4 ProxyPassMatch merge multiple slashes in regex - 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.

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.

match multiple slashes in url, but not in protocol

i try to catch multiple slashes at the ende or inside of url, but not those slashes (which could be two or more), which are placed after protocol (http://, https://, ftp:// file:///)
i tried many findings in similar SO-threads, like ^(.*)//+(.*)$ or [^:](\/{2,}), or ^(.*?)(/{2,})(.*)$ in http://www.regexr.com/, https://regex101.com and http://www.regextester.com/. But nothing worked clear for me.
Its pretty weird, that i can't find a working example - this goal isn't such rar. Could somebody share a working regex?
Here is a rule that you can use in your site root .htaccess to strip out multiple slashes anywhere from input URLs:
RewriteEngine On
RewriteCond %{THE_REQUEST} //
RewriteRule ^.*$ /$0 [R=301,L,NE]
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of some rewrite rules. Example value of this variable is GET /index.php?id=123 HTTP/1.1.
Pattern inside RewriteRule automatically converts multiple slashes into single one.

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

Apache RewriteRule for removing tailing slash only at root

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.

htaccess redirect - use subfolders as parameters

I've been working out an htaccess redirect directive for (example) an online shop.
Products are displayed on product.php, with an ID parameter passed in.
What I'm aiming for is to have
products/someValue/someID
map to
product.php?param1=someValue&param2=someID
Here's where I'm at so far. This mostly works, but a couple of things are not quite what I want. I need it to basically separate everything after products/ by forward slashes and use each of those as a parameter, regardless of how many or few. also, a trailing slash is optional - my rule throws a 404 if it's not included. Can anyone point me in the right direction?
RewriteRule ^products/(.*)/(.*)/.*$ /product.php?param1=$1&param2=$2
Your current regex is greedy. Quantifiers are greedy by default. Adding a ? makes them ungreedy. Or you can change your regex to match anything except / Either of these should work:
RewriteRule ^products/(.*?)/(.*?)(/.*)?$ /product.php?param1=$1&param2=$2
RewriteRule ^products/([^/]*)/([^/]*)(/.*)?$ /product.php?param1=$1&param2=$2
Read up on greediness in regexes to understand this better.
Try changing the regex to non-greedy:
RewriteRule ^products/(.*?)/(.*?)/.*$ /product.php?param1=$1&param2=$2
or:
RewriteRule ^products/([^/]+)/([^/]+)/.*$ /product.php?param1=$1&param2=$2