RewriteCond backrefrence to another RewriteCond causing 500 - apache

I have setup a *.mydomain.com subdomain in cpanel (cpanel, no shell access)
Going to anything.mydomain.com gets me to the same directory which I mounted for *.mydomain.com
So when I go to test.mydomain.com with the following in .htaccess,
What works properly is:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.+)\.(.+?\..+?)$ [NC]
RewriteCond %{REQUEST_URI} !^/test/(.+)?$
RewriteRule ^(.*) /%1/$1
What doesn't work and gives a 500 Error is this (Just replaced the test with %1):
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.+)\.(.+?\..+?)$ [NC]
RewriteCond %{REQUEST_URI} !^/%1/(.+)?$
RewriteRule ^(.*) /%1/$1
What I want to do is allow dynamic setup of subdomains if a subdirectory with it's name exists. The rewriting is done gracefully when I hardcode the subdomain name test in the .htaccess and not when I use a backrefrence %1 for it.

You can't use a % variable or a backreference as part of the regular expression in a RewriteCond. You can create a string usimg a backreference and a # regex backreference:
RewriteCond %1:%{REQUEST_URI} !^([^:]+):/\1/(.+)?$
So you create a string made up of the subdomain of the host match, a colon, then the URI, match against the subdomain in your regex, and reference it using \1.
Additionally, you may need to add another %{HTTP_HOST} match right after because the %1 backreference might have gotten reset because you can't backreference a non match.

Related

Redirect from root to Specific URI with HTTPD.conf

The first rule works fine when the maintenance file is in place. When it's not - the second rule is not redirecting to the specific URI. Is there an ordering issue of rules or ?
#########################################
RewriteCond %{DOCUMENT_ROOT}/server_maintenance.html -f
RewriteCond %{REQUEST_FILENAME} !/server_maintenance.html
RewriteRule ^.*$ /server_maintenance.html [L]
#########################################
## the %{HTTP_HOST} evaluates to the HTTP header with the name given in this case host.server.org, with NC being non case sensitive.
## it will rewrite the url at the server side to append the URI of lawson/portal
##########################################################################
RewriteCond %{HTTP_HOST} ^host\.server\.org$ [NC]
RewriteRule ^host\.server\.org$ "https\:\/\/host\.server\.org\/lawson\/portal" [L]
#########################################
You don't match a hostname in a RewriteRule, even so with more reason if you are already matching it in a previously defined RewriteCond.
So just do:
RewriteCond %{HTTP_HOST} ^host\.server\.org$ [NC]
RewriteRule ^ https://host.server.org/lawson/portal [L]
Note: RewriteRule target/destination is not regix so do not need to escape every single little thing.
Note2: a single ^ will match anything

Redirect pages from subdomain to the same full path on main domain

I have many pages with the following type of paths and subdomains:
place1.maindomain.com/travel/place1/go/
place2.maindomain.com/travel/place2/go/
place1.maindomain.com/travel/place1/widgets/
place2.maindomain.com/travel/place2/widgets/
I want to make all of these domains redirect automatically with a wildcard to the www and not the subdomain, so they would appear as follows:
www.maindomain.com/travel/place1/go/
www.maindomain.com/travel/place2/go/
www.maindomain.com/travel/place1/widgets/
www.maindomain.com/travel/place2/widgets/
My programmer has tried but he says he cannot do it. Is there a reason this type of subdomain wildcard redirect is not possible?
The redirect is easy. What's preventing you from just doing something like:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^(www\.)?maindomain\.com$ [NC]
RewriteRule ^ http://www.maindomain.com%{REQUEST_URI} [L,R=301]
If you mean tha tthe "place1" part must match the "place1" part in the path, then you can do:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^(www\.)?maindomain\.com$ [NC]
RewriteCond %{REQUEST_URI} ^/[^/]+/([^/]+)/
RewriteCond %{HTTP_HOST}|%1 ^([^.]+)\.maindomain\.com|\1$
RewriteRule ^ http://www.maindomain.com%{REQUEST_URI} [L,R=301]

*Generic* httpd.conf redirect non-www to www

Is it possible to have a generic / multi-domain httpd.conf line that will redirect any non-www request to its www equivalent?
By generic, I mean something that does not rely on hardcoded domain name, ie.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^yourdomain.com [NC]
RewriteRule ^(.*)$ http://www.yourdomain.com/$1 [L,R=301]
I really don't want to edit httpd.conf every time I have another website added/removed from my server, esp. that websites are added/removed dynamically!
The mod_rewrite documentation has all the information you need, but there is a lot to read. There are two parts to what you want: first, you need to match any domain not starting with www.; then, you need to prefix www. to the current URL.
For the first part, there's this (which applies to both RewriteCond and RewriteRule):
You can prefix the pattern string with a '!' character (exclamation mark) to specify a non-matching pattern.
So "hostname doesn't begin www." could be tested like this:
RewriteCond %{HTTP_HOST} !^www\. [NC]
For the second part, there's this:
In addition to plain text, the Substition string can include [...] server-variables as in rule condition test-strings (%{VARNAME})
So the actual redirect can be made generic like this:
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L,R=301]
Incidentally, it's also possible to do the opposite (redirect everything to not have the www.) because RewriteRule substitutions can also use this:
back-references (%N) to the last matched RewriteCond pattern
So you could capture everything in the hostname after the www. and use that as the target of the rule:
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

Using .htcaccess to redirect to www. AND add trailing forward slash

I have searched around for a while and had a go at tweaking this file myself and I'm almost there but there is one case which I can't figure out...
How to get both a www. AND a forward slash at the same time
If I type in spectrl.com, it redirects to www.spectrl.com CORRECT - Adds www.
If I type in www.spectrl.com/ebaycalculator it redirects to www.spectrl.com/ebaycalculator/ CORRECT - Adds /
But if I type in spectrl.com/ebaycalculator I get a 404 error when it should go to www.spectrl.com/ebaycalculator/
Here's my .htcaccess file, kept at the root:
RewriteBase /
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://spectrl.com/$1/ [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Thanks
#Kavi
Try this:
RewriteEngine On
RewriteCond "%{HTTP_HOST}" "^(?:www\.)?(.*)" [NC]
RewriteCond "%{REQUEST_URI}" "!/$"
RewriteRule "(.*)" "http://www.%1%/$1/" [R=301,L]
RewriteCond "%{HTTP_HOST}" "!^www\." [NC]
RewriteRule "(.*)" "http://www.%1/$1" [R=301,L]
The first RewriteCond captures the hostname (without any leading www.) in the reference %1. That condition will always succeed.
The second RewriteCond checks for the trailing slash; if not found, the next RewriteRule will be triggered.
That first RewriteRule uses the captured www.-less host name to construct a redirect that includes www. and the training /.
The second stanza will be triggered if the request falls through because it does have a trailing /. It checks for a leading www., and does the same sort of redirect (only without appending a slash, since there's already one there) as the first stanza.
At least, that's how is should work; I haven't tested it. :-)
After removing and re-uploading .htaccess and then clearing the cache, everything seems to be working as intended using my original code in the question.
Hope this will be helpful for someone else.

How can I change all subdomains to read different content from their respective subdirectories?

I have my DNS configured to accept any subdomain (wildcard *), but I am having trouble feeding back the required content to the browsers.
I would like each subdomain to return the relative content, which resides in subdirectories of the same name within the public_html path of my server.
eg, example.domain.com/picture.jpg would actually request the file at public_html/example/picture.jpg
Currently I have tested the followed .htaccess code, but it is not functional:
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com$ [NC]
RewriteRule ^(.*)$ %1/$1 [L]
This code, and similar tests, can redirect based on the subdomain (%1) fine, but the request string ($1) seems to be the issue.
Maybe you could take a look at the mod_vhost_alias module :
http://httpd.apache.org/docs/2.0/mod/mod_vhost_alias.html
Try the following:
RewriteCond %{HTTP_HOST} ^([0-9a-z-]+).domain.com [NC]
RewriteRule ^/(.*) http://domain.com/%1/$1 [L]
I didn't test this one but I use similar rules for proxying:
RewriteCond %{HTTP_HOST} !^domain.local [NC]
RewriteCond %{HTTP_HOST} ^([0-9a-z-]+).domain.com [NC]
RewriteRule ^/(.*) http://domain.local/%1/$1 [P]