146 lines
3.1 KiB
PHP
146 lines
3.1 KiB
PHP
<?php
|
|
require 'Cache.php';
|
|
|
|
/**
|
|
todo:
|
|
- limit download size
|
|
- santize input
|
|
*/
|
|
|
|
class GopherGetter {
|
|
public $uri;
|
|
public $host;
|
|
public $port;
|
|
public $path;
|
|
public $key;
|
|
|
|
public $input;
|
|
|
|
private $cache;
|
|
|
|
function __construct($u, $i = NULL) {
|
|
$this->cache = new Cache(CACHE_PATH); //Make sure it exists and is writeable
|
|
|
|
// split the incoming URI on :// to prevent too much fooling
|
|
// around and to make sure that we normalize our data
|
|
$u = array_pop(explode("://", $u));
|
|
|
|
|
|
// strip any leading slash from the path
|
|
$u = ltrim($u, '/');
|
|
$this->uri = "gopher://$u";
|
|
|
|
// split host and port from uri
|
|
$data = parse_url($this->uri);
|
|
|
|
$this->host = $data['host'];
|
|
$this->port = array_key_exists('port', $data) ? $data['port'] : 70;
|
|
|
|
// only allow port 70, or if ALLOW_ALL_PORTS is true, also allow ports over 1024
|
|
if ( $this->port != 70 && ( (defined('ALLOW_ALL_PORTS') && ALLOW_ALL_PORTS != true) || $this->port < 1024 ) ) {
|
|
throw new Exception("Port violation");
|
|
}
|
|
|
|
if ( defined('RESTRICT_TO_MATCH') && ! preg_match(RESTRICT_TO_MATCH, $this->host) ) {
|
|
throw new Exception("Host violation");
|
|
}
|
|
|
|
|
|
// strip the leading slash from the path
|
|
if ( array_key_exists('path', $data) ) {
|
|
$this->path = ltrim($data['path'], '/');
|
|
}
|
|
else {
|
|
$this->path = "/";
|
|
}
|
|
|
|
$this->path = urldecode($this->path);
|
|
$this->input = $i;
|
|
|
|
$this->key = "$this->host:$this->port$this->path?$this->input";
|
|
}
|
|
|
|
function isValid() {
|
|
return isSet($this->host) && isSet($this->port) && isSet($this->path);
|
|
}
|
|
|
|
|
|
function isBinary() {
|
|
return $this->cache->isBinary($this->key);
|
|
}
|
|
|
|
function isImage() {
|
|
return $this->cache->isImage($this->key);
|
|
}
|
|
|
|
function urlFor() {
|
|
return $this->cache->url($this->key);
|
|
}
|
|
|
|
function get() {
|
|
|
|
$this->result = "";
|
|
$this->errstr = "";
|
|
$this->errno = "";
|
|
|
|
$this->result = $this->cache->get($this->key);
|
|
if ( $this->result === FALSE ) {
|
|
error_log("load it");
|
|
$fp = stream_socket_client("tcp://$this->host:$this->port", $this->errno, $this->errstr, 30);
|
|
|
|
if (!$fp) {
|
|
return FALSE;
|
|
}
|
|
else {
|
|
$data = $this->path;
|
|
if ( isset($this->input) && $this->input != "" ) {
|
|
$data .= "\t$this->input";
|
|
}
|
|
|
|
fwrite($fp, "$data\r\n");
|
|
$size = 0;
|
|
while (!feof($fp)) {
|
|
$buf = fread($fp, 1024);
|
|
$this->result .= $buf;
|
|
$size += strlen($buf);
|
|
|
|
if ( defined('MAX_FILESIZE') && $size > MAX_FILESIZE ) {
|
|
fclose($fp);
|
|
$this->cache->clear($this->key);
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
fclose($fp);
|
|
}
|
|
|
|
|
|
$this->cache->set($this->key, $this->result);
|
|
}
|
|
|
|
$this->logTraffic($this->host, $this->path);
|
|
return TRUE;
|
|
}
|
|
|
|
function size() {
|
|
return $this->cache->size($this->key);
|
|
}
|
|
|
|
function logTraffic($host, $selector) {
|
|
if ( ! defined('LOG_STATS') || LOG_STATS != true ) {
|
|
return;
|
|
}
|
|
|
|
$ip_address = ip2long($_SERVER['REMOTE_ADDR']);
|
|
|
|
DB::insert('traffic', array(
|
|
'hostname' => $host,
|
|
'selector' => $selector,
|
|
'remote_ip' => $ip_address,
|
|
'filesize' => $this->size(),
|
|
'request_at' => DB::sqleval("NOW()")
|
|
));
|
|
|
|
}
|
|
};
|
|
?>
|