* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. */ // The 'service' GET parameter selects which remote webservice to use. // This script then retrieves the document from the remote server, // optionally performs some transformations, and then forwards it on // in its response. // // This script is not a proxy in the RFC2616 (HTTP) sense. However, // it does try to do the right thing with headers so as to be // transparent. // HEADER PROCESSING ////////////////////////////////////////////////// if (!function_exists('getallheaders')): // alternative implementation for non-Apache servers function getallheaders() { $lines = explode("\n", $_SERVER['ALL_RAW']); $headers = array(); preg_match_all('/^([^:]+):\s*((?:[^\n]+\n[ \t])*[^\n]+)\n/', $_SERVER['ALL_RAW'], $m, PREG_SET_ORDER); foreach ($m as $h) { $val = preg_replace('/\n\s+/g', ' ', $h[2]); $headers[$h[1]] = $val; } return $headers; } endif; function filter_response_headers($ch, $content) { if (!preg_match('/^(?:Connection|Transfer-Encoding|Content-Encoding|Content-Length):/', $content)) { header($content); } return strlen($content); } // SERVICE RULES ////////////////////////////////////////////////////// function lastfm_jsonise($response) { if ($_GET['callback']) header('Content-Type: text/javascript; charset=utf-8'); else header('Content-Type: text/x-json; charset=utf-8'); if ($_GET['callback']) echo $_GET['callback'] . '('; if (0 < preg_match_all('/^\d+,(.+)$/m', $response, $m)) { if ($count = $_GET['count']) $m[1] = array_slice($m[1], 0, $count); foreach ($m[1] as &$trackname) { $trackname = "'" . addslashes($trackname) . "'"; } echo '[' . implode(',', $m[1]) . ']'; } else { echo '["Silence"]'; } if ($_GET['callback']) echo ');'; } function service_url() { $args = array(); if ($_GET['count']) $args['count'] = (int)$_GET['count']; if ($_GET['callback']) $args['callback'] = $_GET['callback']; switch ($_GET['service']) { case 'lastfm': return 'http://ws.audioscrobbler.com/1.0/user/' . $_GET['user'] . '/recenttracks.txt'; case 'delicious': return 'http://feeds.delicious.com/v2/json/' . $_GET['user'] . '?' . http_build_query($args); case 'delicious_tag': return 'http://feeds.delicious.com/v2/json/network/' . $_GET['user'] . "/" . $_GET['tag'] . '?' . http_build_query($args); case 'twitter': return 'http://twitter.com/statuses/user_timeline/' . $_GET['user'] . '.json?' . http_build_query($args); default: exit(0); } } function filter_response_body($ch, $body) { $len = strlen($body); switch ($_GET['service']) { case 'lastfm': lastfm_jsonise($body); break; case 'delicious': echo $body; break; case 'twitter': echo $body; break; default: echo $body; break; } return $len; } // MAIN /////////////////////////////////////////////////////////////// $ch = curl_init(); $req = getallheaders(); // HTTP/1.1 wouldn't want us propagating these... unset($req['Host']); unset($req['Connection']); unset($req['Accept-Encoding']); if ($req['Referer']) { @curl_setopt($ch, CURLOPT_REFERER, $req['Referer']); unset($req['Referer']); } if ($req['User-Agent']) { @curl_setopt($ch, CURLOPT_USERAGENT, $request_headers['User-Agent']); unset($req['User-Agent']); } if ($req['If-Modified-Since']) { $time = strtotime($req['If-Modified-Since']); @curl_setopt($ch, CURLOPT_TIMEVALUE, $time); @curl_setopt($ch, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); } $url = service_url(); @curl_setopt($ch, CURLOPT_URL, $url); @curl_setopt($ch, CURLOPT_HTTPHEADER, $req); @curl_setopt($ch, CURLOPT_HEADER, 0); @curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8); @curl_setopt($ch, CURLOPT_BUFFERSIZE, 2048); // should be enough for a header @curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'filter_response_headers'); $body = @curl_exec($ch); if ($body) filter_response_body($ch, $body); curl_close($ch); ?>