Location: PHPKode > scripts > gHttp > ghttp/gHttp.php
<?php
/*
**    This class provides a 'http' replacement wrapper for php5 and for olders
**    a 'ghttp' wrapper. This is useful for open and get pages with a fopen because    
**    many hosting deny it in the php.ini for security reasons.
**    The ghttp stream wreaper are created by defualt. And for php5 the http is replaced,
**    this is only because the php5 has a function for unregister wrappers and olders
**    versions do not :'(
**
**    This code is free, I disclaims the copyright over this class, 
**    the only think that I ask you is that is you find a bug or something for make 
**    this class work better plz tellme in the forums of phpclasses. 
**
**    Cesar D. Rodas
*/
class gHttp  {
    var $position;
    var $url;
	
    var $http;
    
    var $isEOF;
    var $isCompressedPage;
    var $content;
	
	
	
	/*
	**	gHttp gather cache, it is only for make a better performance
	**	when you download many pages, and usually the same page.
	*/
	var $isCached;
	function doFileCache() {
		global $gHttpCache;
		global $gHeaders;
		if ($this->isCached) return true;
		if ($gHttpCache && is_array($gHttpCache)) {
			$path = $gHttpCache['folder'].'/'.md5($this->url);
			$f = fopen($path,'w');
				fwrite($f, $this->content);
			fclose($f);
			$f = fopen("${path}.header",'w');
				fwrite($f, serialize($gHeaders));
			fclose($f);
		}
		return true;
	}
	
	function isFileValid($path, $timeout) {
		if (!is_file($path)) return false;
	 	$info = stat($path);
        if ($timeout > 0 && $info['mtime'] + $timeout < time())
			return false;
		return true;
	}
	 
	function isFoundInCache() {
		global $gHttpCache;
		global $gHeaders;
		if ($gHttpCache && is_array($gHttpCache)) {
			@clearstatcache();
			$path = $gHttpCache['folder'].'/'.md5($this->url);
			
			if ( 
				!$this->isFileValid($path, $gHttpCache['timeout']) or
				!$this->isFileValid("${path}.header", $gHttpCache['timeout']) 
			)
				return false;
				
			$f = fopen($path,'rb');
				$this->content = fread($f, filesize($path) );
			fclose($f);
			
			$f = fopen("${path}.header",'rb');
				$gHeaders = unserialize( fread($f, filesize("${path}.header"))  );
			fclose($f);
			return true;
		}
		return false;
	}
	/* end of cache */
	
    function configProxy(&$args) {
        global $Proxy;
        $proxy = &$Proxy;
        if ($proxy && is_array($proxy)) {
            $args["ProxyHostName"]=$proxy['host'];
            $args["ProxyHostPort"]=$proxy['port'];
            $args["ProxyUser"]=$proxy['user'];
            $args["ProxyPassword"]=$proxy['pass'];
            $args["ProxyRealm"] = isset($proxy['realm']) ? $proxy['realm'] : "proxyrealm" ;
            $this->http->proxy_authentication_mechanism= isset($proxy['mech']) ? $proxy['mech']:  ""; 
         }
    }

    function stream_open($path, $mode, $options, &$opened_path) 
    {
        global $gHttpErr;
        global $gHeaders;
		
		$method = 'GET';
        /*
         *    change an ghttp://www.cesarodas.com URL for
         *    http://www.cesarodas.com/
         */
        if (strtolower($path[0]) == 'g') $path = substr($path,1);
				
		if (strtolower($path[0]) == 'p') {
			global $gPost;
			if ( !isset($gPost) || !is_array($gPost)) {
				trigger_error('Missing $gPost array.', E_USER_WARNING);
				return false;
			}
			
			$path = substr($path,1);
			$method = 'POST';
		}

		$this->url= $path;
		$this->isEOF = false;
		$this->isCached =  $this->isFoundInCache(); 
		
        if ( $this->isCached ) return true;
		
		$this->http=new http_class;
        $this->http->timeout=0;
        $this->http->data_timeout=0;
        $this->http->debug=0;
        $this->http->html_debug=0;
        $this->http->user_agent="gHttp (+http://cesars.users.phpclasses.org/ghttp)";
        $this->http->follow_redirect=1;
        $this->http->redirection_limit=5;
        $this->http->exclude_address="";
        $this->http->request_method= $method;
        
        /*
         * Http is amazing!, it has its own URL parse
         * so, I do not worry about this.
         */
        $this->http->GetRequestArguments($path,$arguments);
		if ($method == 'POST')
			$arguments['PostValues'] = &$gPost;
        /* Config a proxy */
        $this->configProxy($arguments);

        /* Ask for compressed page, for keep bandwith */
        $arguments['Headers']['Accept-encoding'] = "gzip";
        /* Open connection */
        $gHttpErr = $this->http->Open($arguments);
        if ($gHttpErr != "") return false;
        /* Send Request */
        $this->http->SendRequest($arguments);
        if ($gHttpErr != "") return false;
        /* Get Header */
        $gHttpErr = $this->http->ReadReplyHeaders($gHeaders);
        if ($gHttpErr != "") return false;
        /* */
        if ($this->http->response_status != 200) { 
            $gHttpErr = "Page status: ".$this->http->response_status;
            $this->http->Close();
            return false;
        }
		
        /* */
        
        if (isset($gHeaders['content-encoding']) && 
            strtolower($gHeaders['content-encoding']) == 'gzip') 
        {
			$buffer = '';
            while (!$this->isEOF &&  $r = $this->stream_read(1024)  )
                $buffer .= $r;
            
            $this->content = substr($buffer, 10); 
            $this->content = gzinflate($this->content);
            $this->position = 0;
                        
            $this->isCompressedPage = true;    
			$this->doFileCache();
        }
        
        return true;
    }

    function stream_read($count) 
    {
        global $gHttpErr;
		
        if ( !$this->isCompressedPage && !$this->isCached) {
            $gHttpErr=$this->http->ReadReplyBody($ret,$count);
            if($gHttpErr!="" && strlen($ret)==0) $this->isEOF = true;
            $this->content .= $ret; /* buffer this! */
        } else {
            $ret = substr($this->content, $this->position, $count);
        }

        $this->position += strlen($ret);
        return strlen($gHttpErr)>0 ? false : $ret;
    }

    function stream_write($data) 
    {
        return false; /* you cannot write ;-) */
    }

    function stream_tell() 
    {
        return $this->position; /* */
    }

    function stream_eof() 
    {
        return $this->isEOF;
    }
    /*
     *    What usually people do is to open, read, and close a connection,    
     *    i dont know if fseek is supported, it is supported in this class
     *    but with a single caracterist... it only could rewind or set a position
     *    lower than the actual position. I can change this, but for me it is not
     *    useful bacause this class will need to download the hole page and buffer
     *    it... what do you think of it? saddor [(a)] gmail [dot ]com answear me plz!
     */
    function stream_seek($offset, $whence) 
    {
        $max = &$this->position;
        switch ($whence) {
            case SEEK_SET:
                if ($offset < $max && $offset >= 0) {
                    $this->position = $offset;
                    return true;
                } else {
                    return false;
                }
                break;
                   
            case SEEK_CUR:
                if ($offset >= 0) {
                    $this->position += $offset;
                    return true;
                } else {
                    return false;
                }
                break;
                   
            case SEEK_END:
               if ($max + $offset >= 0 && $offset >= 0) {
                    $this->position = $max + $offset;
                    return true;
               } else {
                    return false;
               }
               break;
                   
            default:
                return false;
        }
    }

    function stream_flush() {
		$this->doFileCache();
		if (!$this->isCached) $this->http->Close(); /* close the http-class */
    }
}

/* ghttp(s)*/
stream_wrapper_register("ghttp", "gHttp") or die("Failed to register protocol");
stream_wrapper_register("ghttps", "gHttp") or die("Failed to register protocol");
/* post */
stream_wrapper_register("phttp", "gHttp") or die("Failed to register protocol");
stream_wrapper_register("phttps", "gHttp") or die("Failed to register protocol");
/* replacing standar http(s) wrapper */
if ( is_callable('stream_wrapper_unregister') ) {
    stream_wrapper_unregister('http');
	stream_wrapper_unregister('https');
    stream_wrapper_register("http", "gHttp");
	stream_wrapper_register("http2", "gHttp");
}

?>
Return current item: gHttp