|
|
|
@ -5,10 +5,10 @@
|
|
|
|
|
*
|
|
|
|
|
* Driver to change passwords via DirectAdmin Control Panel
|
|
|
|
|
*
|
|
|
|
|
* @version 2.1
|
|
|
|
|
* @author Victor Benincasa <vbenincasa@gmail.com>
|
|
|
|
|
* @version 2.2
|
|
|
|
|
* @author Victor Benincasa <vbenincasa @ gmail.com>
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2005-2013, The Roundcube Dev Team
|
|
|
|
|
* Copyright (C) 2005-2018, The Roundcube Dev Team
|
|
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
@ -79,427 +79,426 @@ class rcube_directadmin_password
|
|
|
|
|
*
|
|
|
|
|
* Very, very basic usage:
|
|
|
|
|
* $Socket = new HTTPSocket;
|
|
|
|
|
* echo $Socket->get('http://user:pass@somehost.com:2222/CMD_API_SOMEAPI?query=string&this=that');
|
|
|
|
|
* echo $Socket->get('http://user:pass@somesite.com/somedir/some.file?query=string&this=that');
|
|
|
|
|
*
|
|
|
|
|
* @author Phi1 'l0rdphi1' Stier <l0rdphi1@liquenox.net>
|
|
|
|
|
* @updates 2.7 and 2.8 by Victor Benincasa <vbenincasa @ gmail.com>
|
|
|
|
|
* @package HTTPSocket
|
|
|
|
|
* @version 2.8
|
|
|
|
|
*/
|
|
|
|
|
class HTTPSocket {
|
|
|
|
|
|
|
|
|
|
var $version = '2.8';
|
|
|
|
|
|
|
|
|
|
/* all vars are private except $error, $query_cache, and $doFollowLocationHeader */
|
|
|
|
|
|
|
|
|
|
var $method = 'GET';
|
|
|
|
|
|
|
|
|
|
var $remote_host;
|
|
|
|
|
var $remote_port;
|
|
|
|
|
var $remote_uname;
|
|
|
|
|
var $remote_passwd;
|
|
|
|
|
|
|
|
|
|
var $result;
|
|
|
|
|
var $result_header;
|
|
|
|
|
var $result_body;
|
|
|
|
|
var $result_status_code;
|
|
|
|
|
|
|
|
|
|
var $lastTransferSpeed;
|
|
|
|
|
|
|
|
|
|
var $bind_host;
|
|
|
|
|
|
|
|
|
|
var $error = array();
|
|
|
|
|
var $warn = array();
|
|
|
|
|
var $query_cache = array();
|
|
|
|
|
|
|
|
|
|
var $doFollowLocationHeader = TRUE;
|
|
|
|
|
var $redirectURL;
|
|
|
|
|
|
|
|
|
|
var $extra_headers = array();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create server "connection".
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function connect($host, $port = '' )
|
|
|
|
|
{
|
|
|
|
|
if (!is_numeric($port))
|
|
|
|
|
{
|
|
|
|
|
$port = 2222;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->remote_host = $host;
|
|
|
|
|
$this->remote_port = $port;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bind( $ip = '' )
|
|
|
|
|
{
|
|
|
|
|
if ( $ip == '' )
|
|
|
|
|
{
|
|
|
|
|
$ip = $_SERVER['SERVER_ADDR'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->bind_host = $ip;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Change the method being used to communicate.
|
|
|
|
|
*
|
|
|
|
|
* @param string|null request method. supports GET, POST, and HEAD. default is GET
|
|
|
|
|
*/
|
|
|
|
|
function set_method( $method = 'GET' )
|
|
|
|
|
{
|
|
|
|
|
$this->method = strtoupper($method);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Specify a username and password.
|
|
|
|
|
*
|
|
|
|
|
* @param string|null username. default is null
|
|
|
|
|
* @param string|null password. default is null
|
|
|
|
|
*/
|
|
|
|
|
function set_login( $uname = '', $passwd = '' )
|
|
|
|
|
{
|
|
|
|
|
if ( strlen($uname) > 0 )
|
|
|
|
|
{
|
|
|
|
|
$this->remote_uname = $uname;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( strlen($passwd) > 0 )
|
|
|
|
|
{
|
|
|
|
|
$this->remote_passwd = $passwd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Query the server
|
|
|
|
|
*
|
|
|
|
|
* @param string containing properly formatted server API. See DA API docs and examples. Http:// URLs O.K. too.
|
|
|
|
|
* @param string|array query to pass to url
|
|
|
|
|
* @param int if connection KB/s drops below value here, will drop connection
|
|
|
|
|
*/
|
|
|
|
|
function query( $request, $content = '', $doSpeedCheck = 0 )
|
|
|
|
|
{
|
|
|
|
|
$this->error = $this->warn = array();
|
|
|
|
|
$this->result_status_code = NULL;
|
|
|
|
|
|
|
|
|
|
// is our request a http(s):// ... ?
|
|
|
|
|
if (preg_match('/^(http|https):\/\//i',$request))
|
|
|
|
|
{
|
|
|
|
|
$location = parse_url($request);
|
|
|
|
|
$this->connect($location['host'],$location['port']);
|
|
|
|
|
$this->set_login($location['user'],$location['pass']);
|
|
|
|
|
* @version 3.0.2
|
|
|
|
|
|
|
|
|
|
$request = $location['path'];
|
|
|
|
|
$content = $location['query'];
|
|
|
|
|
* 3.0.2
|
|
|
|
|
* added longer curl timeouts
|
|
|
|
|
|
|
|
|
|
if ( strlen($request) < 1 )
|
|
|
|
|
{
|
|
|
|
|
$request = '/';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
* 3.0.1
|
|
|
|
|
* support for tcp:// conversion to http://
|
|
|
|
|
|
|
|
|
|
$array_headers = array(
|
|
|
|
|
'User-Agent' => "HTTPSocket/$this->version",
|
|
|
|
|
'Host' => ( $this->remote_port == 80 ? parse_url($this->remote_host,PHP_URL_HOST) : parse_url($this->remote_host,PHP_URL_HOST).":".$this->remote_port ),
|
|
|
|
|
'Accept' => '*/*',
|
|
|
|
|
'Connection' => 'Close' );
|
|
|
|
|
|
|
|
|
|
foreach ( $this->extra_headers as $key => $value )
|
|
|
|
|
{
|
|
|
|
|
$array_headers[$key] = $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->result = $this->result_header = $this->result_body = '';
|
|
|
|
|
|
|
|
|
|
// was content sent as an array? if so, turn it into a string
|
|
|
|
|
if (is_array($content))
|
|
|
|
|
{
|
|
|
|
|
$pairs = array();
|
|
|
|
|
|
|
|
|
|
foreach ( $content as $key => $value )
|
|
|
|
|
{
|
|
|
|
|
$pairs[] = "$key=".urlencode($value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$content = join('&',$pairs);
|
|
|
|
|
unset($pairs);
|
|
|
|
|
}
|
|
|
|
|
* 3.0.0
|
|
|
|
|
* swapped to use curl to address ssl certificate issues with php 5.6
|
|
|
|
|
|
|
|
|
|
$OK = TRUE;
|
|
|
|
|
* 2.7.2
|
|
|
|
|
* added x-use-https header check
|
|
|
|
|
* added max number of location redirects
|
|
|
|
|
* added custom settable message if x-use-https is found, so users can be told where to set their scripts
|
|
|
|
|
* if a redirect host is https, add ssl:// to remote_host
|
|
|
|
|
|
|
|
|
|
// instance connection
|
|
|
|
|
if ($this->bind_host)
|
|
|
|
|
{
|
|
|
|
|
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
|
|
|
|
socket_bind($socket,$this->bind_host);
|
|
|
|
|
* 2.7.1
|
|
|
|
|
* added isset to headers['location'], line 306
|
|
|
|
|
|
|
|
|
|
if (!@socket_connect($socket,$this->remote_host,$this->remote_port))
|
|
|
|
|
{
|
|
|
|
|
$OK = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$socket = @fsockopen( $this->remote_host, $this->remote_port, $sock_errno, $sock_errstr, 10 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !$socket || !$OK )
|
|
|
|
|
{
|
|
|
|
|
$this->error[] = "Can't create socket connection to $this->remote_host:$this->remote_port.";
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if we have a username and password, add the header
|
|
|
|
|
if ( isset($this->remote_uname) && isset($this->remote_passwd) )
|
|
|
|
|
{
|
|
|
|
|
$array_headers['Authorization'] = 'Basic '.base64_encode("$this->remote_uname:$this->remote_passwd");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for DA skins: if $this->remote_passwd is NULL, try to use the login key system
|
|
|
|
|
if ( isset($this->remote_uname) && $this->remote_passwd == NULL )
|
|
|
|
|
{
|
|
|
|
|
$array_headers['Cookie'] = "session={$_SERVER['SESSION_ID']}; key={$_SERVER['SESSION_KEY']}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if method is POST, add content length & type headers
|
|
|
|
|
if ( $this->method == 'POST' )
|
|
|
|
|
{
|
|
|
|
|
$array_headers['Content-type'] = 'application/x-www-form-urlencoded';
|
|
|
|
|
$array_headers['Content-length'] = strlen($content);
|
|
|
|
|
}
|
|
|
|
|
// else method is GET or HEAD. we don't support anything else right now.
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ($content)
|
|
|
|
|
{
|
|
|
|
|
$request .= "?$content";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// prepare query
|
|
|
|
|
$query = "$this->method $request HTTP/1.0\r\n";
|
|
|
|
|
foreach ( $array_headers as $key => $value )
|
|
|
|
|
{
|
|
|
|
|
$query .= "$key: $value\r\n";
|
|
|
|
|
}
|
|
|
|
|
$query .= "\r\n";
|
|
|
|
|
|
|
|
|
|
// if POST we need to append our content
|
|
|
|
|
if ( $this->method == 'POST' && $content )
|
|
|
|
|
{
|
|
|
|
|
$query .= "$content\r\n\r\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// query connection
|
|
|
|
|
if ($this->bind_host)
|
|
|
|
|
{
|
|
|
|
|
socket_write($socket,$query);
|
|
|
|
|
|
|
|
|
|
// now load results
|
|
|
|
|
while ( $out = socket_read($socket,2048) )
|
|
|
|
|
{
|
|
|
|
|
$this->result .= $out;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fwrite( $socket, $query, strlen($query) );
|
|
|
|
|
|
|
|
|
|
// now load results
|
|
|
|
|
$this->lastTransferSpeed = 0;
|
|
|
|
|
$status = socket_get_status($socket);
|
|
|
|
|
$startTime = time();
|
|
|
|
|
$length = 0;
|
|
|
|
|
while ( !feof($socket) && !$status['timed_out'] )
|
|
|
|
|
{
|
|
|
|
|
$chunk = fgets($socket,1024);
|
|
|
|
|
$length += strlen($chunk);
|
|
|
|
|
$this->result .= $chunk;
|
|
|
|
|
|
|
|
|
|
$elapsedTime = time() - $startTime;
|
|
|
|
|
|
|
|
|
|
if ( $elapsedTime > 0 )
|
|
|
|
|
{
|
|
|
|
|
$this->lastTransferSpeed = ($length/1024)/$elapsedTime;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $doSpeedCheck > 0 && $elapsedTime > 5 && $this->lastTransferSpeed < $doSpeedCheck )
|
|
|
|
|
{
|
|
|
|
|
$this->warn[] = "kB/s for last 5 seconds is below 50 kB/s (~".( ($length/1024)/$elapsedTime )."), dropping connection...";
|
|
|
|
|
$this->result_status_code = 503;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $this->lastTransferSpeed == 0 )
|
|
|
|
|
{
|
|
|
|
|
$this->lastTransferSpeed = $length/1024;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list($this->result_header,$this->result_body) = preg_split("/\r\n\r\n/",$this->result,2);
|
|
|
|
|
|
|
|
|
|
if ($this->bind_host)
|
|
|
|
|
{
|
|
|
|
|
socket_close($socket);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fclose($socket);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->query_cache[] = $query;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$headers = $this->fetch_header();
|
|
|
|
|
|
|
|
|
|
// what return status did we get?
|
|
|
|
|
if (!$this->result_status_code)
|
|
|
|
|
{
|
|
|
|
|
preg_match("#HTTP/1\.. (\d+)#",$headers[0],$matches);
|
|
|
|
|
$this->result_status_code = $matches[1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// did we get the full file?
|
|
|
|
|
if ( !empty($headers['content-length']) && $headers['content-length'] != strlen($this->result_body) )
|
|
|
|
|
{
|
|
|
|
|
$this->result_status_code = 206;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// now, if we're being passed a location header, should we follow it?
|
|
|
|
|
if ($this->doFollowLocationHeader)
|
|
|
|
|
{
|
|
|
|
|
if ($headers['location'])
|
|
|
|
|
{
|
|
|
|
|
$this->redirectURL = $headers['location'];
|
|
|
|
|
$this->query($headers['location']);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getTransferSpeed()
|
|
|
|
|
{
|
|
|
|
|
return $this->lastTransferSpeed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The quick way to get a URL's content :)
|
|
|
|
|
*
|
|
|
|
|
* @param string URL
|
|
|
|
|
* @param boolean return as array? (like PHP's file() command)
|
|
|
|
|
* @return string result body
|
|
|
|
|
*/
|
|
|
|
|
function get($location, $asArray = FALSE )
|
|
|
|
|
{
|
|
|
|
|
$this->query($location);
|
|
|
|
|
|
|
|
|
|
if ( $this->get_status_code() == 200 )
|
|
|
|
|
{
|
|
|
|
|
if ($asArray)
|
|
|
|
|
{
|
|
|
|
|
return preg_split("/\n/",$this->fetch_body());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->fetch_body();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the last status code.
|
|
|
|
|
* 200 = OK;
|
|
|
|
|
* 403 = FORBIDDEN;
|
|
|
|
|
* etc.
|
|
|
|
|
*
|
|
|
|
|
* @return int status code
|
|
|
|
|
*/
|
|
|
|
|
function get_status_code()
|
|
|
|
|
{
|
|
|
|
|
return $this->result_status_code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds a header, sent with the next query.
|
|
|
|
|
*
|
|
|
|
|
* @param string header name
|
|
|
|
|
* @param string header value
|
|
|
|
|
*/
|
|
|
|
|
function add_header($key,$value)
|
|
|
|
|
{
|
|
|
|
|
$this->extra_headers[$key] = $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Clears any extra headers.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function clear_headers()
|
|
|
|
|
{
|
|
|
|
|
$this->extra_headers = array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the result of a query.
|
|
|
|
|
*
|
|
|
|
|
* @return string result
|
|
|
|
|
*/
|
|
|
|
|
function fetch_result()
|
|
|
|
|
{
|
|
|
|
|
return $this->result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the header of result (stuff before body).
|
|
|
|
|
*
|
|
|
|
|
* @param string (optional) header to return
|
|
|
|
|
* @return array result header
|
|
|
|
|
*/
|
|
|
|
|
function fetch_header( $header = '' )
|
|
|
|
|
{
|
|
|
|
|
$array_headers = preg_split("/\r\n/",$this->result_header);
|
|
|
|
|
$array_return = array( 0 => $array_headers[0] );
|
|
|
|
|
unset($array_headers[0]);
|
|
|
|
|
|
|
|
|
|
foreach ( $array_headers as $pair )
|
|
|
|
|
{
|
|
|
|
|
list($key,$value) = preg_split("/: /",$pair,2);
|
|
|
|
|
$array_return[strtolower($key)] = $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $header != '' )
|
|
|
|
|
{
|
|
|
|
|
return $array_return[strtolower($header)];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $array_return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the body of result (stuff after header).
|
|
|
|
|
*
|
|
|
|
|
* @return string result body
|
|
|
|
|
*/
|
|
|
|
|
function fetch_body()
|
|
|
|
|
{
|
|
|
|
|
return $this->result_body;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
class HTTPSocket {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return parsed body in array format.
|
|
|
|
|
*
|
|
|
|
|
* @return array result parsed
|
|
|
|
|
*/
|
|
|
|
|
function fetch_parsed_body()
|
|
|
|
|
{
|
|
|
|
|
parse_str($this->result_body,$x);
|
|
|
|
|
return $x;
|
|
|
|
|
}
|
|
|
|
|
var $version = '3.0.2';
|
|
|
|
|
|
|
|
|
|
/* all vars are private except $error, $query_cache, and $doFollowLocationHeader */
|
|
|
|
|
|
|
|
|
|
var $method = 'GET';
|
|
|
|
|
|
|
|
|
|
var $remote_host;
|
|
|
|
|
var $remote_port;
|
|
|
|
|
var $remote_uname;
|
|
|
|
|
var $remote_passwd;
|
|
|
|
|
|
|
|
|
|
var $result;
|
|
|
|
|
var $result_header;
|
|
|
|
|
var $result_body;
|
|
|
|
|
var $result_status_code;
|
|
|
|
|
|
|
|
|
|
var $lastTransferSpeed;
|
|
|
|
|
|
|
|
|
|
var $bind_host;
|
|
|
|
|
|
|
|
|
|
var $error = array();
|
|
|
|
|
var $warn = array();
|
|
|
|
|
var $query_cache = array();
|
|
|
|
|
|
|
|
|
|
var $doFollowLocationHeader = TRUE;
|
|
|
|
|
var $redirectURL;
|
|
|
|
|
var $max_redirects = 5;
|
|
|
|
|
var $ssl_setting_message = 'DirectAdmin appears to be using SSL. Change your script to connect to ssl://';
|
|
|
|
|
|
|
|
|
|
var $extra_headers = array();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create server "connection".
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function connect($host, $port = '' )
|
|
|
|
|
{
|
|
|
|
|
if (!is_numeric($port))
|
|
|
|
|
{
|
|
|
|
|
$port = 2222;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->remote_host = $host;
|
|
|
|
|
$this->remote_port = $port;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bind( $ip = '' )
|
|
|
|
|
{
|
|
|
|
|
if ( $ip == '' )
|
|
|
|
|
{
|
|
|
|
|
$ip = $_SERVER['SERVER_ADDR'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->bind_host = $ip;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Change the method being used to communicate.
|
|
|
|
|
*
|
|
|
|
|
* @param string|null request method. supports GET, POST, and HEAD. default is GET
|
|
|
|
|
*/
|
|
|
|
|
function set_method( $method = 'GET' )
|
|
|
|
|
{
|
|
|
|
|
$this->method = strtoupper($method);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Specify a username and password.
|
|
|
|
|
*
|
|
|
|
|
* @param string|null username. default is null
|
|
|
|
|
* @param string|null password. default is null
|
|
|
|
|
*/
|
|
|
|
|
function set_login( $uname = '', $passwd = '' )
|
|
|
|
|
{
|
|
|
|
|
if ( strlen($uname) > 0 )
|
|
|
|
|
{
|
|
|
|
|
$this->remote_uname = $uname;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( strlen($passwd) > 0 )
|
|
|
|
|
{
|
|
|
|
|
$this->remote_passwd = $passwd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Query the server
|
|
|
|
|
*
|
|
|
|
|
* @param string containing properly formatted server API. See DA API docs and examples. Http:// URLs O.K. too.
|
|
|
|
|
* @param string|array query to pass to url
|
|
|
|
|
* @param int if connection KB/s drops below value here, will drop connection
|
|
|
|
|
*/
|
|
|
|
|
function query( $request, $content = '', $doSpeedCheck = 0 )
|
|
|
|
|
{
|
|
|
|
|
$this->error = $this->warn = array();
|
|
|
|
|
$this->result_status_code = NULL;
|
|
|
|
|
|
|
|
|
|
$is_ssl = FALSE;
|
|
|
|
|
|
|
|
|
|
// is our request a http:// ... ?
|
|
|
|
|
if (preg_match('!^http://!i',$request) || preg_match('!^https://!i',$request))
|
|
|
|
|
{
|
|
|
|
|
$location = parse_url($request);
|
|
|
|
|
if (preg_match('!^https://!i',$request))
|
|
|
|
|
{
|
|
|
|
|
$this->connect('https://'.$location['host'],$location['port']);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
$this->connect('http://'.$location['host'],$location['port']);
|
|
|
|
|
|
|
|
|
|
$this->set_login($location['user'],$location['pass']);
|
|
|
|
|
|
|
|
|
|
$request = $location['path'];
|
|
|
|
|
$content = $location['query'];
|
|
|
|
|
|
|
|
|
|
if ( strlen($request) < 1 )
|
|
|
|
|
{
|
|
|
|
|
$request = '/';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (preg_match('!^ssl://!i', $this->remote_host))
|
|
|
|
|
$this->remote_host = 'https://'.substr($this->remote_host, 6);
|
|
|
|
|
|
|
|
|
|
if (preg_match('!^tcp://!i', $this->remote_host))
|
|
|
|
|
$this->remote_host = 'http://'.substr($this->remote_host, 6);
|
|
|
|
|
|
|
|
|
|
if (preg_match('!^https://!i', $this->remote_host))
|
|
|
|
|
$is_ssl = TRUE;
|
|
|
|
|
|
|
|
|
|
$array_headers = array(
|
|
|
|
|
'Host' => ( $this->remote_port == 80 ? $this->remote_host : "$this->remote_host:$this->remote_port" ),
|
|
|
|
|
'Accept' => '*/*',
|
|
|
|
|
'Connection' => 'Close' );
|
|
|
|
|
|
|
|
|
|
foreach ( $this->extra_headers as $key => $value )
|
|
|
|
|
{
|
|
|
|
|
$array_headers[$key] = $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->result = $this->result_header = $this->result_body = '';
|
|
|
|
|
|
|
|
|
|
// was content sent as an array? if so, turn it into a string
|
|
|
|
|
if (is_array($content))
|
|
|
|
|
{
|
|
|
|
|
$pairs = array();
|
|
|
|
|
|
|
|
|
|
foreach ( $content as $key => $value )
|
|
|
|
|
{
|
|
|
|
|
$pairs[] = "$key=".urlencode($value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$content = join('&',$pairs);
|
|
|
|
|
unset($pairs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$OK = TRUE;
|
|
|
|
|
|
|
|
|
|
if ($this->method == 'GET')
|
|
|
|
|
$request .= '?'.$content;
|
|
|
|
|
|
|
|
|
|
$ch = curl_init($this->remote_host.':'.$this->remote_port.$request);
|
|
|
|
|
|
|
|
|
|
if ($is_ssl)
|
|
|
|
|
{
|
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //1
|
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //2
|
|
|
|
|
//curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
|
|
|
|
|
curl_setopt($ch, CURLOPT_USERAGENT, "HTTPSocket/$this->version");
|
|
|
|
|
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
|
|
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
|
|
|
|
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
|
|
|
|
|
curl_setopt($ch, CURLOPT_HEADER, 1);
|
|
|
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 512);
|
|
|
|
|
curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 120);
|
|
|
|
|
|
|
|
|
|
//if ($this->doFollowLocationHeader)
|
|
|
|
|
//{
|
|
|
|
|
// curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
|
|
|
|
|
// curl_setopt($ch, CURLOPT_MAXREDIRS, $this->max_redirects);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
// instance connection
|
|
|
|
|
if ($this->bind_host)
|
|
|
|
|
{
|
|
|
|
|
curl_setopt($ch, CURLOPT_INTERFACE, $this->bind_host);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if we have a username and password, add the header
|
|
|
|
|
if ( isset($this->remote_uname) && isset($this->remote_passwd) )
|
|
|
|
|
{
|
|
|
|
|
curl_setopt($ch, CURLOPT_USERPWD, $this->remote_uname.':'.$this->remote_passwd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for DA skins: if $this->remote_passwd is NULL, try to use the login key system
|
|
|
|
|
if ( isset($this->remote_uname) && $this->remote_passwd == NULL )
|
|
|
|
|
{
|
|
|
|
|
$array_headers['Cookie'] = "session={$_SERVER['SESSION_ID']}; key={$_SERVER['SESSION_KEY']}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if method is POST, add content length & type headers
|
|
|
|
|
if ( $this->method == 'POST' )
|
|
|
|
|
{
|
|
|
|
|
curl_setopt($ch, CURLOPT_POST, 1);
|
|
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
|
|
|
|
|
|
|
|
|
|
//$array_headers['Content-type'] = 'application/x-www-form-urlencoded';
|
|
|
|
|
$array_headers['Content-length'] = strlen($content);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $array_headers);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( !($this->result = curl_exec($ch)) )
|
|
|
|
|
{
|
|
|
|
|
$this->error[] .= curl_error($ch);
|
|
|
|
|
$OK = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
|
|
|
|
$this->result_header = substr($this->result, 0, $header_size);
|
|
|
|
|
$this->result_body = substr($this->result, $header_size);
|
|
|
|
|
$this->result_status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
|
|
|
|
|
|
$this->lastTransferSpeed = curl_getinfo($ch, CURLINFO_SPEED_DOWNLOAD) / 1024;
|
|
|
|
|
|
|
|
|
|
curl_close($ch);
|
|
|
|
|
|
|
|
|
|
$this->query_cache[] = $this->remote_host.':'.$this->remote_port.$request;
|
|
|
|
|
|
|
|
|
|
$headers = $this->fetch_header();
|
|
|
|
|
|
|
|
|
|
// did we get the full file?
|
|
|
|
|
if ( !empty($headers['content-length']) && $headers['content-length'] != strlen($this->result_body) )
|
|
|
|
|
{
|
|
|
|
|
$this->result_status_code = 206;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// now, if we're being passed a location header, should we follow it?
|
|
|
|
|
if ($this->doFollowLocationHeader)
|
|
|
|
|
{
|
|
|
|
|
//dont bother if we didn't even setup the script correctly
|
|
|
|
|
if (isset($headers['x-use-https']) && $headers['x-use-https']=='yes')
|
|
|
|
|
die($this->ssl_setting_message);
|
|
|
|
|
|
|
|
|
|
if (isset($headers['location']))
|
|
|
|
|
{
|
|
|
|
|
if ($this->max_redirects <= 0)
|
|
|
|
|
die("Too many redirects on: ".$headers['location']);
|
|
|
|
|
|
|
|
|
|
$this->max_redirects--;
|
|
|
|
|
$this->redirectURL = $headers['location'];
|
|
|
|
|
$this->query($headers['location']);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getTransferSpeed()
|
|
|
|
|
{
|
|
|
|
|
return $this->lastTransferSpeed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The quick way to get a URL's content :)
|
|
|
|
|
*
|
|
|
|
|
* @param string URL
|
|
|
|
|
* @param boolean return as array? (like PHP's file() command)
|
|
|
|
|
* @return string result body
|
|
|
|
|
*/
|
|
|
|
|
function get($location, $asArray = FALSE )
|
|
|
|
|
{
|
|
|
|
|
$this->query($location);
|
|
|
|
|
|
|
|
|
|
if ( $this->get_status_code() == 200 )
|
|
|
|
|
{
|
|
|
|
|
if ($asArray)
|
|
|
|
|
{
|
|
|
|
|
return preg_split("/\n/",$this->fetch_body());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->fetch_body();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the last status code.
|
|
|
|
|
* 200 = OK;
|
|
|
|
|
* 403 = FORBIDDEN;
|
|
|
|
|
* etc.
|
|
|
|
|
*
|
|
|
|
|
* @return int status code
|
|
|
|
|
*/
|
|
|
|
|
function get_status_code()
|
|
|
|
|
{
|
|
|
|
|
return $this->result_status_code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds a header, sent with the next query.
|
|
|
|
|
*
|
|
|
|
|
* @param string header name
|
|
|
|
|
* @param string header value
|
|
|
|
|
*/
|
|
|
|
|
function add_header($key,$value)
|
|
|
|
|
{
|
|
|
|
|
$this->extra_headers[$key] = $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Clears any extra headers.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function clear_headers()
|
|
|
|
|
{
|
|
|
|
|
$this->extra_headers = array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the result of a query.
|
|
|
|
|
*
|
|
|
|
|
* @return string result
|
|
|
|
|
*/
|
|
|
|
|
function fetch_result()
|
|
|
|
|
{
|
|
|
|
|
return $this->result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the header of result (stuff before body).
|
|
|
|
|
*
|
|
|
|
|
* @param string (optional) header to return
|
|
|
|
|
* @return array result header
|
|
|
|
|
*/
|
|
|
|
|
function fetch_header( $header = '' )
|
|
|
|
|
{
|
|
|
|
|
$array_headers = preg_split("/\r\n/",$this->result_header);
|
|
|
|
|
|
|
|
|
|
$array_return = array( 0 => $array_headers[0] );
|
|
|
|
|
unset($array_headers[0]);
|
|
|
|
|
|
|
|
|
|
foreach ( $array_headers as $pair )
|
|
|
|
|
{
|
|
|
|
|
if ($pair == '' || $pair == "\r\n") continue;
|
|
|
|
|
list($key,$value) = preg_split("/: /",$pair,2);
|
|
|
|
|
$array_return[strtolower($key)] = $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $header != '' )
|
|
|
|
|
{
|
|
|
|
|
return $array_return[strtolower($header)];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $array_return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the body of result (stuff after header).
|
|
|
|
|
*
|
|
|
|
|
* @return string result body
|
|
|
|
|
*/
|
|
|
|
|
function fetch_body()
|
|
|
|
|
{
|
|
|
|
|
return $this->result_body;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return parsed body in array format.
|
|
|
|
|
*
|
|
|
|
|
* @return array result parsed
|
|
|
|
|
*/
|
|
|
|
|
function fetch_parsed_body()
|
|
|
|
|
{
|
|
|
|
|
parse_str($this->result_body,$x);
|
|
|
|
|
return $x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set a specifc message on how to change the SSL setting, in the event that it's not set correctly.
|
|
|
|
|
*/
|
|
|
|
|
function set_ssl_setting_message($str)
|
|
|
|
|
{
|
|
|
|
|
$this->ssl_setting_message = $str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|