Rewrite URL one folder up - php

I am trying to redirect my project folders one level up in stucture.
I would like to change URL adresses as follows:
http://localhost/my-website/projects/project1/
http://localhost/my-website/projects/project2/
...
to
http://localhost/my-website/project1/
http://localhost/my-website/project2/
...
In root folder I do not have these project folders, they are in "projects" folder
the structure is like this
/root/
/projects/
/project1/
index.php
/project2/
index.php
/project3/
index.php
index.php
.htaccess
So if user enters URL http://localhost/my-website/project1/, the URL stays the same but it works as if he entered the full adress. Is this achievable? I tried so many options so far and I am still not able to do it...

First of all, don't use a .htaccess file, if you can modify the Apache config files.
It's better to add these types of configuration inside the vhost config instead.
With that said:
.htaccess
<Location "/">
AllowOverride None
Options FollowSymLinks
Require all granted
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# RewriteRule ^project(.*) projects/project$1 [QSA,L]
# RewriteRule ^project([0-9*]?)/(.*) projects/project$1/$2 [QSA,L]
</IfModule>
</Location>
/my-website/project1/ becomes /my-website/projects/project1/
/my-website/project1/whatever becomes /my-website/projects/project1/whatever
Uncomment the one that is more up your ally,
the first one is more generic and catches all after project,
the second one is more specific and looks for a number.

Related

mod_rewrite redirects don’t work as expected

I have two problems actually:
First, I’m trying to redirect several short URLs to a single page with more actions, like this:
RewriteEngine On
RewriteRule ^/login?$ ^login.php?action=login&next=$1 [L]
RewriteRule ^/reset?$ ^login.php?action=reset&next=$1 [L]
This is being written in the .conf file inside <Directory>. The problem is that the first rule gets executed, while the second doesn’t and I can’t figure why.
I also tried writing them like this:
RewriteCond %{REQUEST_URI} /login$
RewriteRule ^login.php?action=login&next=$1 [L]
RewriteCond %{REQUEST_URI} /reset$
RewriteRule ^login.php?action=reset&next=$1 [L]
I should probably mention that login.php does not reside in the root directory, but in different subdirectories.
What am I doing wrong and how can I fix it?
The second issue I have is that if I put an .htaccess file inside the root directory, the rules in the .conf file don’t get executed anymore.
Inside the .conf file I have these rules:
<Directory>
Options Indexes FollowSymLinks ExecCGI Includes MultiViews
AllowOverride All
Order allow,deny
Allow from all
RewriteEngine On
</Directory>
Why is this and how can I fix it?
Just to extend on from my comments above. Place these rules in your site root .htaccess or in httpd.conf file:
Options -MultiViews
RewriteEngine On
RewriteRule ^/?login(?:/(.*))?$ subdir1/login.php?action=login&next=$1 [L,NC,QSA]
RewriteRule ^/?reset(?:/(.*))?$ subdir1/login.php?action=reset&next=$1 [L,NC,QSA]
Option MultiViews (see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So if /file is the URL then Apache will serve /file.html.

htaccess: how to forward a request to a forbidden folder?

desired:
user calls domain.tld/download/file_01.zip
htaccess calls private/download.php
file_01.zip starts to download
Note: file_01.zip must be protected from direct access.
Simplified folder structure:
root/
public/
.htaccess
index.php
private/ <<< this area is blocked from direct access >>>
files/
file_01.zip
file_02.zip
.htaccess
download.php
public/.htaccess
RewriteRule ^download/(.*)?$ ./../private/download.php?file=$1 [NC,L]
private/.htaccess (Edit)
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
download.php
$file = 'files/'.$_GET['file'];
// check: user allowed to download?
// check: more stuff (security, etc.) ...
forceDownload($file);
The RewriteRule works, but I'm getting the error Forbidden: You don't have permission to access [...] on this server, probably because the user calls the request, not the server.
Any idea?
Thanks in advance!
There is one more approach. Rename particular directory (add a single dot before it's current name, .private for example) and place this inside .htaccess file.
RewriteRule (^\.|/\.) - [F]
After adding this rule, each and every file and directory that begins with one . will be forbidden/protected, just like .htaccess it self is. :)
This will prevent access to anyone but PHP to open, view, modify file/dir contents.
Here is sample of (very common I believe) basic .htaccess *(sitting in DOCUMENT_ROOT directory) mod_rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule (^\.|/\.) - [F]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)$ /$1.php [QSA,L]
</IfModule>
Once that this is being done, You don't serve direct links to .zip or whichever file ext. You have in mind, but do that in some other fashion with favorite PHP 'tricks' of Yours. :)
If You feel that this will give You a lot of code refactoring, just because one directory, You can add those dots to zip files, and move them elsewhere, direct access to dotted files, still won't be possible.
As RiggsFolly stated in their comment.
You need to modify that private/ .htaccess file to something like:
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
Allow from 127.0.0.1 #or your server address/etc
</IfModule>
Here is another solution, giving that your Apache version is >=2.4. (via using Require)
<IfModule !mod_authz_core.c>
Require all granted
Require ip 127.0.0.1
</IfModule>

Issues Removing index.php from Mediawiki URL

I have a php website (laravel) that is set to the root of a subdomain using a virtualhost. So http://subdomain.website.com will go to the laravel website. I want to be able to go to http://subdomain.website.com/wiki and it will direct to the mediawiki install. To do this is setup an alias within the virtualhost.
<VirtualHost *:80>
DocumentRoot "/var/www/laravel/public"
ServerName sub.domain.com
Alias /wiki "/var/www/mediawiki"
Alias /w "/var/www/mediawiki"
<Directory "/var/www/laravel/public">
AllowOverride All
Options +FollowSymLinks
RewriteEngine On
</Directory>
</VirtualHost>
This is working exactly the way i want it to work, but there is an issue. I want to remove index.php from the url. So that "/wiki/index.php/Main_Page" becomes "/wiki/Main_Page".
I tried using http://shorturls.redwerks.org/ which i found in other guides, but it isnt working for me. Any code generated will produce wiki/wiki/Main_page and even at that the page throws an error.
The requested URL /wiki/wiki/Main_Page was not found on this server.
I have tried messing around with a large amount of different combinations with the url and cant get this to work. Since this website is a subdomain im not able to use wiki.domain.com. This wiki needs to be part of the subdomain. Anyone know what i need to do to make this work?
The end result i need is for this URL to bring me to the main page
http://sub.domain.com/wiki/Main_Page
You need to have mod_rewrite enabled and then you can use rules like this to remove index.php. You can use this in your .htaccess in Wiki folder.
RewriteEngine On
RewriteBase /wiki
#redirect index.php to non index.php
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\ /(.*)index\.php
RewriteRule ^ %1? [R=301,L]
#internally rewrite request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
Update: Ordinarily this should work for typical CMS' however mediawiki itself has a unique because of the using wiki and w folders.
http://www.mediawiki.org/wiki/Manual%3aShort_URL/Apache
Depending on the mediawiki structure chosen, it would require a rule such as this
RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [L]

Apache htaccess mod rewrite redirection using Controller GET variables in PHP index page

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).

CodeIgniter configuration with mod_rewrite, xampp and windows

I'm a noob to CodeIgniter and am trying to figure out the configuration for an app I'm building. Something is wrong with my setup.
I'm running XAMPP on Windows and am using an alias directory to point to the applications directory. In other words: "http://localhost/app_name/ " points to the root directory of the application. It all seems to work well until I do the .htaccess for mod_rewrite. Then every time I try to go to a controller I get pitched back to the xampp root.
My config is:
Directories
/app_root
/app_root/codeigniter // where code igniter is located.
/app_root/main // where the main app is located. It' the applications
// directory cut from code igniter and renamed.
.htaccess
<IfModule mod_rewrite.**so**>
RewriteEngine On
RewriteBase **/app_name/**
RewriteCond %{REQUEST_URI} ^codeigniter.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
ErrorDocument 404 /index.php
</IfModule>
index.php
$system_folder = "#codeigniter";
$application_folder = "main";
app_name/main/config/config.php
$config['base_url'] = "http://localhost/app_name/";
$config['index_page'] = "";
app_name/main/config/routes.php
$route['default_controller'] = "welcome";
I should also state that the app_name directory is an alias for a different drive than the apache root.
Apache Root: c:\xampp\htdocs\
App_name: d:\projects\app_name\development\
The alias is:
Alias /app_name "d:/projects/app name/development"
<Directory "d:/projects/app name/development">
Options Indexes FollowSymLinks ExecCGI
AllowOverride All
Order allow,deny
Allow from all
</Directory>
Thanks in advance for the help... And if you don't mind please "explain" what you're doing when you answer with code. I want to know what I'm doing wrong. If you can help me with this I'll buy you a beer (via PayPal). This is frustrating.
Success!!
I finally managed to get URL rewrite working and what a long arduous journey it was. Here is what I got working finally. Take note that there is no backslash on the RewriteBase. Very interesting given what I've read. Thanks to everybody who tried to help.
# Options
Options -Multiviews
Options +FollowSymLinks
#Enable mod rewrite
RewriteEngine On
#the location of the root of your site
#if writing for subdirectories, you would enter /subdirectory
RewriteBase /app_name
#Removes access to CodeIgniter system folder by users.
#Additionally this will allow you to create a System.php controller,
#previously this would not have been possible.
#'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#This last condition enables access to the images and css
#folders, and the robots.txt file
RewriteCond $1 !^(index\.php|images|robots\.txt|css)
RewriteRule ^(.*)$ index.php?/$1 [L]
If your using XAMPP on a local machine, your should use internal rather than mod_rewrite.
It will load your pages under the alias name.
it took me a while to figure that out - apparently you should use mod_rewrite on remote servers to achieve the same thing.
RewriteBase /
in your .htaccess should be
RewriteBase /app_name/
to specify which directory it is..
First, a question. Is your $system_folder variable really set to:
$system_folder = "#codeigniter";
or was that a nerf from the weird (to me) way SO uses markdown? If it is, remove the #. It is an invalid character for directory/file names.
Next, I believe your RewriteBase should be /, since you use an alias in Apache, but don't quote me on that.
I personally use the .htaccess format supplied here: CodeIgniter URLs in the User Guide; under the heading Removing the index.php file. There are many ways to do it, however. A quick Google search yields a couple thousand.
Do you have mod_rewrite enabled? Check the forum post here.

Categories