htaccess Subdomain don't work with mod_rewrite enable - .htaccess

I already searched for many tutorials and nothing worked to me.
I want create virtual subdomains with htacces but when I enable mod_rewrite my software disable the original urls. For example:
mod_rewrite disabled:
http://domain.com/listings.php?category=35
mod_rewrite enabled:
http://domain.com/35-finance/listings.html
When enabled I can't acces http://domain.com/listings.php?category=35...
In my htacces, if mod_rewrite disabled, this works:
RewriteCond %{HTTP_HOST} !www.domain.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www.)?([a-z0-9-_]+).domain.com [NC]
RewriteRule (.*) listings.php?category=%2 [NC,QSA]
But if enabled, it don't work, it don't understand the 'category' parameter.
I tried this:
RewriteRule (.*) http://www.domain.com/%1/listings.html [L]
I'm redirected to the correct page, but I want to keep the subdomain in the browser bar...
I tried this:
RewriteRule (.*) /%1/listings.html [L]
It results in internal server error.
I really tried many things before in this week, but nothing works...

RewriteCond %{HTTP_HOST} ^(www.)?([a-z0-9-_]+).domain.com [NC]
RewriteRule (.*) listings.php?category=%2 [NC,QSA]
But if enabled, it don't work, it don't understand the 'category' parameter.
The %2 means to match the second pattern in the RewriteConds. In this cae, the second pattern is the ([a-z0-9-_]+) part.
In my htacces, if mod_rewrite disabled, this works:
If mod_rewrite is truly disabled, then those rules aren't being used.
RewriteRule (.*) http://www.domain.com/%1/listings.html [L]
I'm redirected to the correct page, but I want to keep the subdomain in the browser bar...
If you supply a domain in the RewriteRule, you will always be redirected, you need to supply a path only (like /%1/listings.html). If the domains are all part of the same VirtualHost, this should not be a problem.

I got solve the problem using this php code: (www.gitme.net/php/ >> Gitme url2subdomain )
<?php
// code by büyücü. www.gitme.net/php/
$full_url = sprintf($HTTP_HOST);
$subdomain = "";
for($i = 0;$i<=strlen($full_url);$i++)
{
$dummy = substr($full_url,$i,1);
if($dummy == ".")
{
break;
}
$subdomain = $subdomain.$dummy;
}
//
if ($subdomain <> "www")
{
switch($subdomain)
{
case "gazeteler":
$real_url = "http://www.gitme.net/gazeteler.htm";
break;
case "guzel-sozler":
$real_url = "http://www.gitme.net/guzel-sozler.php";
break;
case "burclar":
$real_url = "http://www.gitme.net/burclar.html";
break;
default : $real_url="http://www.gitme.net/";
}
include "$real_url";
exit;
}
?>

Related

Rewrite url to pretty after redirect to folder - htaccess laravel

Hello I have a "protected" folder on my server. In its .htaccess file for conditional redirect of some users I use the following rules:
RewriteCond %{REMOTE_ADDR} ^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} !^/special
RewriteRule ^$ /special [R,NE,NC]
In the /special folder I have a .htaccess file with the following rules:
RewriteCond %{REMOTE_ADDR} !^1\.2\.3\.4$
RewriteRule ^(.*)$ / [R=301,NE,NC,L]
The application in the folder will be laravel based so my content will have to be served from index.php file residing in /special/laravel/public/index.php
I want the URL to look like /special/.
What rules should I put and where for this to happen?
This is a follow up to my previous question:
https://stackoverflow.com/questions/24487012/redirecting-specific-ip-to-special-content-htaccess-vs-php
Simply rewrite the URL with .htaccess: (goes in /)
DirectoryIndex index.php
#Redirect to /special/laravel/public if you haven't already and the IP is okay
RewriteCond %{REMOTE_ADDR} ^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} !^/special/laravel/public
RewriteRule ^(/special)(/laravel)?(.+) /special/laravel/public$2 [L]
#if IP does not match and you ARE in the folder, then Redirect to root
RewriteCond %{REMOTE_ADDR} !^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} ^/special/laravel/public
RewriteRule .? / [R=301,L]
I think that'll work. I didn't test it though. I can add to it if you need me to. And of course for your use case you may need to add some more RewriteConds in there for validating the REMOTE_ADDR.
The way I handle it:
.htaccess:
RewriteCond %{REQUEST_URI} !^/load_page.php$
RewriteRule ^(.+)$ /load_page.php [QSA, L]
That causes the server to redirect internally to load_page.php if the requested URL is not load_page. Without the RewriteCond, I believe it would cause an infinite redirect. This should work, but I didn't test it because it's different from my implementation, since mine also handles rewriting URLS to have trailing slashes and never show .php which makes it a bit more complex and quite different.
load_page.php:
$SITE_ROOT = $_SERVER['DOCUMENT_ROOT'];
$URL = $_SERVER['REQUEST_URI'];
ob_start();
if (conditionOne){
//change $URL here if you need to or do nothing
} else if (conditionTwo){ //check the IP or whatever you want to here
if (aCondition){//if $URL starts with '/special'
$URL = str_ireplace('/special/','/special/laravel/public/',$URL,1);
}
if (is_dir($SITE_ROOT.$URL))$URL .='index.php';
}
if (!file_exists($SITE_ROOT.$URL))$URL = '/error/404.php';
include($SITE_ROOT.$URL);
$content = ob_get_clean();
echo $content;
It's something to that affect. The user doesn't see load_page.php and they don't see that you changed the URL to special/laravel/public, but you include the correct file.

Force language GET variable via htaccess or ...?

I have 3 subdomains , which are based on Opencart.
What I need to force on each domain given language
to do so _GET['language'] should be defined strictly for each subdomain
en.handmade24.at -> language=en
ru.handmade24.at -> language=ru
www.handmade.24.at -> language=de
I was told .htaccess was a good option to force language variable...
But how can i define the rules? Any help? I am dummy in htaccess...
my Htaccess looks like this
Options +FollowSymlinks
# Prevent Directoy listing
Options -Indexes
# Prevent Direct Access to files
<FilesMatch "\.(tpl|ini)">
Order deny,allow
Deny from all
</FilesMatch>
# SEO URL Settings
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
Or maybe you could offer nicer solution?
RewriteCond %{HTTP_HOST} ^(www\.)?handmade24\.at
RewriteRule ^(.*)$ $1?language=de [QSA,L]
RewriteCond %{HTTP_HOST} ^(\w+)\.handmade24\.at
RewriteRule ^(.*)$ $1?language=%1 [QSA,L]
Here is the .htaccess that should work for you:
Options +FollowSymlinks
# Prevent Directoy listing
Options -Indexes
# Prevent Direct Access to files
<FilesMatch "\.(tpl|ini)">
Order deny,allow
Deny from all
</FilesMatch>
# SEO URL Settings
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?_route_=$1 [QSA,L,NE]
RewriteCond %{HTTP_HOST} ^(www\.)?handmade24\.at$ [NC]
RewriteRule ^(.*)$ $1?language=de [QSA,L]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.handmade24\.at$ [NC]
RewriteRule ^(.*)$ $1?language=%1 [QSA,L]
First of all, I have taken out the OpenCart system for the project which I solved your issue, but this trick should work just fine.
Yes you can do it with .htaccess, however I do not want to recommend doing that. Messing with .htaccess can be a pain in a certain place. If you do it, at some point you will most likely end up doing something wrong and corrupt something. It isn't the only solution, and that is why I wont tell you how to do it with .htaccess.
The solution I would recommend is a neat little work-around/hack I've just made. I where looking for a way to do it with subdomains, since it is Google's preferred choice of doing the multi language versions of websites (except of TLD's of course).
I came up with the solution to overrule the default OpenCart language selection/detection.
First of all open up index.php in the root of your OpenCart install.
Go find the lines with this:
if (isset($session->data['language']) && array_key_exists($session->data['language'], $languages) && $languages[$session->data['language']]['status']){
$code = $session->data['language'];
} elseif (isset($request->cookie['language']) && array_key_exists($request->cookie['language'], $languages) && $languages[$request->cookie['language']]['status']) {
$code = $request->cookie['language'];
} elseif ($detect) {
$code = $detect;
} else {
$code = $config->get('config_language');
}
Then replace those lines with this:
$url_info = parse_url(str_replace('&', '&', $config->get('config_url')));
foreach ($languages as $language)
{
if ($language['code'] . '.' . $url_info['host'] == $request->server['HTTP_HOST'])
{
$overwrite_language = $language;
break;
}
}
if (isset($overwrite_language)) {
$code = $overwrite_language['code'];
} elseif (isset($session->data['language']) && array_key_exists($session->data['language'], $languages) && $languages[$session->data['language']]['status']) {
$code = $session->data['language'];
} elseif (isset($request->cookie['language']) && array_key_exists($request->cookie['language'], $languages) && $languages[$request->cookie['language']]['status']) {
$code = $request->cookie['language'];
} elseif ($detect) {
$code = $detect;
} else {
$code = $config->get('config_language');
}
What this do is (note: OpenCart did load the available languages from the database a few lines earlier):
We get the URL from the database ("setting table" where key = 'config_url'), then we use the PHP function parse_url, which splits it up in parts (do a print_r() on it to see what parts).
We then loops through the languages that is available (those that are enabled in the admin panel).
In the loop we check if the $language['code'] . '.' . $url_info['host'] == $request->server['HTTP_HOST'] (an alias of $_SERVER['HTTP_HOST']). I've put in a break so it would stop wasting resources if it already have found a matching language for the domain.
I've edited the if elseif etc etc else statement that OpenCart made whith the above one. What it does is that it check if $overwrite_language is set, if it is then it makes that the language that the user " * selected * ", since it hit the if in the if elseif etc etc else statement then it wont run any of the others (which then would overwrite this little work-arround/hack).
-- Bonus tip --
If you have access to the php.ini config file, or you have permission to use ini_set(), then you can share your PHP session between subdomains
ini_set('session.cookie_domain', '.yourdomain.TLD');
(you may need to destroy an already created session). That could be an advantage, however note that it will overwrite the default shop language, but you can modify the 2 if's below the lines you just changed. The currencies should work as usual though.
-- Finishing up --
That should be it, hope you will like it and can use it, even though it is a long time you asked this question, maybe someone else could use it, just as I could a few hours ago.

How to rewrite URLS to remove index.php AND force lowercase with codeigniter?

I’m having trouble doing both of these at once with .htaccess.
Removing index.php is working, but trying to add the force lowercase keeps throwing a 500 error. I am using codeigniter. Any help is appreciated!
here’s my .htaccess code:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1
RewriteMap lc int:tolower
RewriteCond %{REQUEST_URI} [A-Z]
RewriteRule (.*) ${lc:$1} [R=301,L]
The php code suggested does not work if you are just trying to force to lowercase. Below is the correct php code.
$url = $_SERVER['REQUEST_URI'];
$pattern = '/([A-Z]+)/';
if(preg_match($pattern, $url)) {
$new_url = strtolower($url);
Header( 'HTTP/1.1 301 Moved Permanently' );
Header( 'Location: ' . $new_url );
exit;
}
// your code here
Discussion Found Here Force lowercase .htaccess
That is because it is impossible, let me explain.
Removing the index.php still sends all requests to index.php/yadda/yadda so the requested uri still has the index.php in it even though you do not see it or add it into the url.
The redirect (triggered by the 2nd rewrite rule) nulls the index section so you would then get mysite.com/index.php/lowercase/
BUT beyond all this RewriteMap can only be declared in your Httpd.conf file, you would declare it there with:
RewriteMap lc int:tolower
Then in your .htaccess file use your variable lc, but then again only one of the two will win you can't have both.
You will either get the URL lowercase or have the site working without using the index.php because they are always going to conflict because of the nature of what each one does.
Really the only way I can see it happening is in php, like so:
$this->load->helper('url');
$your_URL = uri_string();
preg_match_all('/[A-Z]/', $your_URL, $match) ;
$total_count = count($match [0]);
if($total_count > 0){
$new_line = strtolower($your_URL);
redirect($new_line);
}
This I would put into the main construct of your classes, I hope this helps you.

.htaccess subdomains redirect is not working

Ok, now I am lost.
I am trying to do a simple .htaccess redirect of subdomains to a specific folder on the server, meaning all
subdomain.mywebsite.com
will go to
www.mywebsite.com/s_subdomain
But for some reasons this doesn't work.
I have tried a lot of settings in .htaccess but for no good. Now in my .htaccess I have:
RewriteEngine on
Options +FollowSymLinks
Options +SymlinksIfOwnerMatch
RewriteCond %{HTTP_HOST} !^(www|ftp|mail)\.mywebsite\.com
RewriteCond %{HTTP_HOST} ^([^.]+)\.mywebsite\.com
RewriteRule (.*) /s_%1/$1 [L]
Are there any other settings, or is somethig I have missed?
PS. - I don't have access to http.conf. I have to do it using only .htaccess
Thanks!
This is just a "plain" rewrite (the browser won't see it). To redirect, add the R flag to your RewriteRule.
RewriteRule (.*) /s_%1/$1 [L,R]
The rest seems right, although I haven't tested it. For debugging you could consider RewriteLog, see http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#rewritelog
So, neither solution does work? Try something simple then.
RewriteEngine on
RewriteCond ${SERVER_NAME} ^(subdomain)\.yoursite\.com$ [nc]
RewriteRule ^(.*)$ http://www.yoursite.com/s_%1/$1 [L,R]
To test if your subdomain is handled correctly, create random.html file, place it where it should be read from, and try opening it via http://subdomain.yoursite.com/random.html. Then you can try some stuff like:
RewriteRule ^random.html - [F]
...and if that blocks access to file, try prepending
RewriteCond ${SERVER_NAME} ^subdomain\.yoursite\.com$ [nc]
to previous rule, to block access to that file, to make sure that rewrite engine is actually hitting your rules. That would target only desired subdomain (www.yoursite.com/random.html should work, but access via subdomain shouldn't).
Then if those rules work, it's just a matter of adding more stuff and see when it stops working.
RewriteRules are a bitch.
The following should work:
.htaccess:
RewriteCond ${SERVER_NAME} !^(www|ftp|mail)\.example\.com$
RewriteCond ${SERVER_NAME} !^([^.]+)\.example\.com$
RewriteRule .* redirect.php?to=%1
redirect.php
<?php
$desired_server_name = 'http://example.com';
$subdir = 's_' . $_GET['to'];
$url = $desired_server_name . '/' . $to . $_SERVER['REQUEST_URI'];
// Permanent redirects
header('HTTP/1.1 301 Moved Permanently');
// Or simple redirects:
header('HTTP/1.1 302 Found');
header('Location: '.$url);
?>
Works on my server (debian 4/apache 2).
Bonus: do not EVER use HTTP_HOST! See the following request:
HTTP/1.1 GET /foo/bar.php
Host: www.host.tld"><script>alert(/Hello/)</script
Connection: close
If you use $_SERVER['HTTP_HOST'] in your .php scripts to construct links or .htaccess rules for that matter and "www.host.tld" is the virtual-host or the only host configured for Apache, the XSS in the HTTP request header will be passed down unescaped.
We have a similar thing working on our Virtual Machines, where we redirect anything.usertld to a folder for that domain, that was in httpd.conf, tried in in the .htaccess and like yours it didn't work.
Tweaking it, this works for me (my VM occupies a tld called benb, but changing it to your domain should be fine):
RewriteCond %{HTTP_HOST} !^www\.benb
RewriteCond %{HTTP_HOST} ^(.*)\.benb
RewriteCond %{REQUEST_URI} !^/{0,1}s_
RewriteRule ^(.*)$ s_%1/$1 [L]
Also this captures all the text before the domain.. you should be able to change:
RewriteCond %{HTTP_HOST} ^(.*)\.benb
to
RewriteCond %{HTTP_HOST} ^([^.]+)\.benb
to handle just 1 level of subdomain. Also your other part about (www|ftp|mail) would work fine too.

Redirect pages from old to new site - one by one

I'm trying to redirect pages from several old domains on one new domain on a page-to-page basis, that is:
page 1: http://www.example.org/default.asp?id=1 redirects to http://www.example2.org/newpage.html
page 2: http://www.example2.org/default.asp?id=2 redirects to http://www.example.org/contact.html
...and so on. Every old page will redirect to a specific new page.
I have tried to write something in .htaccess along the lines of
Redirect 301 http://www.example.org/default.asp?id=1 h-tp://www.example.org/newpage.html
Redirect 301 http://www.example2.org/default.asp?id=2 h-tp://www.example.org/contact.html
But no luck so far. mod_alias is enabled...
I also tried using RewriteCond and RewriteRule like this:
RewriteCond %{HTTP_HOST} example.org
RewriteRule default.asp?id=1 http://www.example.org/newpage.html [NC,L,R=301]
...
In other words: I want to do a page-by-page redirect from id-based to alias-based along with a merge of three sites/domains into one site.
I hope there is a useful solution. Thanks in advance!
The Redirect directive does only work with the URL path but not the host or query of the URL.
But it is possible with mod_rewrite:
RewriteCond %{HTTP_HOST} =example.org
RewriteCond %{QUERY_STRING} =id=1
RewriteRule ^default\.asp$ http://www.example.org/newpage.html [NC,L,R=301]
And as already said in the comments, you can use a rewrite map for the ID-to-alias mapping:
1 foo-page
2 bar-page
3 baz-page
…
The RewriteMap declaration (here a simple plain text file):
RewriteMap id-to-alias txt:/absolute/file/system/path/to/id-to-alias.txt
And finally the application:
RewriteCond %{HTTP_HOST} =example.org
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([0-9]+)&?([^&].*)?$
RewriteCond ${id-to-alias:%3}&%1%4 ^([^&]+)&(.*)
RewriteRule ^default\.asp$ http://www.example.org/%1.html?%2 [NC,L,R=301]
That should also preserver the remaining query. If you don’t want that:
RewriteCond %{HTTP_HOST} =example.org
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([0-9]+)&?([^&].*)?$
RewriteCond ${id-to-alias:%3} .+
RewriteRule ^default\.asp$ http://www.example.org/%0.html? [NC,L,R=301]
A good alternative to mod_rewrite is to use whatever language you are most comfortable with and put the logic in your script. Point all URLs you'd like to redirect to your simple front controller.
RewriteRule ^default.asp$ /redirect.php [L]
RewriteRule ^another/path/to_some_file.ext$ /redirect.php [L]
And then, in redirect.php:
<?php
if ($_SERVER['SCRIPT_URL'] == '/default.asp'){
$map = array(
1 => '/newpage.html',
2 => '/contact.html'
);
if (isset($_GET['id'])){
$id = $_GET['id'];
if (isset($map[$id])){
header('HTTP/1.1 301 Moved Permanently', true, 301);
header('Location: http://'.$_SERVER['HTTP_HOST'].$map[$id]);
exit;
}
}
}
// ... handle another/path/to_some_file.ext here, or other domains, or whatever ...
// If we get here, it's an invalid URL
header('HTTP/1.1 404 Not Found', true, 404);
echo '<h1>HTTP/1.1 404 Not Found</h1>';
echo '<p>The page you requested could not be found.</p>';
exit;
?>
Just adding some more info
The OP's redirect directives are probably in the wrong format - from the relevant apache doc page:
The Redirect directive maps an old URL
into a new one by asking the client to
refetch the resource at the new
location.
The old URL-path is a case-sensitive
(%-decoded) path beginning with a
slash. A relative path is not
allowed. The new URL should be an
absolute URL beginning with a scheme
and hostname. Example:
Redirect /service http://foo2.bar.com/service
So that would make it:
Redirect 301 /default.asp?id=1 http://www.example.org/newpage.html
Hope that helps
In httpd.conf:
RedirectPermananent URL1 URL2

Resources