PHP: class HTTP – A Curl Alternative – support proxy, socks4, socks4a, socks5, ssh …
This is pure PHP class support many feature of CURL like file upload, …
<?php /** * @author Sans_Amour - WWW.TUTORIALSPOTS.COM * @package HTTP * @version 2.0.1 * @start 07/02/2012 * @last 11/07/2016 * History: * 07/02/2012 start v1.0 * 07/12/2012 v1.1 * using http proxy and socks4/5 * 07/13/2012 v1.2 * using cookie file like CURL cookie file * 07/16/2012 v1.3 * file upload * authorization basic * 07/18/2012 v1.4 * socks4a * 07/24/2012 * add cookie from additional headers * 08/08/2012 v1.5 * https connection with https proxy, socks4/4a/5 * 03/28/2015 fix cookie_file::add * 03/19/2016 v1.6 ssh for http * 07/11/2016 v2.0 ssh for https * 05/15/2020 v2.0.1 change fsockopen to stream_socket_client */ date_default_timezone_set('Asia/Saigon'); if (!function_exists('mime_content_type')) { function mime_content_type($filename) { $mime_types = array('txt' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html', 'php' => 'text/html', 'css' => 'text/css', 'js' => 'application/javascript', 'json' => 'application/json', 'xml' => 'application/xml', 'swf' => 'application/x-shockwave-flash', 'flv' => 'video/x-flv', // images 'png' => 'image/png', 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'bmp' => 'image/bmp', 'ico' => 'image/vnd.microsoft.icon', 'tiff' => 'image/tiff', 'tif' => 'image/tiff', 'svg' => 'image/svg+xml', 'svgz' => 'image/svg+xml', // archives 'zip' => 'application/zip', 'rar' => 'application/x-rar-compressed', 'exe' => 'application/x-msdownload', 'msi' => 'application/x-msdownload', 'cab' => 'application/vnd.ms-cab-compressed', // audio/video 'mp3' => 'audio/mpeg', 'qt' => 'video/quicktime', 'mov' => 'video/quicktime', // adobe 'pdf' => 'application/pdf', 'psd' => 'image/vnd.adobe.photoshop', 'ai' => 'application/postscript', 'eps' => 'application/postscript', 'ps' => 'application/postscript', // ms office 'doc' => 'application/msword', 'rtf' => 'application/rtf', 'xls' => 'application/vnd.ms-excel', 'ppt' => 'application/vnd.ms-powerpoint', // open office 'odt' => 'application/vnd.oasis.opendocument.text', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', ); $ext = strtolower(array_pop(explode('.', $filename))); if (array_key_exists($ext, $mime_types)) return $mime_types[$ext]; elseif (function_exists('finfo_open')) { $finfo = finfo_open(FILEINFO_MIME); $mimetype = finfo_file($finfo, $filename); finfo_close($finfo); return $mimetype; } else return 'application/octet-stream'; } } class http { public $timeout = 10; public $referer = ''; public $useragent = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0.1) Gecko/20100101 Firefox/8.0.1'; public $boundary = ''; public $contenttype = 'application/x-www-form-urlencoded'; public $length = 4096; //1024 public $cookiefile = 'cookie.txt'; //more header: 2 types public $header = array(); public $usecookie = true; public $loadcookie = true; public $headercookie = true; public $connection = 'close'; public $contentlength = 0; public $followlocation = false; public $maxredirect = 1; public $method = 'GET'; public $url = ''; public $autoreferer = true; public $authorization = array(); public $proxy_type = ''; public $proxy = ''; public $proxy_port = ''; public $proxy_user = ''; public $proxy_pass = ''; //public $returnheader = true; public $fp = false; public $_cookies = array(); private $cf = false; //cookie_file private $pack = ''; private $vars = array(); private $files = array(); private $content = ''; private $var = ''; //private $_header = array(); public $query_time; public $echo=false; public $raw=false; /** * @since v2.0 */ public $ssh_ip = ''; public $ssh_user = ''; public $ssh_pass = ''; public $validateHttpResponse = false; public $responseheaders = null; public $getcount = 1000; function __construct() { srand((double)microtime() * 1000000); $this->boundary = "---------------------" . substr(md5(rand(0, 32000)), 0, 10); } /** * @since v1.1 */ public function proxy($proxy, $user = '', $type = 'http') { $valid_types = array('http', 'socks4', 'socks4a', 'socks5'); if (in_array($type, $valid_types)) { $this->proxy_type = $type; if (preg_match("/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(\:(\d{1,5}))?/", $proxy, $m)) { $this->proxy = $m[1]; $this->proxy_port = $m[3] ? $m[3] : '80'; if ($user && strpos($user, ':') !== false) { $user = explode(":", $user); $this->proxy_user = $user[0]; $this->proxy_pass = $user[1]; } } else $this->proxy_type = ''; } else $this->proxy_type = ''; } /** * @since v2.0 */ public function ssh($ssh_ip, $user = '') { $this->ssh_ip = $ssh_ip; if ($user && strpos($user, ':') !== false) { $user = explode(":", $user); $this->ssh_user = $user[0]; $this->ssh_pass = $user[1]; } } /** * @since v1.0 */ public function get($url, $ret = 1) { $return = $this->exec('GET', $url, '', $ret); $this->clear(); if($this->echo) echo $return; return $return; } /** * @since v1.0 */ public function post($url, $var = null, $ret = 1) { $return = $this->exec('POST', $url, $var, $ret); $this->clear(); if($this->echo) echo $return; return $return; } /** * @since v1.0 */ public function parseHeaders($headers) { $h = array(); if (!$this->cf) $this->loadCookie(); foreach ($headers as $header) { if (strpos($header, ': ') !== false) { $h2 = explode(': ', $header, 2); if ($h2[0] != "Set-Cookie") $h[$h2[0]] = $h2[1]; else { //var_dump($h2); if ($this->usecookie) { if (!isset($h["Set-Cookie"])) $h["Set-Cookie"] = array(); $_c = cookie::grab($header, $this->url); //var_dump($_c); if (!cookie_file::exists($h["Set-Cookie"], $_c)) $h["Set-Cookie"][] = $_c; if (!cookie_file::exists($this->_cookies, $_c)) $this->_cookies[] = $_c; //var_dump($this->cf->cookies); $this->cf->add($_c, $this->url); //var_dump($this->cf->cookies); } } } } //var_dump($headers); return $h; } /** * @since v1.0 */ public function saveCookie() { if (!$this->cf) $this->loadCookie(); //var_dump($this->cf->lines); //var_dump($this->_cookies); $this->cf->write_file($this->url); $this->_cookies = array(); $this->cf->cookies = array(); } /** * @since v1.0 */ public function loadCookie() { $this->cf = new cookie_file($this->cookiefile); $cd = $this->cf->domain($this->url, false); //var_dump($cd);die(); if ($cd) $this->_cookies = $cd; } /** * @since v1.0 */ private function content($array) { if($this->raw) return $array; if (is_string($array)) { if (strpos($array, 'Content-Disposition: form-data') !== false) return $array; parse_str($array, $vars); $array = $vars; } $this->detect_file_upload($array); if (count($this->files)) { $this->contenttype = "multipart/form-data; boundary={$this->boundary}"; //, // attach post vars $data = self::form_data($this->vars, $this->boundary); $data .= "--{$this->boundary}\r\n"; // and attach the file foreach ($this->files as $index => $file) { $content_file = join("", file($file)); $content_type = mime_content_type($file); $data .= "Content-Disposition: form-data; name=\"" . urldecode($index) . "\"; filename=\"" . basename($file) . "\" Content-Type: $content_type $content_file --{$this->boundary}"; } $data .= "--\r\n\r\n"; return $data; } else return http_build_query($this->vars); } /** * @since v1.2 */ public static function form_data($vars, $boundary) { $data = ''; foreach ($vars as $index => $value) { $data .= "--{$boundary}\r\n"; $data .= "Content-Disposition: form-data; name=\"" . urldecode($index) . "\"\r\n"; $data .= "\r\n" . $value . "\r\n"; $data .= "--{$boundary}\r\n"; } return $data; } /** * @since v1.0 */ private function detect_file_upload($array) { if (!is_array($array)) return false; foreach ($array as $key => $var) { if (substr($var, 0, 1) == '@') $this->files[$key] = substr($var, 1); else $this->vars[$key] = $var; } } /** * @since v1.1 */ private function pack($t, $content) { return implode("\r\n", $t) . "\r\n\r\n" . $content; } /** * @since v1.5 */ public function parse($url, &$host, &$port, &$uri, &$sslhost) { $url2 = parse_url($url); $host = $url2['host']; $port = isset($url2['port']) ? $url2['port'] : ($url2['scheme'] == 'https' ? 443 : ($url2['scheme'] == 'ftp' ? 21 : 80)); $uri = $url2['path'] == '' ? '/' : $url2['path']; if (isset($url2["query"])) $uri .= '?' . $url2["query"]; if ($port == 443) $sslhost = "ssl://" . $host; elseif ($port == 21) $sslhost = "ftp://" . $host; else $sslhost = $host; } /** * @since v1.5 */ public function socket($host, $port, &$errno, &$errstr, $timeout) { //var_dump($host, $port, $errno, $errstr, $timeout); //die('2'); $contextOptions = array('ssl' => array( //'cafile' => openssl_get_cert_locations()['default_cert_file'], 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true )); $streamContext = stream_context_create($contextOptions); $this->fp = stream_socket_client($host.':'.$port, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $streamContext); //$this->fp = @fsockopen($host, $port, $errno, $errstr, $timeout); } /** * @since v2.0 */ public function sshsocket($host, $port) { $connection = ssh2_connect($this->ssh_ip, 22); if(!$connection) return false; if(!ssh2_auth_password($connection, $this->ssh_user, $this->ssh_pass)) return false; //var_dump($this->ssh_ip, $this->ssh_user, $this->ssh_pass,$host, $port); //$ip = gethostbyname($host) $this->fp = ssh2_tunnel($connection, $host, $port); } /** * @since v1.5 */ public function send($cmd) { return fwrite($this->fp, $cmd); } /** * @since v1.0 * ret = 0: not return transfer * ret = 1: return body default * ret = 2: return array header * ret = 3: return array header parsed * ret = 4: return full response * ret = 5: return array (array header, body) */ public function exec($method = 'POST', $url, $content = null, $ret = 1) { if (empty($content) && $method == 'POST') return false; $_bm = microtime(1); $this->method = $method; $this->url = $url; $this->var = $content; $this->parse($url, $host, $port, $uri, $sslhost); $content = $this->content($content); if ($this->usecookie && ($this->loadcookie || ($this->cf && !$this->loadcookie))) $this->loadCookie(); //$this->headercookie = true; if ($this->ssh_ip && $port == '443'){ $connection = ssh2_connect($this->ssh_ip, 22); if(!$connection) return false; if(!ssh2_auth_password($connection, $this->ssh_user, $this->ssh_pass)) return false; $cmd = "curl --include". " -H ".('\'Host: ' . $host . ($port == 80 ? '' : ":$port"))."'". " -H "."'User-Agent: {$this->useragent}'"; if ($this->contenttype) $cmd .= ' -H \'Content-Type: ' . $this->contenttype."'"; if ($this->referer) $cmd .= " -H 'Referer: {$this->referer}'"; if (count($this->authorization) == 2) $cmd .= " -H 'Authorization: Basic " . base64_encode("{$this->authorization[0]}:{$this->authorization[1]}")."'"; if ($this->method == 'POST') $cmd .= ' -H \'Content-Length: ' . ($this->contentlength <> 0 ? $this->contentlength : strlen($content))."'"; $cmd .= ' -H \'Connection: ' . $this->connection."'"; if (count($this->header)) { if (isset($this->header[0])) $this->header = $this->parseHeaders($this->header); foreach ($this->header as $k => $h) { if (!is_array($h)) $cmd .= " -H '$k: $h'"; } } $cmd .= " -X ".$this->method." --cookie-jar ".$this->cookiefile. " --cookie ".$this->cookiefile." ".($content!=null?"-d '".str_replace("'","\'",$content)."'":"")." ".$this->url; $x = ssh2_exec($connection,$cmd); stream_set_blocking($x, true); $rsp = $this->content = stream_get_contents($x); //return $this->content; //return false; }else{ $t = array(); $t[] = $method . ' ' . $uri . ' HTTP/1.1'; //$t[] = 'Host: ' . $sslhost; //$t[] = 'Host: ' . $host . ($port == 443 ? ':443' : ''); $t[] = 'Host: ' . $host . ($port == 80 ? '' : ":$port"); if ($this->contenttype) $t[] = 'Content-Type: ' . $this->contenttype; if ($this->referer) $t[] = "Referer: {$this->referer}"; $t[] = "User-Agent: {$this->useragent}"; if (count($this->authorization) == 2) $t[] = "Authorization: Basic " . base64_encode("{$this->authorization[0]}:{$this->authorization[1]}"); if ($this->method == 'POST') $t[] = 'Content-Length: ' . ($this->contentlength <> 0 ? $this->contentlength : strlen($content)); $t[] = 'Connection: ' . $this->connection; if (count($this->header)) { if (isset($this->header[0])) $this->header = $this->parseHeaders($this->header); foreach ($this->header as $k => $h) { if (!is_array($h)) $t[] = "$k: $h"; } } if (count($this->_cookies) && ($this->loadcookie || (!$this->loadcookie && $this->cf)) && $this->headercookie) $t[] = cookie_file::toString($this->_cookies); $t = array_unique($t); $this->pack = $this->pack($t, $content); // var_dump($this->pack);die(); //var_dump($this->proxy_type,$this->proxy_type);die(); if (!$this->proxy_type) { if($this->ssh_ip){ //$this->sshsocket($sslhost, $port); $this->sshsocket($host, $port); }else $this->socket($sslhost, $port, $errno, $errstr, $this->timeout); //var_dump($this->fp,$sslhost, $port, $errno, $errstr, $this->timeout);die(); if (!$this->fp || !(get_resource_type($this->fp) == 'stream')) return false; //if ($this->ssh_ip && $port == '443') // self::_ssl_encrypt(); //if ($port == '443') // self::_ssl_encrypt(); if (!$this->send($this->pack)) { fclose($this->fp); return false; } if ($this->ssh_ip) { stream_set_blocking($this->fp, true); } } else { $this->socket($this->proxy, $this->proxy_port, $errno, $errstr, $this->timeout); if (!$this->fp || !(get_resource_type($this->fp) == 'stream')) return false; if ($this->proxy_type == 'http') { if ($this->proxy_user && $this->proxy_pass) $t[] = "Proxy-Authorization: basic " . base64_encode($this->proxy_user . ":" . $this-> proxy_pass); $url = 'http' . ($port == 443 ? 's' : '') . '://' . $host . $uri; $t[0] = $method . " " . $url . " HTTP/1.0"; $this->pack = $this->pack($t, $content); //var_dump($this->pack); if ($port == '443') { /* The practical way to handle https destination+http proxy is: connect http(not encrypted) connection to the proxy server. send CONNECT request to start ssl tunneling. change the connection to encrypted mode. send normal proxy request (GET or POST). */ $t3 = $t; $t3[0] = 'CONNECT ' . $host . ':' . $port . ' HTTP/1.0'; $_pack = $this->pack($t3, ''); //HTTP/1.0 200 Connection established //HTTP/1.0 200 OK /*var_dump($_pack); $_pack = "CONNECT httpbin.org:443 HTTP/1.0 Host: httpbin.org:443 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:8.0.1) Gecko/20100101 Firefox/8.0.1 Connection: close ";*/ if (!$this->send($_pack)) { fclose($this->fp);//var_dump('1'); return false; } //var_dump(fgets($this->fp, $this->length));die(); $q = fgets($this->fp, $this->length); if (strpos($q, '200 Connection established') === false && strpos($q, '200 OK') === false) { fclose($this->fp); return false; } //var_dump('1'); self::_ssl_encrypt(); } if (!$this->send($this->pack)) { fclose($this->fp); return false; } } elseif ($this->proxy_type == 'socks4') { //http://www.openssh.org/txt/socks4.protocol $ip = gethostbyname($host); if (preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $ip, $matches)) $int = pack('C4', $matches[1], $matches[2], $matches[3], $matches[4]); else { fclose($this->fp); return false; } $request = pack('C2', 0x04, 0x01) . pack('n', $port) . $int . ($this->proxy_user ? $this-> proxy_user : '0') . pack('C', 0x00); fwrite($this->fp, $request); $resp = fread($this->fp, 9); if (strlen($resp) != 8) { fclose($this->fp); return false; } $answer = unpack('Cvn/Ccd', substr($resp, 0, 2)); //var_dump($answer); if ($answer['vn'] != 0x00 && $answer['vn'] != 0x04) { fclose($this->fp); return false; } if ($answer['cd'] != 0x5A) { fclose($this->fp); return false; } if ($port == '443') self::_ssl_encrypt(); if (!$this->send($this->pack)) { fclose($this->fp); return false; } } elseif ($this->proxy_type == 'socks4a') { //http://ballastsec.blogspot.com/2012/06/php-socks4a-interface.html //http://www.openssh.org/txt/socks4a.protocol $ip = rand(1, 255); $int = pack('C4', 0, 0, 0, $ip); $request = pack('C2', 0x04, 0x01) . pack('n', $port) . $int . ($this->proxy_user ? $this-> proxy_user : '') . pack('C', 0x00) . $host . pack('C', 0x00); $this->send($request); $resp = fread($this->fp, 9); if (strlen($resp) != 8) { fclose($this->fp); return false; } $answer = unpack('Cvn/Ccd', substr($resp, 0, 2)); if ($answer['vn'] != 0x00 && $answer['vn'] != 0x04) { fclose($this->fp); return false; } if ($answer['cd'] != 0x5A) { fclose($this->fp); return false; } if ($port == '443') self::_ssl_encrypt(); if (!$this->send($this->pack)) { fclose($this->fp); return false; } } elseif ($this->proxy_type == 'socks5') { if ($this->proxy_user && $this->proxy_pass) $request = pack('C4', 0x05, 0x02, 0x00, 0x02); else $request = pack('C3', 0x05, 0x01, 0x00); $this->send($request); $resp = fread($this->fp, 3); $answer = @unpack('Cver/Cmethod', $resp); if (!$answer) return false; $answermethod = $answer['method']; if ($answermethod == 0x02) { $request = pack('C', 0x01) . pack('C', strlen($this->proxy_user)) . $this->proxy_user . pack('C', strlen($this->proxy_pass)) . $this->proxy_pass; fwrite($this->fp, $request); $resp = fread($this->fp, 3); $answer = unpack('Cvn/Cresult', $resp); if ($answer['vn'] != 0x01 || $answer['result'] != 0x00) { fclose($this->fp); return false; } } if ($answermethod == 0x00 || $answermethod == 0x02) { $ip = gethostbyname($host); if (preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $ip, $matches)) $int = pack('C4', $matches[1], $matches[2], $matches[3], $matches[4]); else { fclose($this->fp); return false; } $request = pack('C4', 0x05, 0x01, 0x00, 0x01) . $int . pack('n', $port); // pack("C2", 0x00, 0x00); $this->send($request); $resp = fread($this->fp, 11); $answer = @unpack('Cver/CREP', substr($resp, 0, 2)); if (!$answer) return false; if ($answer['REP'] != 0x00) { fclose($this->fp); return false; } if ($port == '443') self::_ssl_encrypt(); if (!$this->send($this->pack)) { fclose($this->fp); return false; } } else return false; } } if ($ret > 0) { $rsp = ''; $ec = 0; $ccc = 0; //var_dump($this->fp); stream_set_timeout($this->fp,$this->timeout); while ((!feof($this->fp)) && (($ccc++)<$this->getcount)) { $rsp .= fgets($this->fp, $this->length); //if ($ec++ == 0 && $fget == "\r\n") // && $this->length == 4096 // $rsp .= ''; //else //$rsp .= $fget; } //var_dump($rsp); //die(); } fclose($this->fp); $this->content = $rsp; } $this->query_time = microtime(1)-$_bm; if ($this->autoreferer) $this->referer = $url; if ($this->usecookie) { $res = $this->parseHttpResponse($rsp, $ret); $this->saveCookie(); } if ($ret == 4) { return $rsp; } if ($ret > 0) { return $this->usecookie ? $res : $this->parseHttpResponse($rsp, $ret); } } /** * @since v.15 */ private function _ssl_encrypt(){ if (!in_array('ssl', stream_get_transports())) die('not support ssl'); //var_dump(stream_get_transports());die(); //stream_set_blocking($this->fp, true); $modes = array( //STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, //STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, //STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT, STREAM_CRYPTO_METHOD_TLS_CLIENT, STREAM_CRYPTO_METHOD_SSLv3_CLIENT, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, STREAM_CRYPTO_METHOD_SSLv2_CLIENT ); $success = false; foreach ($modes as $mode) { $success = @stream_socket_enable_crypto($this->fp, true, $mode); if ($success) break; //else stream_socket_enable_crypto($this->fp, false); } //var_dump($success); //stream_set_blocking($this->fp, false); } /** * @since v1.2 */ public function clear() { $this->pack = ''; $this->content = ''; $this->vars = array(); $this->files = array(); } /** * @since v1.0 */ public function parseHttpResponse($content = null, $ret = 1) { if (empty($content)) { return false; } $nl = "\r\n"; //$content = trim($content); $content = ltrim($content); $hunks = explode($nl . $nl, $content, 2); //var_dump($hunks); if (!is_array($hunks)) return false; if (count($hunks) < 2) $body = ''; else $body = end($hunks); $header = reset($hunks); $this->responseheaders = $headers = explode($nl, $header); unset($hunks); unset($header); if ($this->validateHttpResponse && !self::validateHttpResponse($headers)) { return false; } if ($this->followlocation && $this->maxredirect > 0) { $_headers = $this->parseHeaders($headers); if (isset($_headers["Location"])) { $newobject = $this->_clone(); $newobject->maxredirect = $newobject->maxredirect - 1; //if ($this->autoreferer) // $newobject->referer = $this->url; $newobject->autoreferer = false; $newobject->referer = ''; $newobject->loadcookie = false; $newobject->url = $_headers['Location']; $newobject->clear(); // var_dump($newobject,$ret);die(); return $newobject->exec($this->method, $_headers['Location'], $this->var, $ret); } } if ($ret == 2) return $headers; if ($ret == 3) return $this->parseHeaders($headers); //var_dump($headers,$ret,$body);die(); if ($ret == 1 || $ret == 5) { //$this->parseHeaders($headers); //var_dump($headers);die(); if (in_array('Transfer-Coding: chunked', $headers) || in_array('Transfer-Encoding: chunked', $headers)) $body = trim(self::unchunkHttpResponse($body)); else $body = trim($body); return $ret==1?$body:array($headers, $body); } } /** * @since v1.0 */ public static function validateHttpResponse($headers = null) { if (!is_array($headers) or count($headers) < 1) { return false; } if (strpos(trim(strtolower($headers[0])), "200") !== false || strpos(trim(strtolower($headers[0])), "100") !== false || strpos(trim(strtolower($headers[0])), "301") !== false || strpos(trim (strtolower($headers[0])), "302") !== false) return true; return false; } /** * @since v1.0 */ public static function unchunkHttpResponse2($result) { return preg_replace('/([0-9A-F]+)\r\n(.*)/sie', '($cnt=@base_convert("\1", 16, 10)) ?substr(($str=@strtr(\'\2\', array(\'\"\'=>\'"\', \'\\\\0\'=>"\x00"))), 0, $cnt).http::unchunkHttpResponse(substr($str, $cnt+2)) :""', $result); } public static function unchunkHttpResponse($data) { //die(); $fp = 0; $outData = ""; while ($fp < strlen($data)) { $rawnum = substr($data, $fp, strpos(substr($data, $fp), "\r\n") + 2); $num = hexdec(trim($rawnum)); $fp += strlen($rawnum); $chunk = substr($data, $fp, $num); $outData .= $chunk; $fp += strlen($chunk); } return $outData; } /** * @since v1.1 */ private function _clone() { return $this; } } class cookie_file { public $cookies = array(); public $filename = 'c.txt'; public $f = false; public $content = ''; private $head = '# Netscape HTTP Cookie File # http://curl.haxx.se/rfc/cookie_spec.html # This file was generated by sa_http_class! Edit at your own risk. '; public $lines = array(); function __construct($filename = '') { if ($filename != '') $this->filename = $filename; if(!file_exists($this->filename)){ $_f = fopen($this->filename, 'w'); fclose($_f); } $this->f = fopen($this->filename, 'r+'); if(!$this->f) return false; $this->read(); if ($this->content != '') $this->parselines(); else { $this->write_new_file(); $this->content = $this->head; $this->lines = explode("\r\n", $this->head); } } public function write_new_file() { file_put_contents($this->filename, $this->head); } public function write_file($url) { $cookie_domains = $this->domain($url, false); //var_dump($cookie_domains); if ($cookie_domains) { foreach ($cookie_domains as $k => $c) { if ($c->expired()) unset($this->lines[$k]); else $this->lines[$k] = $c->toString(); } file_put_contents($this->filename, implode("\r\n", $this->lines) . "\r\n"); $this->__construct($this->filename); } } public function add($cookie, $url = false) //cookie $cookie { if(!($cookie instanceof cookie)) return; if ($url === false) $url = 'http://' . ltrim($cookie->domain, '.') . $cookie->path; //first select all cookie of domain $cookie_domains = $this->domain($url, false); if ($cookie_domains && count($cookie_domains) > 0) { //check douplicate name of cookie foreach ($cookie_domains as $k => $c) { if ($c->name == $cookie->name) { //update $sd = $this->cookies[$k]->domain; $this->cookies[$k] = $cookie; // = $cookie_domains[$k] = $c $this->cookies[$k]->domain = $sd; $this->lines[$k] = $cookie->toString(); $updated = true; break; } } if (!isset($updated)) { //insert new $new_key = count($this->lines); $this->cookies[$new_key] = $cookie; $this->lines[$new_key] = $cookie->toString(); unset($updated); } } else { $new_key = count($this->lines); $this->cookies[$new_key] = $cookie; $this->lines[$new_key] = $cookie->toString(); } } public function parselines() { //$lines = explode("\r\n", $this->content); $lines = preg_split("/(\r)?\n/", $this->content); //var_dump($lines); if (count($lines) > 0) { foreach ($lines as $k => $line) { $line = trim($line); if (substr($line, 0, 1) != '#' && $line <> '') { $c = self::parseline($line); if ($c) $this->cookies[$k] = $c; } $this->lines[$k] = $line; } } } public function read($bytes = 1024) { while (!feof($this->f)) $this->content .= fgets($this->f, $bytes); $this->content = trim($this->content); } function __destruct() { if ($this->f !== false) @fclose($this->f); } public static function parseline($line) { //echo $line; $cookie = new cookie; $line2 = explode("\t", $line); if (!isset($line2[0]) || !isset($line2[6])) return false; $cookie->setvalue($line2[5], $line2[6]); $cookie->expires = $line2[4]; $cookie->path = $line2[2]; $cookie->domain = $line2[0]; $cookie->secure = $line2[3] == 'TRUE'; //check expires //if (!$cookie->expired()) return $cookie; //return false; } public function domain($url, $tostring = true) { $url2 = parse_url($url); $domain = $url2['host']; $port = isset($url2['port']) ? $url2['port'] : ($url2['scheme'] == 'https' ? 443 : 80); $path = isset($url2['path']) ? $url2['path'] : '/'; //var_dump($this->cookies); if (count($this->cookies) > 0) { $ret = array(); foreach ($this->cookies as $k => $c) { if (($port == 443) ^ $c->secure) continue; if ($c->path != '/') { $pl = strlen($c->path); if (substr($path, 0, $pl) != $c->path) continue; } if ($c->allowsub()) { //$pl = strlen($domain); $pl = strlen($c->domain); //if (substr($c->domain, -$pl) == $domain) { //var_dump($domain,$c->domain); if ((substr($domain, -$pl) == $c->domain) || ($domain == substr($c->domain, 1))) $ok = true; } elseif ($domain == $c->domain) $ok = true; if (isset($ok)) { $ret[$k] = $c; unset($ok); } } return $tostring ? self::toString($ret) : $ret; } return false; } public static function toString($domain_cookies, $prefix = true) { if (($count = count($domain_cookies)) == 0) return ''; $ret = $prefix ? 'Cookie: ' : ''; foreach ($domain_cookies as $k => $c) $ret .= $c->name . "=" . $c->value . ($count - 1 == $k ? "" : "; "); return rtrim($ret, '; '); } public static function toArray($domain_cookies) { $ret = array(); if (count($domain_cookies) > 0) { foreach ($domain_cookies as $c) $ret[$c->name] = $c->value; } return $ret; } public static function exists(&$cookies, $new) { foreach ($cookies as $k => $c) { if ($c->name == $new->name) { $cookies[$k]->value = $new->value; return true; } } return false; } } class cookie { private $vars = array("name" => '', "value" => '', "expires" => 0, "path" => '/', "domain" => '', "secure" => false, "httponly" => false, ); private function notnamevalue($val) { $keys = array_slice($this->vars, 2); return array_key_exists($val, $keys); } function setvalue($name, $value = '') { $name2 = strtolower($name); if ($this->notnamevalue($name2)) $this->vars[$name2] = $value; elseif ($this->name == '') { $this->name = $name; $this->value = $value; } } function __set($name, $value = '') { $name = strtolower($name); if (array_key_exists($name, $this->vars)) $this->vars[$name] = $value; } function __get($name) { $name = strtolower($name); if (array_key_exists($name, $this->vars)) return ($name == 'path' && $this->vars[$name] == '') ? '/' : $this->vars[$name]; else return false; } public function allowsub() { if ($this->vars['domain']) return substr($this->vars['domain'], 0, 1) == '.'; else trigger_error('domain not exists'); } public function toString() { return $this->domain . "\t" . ($this->allowsub() ? 'TRUE' : 'FALSE') . "\t" . $this->path . "\t" . ($this->secure ? 'TRUE' : 'FALSE') . "\t" . $this->expires . "\t" . $this->name . "\t" . $this->value; //."\r\n"; } public function expired() { return $this->expires < time() && $this->expires != 0; } public static function grab($line, $url = '') { if (preg_match('/^Set-Cookie: /i', $line)) { $line = preg_replace('/^Set-Cookie: /i', '', trim($line)); if (strpos($line, ';') !== false) { $line = preg_split("/;[ ]*/", $line); $cookie = new cookie; foreach ($line as $k => $l) { if (strpos($l, '=') !== false) { $l2 = explode("=", $l, 2); //$l2[0] = strtolower($l2[0]); $cookie->setvalue($l2[0], strtolower($l2[0]) == 'expires' ? strtotime($l2[1]) : $l2[1]); } elseif ($l != '') $cookie->$l = true; } //var_dump($cookie);die(); if ($cookie->domain == '') { if ($url == '') return false; $cookie->domain = parse_url($url, PHP_URL_HOST); } //var_dump($cookie); return ($cookie); } elseif (strpos($line, '=') !== false) { $l2 = explode("=", $line, 2); $cookie = new cookie; $cookie->name = $l2[0]; $cookie->value = $l2[1]; } } return false; } }
Read more: Some examples of using class HTTP
1 Comment
Some examples of using class HTTP | Free Online Tutorials
(May 15, 2020 - 5:55 am)[…] PHP: class HTTP – A Curl Alternative – support proxy, socks4, socks4a, socks5, ssh ̷… […]