2

I'm building my own URL shortening website and I use this as my .htaccess file:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /go.php [L]
</IfModule>

This should redirect any URL (that is not a file) to go.php, for the URL redirection.

The problem is:

When I go to example.com/keyword, I get the go.php page. Then, I extract the keyword with:

$url = $_SERVER['REQUEST_URI'];
$keyword = strtok($url, '?');
$keyword = ltrim($keyword,"/");

Then I insert the current keyword and its referrer ($_SERVER['HTTP_REFERER]) to the log table in the database.

Everything seems to work just fine, but in my log table there are two new rows instead of one: one with the correct keyword example, and one with the keyword favicon.ico and http://example.com/keyword as the referrer.

What's exactly happening here? I need only the first and correct row. Does this problem happen only with favicon.ico? How can I fix this?

Thank you!

Itay Ganor
  • 3,965
  • 3
  • 25
  • 40

2 Answers2

2

Your browser requests the favicon.ico-file, just after the request. If it exists it will use it as the icon in your browser-tab (for example that neat little stackoverflow-icon).

As it doesn't exists on your server that request will pass all rewrite-conditions. Simple add an extra condition to ignore (not forward to go.php) the favicon-request.

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/favicon.ico$
RewriteRule ^.*$ /go.php [L]

Proof of concept: http://htaccess.mwl.be?share=f2fa97da-14b9-5c2e-8c58-c2c620b35c76

Bonus tip, to ignore all .ico, .jpg, .css etc (my favorite rewrite-rule):

 RewriteRule !\.(js|ico|gif|jpg|png|css|txt)$ /go.php [L]
Peter van der Wal
  • 11,141
  • 2
  • 21
  • 29
  • Hi - I can see you have a better idea about htaccess than I do :). I am doing similar operations as OP, but have looked at how WordPress does it. They have a pretty powerful rewrite engine, where you can have pretty permalinks (basically urls like `/thing/another-thing` instead of `?param=value&another=value`. Their htaccess is not including any special cases for favicon, or else. Only this https://pastebin.com/1SWBy81X is present. So I am wondering why "the world" needs to add each exception (favicon, etc), while they don't - there _must_ be something we miss? –  Mar 03 '22 at 11:35
0

The favicon.ico request is a another request than example.com/keyword. it is requested automatically by the browser, the browser has the control of how the favicon.ico request is going to be. for example the referer header of the request could be the main request URL that triggered the favicon.ico like what happened with you, or it might be empty. This is how the the favicon.ico request is logged in my database. Notice how Firefox requested the file with an empty referer header

enter image description here

How to deal with that request on the server side

you have several options here

1- you can exclude the file from the rewrite rule as @Peter van der Wal said in his answer.

2- you can serve the file yourself with PHP (I will not do that), for example you can do something like this

<?php
$iconFile ="some-media-directory/cool-icon.php";
$fileSize = filesize($iconFile);
$fHandle = fopen($iconFile,"rb");
header("Content-Type: image/ico");
$lastModified = gmdate('D, d M Y H:i:s ', filemtime($logoFile)) . 'GMT';
header("Last-Modified: $lastModified");
header("Content-Disposition: inline");
header("Content-Length: $fileSize");
die(fread($fHandle,$fileSize));

If you are going to serve the file yourself in PHP, then you have to manage the cashe headers. Please see this question (Handling If-modified-since header in a PHP-script)

Accountant م
  • 6,975
  • 3
  • 41
  • 61