htaccess redirect subdomains to certain page? - php

I need all subdomains to be redirected to a specific page, without actually changing the URL, because I will display different content on this specific page depending on what subdomain is in the URL.
Let's say my site is located at testdomain.com/site1/
I want all subdomains, like xyz.testdomain.com/site1/ or even xyz.testdomain.com to be redirected to a specific page at http://testdomain.com/site1/index.php/test.php
The browser will then need to be loading http://testdomain.com/site1/index.php/test.php, but the URL will still be xyz.testdomain.com.
The purpose of this is so that someone can go to abc.testdomain.com or xyz.testdomain.com and both will take the user to testdomain.com/site1/index.php/test.php, and then on test.php, I have some code that will grab the URL, and if the url is abc.testdomain.com, it will display certain content, whereas if the subdomain is xyz.testdomain.com it will display different content.
Is this something I can do in htaccess? If so, how?

Using mod_rewrite you can hack this together.
# Step 1: If the user went to example.com or www.example.com
# then we don't want to redirect them. (S=1 says skip the next rule)
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com
RewriteRule ^ - [S=1]
# Step 2: Anything else is redirected to our catcher script.
# Option 1: keeps the path they went to, but discards the domain
# i.e. xyz.example.com/abc/def.txt => /var/www/cgi-bin/abc/def.txt
RewriteRule ^/?(.*) /var/www/cgi-bin/$1 [QSA,L]
# Or Option 2: take all requests to the same file
# i.e. xyz.example.com/abc/def.txt => /var/www/cgi-bin/myfile.php
RewriteRule ^ /var/www/cgi-bin/myfile.php [QSA,L]
QSA tells it to forward the query string, L tells it to stop looking for more redirects (not absolutely necessary but sometimes helps if you have a lot of this sort of thing going on).
You can also pass variables to your script as query parameters, and the QSA flag ensures they don't replace the original values;
# xyz.example.com/abc/def.txt => /var/www/cgi-bin/myfile.php?host=xyz.example.com&path=/abc/def.txt
RewriteRule ^/?(.*) /var/www/cgi-bin/myfile.php?host=%{HTTP_HOST}&path=/$1 [QSA,L]
It means you don't need to worry about figuring out where the request came from inside your script (which might actually be impossible, I'm not sure). Instead you can just read it as a normal parameter (it's hackable like a normal parameter too; be sure to sanitise it).

Related

Wordpress 404 issue with certain requests containg the string "admin-"

I have a wordpress page that generally works, but tonight, when updating the menu didnt work, I realized that something isn't working. So after choosing which menu items I want to add to the menu and hitting the button "Add to menu" the loading-circle starts to rotate endlesly. After inspecting more details in the developer-console, I see the following:
The GET request to https://URL/wp-admin/-ajax.php results in a 404. The wp-admin/-ajax.php doesnt look right to me. It should actually be wp-dmin/admin-ajax.php. So for some reason the admin part gets stripped away.
I notice the same symptom for loading some CSS files:
https://URL/wp-admin/-bar.min.js can also not be loaded. I think this should in fact be admin-bar.min.js.
My .htaccess looks as follows:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
I also already tried to disable all plugins to no avail.
Any hints on what could cause this issue? What can caus removing the admin part from these requests?
EDIT:
Could the following apache-config be the cause?
RedirectMatch permanent /admin(.*) https://konferenzimforum.at/wp-admin/$1
Why this happens in your configuration
The configuration line you included from your Apache config file is almost certainly the root cause of this behavior. To understand why this is, we must dive just a bit deeper into what the line actually does:
RedirectMatch permanent
Simply enough, this declares a permanent (HTTP code 301) redirect based on a RegExp pattern matching operation.
/admin(.*)
This pattern basically tells Apache, "match any URL that contains /admin, followed by any character, any number of times, while capturing the text after the /admin substring into a temporary variable, $1".
https://konferenzimforum.at/wp-admin/$1
This string then takes that earlier-captured value and instructs Apache to redirect the requestor to the URL https://konferenzimforum.at/wp-admin/, with the earlier-captured value appended to the end.
When this is applied to the URL in your example, wp-admin/admin-ajax.php would become wp-admin/-ajax.php, because /admin triggers the match, then uses the remainder of the URL captured in $1 as a post-fix, which then creates the non-existent URLs you're seeing in your browser's development tools. You can see a more visual & plain-English representation of how this pattern works in practice by using this Regex101. You'll notice on that page that the part that gets removed in your configuration is highlighted a different color than the part of the URL that gets passed through to the redirected URL.
How you can resolve it
There are a number of ways to resolve this; the easiest is probably to just remove this rule entirely (as it's not clear based solely on the information in the question why this rule would be necessary in the first place).
Another way to do it would be to ensure that only requests to /admin/* are matched, instead of arbitrarily matching all URLs that include a /admin sequence (which, as you've seen, can inadvertently target files beginning with /admin), which seems to be more of what you're trying to do (redirect requests for /admin to the appropriate /wp-admin resource):
RedirectMatch permanent /admin/(.*) https://konferenzimforum.at/wp-admin/$1

Redirect specific Url variables

My site used to generate URLs like this:
/data.php?s=1432862823&type=basic
I have modified the program so the new URLs generated are:
/d.php?s=1432862823&t=basic
Since some people have bookmarked the old URLs I want to write a Rewrite rule that will get them to the new url.
I've not this so far:
RewriteEngine on
RewriteRule "^/data\.php$" "/d.php"
but I can't figure out how to account for the variables.
Try this :
RewriteEngine On
RewriteCond %{QUERY_STRING} ^s=([^&]+)&type=([^&]+) [NC]
RewriteRule ^data.php$ /d.php?s=%1&t=%2 [NC,R,L]
This will externally redirect a request for :
/data.php?s=foo&type=bar
to
/d.php?s=foo&t=bar
Edit: I do apologise, I only noticed now that you have changed the type parameter to t. As such, this solution will not fit your needs, unless for a URI where the query string parameters do not change. I'm leaving this answer here so that others may learn from it - you'll be surprised how many people don't know that the query string is automatically transferred to the new destination. Starkeen's answer, therefore, is the correct answer.
You could follow Starkeen's solution, which specifically checks for the query string and explicitly adds it to d.php. Alternatively, for simplicity, you could just use this:
RewriteEngine on
RewriteRule ^data.php$ /d.php [R=302,L]
The query string will automatically be transferred from data.php to d.php, and you will be redirected accordingly.
To make the redirect permanent and cached by browsers and search engines, change 302 to 301.

Lang parameter redirects to subfolder, keep the lang folder name on the next link

The requirement was to have:
http://xxxx.com/it/
To redirect to
http://xxxx.com/index.php?act=setlang&val=it
An the same t to happen for the rest of the links e.g
http://xxxx.com/it/test.php
to
http://xxxx.com/test.php?act=setlang&val=it
I have achieved that using the following:
RewriteRule ^([a-z]{2})$ index.php?act=setlang&val=$1 [L]
RewriteRule ^([a-z]{2})/([a-zA-Z0-9-]+)\.php$ $2.php?act=setlang&val=$1 [L]
The problem is that I would have like to have continuity of the language in the url path and retain it when changing links unless the lang var changes
When I visit http://xxxx.com/it (the language will be set to Italian as expected), when I click on the next link e.g test.php the link will be http://xxxx.com/test.php not http://xxxx.com/it/test.php.
Is there a way to retain it using htaccess until manually changed by the user (user selects another language)
The reason that I am looking to retain it is for SEO purposes really, not sure if it makes any difference? but i presume that if Google had to index 3 test.php (coming from it,en.fr) it wouldn't be able to crawl the individual languages at all?as well as if it has to crawl en/test.php fr/test.php and it/test.php..
Note: As you have guessed the sub-folders don't actually exist and in reality are virtual folders
To keep the language code sticky you can create a cookie first time then /it/ URL is loaded and then prefix every URI that doesn't have it.
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
# if lang cookie is set and URI doesn't start with 2 char lang code
RewriteCond %{HTTP_COOKIE} LANG=([^;]+) [NC]
RewriteRule ^((?![a-z]{2}/).+)$ /%1/$1 [R,L,NC]
RewriteRule ^([a-z]{2})/?$ /index.php?act=setlang&val=$1 [L,CO=LANG:$1:%{HTTP_HOST}]
RewriteRule ^([a-z]{2})/([a-zA-Z0-9-]+)\.php$ $2.php?act=setlang&val=$1 [L,CO=lang:$1:%{HTTP_HOST}]
Is there a way to retain it using htaccess until manually changed by the user (user selects another language)
Htaccess can only change the content of your pages through something like an HTML Proxy, where all the content of your site is filtered through rules and links will magically get changed to include things like /it/ in front of them before they're returned to browsers.
What you should probably do is in your php files, dynamically add a URI base using the contents of the val parameter. So if the request is:
index.php?act=setlang&val=it
index.php will include a
<base href="/it/" />
in the page's headers. That way, your links will appear to be:
http://xxxx.com/it/something.php

Ignoring/accepting forward slashes with htaccess and mod_rewrite

I need a little help on this one.
I'm in the process of making a php page that collects a query string, tests it against a database for matches, and then redirects the user to a different section of the site.
The is how it works currently (without htaccess/mod_rewrite):
User visits: domain.com/redirect/index.php?slug=Test_1
The php page sanitizes and looks up 'Test_1' in the database and retrieves a destination URL to redirect the user to. (e.g. domain.com/New_Test_1)
The php page then 301 redirects accordingly.
This part is working fine. However, due to some variables outside of my control, I need to interpret the original URL (using htaccess/mod_rewrite), like this:
domain.com/redirect/index.php/Test_1
Which still acts the same as:
domain.com/redirect/index.php?slug=Test_1
(note: yes, the index.php needs to stay in the url.)
I have this working with the following in my htaccess, but I know it could be better:
RewriteEngine On
Options +FollowSymLinks
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)$ %{DOCUMENT_ROOT}/redirect/index.php?slug=$2 [PT,L,QSA]
Part I need help with...
Some of the old url slugs had forward slashes in them, like this:
domain.com/redirect/index.php?slug=How_to_Code/Program
Without htaccess, the above still works, but fails with the pretty(ier) url:
domain.com/redirect/index.php/How_to_Code/Program
With my current htaccess, it only captures the 'How_to_Code' part, but ignores everything after it.
So my question is this: how can I restructure my htaccess to grab everything after domain.com/redirect/index.php/(.*)$, including forward slashes?
Edit: this .htaccess is going inside the /redirect directory
If you do this
RewriteRule ^redirect/index.php/([a-zA-Z0-9/_]+)$ redirect/index.php?slug=$1
That will accept forward slashes and underscores. To add anymore allowed characters just add them inside the [] square brackets. Certain characters may need to be escaped so just Google that.

Help with .htaccess file. mod_rewrite for custom urls?

Situation:
I have a few hundred posts each belonging to a particular category.
A] Now when the user visits the home page, the content is irrespective of the category sorted by date.
http://www.example.com
He can navigate through different pages like:
Type 1: http://www.example.com/3 which corresponds to http://www.example.com/index.php?page=3
I can probably do this in mod_rewrite
B] The user can then decide to view by category like:
Type 2: http://www.example.com/Football which will correspond to
http://www.example.com/index.php?page=1&category=Football
He can then navigate through pages like:
Type 3: http://www.example.com/Football/5 which =>
http://www.example.com/index.php?page=5&category=Football
C] I have a directory called View with index.php in it. It only shows individual posts like:
Type 4: http://www.example.com/View/1312 => http://www.example.com/View/index.php?id=1312
Here is the mod_rewrite I do:
RewriteEngine on
RewriteRule ^View/([^/.]+)/?$ View/index.php?id=$1 [L]
Now here are the problems I have
In point C]: http://www.example.com/View/1312 works fine but http://www.example.com/1312/
(notice the trailing slash) breaks apart & gives weird results.
Q1) So how do I maintain consistency here?
Q2) Ideally I would want http://www.example.com/View/1514 to show a 404 Error if there is no post with id 1514, but now I have to manually take care of that in PHP code.
What is the right way of dealing with such dynamic urls? especially if the url is wrong.
Q3) how do I ensure that http://www.example.com & http://www.example.com/ both redirect to http://www.example.com/index.php?page=1; (mod_rewrite code would be helpful)
Please Note that there are only two index.php files. One in the root directory which does everything apart from showing individual posts which is taken care by a index.php in View directory. Is this a logical way of developing a website?
Try these rules:
RewriteRule ^$ index.php?page=1 [L]
RewriteRule ^([0-9]+)/?$ index.php?id=$1 [L]
RewriteRule ^View/([0-9]+)/?$ View/index.php?id=$1 [L]
RewriteRule ^([A-Za-z]+)/?$ index.php?category=$1&page=1 [L]
RewriteRule ^([A-Za-z]+)/([0-9]+)/?$ index.php?category=$1&page=$2 [L]
As for the other question: Yes, since Apache can map these requests to existing files, it responds with a success status code. Now if your application decides that the requested resource does not exist, you need to handle that within your application and send an appropriate status code.
To fix the trailing slash, Just put /? before the $ at the end in your pattern

Categories