I have a php web application on Apache that supports multiple users identified by dist_id in the query string. So https://main.com/login?dist_id=21 shows a differently styled page from https://main.com/login?dist_id=26
What I want to do is register a domain name for each user and keep the URLs clean so that https://brandx.com/login invisibly points to https://main.com/login?dist_id=21. After the login I don't need dist_id anymore but I want to keep the user's domain so that https://brandx.com/products?show=1 etc. still works.
Is this possible and what's the best way to do it (mod_write, DNS, in PHP)?
Note I already have a rewrite rule to add index.php which is the entry point for all requests.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
I think I've gotten close with:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?dist_id=26 [QSA,L]
After logging in this works: https://brandx.com/categories but this gives a 404 error: https://brandx.com/categories?parent_id=12329
Presumably all of these "sites" would share an identical URL structures (minus query parameters)? In that case, it'd probably be simplest to set up a definition for your main.com site, and then add all of your brandx.com domains as aliases, e.g.
<virtualhost *:80>
ServerName main.com
ServerAlias brandx.com brandy.com brandz.com etc...
</virtualhost>
Then you use mod_rewrite to test the HTTP 'Host:` header to see which domain the users are hitting, and re-write as appropriate.
Related
We have Wordpress in the root / in a physical subfolder /wp and Magento in /products.
We are wanting to make the sites multi-language using sub folders e.g domain.com/en
The problem arises as magento appends the store code (language) after the url so we have
domain.com/en (wordpress)
domain.com/products/en (magento)
Naturally we would like
domain.com/en
domain.com/en/products
Now it's very easy to make it work with some rewrite rule
RewriteRule ^(.*)/products/?(.*)$ /products/$1 [L]
But still we have an issue as Magento generates the links as /products/en it's possible to start modifying where these links are generated like in
\Magento\Store\Model\Store
In the _updatePathUseStoreView function, this doesn't seem to handle all links though
In general seems like a bad solution, another idea is to use Apache mod_substitute also seems bad practice, and overhead.
Another option is to have both apps in the root and have some lookup logic to see which url belongs to which app.
Any ideas for a setup that can purely use just Nginx/Apache. That does not compromise on having unique url's or regex'ing content.
This is my .htaccess in the root
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
RewriteCond %{REQUEST_URI} !^/wp/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteCond %{REQUEST_URI} !^/(.*)/products
RewriteRule ^(.*)$ /wp/$1
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
RewriteRule ^(/)?$ wp/index.php [L]
RewriteCond %{REQUEST_URI} ^/(.*)/products
RewriteRule ^(.*)$ /products/index.php [L]
</IfModule>
The exact spec I'm trying to achieve is this.
Wordpress is installed in /wp , Magento in /products
Language codes via subfolders used on both sites to appear as /en/wordpress-page /en/products/magento-page
Attempt 1
Use base link URL entering /en/products there and keeping the base URL as /products
as the first request is forwarded I had to work the setEnv like so in the root .htaccess
RewriteCond %{REQUEST_URI} ^/(.*)/products
RewriteRule ^(.*)$ /products/index.php [E=MAGE_RUN_CODE:%1] [L]
then in /products/.htaccess
RewriteCond "%{ENV:REDIRECT_MAGE_RUN_CODE}"
RewriteRule .* - [E=MAGE_RUN_CODE:%{ENV:REDIRECT_MAGE_RUN_CODE}] [L]
I checked the code was coming through on index.php by doing
echo getenv('MAGE_RUN_CODE');
In my case the store code is "en" etc.. but the language switcher does not work it hits Magento but gets 404 even thought the store code is definitely coming through.
You only need some configuration from backoffice.
System => Configuration => General => Web => Url options
Add Store Code to Urls No
System => Configuration => General => Web => Unsecure
Base Link URL http://example.com/en/products/
System => Configuration => General => Web => Secure
Base Link URL https://example.com/en/products/
Then, add a rule in htaccess to set the correct store code:
SetEnvIf Host .*example.com/en* MAGE_RUN_CODE=en_store
SetEnvIf Host .*example.com/fr* MAGE_RUN_CODE=fr_store
What is the exact spec you're trying to achieve?
Do you have multiple pages like /products, and multiple languages like /en?
I did something similar at BXR.SU — I didn't like the way OpenGrok, my backend, was handling the URLs, so, I would automatically make my nginx fix the URLs on top of OpenGrok, seamlessly fixing the URLs presented to the user, whereas the backend would continue to use the old URLs (e.g., with the /xref/ for most pages, which I don't like, and was set to remove with nginx); this approach appears to be similar to your spec, where you want to do this on the front-end web-server without doing any modifications to the backend.
The approach is briefly described at nginx redirect loop, remove index.php from url, with the idea being that nginx has two types of redirects — internal, where the contents of the $uri variable gets changed (without any visibility to the user), and external, where a 301 Moved (or some such) response is provided to the client (and the user would then see the browser making a request with the new URL).
E.g., you may want to have something like the following:
location /en/ {
# issue an external redirect, unless we're here from an internal one
if ($request_uri ~ "^(/en)(/product)(.*)") {
return 301 $2$1$3; # external redirect
}
proxy_pass …;
}
location /products/ {
rewrite ^(/products/)(en/)(.*) $2$1$3 last; # internal redirect
…
}
Well, I want to know somebody me to explain, if possible, how could I manage one hosting to have two domains pointing to it.
My purpouse is to have two folders, and manage it with htaccess.
I have two parked domains in Hostinguer, now I want to know how can I make that the htaccess only allow one folder to one domain and the other folder to another domain, and take this to all the directories, because now, I can access my webpage by the two domains and I want to know how can I solve it.
My first try was this:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^(www|)\.domain\.com$ [NC]
RewriteRule ^ - [F]
I know more or less what is every thing, there is a little bit of Regex and some instructions that says how it has to works.
Let's say something like that in PHP:
if($_SERVER['SERVER_NAME'] == "www.domain.com") //There is an regex I know
exit; //Or, in this case throw a 403 error.
But, for example, I don't know how can I apply this action to all the subdirectories, avoiding this two-three lines to every .htaccess in every folder.
And also, It didn't work as I expected, because, it throw me a 403 error if I visit it from my domain.com, but also, it throw me a 403 error if I visit it from my subdomain: http://ikillnukes.hol.es/fapi (I will leave it running all the night to prove it)
Note: I don't have access to the Apache, so, don't suggest me to make an virtualhost because I can't. ;-)
EDIT:
I have now:
domain1.com, domain2.com and sub.domain1.com
And those folders:
root
domain1 //This is created by me
sub //This is automatically created by Hostinger, and I can't change the name or the path
domain2 //This is created by me
So, there is any problem by doing what #Walf suggested to me, but I have the problem of the subdomains and the .htaccess #Walf provided to me is a little bit compilcated to understand (my fault), so, what can I should try?
So, any help to me explaining how to approach this would be fantastic!
Thanks in advance!
Your question is probably a duplicate but I can't find one that uses adjacent dirs (as I think you're describing), nor one with a solution I'd use, myself. Try this in your root .htaccess:
RewriteEngine on
# capture the original request so you never have trouble with (un)escaping
RewriteCond %{THE_REQUEST} \S+\s+(\S*)
RewriteRule ^ - [E=REQ:%1]
# ensure the domain goes to a dir with the same name (ignoring www)
# get domain
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)
# see if first dir in url doesn't match domain
RewriteCond %1 =!^(?>([^|]+)\|\1)$
# capture first dir (if any) to check against above conditions and pass through as new url if not prefixed with domain dir
RewriteRule ^[^/]* %1%{ENV:REQ} [NE,DPI,PT]
Your dir structure would then be
docroot/
domain1.com/
whatever
domain2.net/
whatever
.htaccess
You should then be able to have normal .htaccess directives in each subdir, if you wish. Ensure you use RewriteBase / in those dirs.
Re-edit That just makes your situation more like most others'.
RewriteEngine on
RewriteBase /
# capture the original request so you never have trouble with (un)escaping
RewriteCond %{THE_REQUEST} \S+\s+(\S*)
RewriteRule ^ - [E=REQ:%1]
# ensure the domain goes to the required dir
# get domain
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)
RewriteRule ^ - [E=DOM:%1]
# explicitly set dir per host
RewriteCond %{ENV:DOM} =sub.domain1.com [NC]
RewriteRule !^sub/ sub%{ENV:REQ} [NE,DPI,L]
RewriteCond %{ENV:DOM} =domain2.com [NC]
RewriteRule !^d2/ d2%{ENV:REQ} [NE,DPI,L]
# allow domain1.com to proceed to root (any other rules go below)
# rules must still exclude subdirectories for other domains, e.g.:
RewriteRule ^(?!sub/|d2/)([^/]+)/([^/.]+)$ foo.php?bar=$1&baz=$2 [NE,B,L,DPI]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^(?:sub/|d2/|index\.php$) index.php [L,DPI]
# after all other rules, emulate DirectorySlash so that Apache does not naively insert hidden directory into public URL
DirectorySlash off
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (?>.*)(?<!/) %{ENV:REQ}/ [L,DPI,R]
If you're unsure of any regex, paste it into regex101.com (with the g flag off) and look at the explanation.
I own 2 domains that are pointing to the same static ip. I wanted to set domain1.com to be redirected to domain1.com/down.php but only for the target domain1.com and domain.com/index.php/html.
The domain2.com should work as usual, so no redirects here. It should target /var/www/html like it currently does.
Background is: that there was a project which should not be available on the domain1.com, but there are specific files such as domain1.com/subdir/subdir/file1.jpg, which should still be accessible there.
Any ideas?
Many Thanks
.htaccess to redirect domain1.com/*
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain1.com$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ down.php?_url=/$1 [QSA,L]
The rule only works if the condition is meet. ?_url=/$1 is not needed but may prove useful.
If you use htAccess, also it seems you use Apache2
You can also use virtual host directly from apache 2 configuration :
https://httpd.apache.org/docs/current/vhosts/examples.html
I am working with a custom MVC PHP framework and the index page (acting as a router) receives a GET variable "do" which contains the path that it will route to. If this variable is not set, it defaults to the Auth controller, method login.
require_once('config.php');
$controllerAction = isset($_GET['do'])?$_GET['do']:"auth/login";
require_once('core/main.php');
Then the index page (source code above) passes this $controllerAction to the main.php file, which autoloads the main controller and then loads the requested controller.
Thus, the URIs in this framework are of the form mysite.com/?do=controller/method/variable and I need it to be in the form mysite.com/controller/method/variable.
Here is the .htaccess file I tried to use, it just didn't work (I have other htaccess files working on the same server so it's not an Apache problem) :(
RewriteEngine On
RewriteRule ^([^/]*)$ /?do=$1 [L]
Someone suggested that I can do this using PHP but I am not sure how to go about that.
Edit:
The error is that I get "This page cannot be displayed", 404 errors, whenever I try to directly access the mysite.com/controller/method links rather than the default mysite.com?do=controller/method
Further Edit
(please note that other virtual hosts work fine on my localhost):
(XAMPP) Apache Virtual Hosting Info:
<VirtualHost *:80>
DocumentRoot "D:\sites\mysite.com\root\wwwroot"
ServerName mysite.com
ServerAlias mysite.com
<Directory "D:\sites\mysite.com\root\wwwroot">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
File structure (Windows):
D:\
--sites
----mysite.com
--------#client_details
--------root
-----------#devfiles
-----------#vars_pwd
-----------wwwroot
--------------config
--------------core
--------------application
------------------controllers
------------------libraries
------------------models
------------------views
----------------------css
----------------------javascript
----------------------images
----------------------icons
First of all, there are some issues with your .htaccess contents. It's always a good idea to not rewrite if a file with the requested name exists. This allows you to have an img/ folder for your images or any other static content like css files, javascript, downloads, etc.. The first RewriteCond tells Apache to only rewrite if no folder with this name exists. The second one does the same with files. Then you probably want the QSA (i.e. Query String Append) option, which will pass all other GET variables to your script.
Under this conditions you can simplify the regex and use this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?do=$1 [L,QSA]
You might be surprised because this is more or less the same as others posted. I use similar things for many of my projects and I've just tested it, I can guarantee that it works. There must be something wrong with your apache config.
When you have problems with mod_rewrite, the first thing you should try is to enable the module itself. Type these commands as root in your shell:
a2enmod rewrite
/etc/init.d/apache2 restart
The first one activates the module (or complains with Module rewrite already enabled if everything is ok) and the second one restarts your Apache server. The path may of course be different on your server.
Then you have to make sure that your VHost config allows you to use .htaccess files and do rewrites. This means AllowOverride must be set to at least FileInfo (or All). You could also try to put the rewrite rules right into the config file. Your config should look similar to this:
<VirtualHost *:*>
ServerName test.example.com
ServerAlias www.test.example.com
DocumentRoot /home/sites/test/
<Directory "/home/sites/test/">
Allow from all
AllowOverride All
Options +Indexes
</Directory>
</VirtualHost>
Note that you have to restart Apache if you change anything in there.
If that all doesn't help, it's always a good idea to have a look at the error logs. On my system they're located at /var/log/apache2/error.log (debian). They might give you more information on what's going wrong.
Try
RewriteEngine On
RewriteRule ^([^/]*)$ index.php?do=$1 [L]
Try
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?do=$1 [L]
Check your apache logs, access logs specifically. If the folder is present in the web root, then you should be able to access it directly :). You might also want to check if you have duplicate virtualhost entries for the same site by chance.
This one is my customized MVC framework which is based on cake
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?do=$1 [QSA,L]
</IfModule>
May be this should help. The typical URL pattern for this site.com/controller/method
I don't know what your domain setup is like, but here are some suggestions.
If your code resides in the root of your folder, and the index file is called index.php try the following:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?do=$1 [L,QSA]
If your website exists in a subfolder e.g. www.example.com/site/, and the index file is index.php Then try the following (change /site/ to whatever your folder is).
RewriteEngine On
RewriteBase /site/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /site/index.php?do=$1 [L,QSA]
If you still get the 404 error message then do the following:
Make sure your site allows .htaccess files to be processed by checking AllowOverride is set to all. If you don't have access to the necessary config files to check, a simple test is to setup an .htaccess rule to redirect to a dummy file on your system. If it works, then your .htaccess is being executed fine.
Have a look at your MVC framework to see what page it's actually sending the request to. The problem may be that you haven't defined a handler for that particular request, and the default action of your MVC framework is to throw a 404 error.
Edit: Just reading your description, I notice you said that the URL should basically be something like mysite.com/?do=controller/method/variable. If it has be very strict about this format, then you'll also need to put in rules for removing any leading or trailing slashes, e.g. the following re-write rule should do it:
RewriteRule ^\?(.*)\?$ /index.php?do=$1 [L,QSA]
(This makes the leading and trailing slashes optional, but it should remove them from the actual value you pass to do).
I wan't people to be able to register their own sections within my site, and have those sections be their own subdomain of my site. so someone can register 'test' and have 'test.example.com' refer to their site which would be at say /site.php?id=1 So how would i go about writing a mod_rewrite rule for this?
mod_rewrite might not be the best tool for this. RewriteRules are great for mapping a file to something else, but it was not really meant for domain matching.
The best you can do using mod_rewrite is the following:
RewriteEngine On
# Skip www.domain.com
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^([^.]+)\.domain\.com
RewriteRule ^/(.*)$ site.php?domain=%1&file=$1 [L]
Which is not really useful. What I would recommend to do instead if programmatically check the value of HTTP_HOST as such:
function get_subdomain() {
if(preg_match('/^([^.]+)\.domain\.com/i', $_SERVER['HTTP_HOST'], $matches))
return $matches[1];
}
You can configure apache to claim the "special" domains in the apache configuration (e.g. www.mydomain.com, etc), in your virtual host containers and have the others default to your first virtual host. You can then rewrite the base url to a dispatch application that inspects the URL and sends the user off to their correct area.
From Apache 2.0 docs:
Almost any Apache directive may go
into a VirtualHost container. The
first VirtualHost section is used for
requests without a known server name.
Put the code to handle *.mydomain.com in the first virtual host:
<VirtualHost *:80>
Servername custom.mydomain.com
DocumentRoot /var/www/html/custom
RewriteEngine on
RewriteRule ^/$ /var/www/cgi-bin/dispatch.cgi [R]
# more configs here
</VirtualHost>
<VirtualHost *:80>
Servername www.mydomain.com
DocumentRoot /var/www/html/homepage
# more configs here
</VirtualHost>
In dispatch.cgi, inspect the calling url to determine where the user should go. Make sure you set up your DNS to accept all subdomains.
Hope that helps!
Actually, we've been using this technique without much problem for the past year. Our mod_rewrite config looks like:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !www.mydomain.com
RewriteCond %{HTTP_HOST} ^([^.]+)\.mydomain\.com
RewriteCond %{REQUEST_URI} !admin
RewriteRule (.*) /admin/ [R=301,L]
RewriteRule ^admin(.*)$ hosted/admin/$1 [QSA,L]
What happens, is that users are directed to theiraccount.mydomain.com/admin.
We then use PHP to identify the account portion of the domain name. Using something like $_SERVER['SERVER_NAME'] or some method of getting the domain name and parsing it works very well.
Keep these configs in the httpd.conf though, this will become a cpu problem in higher traffic sites if it's kept as .htaccess.