Apache rewrite rule deletes query string - php

I'm trying to rewrite URLs so that they don't have the index.php in them in Apache. Everything has been working fine so far, but I needed to send querystring parameters in a GET request and realized they were being stripped off. I'm using the QSA flag, but it's not working and my query string never gets to the server.
<VirtualHost noomo.jp:443>
DocumentRoot /var/www/noomo-web/public
<Directory "/var/www/noomo-web/public">
AllowOverride All
Options -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L,QSA]
</Directory>
SSLCertificateFile /etc/letsencrypt/live/noomo.jp/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/noomo.jp/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
ServerName noomo.jp
</VirtualHost>
Am I missing something required to pass the query string through? I've looked all over Google, but everything I can find just refers to redirecting based on the query string, not making sure that the query string gets through. I've had this same thing happen on an nginx server before, but I don't know how to fix it on Apache.

Ah! Found it! Alright, I'm gonna answer my own question so people will see this if they Google the same problem, cause this took me hours to realize... Apparently you can't put rewrites inside the entry or they won't work right. I moved the rewrite rules out and put them right inside the entry and it works now.

Related

Apache2 .htaccess rewrite rule for nested URLs doesn't work

I have simple php application with navigation based on domain/foo/bar nested urls.
For instance, I have main page index.php with about nav link which should navigate to domain/en/about, where en and about must be transfered to url param like index.php?url=....
But when I click to about I got to domain/en/aboutand
404 not found instead.
I have configured apache2 virtual domain config as:
<VirtualHost *:80>
ServerAdmin webmaster#localhost
<Directory /var/www/html/domain>
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
DocumentRoot /var/www/domain/
ServerName domain.local
ServerAlias www.domain.local
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
And .htaccess file as:
order deny,allow
RewriteEngine On
RewriteBase /
RewriteRule .* index.php?url=$0 [QSA,L]
mod_rewrite for apache2 is already enabled.
Have no clue what I have missed.
Any help is appreciated!
Thank you in advance!
<Directory /var/www/html/domain>
:
DocumentRoot /var/www/domain/
Your <Directory> section and DocumentRoot directive refer to different locations, so regardless of where you've put the .htaccess file, it's not going to work as intended.
However...
RewriteRule .* index.php?url=$0 [QSA,L]
This rule is not strictly correct, since it ends up rewriting itself on a second pass by the rewrite engine. If it wasn't for the QSA flag, the original url param value (that contains the originally requested URL-path) would be lost. The above ends up rewriting a request for /en/about to index.php?url=index.php&url=en/about. Fortunately, your PHP script still reads $_GET['url'] as en/about. But you can examine the full (erroneous) query string in $_SERVER['QUERY_STRING'].
(And, if you were to simply prefix the substitution string with a slash, ie. a URL-path, you'll get an endless rewrite-loop (500 Internal Server Error). But this could also result from adding additional rules later.)
You should prevent requests to index.php itself being rewritten, which you can do by adding an additional rule. For example:
RewriteRule ^index\.php$ - [L]
RewriteRule .* index.php?url=$0 [QSA,L]
However, this will still rewrite your static assets (assuming you are linking to internal images, CSS and JS files?). So, you would normally need to prevent this with an additional condition that prevents the rule from being processed if the request already maps to a static file.
For example:
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php?url=$0 [QSA,L]
The CondPattern -f checks if the TestString maps to a file. The ! prefix negates this. So the condition is only successful when the request does not map to a file.
You need parenthesis around what you want to capture. Back-references indices start with '1':
RewriteRule (.*) index.php?url=$1 [L,QSA]

$_GET is always empty

My laravel application is working well on localhost, but now having moved my application to a production server, it is no longer recognizing any $_GET variables passed through the URL. My production server is set up to allow multiple laravel installations, and I am handling the rewriting with a vhost.conf file and an .htaccess file located in the laravel root.
.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /international-experts/index.php/?$1 [L]
</IfModule>
vhost.conf
Alias /international-experts "/srv/http/international-experts/public"
<Directory /srv/http/international-experts>
Options Indexes Includes FollowSymLinks MultiViews
AllowOverride AuthConfig FileInfo Indexes
Order allow,deny
Allow from all
</Directory>
What I have done to test it is with print_r($_GET) on multiple pages. Nothing. Reading up on the problem, it sounds like MultiViews might be part of the problem. I know I'm not the only one handling multiple laravel installations on the same server... has anyone else had to tackle this problem?
Thanks
In the rewrite rule
RewriteRule ^(.*)$ /international-experts/index.php/?$1 [L]
you create a new query string with ?$1 and the default behaviour in this case is to throw away the old query string. You need to use the flag QSA, which you can remember as "query string append"
RewriteRule ^(.*)$ /international-experts/index.php/?$1 [L,QSA]
If not enough to solve your problem, it is surely a part of it.
i ran into a similar problem of $_GET[] empty. mostly because of a server issue somewhere and i had to generate my own $GET using $_SERVER['HTTP_REFERER'].
//url='http://example.com/?search=john&location=london';
$get=array();
$query=mb_split("&",parse_url($_SERVER['HTTP_REFERER'],PHP_URL_QUERY));
if(!empty($query)) foreach ($query as $qr){
$vars=mb_split('=',$qr);
$get[$vars[0]]=$vars[1];
}
var_dump($get['search']);

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]

htaccess rewrite - not rewriting to index.php

I have three web servers on three separate computers. I am trying to install a php application that rewrites all url requests to index.php (front controller pattern). The following .htaccess works on two out of the three web servers:
RewriteEngine On
# Redirect everything to the Front Controller
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^(css|images|files)/ index.php [NC,L]
So, when I visit http://example.com/hithere, index.php is called and I can then parse the originally requested url (hithere) to figure out what controller to send it to.
However, for some unknown reason, the above .htaccess file doesn't work on the third webserver. Instead, when I access http://example.com/hithere, I get a 404 not found error in my browser that says this:
The requested URL /full/path/to/application/index.php was not found on this server.
So, based on the above error, I can tell that it's actually trying to redirect to index.php. But the file that the browser lists in the /full/path/... below is actually on my web server - so I have no idea why it can't find it. Could someone please help me and tell me what I'm doing wrong?
Edit: I don't know if something in the httpd.conf could be conflicting, but here are the settings I have in httpd.conf for the directory that this application is in
Alias /myapp /full/path/to/my/app
<Directory /full/path/to/my/app>
Order allow,deny
AllowOverride All
Allow from all
</Directory>
Edit 2: I noticed something peculiar in the Apache logs. It looks Apache is appending index.php, which I am trying to redirect traffic to, to the DocumentRoot:
File does not exist: /document/root/full/path/to/my/app/index.php
When it should be going to:
/full/path/to/my/app/index.php
So I basically need to tell htaccess to ignore the document root. I tried this by specifying this in my .htaccess file:
RewriteBase /full/path/to/my/app/
But it's still searching the document root for index.php :/ Is there a way to reset the DocumentRoot or tell htaccess to ignore it when rewriting to index.php? Even when I use the absolute path in the RewriteRule, it still appends it to the document root.
RewriteEngine On
# Redirect everything to the Front Controller
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^(css|images|files)/ /full/path/to/my/app/index.php [NC,L]
It doesn't make sense to me... Can someone please help?
Thanks
So, based on the above error, I can tell that it's actually trying to
redirect to index.php. But the file that the browser lists in the
/full/path/... below is actually on my web server - so I have no idea
why it can't find it.
Assuming it's a *nix alike system, you might want to check file permissions and make sure that the webserver has read access to the file.
You also need to check the DocumentRoot parameter in httpd.conf
Look for something like this in the file and make sure it's correct. That is also where apache will be getting it from.
DocumentRoot "/var/www/html/path/to/whatever"
Also I would disable SELinux if it's on and you really don't need it because it causes weird problems too.
First enable rewrite module in apache by using $ sudo a2enmod rewrite then restart web server by $ sudo systemctl restart apache2
Put following code in your virtual host.
<Directory /var/www/html/your_app_folder>
Order allow,deny
AllowOverride All
Allow from all
</Directory>
then add following code in your .htaccess file
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>

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

Categories