00001 <?php
00002
00020
00021
00022
00023 class FileWrapper {
00024
00026 var $url;
00027
00029 var $info;
00030
00032 var $fp;
00033
00039 function FileWrapper($url, &$info) {
00040 $this->url = $url;
00041 $this->info = $info;
00042 }
00043
00048 function contents() {
00049 $contents = '';
00050 if ($retval = $this->open()) {
00051 if (is_object($retval)) {
00052 return $retval->contents();
00053 }
00054 while (!$this->eof())
00055 $contents .= $this->read();
00056 $this->close();
00057 }
00058 return $contents;
00059 }
00060
00066 function open($mode = 'r') {
00067 $this->fp = null;
00068 $this->fp = fopen($this->url, $mode);
00069 return ($this->fp !== false);
00070 }
00071
00075 function close() {
00076 fclose($this->fp);
00077 unset($this->fp);
00078 }
00079
00085 function read($len = 8192) {
00086 return fread($this->fp, $len);
00087 }
00088
00093 function eof() {
00094 return feof($this->fp);
00095 }
00096
00097
00098
00099
00100
00101
00107 function &wrapper($url) {
00108 $info = parse_url($url);
00109 if (ini_get('allow_url_fopen') && Config::getVar('general', 'allow_url_fopen')) {
00110 $wrapper = &new FileWrapper($url, $info);
00111 } else {
00112 switch (@$info['scheme']) {
00113 case 'http':
00114 $wrapper = &new HTTPFileWrapper($url, $info);
00115 $wrapper->addHeader('User-Agent', 'PKP-OJS/2.x');
00116 break;
00117 case 'https':
00118 $wrapper = &new HTTPSFileWrapper($url, $info);
00119 $wrapper->addHeader('User-Agent', 'PKP-OJS/2.x');
00120 break;
00121 case 'ftp':
00122 $wrapper = &new FTPFileWrapper($url, $info);
00123 break;
00124 default:
00125 $wrapper = &new FileWrapper($url, $info);
00126 }
00127 }
00128
00129 return $wrapper;
00130 }
00131 }
00132
00133
00137 class HTTPFileWrapper extends FileWrapper {
00138 var $headers;
00139 var $defaultPort;
00140 var $defaultHost;
00141 var $defaultPath;
00142 var $redirects;
00143
00144 var $proxyHost;
00145 var $proxyPort;
00146 var $proxyUsername;
00147 var $proxyPassword;
00148
00149 function HTTPFileWrapper($url, &$info, $redirects = 5) {
00150 parent::FileWrapper($url, $info);
00151 $this->setDefaultPort(80);
00152 $this->setDefaultHost('localhost');
00153 $this->setDefaultPath('/');
00154 $this->redirects = 5;
00155
00156 $this->proxyHost = Config::getVar('proxy', 'http_host');
00157 $this->proxyPort = Config::getVar('proxy', 'http_port');
00158 $this->proxyUsername = Config::getVar('proxy', 'proxy_username');
00159 $this->proxyPassword = Config::getVar('proxy', 'proxy_password');
00160 }
00161
00162 function setDefaultPort($port) {
00163 $this->defaultPort = $port;
00164 }
00165
00166 function setDefaultHost($host) {
00167 $this->defaultHost = $host;
00168 }
00169
00170 function setDefaultPath($path) {
00171 $this->defaultPath = $path;
00172 }
00173
00174 function addHeader($name, $value) {
00175 if (!isset($this->headers)) {
00176 $this->headers = array();
00177 }
00178 $this->headers[$name] = $value;
00179 }
00180
00181 function open($mode = 'r') {
00182 $realHost = $host = isset($this->info['host']) ? $this->info['host'] : $this->defaultHost;
00183 $port = isset($this->info['port']) ? (int)$this->info['port'] : $this->defaultPort;
00184 $path = isset($this->info['path']) ? $this->info['path'] : $this->defaultPath;
00185 if (isset($this->info['query'])) $path .= '?' . $this->info['query'];
00186
00187 if (!empty($this->proxyHost)) {
00188 $realHost = $host;
00189 $host = $this->proxyHost;
00190 $port = $this->proxyPort;
00191 if (!empty($this->proxyUsername)) {
00192 $this->headers['Proxy-Authorization'] = 'Basic ' . base64_encode($this->proxyUsername . ':' . $this->proxyPassword);
00193 }
00194 }
00195
00196 if (!($this->fp = fsockopen($host, $port, $errno, $errstr)))
00197 return false;
00198
00199 $additionalHeadersString = '';
00200 if (is_array($this->headers)) foreach ($this->headers as $name => $value) {
00201 $additionalHeadersString .= "$name: $value\r\n";
00202 }
00203
00204 $request = 'GET ' . (empty($this->proxyHost)?$path:$this->url) . " HTTP/1.0\r\n" .
00205 "Host: $realHost\r\n" .
00206 $additionalHeadersString .
00207 "Connection: Close\r\n\r\n";
00208 fwrite($this->fp, $request);
00209
00210 $response = fgets($this->fp, 4096);
00211 $rc = 0;
00212 sscanf($response, "HTTP/%*s %u %*[^\r\n]\r\n", $rc);
00213 if ($rc == 200) {
00214 while(fgets($this->fp, 4096) !== "\r\n");
00215 return true;
00216 }
00217 if(preg_match('!^3\d\d$!', $rc) && $this->redirects >= 1) {
00218 for($response = '', $time = time(); !feof($this->fp) && $time >= time() - 15; ) $response .= fgets($this->fp, 128);
00219 if (preg_match('!^(?:(?:Location)|(?:URI)|(?:location)): ([^\s]+)[\r\n]!m', $response, $matches)) {
00220 $this->close();
00221 $location = $matches[1];
00222 if (preg_match('!^[a-z]+://!', $location)) {
00223 $this->url = $location;
00224 } else {
00225 $newPath = ($this->info['path'] !== '' && strpos($location, '/') !== 0 ? dirname($this->info['path']) . '/' : (strpos($location, '/') === 0 ? '' : '/')) . $location;
00226 $this->info['path'] = $newPath;
00227 $this->url = $this->glue_url($this->info);
00228 }
00229 $returner =& FileWrapper::wrapper($this->url);
00230 $returner->redirects = $this->redirects - 1;
00231 return $returner;
00232 }
00233 }
00234 $this->close();
00235 return false;
00236 }
00237
00238 function glue_url ($parsed) {
00239
00240
00241 if (! is_array($parsed)) return false;
00242 $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '':'//'): '';
00243 $uri .= isset($parsed['user']) ? $parsed['user'].($parsed['pass']? ':'.$parsed['pass']:'').'@':'';
00244 $uri .= isset($parsed['host']) ? $parsed['host'] : '';
00245 $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
00246 $uri .= isset($parsed['path']) ? $parsed['path'] : '';
00247 $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
00248 $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
00249 return $uri;
00250 }
00251 }
00252
00256 class HTTPSFileWrapper extends HTTPFileWrapper {
00257 function HTTPSFileWrapper($url, &$info) {
00258 parent::HTTPFileWrapper($url, $info);
00259 $this->setDefaultPort(443);
00260 $this->setDefaultHost('ssl://localhost');
00261 if (isset($this->info['host'])) {
00262 $this->info['host'] = 'ssl://' . $this->info['host'];
00263 }
00264 }
00265 }
00266
00270 class FTPFileWrapper extends FileWrapper {
00271
00272 var $ctrl;
00273
00274 function open($mode = 'r') {
00275 $user = isset($this->info['user']) ? $this->info['user'] : 'anonymous';
00276 $pass = isset($this->info['pass']) ? $this->info['pass'] : 'user@example.com';
00277 $host = isset($this->info['host']) ? $this->info['host'] : 'localhost';
00278 $port = isset($this->info['port']) ? (int)$this->info['port'] : 21;
00279 $path = isset($this->info['path']) ? $this->info['path'] : '/';
00280
00281 if (!($this->ctrl = fsockopen($host, $port, $errno, $errstr)))
00282 return false;
00283
00284 if ($this->_open($user, $pass, $path))
00285 return true;
00286
00287 $this->close();
00288 return false;
00289 }
00290
00291 function close() {
00292 if ($this->fp) {
00293 parent::close();
00294 $rc = $this->_receive();
00295 }
00296
00297 $this->_send('QUIT');
00298 $rc = $this->_receive();
00299
00300 fclose($this->ctrl);
00301 $this->ctrl = null;
00302 }
00303
00304 function _open($user, $pass, $path) {
00305
00306 if ($this->_receive() != '220')
00307 return false;
00308
00309
00310 $this->_send('USER', $user);
00311 $rc = $this->_receive();
00312 if ($rc == '331') {
00313 $this->_send('PASS', $pass);
00314 $rc = $this->_receive();
00315 }
00316 if ($rc != '230')
00317 return false;
00318
00319
00320 $this->_send('TYPE', 'I');
00321 if ($this->_receive() != '200')
00322 return false;
00323
00324
00325 $this->_send('PASV');
00326 if ($this->_receiveLine($line) != '227')
00327 return false;
00328
00329 if (!preg_match('/(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/', $line, $matches))
00330 return false;
00331 list($tmp, $h1, $h2, $h3, $h4, $p1, $p2) = $matches;
00332
00333 $host = "$h1.$h2.$h3.$h4";
00334 $port = ($p1 << 8) + $p2;
00335
00336 if (!($this->fp = fsockopen($host, $port, $errno, $errstr)))
00337 return false;
00338
00339
00340 $this->_send('RETR', $path);
00341 $rc = $this->_receive();
00342 if ($rc != '125' && $rc != '150')
00343 return false;
00344
00345 return true;
00346 }
00347
00348 function _send($command, $data = '') {
00349 return fwrite($this->ctrl, $command . (empty($data) ? '' : ' ' . $data) . "\r\n");
00350 }
00351
00352 function _receive() {
00353 return $this->_receiveLine($line);
00354 }
00355
00356 function _receiveLine(&$line) {
00357 do {
00358 $line = fgets($this->ctrl);
00359 } while($line !== false && ($tmp = substr(trim($line), 3, 1)) != ' ' && $tmp != '');
00360
00361 if ($line !== false) {
00362 return substr($line, 0, 3);
00363 }
00364 return false;
00365 }
00366 }
00367
00368 ?>