Created
September 30, 2013 09:50
-
-
Save hakre/6761613 to your computer and use it in GitHub Desktop.
duri - data:// URI based, non-javascript anonymous redirect script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* duri - data:// URI based, non-javascript anonymous redirect script | |
* | |
* Redirects tested to ... | |
* ... work with: | |
* - Firefox (23.0.1) | |
* - Chrome (29.0.1547.76 m) | |
* - Google URL shortener <http://goo.gl/> | |
* ... not work with: | |
* - Internet Explorer (6.x) | |
* - curl (7.21.6) | |
* | |
* Usage: | |
* u ABSOLUTE-URI - generate base64 encoded HTML fragment for the anomyzing redirect | |
* r BASE64-CHUNK - generate HTTP location header based response to data-uri contain- | |
* ning the base64 payload as text/html (301) | |
* | |
* RFC2397 - The "data" URL scheme | |
* <http://tools.ietf.org/html/rfc2397> | |
* | |
* RFC2616 - Hypertext Transfer Protocol -- HTTP/1.1 | |
* <http://tools.ietf.org/html/rfc2616> | |
* 4.2 Message Headers - <http://tools.ietf.org/html/rfc2616#section-4.2> | |
* 10.3.2 301 Moved Permanently - <http://tools.ietf.org/html/rfc2616#section-10.3.2> | |
* 14.30 Location - <http://tools.ietf.org/html/rfc2616#section-14.30> | |
*/ | |
if (@$_GET['u']) | |
{ | |
$dataBase64 = Duri_GenerateBase64EncodedHtmlRefreshBody($_GET['u']); | |
echo "Base64 encoded HTML: <input type=\"text\" value=\"", $dataBase64, "\"><br>\n"; | |
echo "<a href=\"?r=", $dataBase64, "\">Link (relative).</a><br>\n"; | |
$self = SapiHttpRequest::getRequestUri(FALSE); | |
if (FALSE !== $self) { | |
$self .= "?r=" . $dataBase64; | |
echo "<a href=\"", $self,"\">Link (absolute).</a><br>\n"; | |
} | |
if (isset($_GET['t'])) | |
{ | |
$uri = 'data:text/html;base64,' . $dataBase64; | |
$tinyUrl = preg_replace('~^http://~i', 'https://', TinyUrlApi::getShortened($uri)); | |
echo "TinyURL (data:): <tt><a href=\"", Duri_EncodeHtmlAttributeValue($tinyUrl), "\">",Duri_EncodeHtmlText($tinyUrl),"</a></tt><br>\n"; | |
$tinyUrl = preg_replace('~^http://~i', 'https://', TinyUrlApi::getShortened($self)); | |
echo "TinyURL (chain+data:): <tt><a href=\"", Duri_EncodeHtmlAttributeValue($tinyUrl), "\">",Duri_EncodeHtmlText($tinyUrl),"</a></tt><br>\n"; | |
} | |
} | |
if (@$_GET['r']) { | |
$url = strtr($_GET['r'], ' ', '+'); # Work around PHP oldskool URL decoding plusses to spaces by reverting it. | |
# Note: This is for older PHP versions, | |
if (preg_match('~\s~', $url)) { | |
return; | |
} | |
$url = 'data:text/html;base64,' . $url; | |
header('Location: ' . $url, TRUE, 301); | |
echo '<a href="'. Duri_EncodeHtmlAttributeValue($url) . '">Redirecting.</a>'; | |
return; | |
} | |
function Duri_GenerateBase64EncodedHtmlRefreshBody($absoluteUri) { | |
$uriAttribute = Duri_EncodeHtmlAttributeValue($absoluteUri); | |
$html = sprintf( | |
'<meta http-equiv="refresh" content="0; url=%s"><a href="%1$s">Moved.</a>' | |
, $uriAttribute | |
); | |
return rtrim(base64_encode($html), '='); | |
} | |
function Duri_EncodeHtmlText($text) { | |
return htmlspecialchars($text, ENT_COMPAT, 'ISO-8859-1'); | |
} | |
function Duri_EncodeHtmlAttributeValue($value) { | |
return htmlspecialchars($value, ENT_COMPAT, 'ISO-8859-1'); | |
} | |
/** | |
* PHP Sapi Http Request abstraction | |
*/ | |
class SapiHttpRequest | |
{ | |
public static function getRequestUri($includeQuery = TRUE) { | |
$server = $_SERVER; | |
$s = empty($server["HTTPS"]) ? '' : ($server["HTTPS"] == "on") ? "s" : ""; | |
// NOTE: This block seems superfluous, SERVER_PROTOCOL not always available, | |
// the only use is to verify it is set to some HTTP protocol if set. | |
if (isset($server["SERVER_PROTOCOL"])) { | |
$sp = strtolower($server["SERVER_PROTOCOL"]); | |
$spn = substr($sp, 0, strpos($sp, "/")); | |
if ($spn !== 'http') { | |
trigger_error(sprintf('SERVER_PROTOCOL not HTTP: "%s"', $server["SERVER_PROTOCOL"])); | |
} | |
} | |
$protocol = 'http' . $s; | |
if (!isset($server["SERVER_PORT"])) { | |
$server["SERVER_PORT"] = $s ? "443" : "80"; | |
} | |
$port = ($server["SERVER_PORT"] === $s ? "443" : "80") ? "" : (":".$server["SERVER_PORT"]); | |
$host = isset($server['HTTP_HOST']) ? $server['HTTP_HOST'] : $server['SERVER_NAME']; | |
// codepad.viper-7.com fix PHP_SELF (indirect for REQUEST_URI) | |
if ($server ["HTTP_HOST"] === "codepad.viper-7.com" && 0 === strpos($server["PHP_SELF"], $server["DOCUMENT_ROOT"])) { | |
$server["PHP_SELF"] = substr($server["PHP_SELF"], strlen($server["DOCUMENT_ROOT"])) . "/55dev"; | |
} | |
if (!isset($server['REQUEST_URI'])) { | |
$rurib = $server["PHP_SELF"]; | |
isset($server["QUERY_STRING"]) && $rurib .= "?" . $server["QUERY_STRING"]; | |
$server['REQUEST_URI'] = $rurib; | |
} | |
$ruri = $server['REQUEST_URI']; | |
if (!$includeQuery && FALSE !== $qpos = strpos($ruri, "?")) { | |
$ruri = substr($ruri, 0, $qpos); | |
} | |
return $protocol . "://" . $host . $port . $ruri; | |
} | |
} | |
/** | |
* Uri Shortener Service - TinyURL implementation | |
*/ | |
class TinyUrlApi | |
{ | |
public static function getShortened($uri) { | |
// http://tinyurl.com/api-create.php?url=%s | |
$api = new self(); | |
return $api->getShortenedAppspot($uri); | |
} | |
/** | |
* TinyUrl API implementation for Appspot JSON Adapter | |
* Endpoint: http://json-tinyurl.appspot.com/?url=%s | |
* | |
*/ | |
private function getShortenedAppspot($uri) { | |
$apiUrl = sprintf('http://json-tinyurl.appspot.com/?url=%s', rawurlencode($uri)); | |
$resultJson = @file_get_contents($apiUrl); | |
if (FALSE === $resultJson) { | |
return FALSE; | |
} | |
$result = json_decode($resultJson, TRUE); | |
if ($result === NULL || !isset($result['tinyurl'], $result['ok'])) { | |
return FALSE; | |
} | |
return $result['tinyurl']; | |
} | |
} | |
?> | |
<form> | |
<input name="u" type="text" size="80"<?php @$_GET['u'] ? printf(' value="%s"', Duri_EncodeHtmlAttributeValue($_GET['u'])) : NULL; ?>><br> | |
<label><input type="checkbox" name="t"<?php @$_GET['t'] ? printf(' checked') : NULL; ?>> Create TinyURL link</label><br> | |
<input type="submit"> | |
<a href="?">Clear.</a> | |
</form> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment