htaccess mod rewrite - how to create virtual subdomains? - .htaccess

I would like to create virtual subdomains through htaccess in the following way.
Entering:
http://testuser.domain.com/1/2/3/
Should be processed as:
http://www.domain.com/user.php?id=testuser&var1=1&var2=2&var3=3
HOWEVER, this rewrite should not use user.php, but index.php, in case someone enters:
http://www.domain.com or http://domain.com
This is what I got so far, however it doesn't seem to work.
Any help from a mod rewrite expert would be much appreciated.
Thanks in advance.
Options +FollowSymLinks
Options +Indexes
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} ^(www\.)?domain.com$ [NC]
RewriteRule ^(.*)/?(.*)/?(.*)/?$ index.php?var1=$1&var2=$2&var3=$3 [NC,QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} !^(www|mail).domain.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+).domain.com$ [NC]
RewriteRule ^(.*)/?(.*)/?(.*)/?$ user.php?id=%2&var1=$1&var2=$2&var3=$3 [NC,QSA,L]

Your rules are actually very close to doing what you want them to. The only problem that I can see is in your test patterns for your two RewriteRule statements. Currently, you have
RewriteRule ^(.*)/?(.*)/?(.*)/?$ ...
...which happens to be equivalent to this:
RewriteRule ^(.*)$
This is because everything past the first capture group can match nothing and still be considered a match, so that first group is greedy and matches the whole input string without needing to defer to the other parts of the pattern.
Since the capture groups shouldn't capture forward slashes anyway, as they're being used as a variable delimiter here, the straightforward fix is to change them to [^/]*, as so:
Edit: I also modified the RewriteCond set in the second group to ignore the !-f condition in the case of /index.php, which will happen if you request the subdomain without anything after the domain.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} ^(www\.)?domain.com$ [NC]
RewriteRule ^([^/]*)/?([^/]*)/?([^/]*)/?$ index.php?var1=$1&var2=$2&var3=$3 [NC,QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_URI} ^/index.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} !^(www|mail).domain.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+).domain.com$ [NC]
RewriteRule ^([^/]*)/?([^/]*)/?([^/]*)/?$ user.php?id=%2&var1=$1&var2=$2&var3=$3 [NC,QSA,L]

Related

.htaccess Rewrite QSA

So I have an htaccess file that I'm working on for someone, and I'm stuck on passing the URL arguments. Basically any and all arguments need to be passed, however I don't know all the queries, which is where I get lost and need help.
I've literally spent the past hour and a half digging through the internet and read about QSA's but have just gotten completely lost... Needless to say, I'm not well with htaccess files. Lines 1-23 are for something else related, but with the pages themselves.
Here's a few examples in case you're confused:
"/events/?query=dark needs to execute events.php?query=dark"
"http://mywebsite.com/authorize/?name=john would actually execute http://mywebsite.com/authorize.php?name=john"
Here's what I have so far, line 25 and down is just an official query I have atm.
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ "domain"/$1 [R=301,L]
ErrorDocument 404 /404.php
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /events/?$ [NC]
RewriteRule .* /events.php [R=301,NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /authentication/?$ [NC]
RewriteRule .* /authentication.php [R=301,NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /databases/?$ [NC]
RewriteRule .* /databases.php [R=301,NC,L]
RewriteCond %{QUERY_STRING} name=(.*)
RewriteRule ^authorize/(.*) /authorize.php?name=%1

Using .htaccess to route friendly url

I am trying to route an url which is displayed as follows www.example.com/profile/1 to the following page with parameters www.example.com/profile?user=1. I have the following RewriteRule in my .htaccess, yet the routing is not working. Can someone tell me what I am doing wrong?
RewriteEngineOn
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/profile/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) /profile?user=$1 [L,QSA]
I have tried switching up the last RewriteRule to different URL's, but so far no luck. I am probably overseeing a small problem which someone can hopefully help me out with.
You need to allow for profile/\w+ as regex pattern to match /profile/123:
Options -MultiViews
RewriteEngineOn
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^profile/(\w+)/?$ /profile?user=$1 [L,QSA,NC]

HTACCES mod rewrite, stacking rules

We have a rewrite rule that looks like this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule (?!^(cms|images|js|mobile)(/.*|)$)^.*$ page.php [NC,L]
Which works as expected; if the file does not exist, forward to page.php which is a generic page and allows for pages with custom URLs.
We also want to force the www. to precede the domain: example.com -> www.example.com
For that, we use:
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
This also works, but when the two are supposed to work together:
example.com/non-existent-file
We end up getting:
www.example.bom/page.php
Which defaults to our 404 page. How do I modify these rules to work together? I have tried playing with some of the different suffic characters (ie. removing the L in the [NC,L] in an attempt to get both rules to process).
I have also tried repeating the forward to page.php lines beneath the www redirect (and removing the L suffix) with no success.
The entire HTACCESS file looks like:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule (?!^(cms|images|js|mobile)(/.*|)$)^.*$ page.php [NC,L]
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule ^(.*)$ http://www.example.com/$1 [R=302,L]
Also, is there a %{CONSTANT} I can use in place of example.com that represents the current domain?
The constant you're looking for is %{HTTP_HOST} as provided by the HTTP request. Perhaps you are looking for the variable %{SERVER_NAME} for the virtual host's default servername?
Place the hostname checking rule first, and use a RewriteCond in the page.php rule to only apply if the domain is already correct:
RewriteEngine On
# First rewrite the domain
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
# Then rewrite the files
# At this point, the domain should already have been enforced
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule (?!^(cms|images|js|mobile)(/.*|)$)^.*$ page.php [NC,L]

Are conditionals in ModRewrite possible?

I have a simple piece of ModRewrite that channels everything to index.php if it's not an existing file or directory.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
Now I want to add a exception when the domain contains certain strings, but I don't know how to to add this. I was thinking of adding the following.
RewriteCond %{HTTP_HOST} ^(aanmelding|keyclamps|probouw)
RewriteRule ^(.*)$ /project.php/$1 [L]
UPDATE, I found a partial solution
If I put it like this:
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# If not an old project
RewriteCond %{HTTP_HOST} !^(aanmelding|keyclamps|probouw)
# forward it to index.php
RewriteRule ^(.*)$ /index.php/$1 [L]
# Else
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# forward it to project.php
RewriteRule ^(.*)$ /project.php/$1 [L]
It works, but with a bug. Because index.php exists, the second part of the conditional still goes to index.php instead of project.php when a plain domain is called like http://probouw.localhost/
Any ideas?
For anyone that might need this, the solution was:
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# If not an old project
RewriteCond %{HTTP_HOST} !^(aanmelding|keyclamps|probouw)
# forward it to index.php
RewriteRule ^(.*)$ /index.php/$1 [L]
# Else
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_URI} =/
# forward it to project.php
RewriteRule ^(.*)$ /project.php/$1 [L]
Perhaps using OR would help (NC=NotCase sensitive by the way)?
RewriteCond %{HTTP_HOST} ^.*aanmelding.*$ [NC,OR]
RewriteCond %{HTTP_HOST} ^.*keyclamps.*$ [NC,OR]
RewriteCond %{HTTP_HOST} ^.*probouw.*$ [NC]
In reference to your partial solution, if you change the last part does this work?
# forward it to project.php
RewriteRule ^/?$ /project.php [L]
RewriteRule ^(.*?)$ /project.php/$1 [L]

.htaccess redirect main domain?

How can I redirect requests to mydomain.tld/somepage.ext to mydomain.tld/mydomain/somepage.ext? I have subdomains like subdomain.mydomain.tld that I don't want to be affected by this.
I can't seem to get it to work right. I'm trying this:
RewriteEngine on
RewriteCond %{HTTP_HOST} mysite.com
RewriteCond %{REQUEST_URI} !^/mysite
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) /mysite/$1
But it isn't redirecting anything at all.
I also want to exclude one or two folders from this rule.
This seems to be working...
RewriteEngine on
RewriteCond %{HTTP_HOST} mysite\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/mysite/ # but I don't see why this line is needed when I've used [L] below
RewriteCond %{REQUEST_URI} !^/ignored_folder/
RewriteRule .* /mysite/$0 [QSA,L]
At least for now.

Resources