From 6de20842d58bf56a5c7918a1de43f8468c6db656 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 22 Feb 2017 15:53:42 +0100 Subject: [PATCH 1/6] This version is php7 compatible. Additionally inserted some minor issues such as input param checks. --- README | 20 ++++++++++++++++++++ config.php | 6 ++++-- redirect.php | 34 +++++++++++++++++++++++++++++----- rename.htaccess | 6 +++--- shorten.php | 26 +++++++++++++++++++------- 5 files changed, 75 insertions(+), 17 deletions(-) diff --git a/README b/README index 909c774..b53d2e4 100644 --- a/README +++ b/README @@ -34,3 +34,23 @@ 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-02-22] + * 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. + * Tested on Debian8 Jessie, PHP7.0, Apache/2.4.10 (Debian), MySQL 14.14 Distrib 5.7.17, for Linux (x86_64). + \ No newline at end of file diff --git a/config.php b/config.php index bd7ba99..d9e0c94 100644 --- a/config.php +++ b/config.php @@ -3,6 +3,8 @@ * 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. */ // db options @@ -13,8 +15,8 @@ define('DB_TABLE', 'shortenedurls'); // connect to database -mysql_connect(DB_HOST, DB_USER, DB_PASSWORD); -mysql_select_db(DB_NAME); +$mysqli = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); + // base location of script (include trailing slash) define('BASE_HREF', 'http://' . $_SERVER['HTTP_HOST'] . '/'); diff --git a/redirect.php b/redirect.php index d929209..19f77f6 100644 --- a/redirect.php +++ b/redirect.php @@ -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'); @@ -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); @@ -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'); @@ -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']; } \ No newline at end of file diff --git a/rename.htaccess b/rename.htaccess index 347695d..eac8c3d 100644 --- a/rename.htaccess +++ b/rename.htaccess @@ -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 diff --git a/shorten.php b/shorten.php index 74ef577..dbbe911 100644 --- a/shorten.php +++ b/shorten.php @@ -3,10 +3,16 @@ * 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('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)) @@ -36,8 +42,10 @@ } // 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); @@ -45,20 +53,24 @@ 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; From 31e33c0061fd518f72b5ed326daf07fb9fde772b Mon Sep 17 00:00:00 2001 From: "ikaros.kappler" Date: Wed, 22 Feb 2017 16:36:36 +0100 Subject: [PATCH 2/6] Enhanced mod_rewrite rules. --- .htaccess | 17 +++++++++++++++++ README | 6 ++++++ config.php | 6 ++---- 3 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 .htaccess diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..e7581bf --- /dev/null +++ b/.htaccess @@ -0,0 +1,17 @@ +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 + +FileETag none +ServerSignature Off + +Options All -Indexes + + +RewriteEngine On +RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L,NE] +RewriteRule ^([0-9a-zA-Z]{1,6})$ redirect.php?url=$1 [L] + \ No newline at end of file diff --git a/README b/README index b53d2e4..dd4e626 100644 --- a/README +++ b/README @@ -52,5 +52,11 @@ Using your personal URL shortener service * 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. + * Changed this line in the .htaccess file + before: + RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L] + after: + RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L,NE] + Reason: the NE (noescape) flag is required here, otherwise your (hopefully encoded) URL param gets encoded a second time during redirect. * Tested on Debian8 Jessie, PHP7.0, Apache/2.4.10 (Debian), MySQL 14.14 Distrib 5.7.17, for Linux (x86_64). \ No newline at end of file diff --git a/config.php b/config.php index d9e0c94..bd7ba99 100644 --- a/config.php +++ b/config.php @@ -3,8 +3,6 @@ * 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. */ // db options @@ -15,8 +13,8 @@ define('DB_TABLE', 'shortenedurls'); // connect to database -$mysqli = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); - +mysql_connect(DB_HOST, DB_USER, DB_PASSWORD); +mysql_select_db(DB_NAME); // base location of script (include trailing slash) define('BASE_HREF', 'http://' . $_SERVER['HTTP_HOST'] . '/'); From 0db3d04f08c8b0daaf8685d158bc79ff5df83fe6 Mon Sep 17 00:00:00 2001 From: "ikaros.kappler" Date: Wed, 22 Feb 2017 19:17:20 +0100 Subject: [PATCH 3/6] Enhanced mod_rewrite rules. --- .htaccess | 4 +++- README | 15 +++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.htaccess b/.htaccess index e7581bf..f4d8ace 100644 --- a/.htaccess +++ b/.htaccess @@ -12,6 +12,8 @@ Options All -Indexes RewriteEngine On -RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L,NE] +# 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 ^([0-9a-zA-Z]{1,6})$ redirect.php?url=$1 [L] \ No newline at end of file diff --git a/README b/README index dd4e626..8c78ff4 100644 --- a/README +++ b/README @@ -38,8 +38,8 @@ Using your personal URL shortener service = Changelog = - -[2017-02-22] +------------- +[2017-02-22, Ika] * Changed from mysql to mysqli. * New version is compatible with PHP >= 7.0. * Replaced mysql_query by mysqli::query. @@ -52,11 +52,10 @@ Using your personal URL shortener service * 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. - * Changed this line in the .htaccess file - before: - RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L] - after: - RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L,NE] - Reason: the NE (noescape) flag is required here, otherwise your (hopefully encoded) URL param gets encoded a second time during redirect. + * 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. * Tested on Debian8 Jessie, PHP7.0, Apache/2.4.10 (Debian), MySQL 14.14 Distrib 5.7.17, for Linux (x86_64). \ No newline at end of file From 140d142fe3f341f3504d85faf18315fa1e4ec258 Mon Sep 17 00:00:00 2001 From: "ikaros.kappler" Date: Wed, 22 Feb 2017 20:00:30 +0100 Subject: [PATCH 4/6] Added a Content-Type header to the shorten.php --- README | 4 ++-- shorten.php | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README b/README index 8c78ff4..c2ebbde 100644 --- a/README +++ b/README @@ -54,8 +54,8 @@ Using your personal URL shortener service * 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] - + 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). \ No newline at end of file diff --git a/shorten.php b/shorten.php index dbbe911..013f919 100644 --- a/shorten.php +++ b/shorten.php @@ -6,7 +6,9 @@ * * @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) ) { From c5a47018ff230bcb7a6dcbc371316be2d6b9fabc Mon Sep 17 00:00:00 2001 From: "ikaros.kappler" Date: Sat, 25 Feb 2017 20:15:15 +0100 Subject: [PATCH 5/6] Added the Access-Control-Allow-Origin header in the .htaccess to allow remote access via AJAX. --- .htaccess | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.htaccess b/.htaccess index f4d8ace..371726c 100644 --- a/.htaccess +++ b/.htaccess @@ -1,4 +1,4 @@ -DirectoryIndex index.php +DirectoryIndex index.html index.php # remove the next 3 lines if you see a 500 server error php_flag register_globals off @@ -10,6 +10,10 @@ ServerSignature Off Options All -Indexes + + Header set Access-Control-Allow-Origin * + + RewriteEngine On # Use THE_REQUEST to match URL, otherwise double slashes will be stripped From 5a5ae3f77c80cd43b4d9ca0f05a21b061c5bb871 Mon Sep 17 00:00:00 2001 From: Ikaros Kappler Date: Mon, 20 Mar 2017 21:03:03 +0100 Subject: [PATCH 6/6] Added a usage description at /usage. --- .htaccess | 1 + README | 3 +++ index.html | 49 +++++++++++++++++++++++++++++-------------------- rename.htaccess | 1 + usage.txt | 2 ++ 5 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 usage.txt diff --git a/.htaccess b/.htaccess index 371726c..749398c 100644 --- a/.htaccess +++ b/.htaccess @@ -19,5 +19,6 @@ 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] \ No newline at end of file diff --git a/README b/README index c2ebbde..1a9b041 100644 --- a/README +++ b/README @@ -39,6 +39,9 @@ Using your personal URL shortener service = 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. diff --git a/index.html b/index.html index 7d619f9..8e81375 100644 --- a/index.html +++ b/index.html @@ -1,21 +1,30 @@ -

If you are seeing this, your .htaccess file is configured incorrectly or doesn't exist.

-

Copy and paste the code below into your .htaccess file

-
-DirectoryIndex index.php
+
+
+  
+    url.func.name
+  
 
-php_flag register_globals off
-php_flag magic_quotes_gpc off
-
-FileETag none
-ServerSignature Off
-
-Options All -Indexes
-
-<IfModule mod_rewrite.c>
-RewriteEngine On
-RewriteRule ^shorten/(.*)$ shorten.php?longurl=$1 [L]
-RewriteRule ^([0-9a-zA-Z]{1,6})$ redirect.php?url=$1 [L]
-</IfModule>
-
- -

For detailed instructions, visit Brian Cray

\ No newline at end of file + + +
+ Ooooh, that thing has redirects. +
+ — Resource Locating Core +
+
+ + diff --git a/rename.htaccess b/rename.htaccess index eac8c3d..3bf7fb0 100644 --- a/rename.htaccess +++ b/rename.htaccess @@ -13,5 +13,6 @@ Options All -Indexes 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] \ No newline at end of file diff --git a/usage.txt b/usage.txt new file mode 100644 index 0000000..ab6fbe1 --- /dev/null +++ b/usage.txt @@ -0,0 +1,2 @@ +Shorten: ./shorten/ +Redirect: ./