Skip to content

Instantly share code, notes, and snippets.

@hakre
Created September 30, 2013 09:50
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hakre/6761613 to your computer and use it in GitHub Desktop.
Save hakre/6761613 to your computer and use it in GitHub Desktop.
duri - data:// URI based, non-javascript anonymous redirect script
<?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