.htaccess for subfolder - apache

I have the following structure
-www
\-subfolder
In www I have my main site's index.php.
In subfolder I have a sort of admin UI and in there I'd like to have another index.php for the admin UI.
Currently my requests from within /subfolder/index.php get redirected to www/index.php and basically the pages of my admin UI don't show up.
This is my .htaccess file:
RewriteEngine On
RewriteRule ^$ index.php [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)$ index.php?lang=$1&page=$2 [L]
Can you help me? I've tried several options in other answers but as I'm no so advanced a web developer, I couldn't get any to work.
#TerryE, Sorry if I have come off as crude.
I am using a local setup for testing.
I have installed Vertrigo server, which gives me Apache server.Running on Windows7 OS. The server is installed in Program files\VertrigoServ\Apache folder.
My public folder is www. In there I have my main site definition. . The site is accessed locally via 127.0.0.1/index.php or 127.0.0.1/
I have site localization so URLs are constructed as /$lang/$page e.g. HOME
In index.php of main site I have the following:
$page = trim( ( isset( $_GET[ 'page' ] ) ? $_GET[ 'page' ] : 'home' ), '/' );
$lang = trim( ( isset( $_GET[ 'lang' ] ) ? $_GET[ 'lang' ] : 'en' ), '/' );
$langs = array( 'en', 'fr', 'ru' );
And upon this data I get to open the pages this way:
include 'html/'. $lang . '/' . $page . '.php';
All my main site's pages lie in www/html/$lang/
$_SERVER['REQUEST_URI']) gives /en/home for page HOME.
127.0.0.1/en/home WORKS
All navigation works perfectly for the main site.
However I have created an admin UI which lies in folder www/admin - one level below in www.
And in there I don't have any localization. I just have EN as language.
So at the top of the index.php in admin folder I have again
$page = trim( ( isset( $_GET[ 'page' ] ) ? $_GET[ 'page' ] : 'home' ), '/' );
However, here navigation is as follows HOME
and upon this I get to construct the pages in the index.php in admin folder as follows:
include 'html/ . $page . '.php';
the pages lie in www/admin/html
This does not work at all. Whenever I press home link in admin UI, I get redirected to my main site (non-existing page). If I add RewriteRule ^subfolder/ - [L] in .htaccess, I get HTTP 404 NOT Found error.
127.0.0.1/admin/home DOES NOT WORK. Neither does any other navigation from within admin. Thank you for your willingness and patience to help me!

I assume from this that you only have a single .htaccess file in your www directory.
Think about what the rule
RewriteRule ^(.*)/(.*)$ index.php?lang=$1&page=$2 [L]
does when interpreted in a Perdir context from www: take any URI of the form someDir/somePage and replace it by index.php?lang=someDir&page=somePage, so this will intercept and rewrite any /subfolder/index.php.
This isn't well documented but Perdir processing will preferentially use the lowest .htaccess file setting RewriteEngine On on the request path. So if you add an admin-specific .htaccess file in the "subfolder" subfolder, this will preempt the www one and circumvent this problem.
Postscript comments
Veni and other posters get in a Q&A when the real issue is one of "how do I debug my .htaccess rules if I my website is hosted by a shared service?" The reason that I add the shared service qualification is that if you have root access to your LAMP config then you can turn on Rewrite logging and the logfile at a debug level of 4-6 will give you enough forensics to work out what is going on.
However, the large majority of hobby / small service users buy their services on a shared basis and here they don't have root access and the hosting provider disables such logging for performance reasons so they have a binary feedback -- the rules work or they don't. I use a shared service and my approach (described here) is to set up a VM which mirrors this configuration for as a test and integration environment -- and in this I have such root access. However, this is probably far too complicated for most users. This is really a wider topic that merits its own Q / discussion.
On specific points:
If your structure is /(lang|admin)/page, then why do you have this rule because it can cause havoc on perdir retries.
RewriteRule ^$ index.php [QSA,L]
Better something like the following to force a redirect to a default language (assume the lang list is EN and IT in this example:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond $1 !^/(en|it|admin)/
RewriteRule ^(.*) http://yourdomain/en/$1 [R=301,L]
Are you aware of the redirect restart /looping issues? (search for REDIRECT_STATUS)
I'm new to Stackoverflow, but not to sorting out this sort of s**t. I've got a couple of detailed articles on my blog on this.
Postscript comments -- yet more
OK some general help.
Don't us fixed IPs put an alias for 127.0.0.1 in your windows\system32\drivers\etc\hosts
You can turn on rewrite logging in your VertrigoServ Apache config and this gives you a detailed audit of where you have problems
It also helps if you have a little diagnostic stub to help you understand what is going on and this is what I came up with for index.php in the test directories:
<?php header( "Content-type: text.plain" ); echo "main: "; var_export($_GET);
But you really need for each of the following cases:
- to handle the URI exists (and stop rewrite loops)
- the defaults for / and /admin/
- admin/*
- */*
- * (and the language defaults)
and this is what I came up with. I've kept it simple. We could use complex regexps to fold some of these but why bother. You may need to add more QSAs if needed.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [L]
RewriteRule ^$ index.php [QSA,L]
RewriteRule ^admin/?$ admin/index.php [QSA,L]
RewriteRule ^admin/(.*)$ admin/index.php?page=$1 [L]
RewriteRule ^(.*)/(.*)$ index.php?lang=$1&page=$2 [L]
RewriteRule ^(.*)$ index.php?lang=en&page=$1 [L]

RewriteEngine On
RewriteRule ^$ index.php [QSA,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^subfolder/(.*)$ subfolder/index.php?page=$2 [L]
RewriteRule ^(.*)/(.*)$ index.php?lang=$1&page=$2 [L]

You could prevent requests to you subfolder from being rewritten with the change below
RewriteEngine On
RewriteRule ^$ index.php [QSA,L]
#prevent requests to your subfolder from being rewritten
RewriteCond %{REQUEST_URI} !^/subfolder/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)$ index.php?lang=$1&page=$2 [L]

Related

How to redirect all files/folders except index.php, to index.php?

I've set up a dummy website to test MediaWiki at https://wiki.rehman.website/
I want to redirect all direct external traffic to files and folders located after wiki.rehman.website/ to wiki.rehman.website/index.php. So for example:
These should redirect to wiki.rehman.website/index.php:
wiki.rehman.website/extensions/
wiki.rehman.website/docs/contenthandler.txt
wiki.rehman.website/NonExistantFileOrFolder
But obviously these should not be redirected (to prevent circular redirects):
wiki.rehman.website/
wiki.rehman.website/index.php
How do I do that please?
What I'm trying to achieve here is to prevent anonymous users (i.e. non-MediaWiki logged in users) accessing any part of the web directory or files.
This is my first time setting up a website, and my first time installing a private instance of MediaWiki. If you spot any other loophole or issue, it would be most helpful if you could let me know.
Many thanks in advance!
You can setup a .htaccess file in your root folder to accomplish that.
RewriteCond %{REQUEST_URI} !index\.php$ [NC]
RewriteRule ^(.*)$ http://www.example.com/index.php [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA]
See this other question for more information:
How to Redirect All urls to a new domain in apache, except one

access pages without extensions except one page htaccess

I have a website for example :
https://website.com
It loads pages as :
https://website.com/page1.html
https://website.com/page2.html
https://website.com/page3.html
https://website.com/page4.html
I would like to open above pages without extension except page2.html, that is :
https://website.com/page1
https://website.com/page2.html
https://website.com/page3
https://website.com/page4
If user explicitly enters :
https://website.com/page1.html
Then too, it should be redirected to:
https://website.com/page1
Same for page3 and page4
I applied below rule in .htaccess:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
It is able to open pages without extension, that is :
https://website.com/page1
https://website.com/page2
https://website.com/page3
https://website.com/page4
But when I enter:
https://website.com/page1.html
It gets opened, but what am in need of is, when I open:
https://website.com/page1.html
It should be automatically redirected to
https://website.com/page1
This condition should be for all the pages except page2.html
Thanks in advance for helping.
Add something like the following before your existing rewrites.
RewriteCond %{REQUEST_URI} !=/page2.html
RewriteRule ^/?(.*)\.html /$1 [L,R=301]
May need modification depending on exactly what page1/2/3/4 are. The /? bit in the pattern for the RewriteRule is only there to make it generic for both htaccess files and the main Apache configuration files. If you only intend to us this in htaccess files you can remove it.

Moving from IIS ISAPI rewrite to Apache mod_rewrite

I've seen few people have asked this on here already, but none of the solutions provided worked for me so far.
We have always been developing for the IIS ISAPI rewrite (on Windows) and suddenly one of the clients decided to place the project on the Linux server running Apache. As a result some of the rules are no longer working.
Example of an ISAPI rewrite rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^login/?([^/]*)([^/]*)$ /login.cfm?msg=$1&$2 [L,QSA]
RewriteRule ^login.cfm$ /login/ [R=301,L,NC]
login.cfm is an actual existing page and not dynamically generated based on template.
Could someone help me how to translate this for the Apache mod_rewrite please? Currently the rule creates an infinitive loop and the output is:
login/?msg=&&msg=&&msg=&&msg=&&msg=&&msg... (till the limit of the url length)
Safe to say the page is not found either so it doesn't even check whether the file with such name exists.
The page could be /login or /login/wrong so the rule should recognize both cases.
You can use these rules in your site root .htaccess:
RewriteEngine On
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} /login\.cfm\?msg=([^\s&]*)\s [NC]
RewriteRule ^ /login/%1? [R=301,L,NE]
# internal forward from pretty URL to actual one
RewriteRule ^login(?:/([\w-]+))?/?$ login.cfm?msg=$1 [L,QSA,NC]

How to edit this url with mod_rewrite

I have a godaddy linux server and I am wanting to edit my url's
Here is an example of 3 url's from my website
www.website.com/b.php?n=30&t=big
www.website.com/b.php?n=20&t=medium
www.website.com/b.php?n=10&t=small
I would like to be able to change them to
www.website.com/30/big
www.website.com/20/medium
www.website.com/10/small
MY IMAGE CODE
echo '<img src="gifs/' . $_GET["t"] . '/' . $_GET["n"] . '.gif">';
You can change them by changing all the links on your site from the /b.php?n=30&t=big style links to the /30/big style links. Then you can put these rules in the htaccess file in your document root:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)/(.*) /b.php?n=$1&b=$2 [L,QSA]
this will change the URI's back to the ones that route through b.php.
In the event that you have old URL's floating around the internet and they need to be changed to the new ones, you can use these in the same htaccess files:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /b\.php\?n=([^&]+)&t=([^&\ ]+)
RewriteRule ^/?b\.php$ /%1/%2 [L,R=301]
This will redirect the browser (or google index bot) to point permanently to the new URLs.

mod_rewrite with multiple query strings?

I'm trying to cleanup some URLs on my blog, so I've decided to look into mod_rewrite. I haven't a clue what I'm doing though, so I was hoping I could get some help :P I have links like http://kn3rdmeister.com/blog/post.php?y=2012&m=07&d=04&id=4. Although it works, and people still get the content I want them to have, I don't like them having to look at all the query strings. I want to turn the above link into http://kn3rdmeister.com/blog/2012/07/04/4.php.
This is what my .htaccess looks like right now.
RewriteEngine On
RewriteCond %{QUERY_STRING} ^y=([0-9){4})&m=([0-9]{2})&d=([0-9]{2})&id=([0-9]*)$
RewriteRule ^/blog/post\.php$ http://kn3rdmeister.com/blog/%1/%2/%3/%4.php? [L]
Like I said, I'm absolutely clueless :D
If you're using apache 2.0 or higher, you're going to need to remove the leading slash (the prefix) if these rules are in an .htaccess file, so that your regular expression looks like this:
# also note this needs to be a "]"--v
RewriteCond %{QUERY_STRING} ^y=([0-9]{4})&m=([0-9]{2})&d=([0-9]{2})&id=([0-9]*)$
RewriteRule ^blog/post\.php$ http://kn3rdmeister.com/blog/%1/%2/%3/%4.php? [L]
This is going to make it so when someone puts http://kn3rdmeister.com/blog/post.php?y=2012&m=07&d=04&id=4 in their browser's URL address bar, their browser will get redirected to http://kn3rdmeister.com/blog/2012/07/04/4.php and the new URL will appear in their address bar.
I assume you've got something setup on your server to handle a request like blog/2012/07/04/4.php.
At first you should define your URLs!!!
Like:
/blog shows front page
/blog/1234 shows post 1234
/blog/date/2012 shows posts by year
/blog/date/2012/06 shows posts by year and month
/blog/date/2012/06/01 shows posts by year and month and day
and so on...
First option is to rewrite each of your defined URLs to index.php. Your index.php has only to handle the submitted GET parameters.
### Do only if rewrite is installed
<IfModule mod_rewrite.c>
### Start rewrite and set basedir
RewriteEngine on
RewriteBase /
### Rewrite only if no file link or dir exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
### Rewrite frontpage
RewriteRule ^blog$ /index.php?action=showfront [L,QSA]
### Rewrite post
RewriteRule ^blog/([0-9]+)$ /index.php?action=showpost_by_id&id=$1 [L,QSA]
### Rewrite posts by date
RewriteRule ^blog/date/([0-9]{4})$ /index.php?action=showposts_by_date&year=$1 [L,QSA]
RewriteRule ^blog/date/([0-9]{4})/([0-9]{2})$ /index.php?action=showposts_by_date&year=$1&month=$2 [L,QSA]
RewriteRule ^blog/date/([0-9]{4})/([0-9]{2})/([0-9]{2})$ /index.php?action=showposts_by_date&year=$1&month=$2&day=$3 [L,QSA]
### Rewrite posts by tag
RewriteRule ^blog/tag/([a-zA-Z0-9_-]+)$ /index.php?action=showposts_by_tag&tag=$1 [L,QSA]
</IfModule>
Test in index.php with:
print_r($_GET);
print_r($_POST);
The second option is to rewrite all URLs and your index.php needs to handle all possible URLs. So at first it needs something like a router that splits the incoming URL in parts and then send the requested page or an error-page. I would try this at first as the bloody school.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ index.php%{REQUEST_URI} [L]
</IfModule>
Test in index.php with:
print_r(explode('/', ltrim($_SERVER['PATH_INFO'], '/')));
print_r($_GET);
print_r($_POST);
The third option is to use a PHP framework. A framework may help you to write your code quite fast. It delivers you many base-classes like a router. (f.e. ZendFramework, Flow3, Kohana, Symfony, CodeIgniter, CakePHP, yii and others). This will make you more advanced.
The fourth and laziest option is to use a ready made software like Wordpress.