Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .htaccess
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
DirectoryIndex index.html index.php

# remove the next 3 lines if you see a 500 server error
php_flag register_globals off
php_flag magic_quotes_gpc off
php_value display_errors 0

FileETag none
ServerSignature Off

Options All -Indexes

<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin *
</IfModule>

<IfModule mod_rewrite.c>
RewriteEngine On
# Use THE_REQUEST to match URL, otherwise double slashes will be stripped
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+([^/]+)/([^\s]*)\s [NC]
RewriteRule ^shorten/(.*)$ shorten.php?longurl=%2 [L,QSA,NE]
RewriteRule ^usage$ usage.txt
RewriteRule ^([0-9a-zA-Z]{1,6})$ redirect.php?url=$1 [L]
</IfModule>
28 changes: 28 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,31 @@ Using your personal URL shortener service
- To manually shorten URLs open in your web browser the location where you uploaded the files.
- To programmatically shorten URLs with PHP use the following code:
$shortenedurl = file_get_contents('http://yourdomain.com/shorten.php?longurl=' . urlencode('http://' . $_SERVER['HTTP_HOST'] . '/' . $_SERVER['REQUEST_URI']));



= Changelog =
-------------
[2017-03-20, Ika]
* Added a /usage file.

[2017-02-22, Ika]
* Changed from mysql to mysqli.
* New version is compatible with PHP >= 7.0.
* Replaced mysql_query by mysqli::query.
* Replaced mysql_real_escape_string by mysqli::real_escape_string.
* Replace fmod (on integers) by integer modulo operator %.
* Declared (previously undeclared) variable $out in getShortenedURLFromID function.
* Replaced mysql_result by mysqli::query and mysqli_result::fetch_assoc.
* Added param checks for $_GET and $_REQUEST.
* Added a file-exists and file-readable check for the cache (hint: old files in the cache directory are never purged. Idea: use temp directory).
* CACHE usage set to FALSE by default (config).
* Summed up the 'fetch long_url by shortened_url' into one function (fetchURL).
* Added '400 Bad Request' response if input 'long_url' is malformed.
* Added/changes these line(s) in the .htaccess file
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+([^/]+)/([^\s]*)\s [NC]
RewriteRule ^shorten/(.*)$ shorten.php?longurl=%2 [L,QSA,NE]
Reason: the NE (noescape) flag is required here, otherwise your (hopefully encoded) URL param gets encoded a second time during redirect end, and the input is matched with THE_REQUEST so double slashes are not removed from the target URL.
* Added the Content-Type header (text/plain) to the shorten.php.
* Tested on Debian8 Jessie, PHP7.0, Apache/2.4.10 (Debian), MySQL 14.14 Distrib 5.7.17, for Linux (x86_64).

49 changes: 29 additions & 20 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
<p>If you are seeing this, your <code>.htaccess</code> file is configured incorrectly or doesn't exist.</p>
<p>Copy and paste the code below into your <code>.htaccess</code> file</p>
<pre>
DirectoryIndex index.php
<!DOCTYPE html>
<html>
<head>
<title>url.func.name</title>
</head>

php_flag register_globals off
php_flag magic_quotes_gpc off

FileETag none
ServerSignature Off

Options All -Indexes

&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L]
RewriteRule ^([0-9a-zA-Z]{1,6})$ redirect.php?url=$1 [L]
&lt;/IfModule&gt;
</pre>

<p>For detailed instructions, visit Brian Cray</p>
<body>
<style>
div#message {
width : 400px;
height : 100px;
position : fixed;
left : 50%;
top : 50%;
margin-top : -50px;
margin-left : -200px;
text-align : center;
color : #0A5DAB;
font-family : "Palatino Linotype", "Book Antiqua", Palatino, serif;
font-size : 16pt;
}
</style>
<div id="message">
Ooooh, that thing has redirects.
<div style="text-align: right; font-size: 8pt;">
&mdash; Resource Locating Core
</div>
</div>
</body>
</html>
34 changes: 29 additions & 5 deletions redirect.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@
* First authored by Brian Cray
* License: http://creativecommons.org/licenses/by/3.0/
* Contact the author at http://briancray.com/
*
* @modified Ika 2017-02-22 Updated for PHP7.0.
*/

ini_set('display_errors', 0);

if( !array_key_exists('url',$_GET) )
{
die( 'Please pass a short url.' );
}

if(!preg_match('|^[0-9a-zA-Z]{1,6}$|', $_GET['url']))
{
die('That is not a valid short url');
Expand All @@ -18,10 +25,15 @@

if(CACHE)
{
$long_url = file_get_contents(CACHE_DIR . $shortened_id);
if(empty($long_url) || !preg_match('|^https?://|', $long_url))
$long_url = null;
if( file_exists(CACHE_DIR.$shortened_id) && is_readable(CACHE_DIR.$shortened_id) )
{
$long_url = file_get_contents(CACHE_DIR . $shortened_id);
}

if( empty($long_url) || !preg_match('|^https?://|', $long_url) )
{
$long_url = mysql_result(mysql_query('SELECT long_url FROM ' . DB_TABLE . ' WHERE id="' . mysql_real_escape_string($shortened_id) . '"'), 0, 0);
$long_url = fetchURL( $mysqli, $shortened_id );
@mkdir(CACHE_DIR, 0777);
$handle = fopen(CACHE_DIR . $shortened_id, 'w+');
fwrite($handle, $long_url);
Expand All @@ -30,12 +42,12 @@
}
else
{
$long_url = mysql_result(mysql_query('SELECT long_url FROM ' . DB_TABLE . ' WHERE id="' . mysql_real_escape_string($shortened_id) . '"'), 0, 0);
$long_url = fetchURL( $mysqli, $shortened_id );
}

if(TRACK)
{
mysql_query('UPDATE ' . DB_TABLE . ' SET referrals=referrals+1 WHERE id="' . mysql_real_escape_string($shortened_id) . '"');
$mysqli->query('UPDATE ' . DB_TABLE . ' SET referrals=referrals+1 WHERE id="' . $mysqli->real_escape_string($shortened_id) . '";');
}

header('HTTP/1.1 301 Moved Permanently');
Expand All @@ -53,4 +65,16 @@ function getIDFromShortenedURL ($string, $base = ALLOWED_CHARS)
$out += strpos($base, $char) * pow($length, $size - $i);
}
return $out;
}

function fetchURL( $mysqli, $shortened_id )
{
$resulti = $mysqli->query('SELECT long_url FROM ' . DB_TABLE . ' WHERE id="' . $mysqli->real_escape_string($shortened_id) . '";');
$row = $resulti->fetch_assoc();
if( !$row )
{
header("HTTP/1.0 404 Not Found");
die( 'Not found' );
}
return $row['long_url'];
}
7 changes: 4 additions & 3 deletions rename.htaccess
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
DirectoryIndex index.php

# remove the next 3 lines if you see a 500 server error
php_flag register_globals off
php_flag magic_quotes_gpc off
php_value display_errors 0
# php_flag register_globals off
# php_flag magic_quotes_gpc off
# php_value display_errors 0

FileETag none
ServerSignature Off
Expand All @@ -13,5 +13,6 @@ Options All -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L]
RewriteRule ^usage$ usage.txt
RewriteRule ^([0-9a-zA-Z]{1,6})$ redirect.php?url=$1 [L]
</IfModule>
30 changes: 22 additions & 8 deletions shorten.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@
* First authored by Brian Cray
* License: http://creativecommons.org/licenses/by/3.0/
* Contact the author at http://briancray.com/
*
* @modified Ika 2017-02-22 Updated for PHP7.0.
*/


header( 'Content-Type: text/plain;charset=utf-8' );

ini_set('display_errors', 0);

if( !array_key_exists('longurl',$_REQUEST) ) {
die( 'Please pass a longurl.' );
}

$url_to_shorten = get_magic_quotes_gpc() ? stripslashes(trim($_REQUEST['longurl'])) : trim($_REQUEST['longurl']);

if(!empty($url_to_shorten) && preg_match('|^https?://|', $url_to_shorten))
Expand Down Expand Up @@ -36,29 +44,35 @@
}

// check if the URL has already been shortened
$already_shortened = mysql_result(mysql_query('SELECT id FROM ' . DB_TABLE. ' WHERE long_url="' . mysql_real_escape_string($url_to_shorten) . '"'), 0, 0);
if(!empty($already_shortened))
$resulti = $mysqli->query('SELECT id FROM ' . DB_TABLE. ' WHERE long_url="' . $mysqli->real_escape_string($url_to_shorten) . '";');
$row = $resulti->fetch_assoc();
$already_shortened = null;
if( $row && !empty($already_shortened = $row['id']))
{
// URL has already been shortened
$shortened_url = getShortenedURLFromID($already_shortened);
}
else
{
// URL not in database, insert
mysql_query('LOCK TABLES ' . DB_TABLE . ' WRITE;');
mysql_query('INSERT INTO ' . DB_TABLE . ' (long_url, created, creator) VALUES ("' . mysql_real_escape_string($url_to_shorten) . '", "' . time() . '", "' . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . '")');
$shortened_url = getShortenedURLFromID(mysql_insert_id());
mysql_query('UNLOCK TABLES');
$mysqli->query('LOCK TABLES ' . DB_TABLE . ' WRITE;');
$mysqli->query('INSERT INTO ' . DB_TABLE . ' (long_url, created, creator) VALUES ("' . $mysqli->real_escape_string($url_to_shorten) . '", "' . time() . '", "' . $mysqli->real_escape_string($_SERVER['REMOTE_ADDR']) . '");');
$shortened_url = getShortenedURLFromID($mysqli->insert_id);
$mysqli->query('UNLOCK TABLES;');
}
echo BASE_HREF . $shortened_url;
} else {
header("HTTP/1.0 400 Bad Request");
die( 'Bad Request' );
}

function getShortenedURLFromID ($integer, $base = ALLOWED_CHARS)
{
$length = strlen($base);
$out = '';
while($integer > $length - 1)
{
$out = $base[fmod($integer, $length)] . $out;
$out = $base[$integer%$length] . $out;
$integer = floor( $integer / $length );
}
return $base[$integer] . $out;
Expand Down
2 changes: 2 additions & 0 deletions usage.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Shorten: ./shorten/<url>
Redirect: ./<key>