.Htaccess RewriteRule (Subdomain vs Request_URI) - apache

I have several domain names, each with their own multiple subdomains.
currently, I have a global RewriteRule for any domain with a specific Request_URI meant for my REST APIs.
.htaccess
RewriteEngine on
RewriteRule ^/?api/(.*)$ /api/inbound.php [NC,L]
Affected Url Examples:
acct.domain1.com/api/clients/123
my.domain2.com/api/tasks/2323
new.domain3.com/api/products/1212
And the Rule works great!
Now I've started using these subdomains:
api.domain1.com/api/clients/123
api.domain2.com/api/tasks/2323
api.domain3.com/api/products/1212
Though this still works, it's annoyingly redundant.
So, if the Subdomain happens to be "api, sandbox, api.test, or any chosen nuance I'm going to omit the /api/ path from the URL.
How would the RewriteRule look for this scenario?

Examine the HTTP Host Header value with a RewriteCond:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^api(\.test)?|sandbox
RewriteRule ^/?(.*)$ /api/inbound.php [NC,L]

Related

.htaccess redirecting URL but not content for subdomain

I'm trying to set up a test site but having real trouble getting .htaccess to redirect properly.
I want the contents of www.example.com/test to show when a user types in test.example.com. My rewrite rules allow me to use test.example.com in the address bar, but it's actually showing me the content of the root (www.example.com), not the test subfolder.
I'm not an .htaccess guru by any stretch, but I've been using Stack Overflow for 5 years and this is the first time I've been stumped enough to ask a question! Your collective wisdom is appreciated.
Here's the relevant part of my .htaccess code:
RewriteEngine On
# Rewrite for http cases
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
# Rewrite for no www cases
RewriteCond %{HTTP_HOST} !www\.example\.com [NC]
#redirect for test subdomain
RewriteCond %{HTTP_HOST} !^test\.example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
# redirect to correct for old subfolder usage
RewriteRule ^oldsubfolder/$ https://www.example.com/ [L,R=301]
I want the contents of www.example.com/test to show when a user types in test.site.com.
I assume you just have one domain and test.site.com should really be test.example.com (which would seem to be consistent with the rest of your question)?
In the code you've posted, there's nothing that really attempts to do this redirect? In the code you've posted, a request for test.example.com would not be redirected - so if it is then you may be seeing a cached response. Clear your browser cache.
You would need something like:
RewriteCond %{HTTP_HOST} ^(?:www\.)?(test)\.example\.com [NC]
RewriteRule (.*) http://www.example.com/%1/$1 [R,L]
The (?:www\.)? part simply catches an optional www subdomain of the subdomain! Depending on how this subdomain was created, both test.example.com and www.test.example.com might be accessible. (Although I suspect your SSL cert probably doesn't allow this anyway?)
%1 is a backreference to the captured group in the CondPattern (ie. test) and $1 is a backreference to the captured RewriteRule pattern. Capturing the subdomain (eg. "test") just avoids repetition, but also allows for more than one subdomain to be handled by the same rule.
This is also a temporary (302) redirect. Change this to a 301 only when you are sure it's working (if that is the intention). 301s are cached by default, so can make testing problematic.
Clear your browser cache before testing.
# Rewrite for no www cases
RewriteCond %{HTTP_HOST} !www\.example\.com [NC]
#redirect for test subdomain
RewriteCond %{HTTP_HOST} !^test\.example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
The comment in the middle of this block would seem to be misleading (it doesn't "redirect for test subdomain"). The whole block just redirects to www, excluding the test subdomain. The other code then redirects the subdomain.
UPDATE:
I was hoping it would continue to show test.example.com in the address bar
Yes, this is possible. Providing test.example.com and www.example.com point to the same filesystem then you can simply rewrite the request without actually changing the host. For this example, I'll assume test.example.com and www.example.com point to the same document root.
Change the above redirect to the following rewrite:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} ^(?:www\.)?(test)\.example\.com [NC]
RewriteRule (.*) /%1/$1 [L]
The request now stays on test.example.com and will serve content from test.example.com/test (although this is hidden from the user) since test.example.com and www.example.com are really the same thing.
The check against REDIRECT_STATUS ensures we are only processing the intial request and not the rewritten request, thus avoiding a rewrite loop. REDIRECT_STATUS is empty on the initial request and set to 200 after the first successful rewrite.
However, if test.example.com points somewhere entirely different then you'll need to implement a reverse proxy and "proxy" the request to www.example.com in order to "hide" this from the user.

Rewrite part of query string with apache mod_rewrite

Need help with rewriting part of query string with mod_rewrite.
Looked through a lot of resources and have a general understanding of how stuff works but cannot figure out correct solution
This link:
http://example.com/?param=home&shop_id=1000005620&ate=bow&b_uid=-1&tg=one
Has to become this
http://example.com/?param=home/#/shop/1000005620?ate=bow&b_uid=-1&tg=one
If shorter, then this part of query string
&shop_id=1000005620& transforms into /#/shop/1000005620?
UPDATE:
Answer gave me a clear understanding what I had to do.
Exact rules that fixed my issue were like this:
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} ^(.*)&shop_id=([0-9]{10,12})(?:&)(.*)$
RewriteRule ^(.*)$ https://%{SERVER_NAME}/$1?%1/#/shop/%2\?%3 [NE,L,R]
</IfModule>
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} ^shop_id=([0-9]{10,12})$
RewriteRule ^(.*)$ https://%{SERVER_NAME}/#/shop/%1? [NE,L,R]
</IfModule>
Reason for this rewrite rules is hash handling with safari and ie
I have links that are used by external pages and also I have a redirection to https if site request http. If there is a hash in the link and request is sent from Safari or IE hash goes away from the URL and does not come back after redirection. I want to note very important fact that Chrome, Firefox do not have problems with keeping the URL with hash even after redirect to https. This involved to reconstruct our URL but it is worth it and now everything is working as it should.
You can try:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^(.*)&shop_id=([^&]+)&?(.*)$
RewriteRule ^(.*)$ /$1?%1/#shop_id=%2?%3 [L,R,NE]
EDIT:
what about if I only what to rewrite http://example.com/?shop_id=1000005620 into http://example.com/#/shop/1000005620 what the rewrite rule be then?
Just change the relevant parts of the regex pattern:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^shop_id=([^&]+)$
RewriteRule ^(.*)$ /$1/#shop_id=%2? [L,R,NE]

ReWrite Rules Issue

I seem to be having an issue with my Apache Rewrites
RewriteEngine on
RewriteBase /
RewriteRule ^wordpress/?$ / [NC,L,R=301]
RewriteRule ^/$ wordpress/ [NC,L]
I simply need to remove /wordpress from the URL as I have pages within Wordpress I want to be seen as the main directory
At the moment the urls are
domain.com/wordpress/blog
I'd rather not have /wordpress, rather domain.com/blog
Any help?
RewriteEngine on
RewriteBase /
RewriteRule ^wordpress/(.*)$ blog/$1 [L]
At the moment the urls are
domain.com/wordpress/blog
I'd rather not have /wordpress, rather domain.com/blog
So it looks like you want to redirect the browser if someone makes a request for domain.com/wordpress/ to a URL without the wordpress bit, then internally rewrite the wordpress bit back into the URI? That's definitely do-able but if you have wordpress rewrite rules somewhere they're not going to play nicely with each other at all.
Any rules in the /wordpress directory will supercede any rules you put in the document root, which is where these rules need to go, and your remove-the-wordress-from-URI rules will be completely ignored. Even if you have rule inheritance turned on, the rules in the /wordpress directory will get executed first.
If all of your wordpress rules are actually in the document root's htaccess file, then just make sure to put these before the wordpress ones:
RewriteEngine on
RewriteBase /
# redirect the browser if someone makes a request for domain.com/wordpress/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /wordpress/
RewriteRule ^/?wordpress/(.*)$ /$1 [L,R=301]
# internally rewrite the wordpress bit back into the URI
RewriteRule %{DOCUMENT_ROOT}/wordpress%{REQUEST_URI} -f [OR]
RewriteRule %{DOCUMENT_ROOT}/wordpress%{REQUEST_URI} -d
RewriteRule ^(.*)$ /wordpress/$1 [L]

htaccess / mod_rewrite for Search Engine Friendly URLs

I have a bunch of files in the web root: -
/abc-674.php
/def-643.php
etc.etc.
I want to show these when the following URL's are requested, without changing the URL in the browser: -
/products/abc-674/this_can_be_anything.php
/products/abc-674/or_this.php
both redirect to /abc-674.php, and
/products/def-643/this_can_be_anything.php
/products/def-643/or_this.php
both redirect to /def-643.php.
So, basically, the bit between products/ and the next / is the target, while anything after that can effectively be ignored.
If it matters, I've already got a little code in my .htaccess to direct all traffic to my preffered domain (with www): -
# Direct all traffic to domain.com
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.domain\.com [NC]
RewriteCond %{HTTP_HOST} !^domain$ [NC]
RewriteRule ^(.*) http://www.domain.com/$1 [R=301,L]
EDIT: To clarify - the 2nd last line in the above is because I access the site on my dev server via http://domain/ only, and so don't want that rewrite to apply for those requests. I do, however, want this new rewrite to apply to all requests.
Any help greatly appreciated!
I think, you can use the next rule in .htaccess:
RewriteRule ^products/([\d\w]+)/(.*)$ /$1.php

How to rewrite URL based on domain in apache and add extra parameter?

Basically, what I want to do is to rewrite all urls because we have many different languages. We have a server that hosts several domains. We have www.example.com, www.example.fr, www.example.de, www.anotherdomain.com, www.anotherdomain.de. What I want to do is to redirect all requests from example.xxx to www.example.com with extra url parameter lang=en. This should not affect other domains like www.anotherexample.com etc.
This does not work:
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.de$
RewriteRule ^(.*)$ http://www.example.com/$1?lang=de [PT]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.fr$
RewriteRule ^(.*)$ http://www.example.com/$1?lang=fr [PT]
One thing that makes it even more difficult is that the ServerName is totally different than the host name, it is called prod.migr.com.
Any suggestions would be appreciated.
Try this:
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.de$
RewriteRule ^ http://www.example.com%{REQUEST_URI}?lang=de [L,R=301,QSA]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.fr$
RewriteRule ^ http://www.example.com%{REQUEST_URI}?lang=fr [L,R=301,QSA]
The PT flag is most likely your problem. I've never seen it used when the target is a full domain address because it's meant for URI's to be further redirected with mod_alias.
The flag you should be using is the QSA flag in case the page the user is visiting has a query string on it.
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.de$
RewriteRule ^(.*)$ http://www.example.com/$1?lang=de [QSA]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.fr$
RewriteRule ^(.*)$ http://www.example.com/$1?lang=fr [QSA]
However, a much better solution would be to check the host the user is visiting in your server-side language such as php or asp if all languages are hosted on the same server like this.
EDIT in response to additional information:
You can not get POST variables through rewriting to different domains like that because it has to redirect the request.
Your best bet is to determine the language in your server side language instead of using mod_rewrite.
If you use php it would be like this
$lang = substr(strrchr($_SERVER['HTTP_HOST'], '.'), 1);
Other languages have similar ways to determine the host.