Requests to existing files execute index.php - php

I use the following .htaccess code to enable friendly URLs in a website.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L]
</IfModule>
The code works fine with a small exception. When I request a file in the browser (i.e. an image), the browser loads it (as I would expect), but along with that index.php gets executed.
I wonder why.

It turned out the browser was making GET /favicon.ico requests and since there was no file with that name on the server, based on the rules in the .htaccess file, the requests were redirecting to /index.php.

Related

htaccess issues with non exist files

I have a wordpress site with the following .htaccess file:
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
However, it will show 200 OK response (with showing the "Media Library" page in wordpress) with the following url:
http://localhost/wp-admin/upload.php/user-new.php/66868
It's intepreting upload.php file which exist, but the ideal response should be 404 where /user-new.php/66868 does not exist
Any idea on this ?
This is the effect of the “path info” feature.
Apache realizes that /wp-admin/upload.php exists as a physical file, so it serves up that, and passes the rest of the requested URL on in the PATH_INFO environment variable.
AcceptPathInfo is the name of the directive you can use to turn this off.

Redirect all requests to single page

I have a food blog website, with many posts stored in a database. When someone clicks on a link to a post, the website searches the database for the post and presents it in a template. I don't store an HTML file for each post.
Right now, I do it by handling a 404 error (which goes off because the requested HTML file doesn't exist) and searching the database from there. I know this isn't right.
How can I set up my web server (Apache running on a Raspberry Pi), so that all requests go to one page, which will do the searching and send the user to the right page? And is this the right thing to do?
You can do that with a file you put in your website root named .htaccess and using the mod_rewrite module. You'll need to make sure .htaccess and mod_rewrite are enabled in the Apache configuration. But once enabled you can do something like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
That will rewrite any URL that doesn't refer to an actual existing file or directory to your index.php which you can use to handle the request.
For example, if someone visits http://yourdomain.com/article, the path will be internally rewritten to index.php?path=article and you can access the path using $_GET['path'].
Note: If you want to literally serve everything through that single entry point you could remove the two middle lines and that would send everything through there. Including images, scripts, CSS etc, which is generally not what you want.
You need proper .htaccess rules in your public root directory and you need a apache2 mod_rewrite module enabled.
On Ubuntu you can can enable it with the following command:
sudo a2enmod rewrite
your .htaccess file could look like the following:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>

How to redirect static to dynamic URL's using .htaccess (on Wordpress site)

I've taken over a former site/domain, and set up a new site using Wordpress. The WP installation rewrites URL's to static ones, as you'd expect it to.
At the same time I want to preserve the former pages, as they have incoming links. I'm not interested in 301'ing them to "new" pages.
The old URL structure is /index.php?id=123, which I suspect is causing the problem with the WP .htaccess file. For reference, this is what it looks like:
# 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've tried adding the following:
RewriteRule ^([0-9]+).html index.php?id=$1 [R,L]
Doesn't work. Just redirects to site.com/?id=123 and shows the front page.
I should add that I plan on just adding these new pages as regular static HTML files in the format of 123.html, 321.html etc.
How do I use .htaccess to make this work together with the WP installation and what WP puts into the .htaccess file?
To clarify:
I want to have my 123.html static HTML page be index.php?id=123. When you access index.php?id=123 it should bring up 123.html, but show index.php?id=123 in the address bar. If you access 123.html it should 301 to index.php?id=123.
To map an URL with a querystring up to an actual file you'll need to use a RewriteCond to match the querystring itself (as RewriteRule doesn't):
Something along these lines ought to do it:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# retrieve X.html when index.php?id=X is requested
RewriteCond %{REQUEST_FILENAME} index\.php
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteCond %1.html -F
RewriteRule .* %1.html? [L]
# standard WordPress routing
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
This will first check to see if you've got a request for index.php with a querystring like id=X.
Then it'll check to see if a file called X.html actually exists; I'm not 100% happy about having to use the more system hungry subrequest file check -F rather than the standard -f but I can't see a way around it in .htaccess in this case.
If X.html actually exists, it'll fetch that file whilst leaving the URL as index.php?id=X.
However if that file doesn't exist it'll fall back to standard WordPress no file, no directory routing to index.php
I'm not a WordPress expert but that should work; I guess the main WordPress controller uses $_SERVER['REQUEST_URI'] to determine the action.
Note: This won't, however, prevent people from accessing 123.html directly by going to the URL www.site.com/123.html - I kept falling into infinite loops and Apache 500 errors trying to prevent that :|

Sending specific folder to HTTPS and the rest from non-www to www, while keeping the rest of the laravel routes working?

I am trying to write a .htacess file such that:
The site runs php 5.4
Requests to domain.com run index.php first
Requests to http://domain.com/checkout are redirected to https://domain.com/checkout
All requests to domain.com are redirected to www.domain.com
So here is my attempt:
<IfModule mod_rewrite.c>
# Use PHP 5.4
AddType application/x-httpd-php54 .php
Options -MultiViews
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{HTTP_HOST} !^www\.domain\.com
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=permanent,L]
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} ^(/checkout|/order)
RewriteRule ^(.*)$ https://www.domain.com/$1 [R,L]
</IfModule>
But when I make a post to domain.com/cart the user is automatically redirected to domain.com/index.php
Please let me know where I am going wrong...
First off, you need to understand that such rules in .htaccess files are run on a first-come, first-serve basis. Also, you are using the L flag for each of them.
So, you should make sure that the two conditions and rule for silent-mapping to index.php should come last. Move those down to below the https and www-on rules.
Now, of course a request to /cart will be mapped to index.php; that's what it's programmed to do. However, you say "redirected"... Does that mean that it shows index.php in the address bar? If that is the case, the fix I've mentioned should sort that out (always check for redirects first, and then do the necessary mapping).
Like #scotsninja said in the comments, these things should be handled by Laravel itself. Your .htaccess file should only be used to map anything that is not a file or directory to the index file, or Laravel bootstrap.

Strange server response

I have a sitw built using codeigniter using htaccess. But on some requests are really strange. The include one specific file(trough codeigniter) at the begginning. This happens really often, if cache is tured off. It happens with different files and doens't matter if the file is on filesystem or request goes trough codeigniter. I guess there something up with htacccess, but i'm not sure.I'll include htaccess and screenshot from fiddler on the bottom:
<IfModule mod_rewrite.c>
RewriteEngine on
#Options -Indexes
#Force non-www
RewriteCond %{HTTP_HOST} ^www\.(.*)
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
#If image, javascript or css file does not exists, then try application folder
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(images|js|css)/(.*)$ ./application/$1/$2 [L]
#If javascript or css file exists, send it to minifier
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*)(\.(js|css))$ ./standalone/min/?f=$1$2 [L]
#If isn't file or folder then send it to codeigniter
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
ErrorDocument 404 ./index.php
</IfModule>
And as you can see original request is to top-bar-large.png and echoing $_SERVER out from coudeigniter, shows "upper request" is to parim.js. And parim.js should javascript file after all. Any ideas?
PHP_SELF is index.php... so it seems like you are be getting a CI error page on which the js files are included.
By default, codeigniter comes with an .htaccess file in the application directory with Deny all; so anything in those folders will not be publicly accessible (including your images folder in there) unless you've modified it.
Also, make make sure the images exist.

Categories