Hi,
habt ihr irgendwelche url shortener am laufen? Am besten welche, die leicht zu konfigurieren und warten sind?
Habe nen EiWoMiSau Hosting Paket.
Danke und Gruß
Ben
Hi,
habt ihr irgendwelche url shortener am laufen? Am besten welche, die leicht zu konfigurieren und warten sind?
Habe nen EiWoMiSau Hosting Paket.
Danke und Gruß
Ben
Da gibt es z.B. YOURLS sollte auch auf einem shared hosting zu installieren sein.
Ich habe mir da mal selbst was gebaut, habe das in einem kleinen Webhosting laufen.
Das ist prinzipiell nur eine PHP Datei die ziemlich rustikal ist. Als Backend hab ich da ne MySQL Datenbanktabelle benutzt.
<?php
//create the database connection
$pdo = new PDO('mysql:host=DBIP;dbname=DBNAME', 'DBUSER', 'DBPASSWD');
//check whether a string is given via $_GET as input or not, then execute the program block for the situation
if (isset($_GET['v'])) {
//if yes, search for the string in the database
$moveto = $_GET['v'];
$mode = 'redirect';
$title = 'My URL Shortener | Sie werden in Kürze weitergeleitet...';
//check whether the length of the input string is correct (3 chars)
if (strlen($moveto) == 3) {
//if yes, check whether the string is given in the database
$statement = $pdo->prepare('SELECT `link` FROM `links` WHERE `short` = "'. $moveto .'" LIMIT 1');
$statement->execute();
$data = $statement->fetch();
//check whether we got link out of the database
if (isset($data['link'])) {
//if yes, finally redirect (redirection could be found in the header)
$link = $data['link'];
$result = '<div class="text">Sie werden in Kürze weitergeleitet...<br><br>Sollten sie nicht weitergeleitet werden, dann klicken sie <a href="'. $link .'" target="_self">hier</a>.</div>';
} else {
//if not, then set the result to not found
$result = '<div class="text">Der angefragte Link wurde nicht gefunden!<br><br><a href="'. $_SERVER['SCRIPT_NAME'] .'">Zurück zur Startseite</div>';
}
} else {
//if not, $moveto is invalid, so put the error in the result
$result = '<div class="text">Ungültiger Link!<br><br><a href="'. $_SERVER['SCRIPT_NAME'] .'">Zurück zur Startseite</div>';
}
} else {
//if not, try to create a short link or show the options to create a short link
$mode = 'create';
$title = 'My URL Shortener';
if (isset($_POST['link']) and isset($_POST['password'])) {
//check whether the link is valid
if (! strpos($_POST['link'], '.') OR strlen($_POST['link']) < 5 OR substr($_POST['link'], 0, 1) == '.') {
//if the link is invalid (doesn't contain at least one dot), put a error to the result
$result = '<div class="text">Ungültige Eingabe!<br><br><a href="'. $_SERVER['SCRIPT_NAME'] .'">Zurück zur Startseite</div>';
//check whether the password is correct
} else if ($_POST['password'] == 'PASSWORT') {
//if yes, make a short link
//before we create a short link, we check whether the link is already in the database
$buffer = $_POST["link"];
$buffer = (substr($buffer, 0, 4 ) === "http" || substr($buffer, 0, 6 ) === "ftp://"?$buffer:'http://'.$buffer);
$statement = $pdo->prepare('SELECT `short` FROM `links` WHERE `link` = "'. $buffer .'" LIMIT 1');
$statement->execute();
$data = $statement->fetch();
//if we didn't found a the short link in the database, we're going to create it
if (! isset($data['short'])) {
//chars defines the possible chars, that can be part of a short link
$chars = 'abcdefghujklmmnopqrstuvwxyzABDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
//possible contains the possibility, whether a short link is already in use
$possible = FALSE;
$i = 0;
//try as long as necessary to find a short link, that doesn't exist in the database
while ($possible == FALSE AND $i <= 1000) {
//increase $i
$i++;
//generate a short link
$short = substr(str_shuffle($chars), 0, 3);
//search for the generated short link in the database
$statement = $pdo->prepare('SELECT `ID` FROM `links` WHERE `short` = "'. $short .'" LIMIT 1');
$statement->execute();
$data = $statement->fetch();
//if there's a result, set possible to TRUE
$possible = (isset($data['short'])?FALSE:TRUE);
}
//check whether the loop exited with $i < 1000
if ($i < 1000) {
//if we found a possible short string, we will insert them to the database
$timestamp = time();
$statement = $pdo->prepare('INSERT INTO `links`(`short`, `link`, `timestamp`) VALUES ("'. $short .'","'. $buffer .'","'. $timestamp .'")');
$statement->execute();
$data = $statement->fetch();
} else {
$error = 'databasefull';
}
} else {
$short = $data['short'];
}
//check whether we have a error
if (! isset($error)) {
//return the short link
$result = '<div class="text">Der Link wurde erfolgreich gekürzt!</div>';
$request = 'https://' . $_SERVER["SERVER_NAME"] .'?v='. $short;
$result .= '<p class="link"><a href="'. $request .'" target="_blank">'. $request .'</a></p>';
$result .= '<center><input type="text" value="'. $request .'" style="width: 200px; height: 20px; text-align: center;" readonly></center>';
$result .= '<div class="smalltext">Text markieren und mit Strg+C kopieren</div><br><br>';
$result .= '<div class="text"><a href="'. $_SERVER["SCRIPT_NAME"] .'">Zurück zur Startseite</a>';
} else {
//Error! Maybe the database must be cleaned up
$result = '<div class="text">Datenbankfehler! Es konnte kein verfügbarer kurzer Link gefunden werden!<br><br><a href="'. $_SERVER["SCRIPT_NAME"] .'">Zurück zur Startseite</a></div>';
}
} else {
//if not, return a error message
$result = '<div class="text">Das Passwort ist falsch!<br><br><a href="'. $_SERVER["SCRIPT_NAME"] .'">Zurück zur Startseite</a></div>';
}
} else {
$result = '<form action="'. $_SERVER['SCRIPT_NAME'] .'" id="input" method="post">';
$result .= '<h2>My URL Shortener</h2>';
$result .= '<table border=0 width="100%"><tr><td align="right"><label for="link" class="text">Link: </label></td><td><input type="text" name="link" id="link" maxlength="1024" style="width: 100%;"></td></tr>';
$result .= '<tr><td align="right" width="10%"><label for="password" class="text">Passwort: </label></td><td><input type="password" name="password" id="password" maxlength="64" style="width: 100%;"></td></tr></table>';
$result .= '<center><button type="submit" class="button">Link kürzen</button></center>';
$result .= '</form>';
}
}
//append the head to the output
$output = '<!DOCTYPE html><html><head><title>'. $title .'</title><meta name="robots" content="noindex, nofollow" /><link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">';
$output .= (isset($link)?'<meta http-equiv="refresh" content="1; URL='. $link .'">':'');
//append the css style
$output .= '<style>body {background-color:#333333;}';
$output .= 'h2 {font-family: Arial,sans-serif; font-size: 16pt; font-weight: bold; text-align: center;}';
$output .= '.text {font-family: Arial,sans-serif; font-size: 12pt; font-weight: bold; text-align: center;}';
$output .= '.smalltext {font-family: Arial,sans-serif; font-size: 8pt; font-weight: bold; text-align: center;}';
$output .= '.button {font-family: Arial,sans-serif; font-size: 12pt; font-weight: bold; width: 40%; height: 25px;}';
$output .= '.link {font-family: Arial,sans-serif; font-size: 12pt; font-weight: bold; font-style: italic; text-align: center;}';
$output .= '.box {background-color: #ffffff; width: 40%; padding: 10px; border: 0px; border-radius: 15px; opacity: 0.95;}</style>';
$output .= '</head><body><br><br>';
//append the body to the output
$output .= '<span style="display: flex; align-items: center; justify-content: center;" width="100%"><div class="box">'. $result. '</div></span>';
//append the footer to the output
$output .= '</body></html>';
//output of the document
echo $output;
?>
Alles anzeigen
CREATE TABLE `links` (
`ID` int(11) NOT NULL,
`link` varchar(1024) NOT NULL,
`short` varchar(3) NOT NULL,
`timestamp` int(11) NOT NULL
) DEFAULT CHARSET=latin1;
Macht bei mir was er soll und arbeitet zuverlässig. Aber ohne Gewähr...
Ich habe meinen URL Shortener gerade nochmal etwas überarbeitet. Repository
Ist jetzt etwas weniger rustikal und etwas mehr sicher.
Danke fürs teilen whoami0501
Schaut gut aus.
whoami0501 Ich wollte gerade was über Prepared Statements und SQL Injections schreiben. Mittlerweile hast Du da größtenteils nachgebessert
Aber leider ziehst Du bei redirect.php noch immer keinen Vorteil aus den Prepared Statements. Du prüfst die Variable zwar deutlich besser, fügst sie aber immer noch direkt in den Query ein. Das Thema XSS solltest Du Dir trotzdem noch einmal ansehen! Du könntest die URL auch einmal durch parse_url() o.ä. jagen.
Tipp: Du musst das Statement beim Insert nicht bei jedem Schleifendurchlauf neu erstellen. Der Vorteil von Prepared Statements ist ja gerade, dass man den Query einmal vorbereitet und in der Schleife quasi nur die Variable aktualisiert. Das spart bei größeren Dingen deutlich Ressourcen.
whoami0501 Ich wollte gerade was über Prepared Statements und SQL Injections schreiben. Mittlerweile hast Du da größtenteils nachgebessert
Aber leider ziehst Du bei redirect.php noch immer keinen Vorteil aus den Prepared Statements. Du prüfst die Variable zwar deutlich besser, fügst sie aber immer noch direkt in den Query ein. Das Thema XSS solltest Du Dir trotzdem noch einmal ansehen! Du könntest die URL auch einmal durch parse_url() o.ä. jagen.
Tipp: Du musst das Statement beim Insert nicht bei jedem Schleifendurchlauf neu erstellen. Der Vorteil von Prepared Statements ist ja gerade, dass man den Query einmal vorbereitet und in der Schleife quasi nur die Variable aktualisiert. Das spart bei größeren Dingen deutlich Ressourcen.
Huch, verdammt. Ist gefixt.
Ich muss dazu sagen, dass ich das gebaut habe, als ich noch ein blutiger Anfänger in PHP und Co. war. Gestern abend habe ich das ganze ja nochmal überarbeitet und da ist mir die Stelle wohl durch die Lappen gegangen. Jetzt sollte es stimmen.
Über parse_url kann man sich jetzt streiten - ich wüsste nicht, wie ich da zusammen mit meinen RegEx Tests noch einen Mehrwert rausholen sollte...
EDIT: Ein XSS Angriff wird eigentlich schon dadurch ausgeschlossen, dass die script-src in der CSP auf none steht. Ich schaue mir das Thema aber trotzdem nochmal an.
Super! Danke.
Hier noch der Code von dem Shortlinker, den ich unter anderem in der Signatur hier im Forum benutze:
https://github.com/perryflynn/huepf
Demo: https://hüpf.net/laengstes
Hier sieht man, dass der Referer wirklich entfernt wird: https://hüpf.net/req