elFinder::fsock_get_contents PHP Method

fsock_get_contents() protected method

Get remote contents with fsockopen()
Author: Naoki Sawada
protected fsock_get_contents ( string &$url, integer $timeout, integer $redirect_max, string $ua, resource $outfp ) : string
$url string url
$timeout integer timeout (sec)
$redirect_max integer redirect max count
$ua string
$outfp resource
return string or bool(false)
    protected function fsock_get_contents(&$url, $timeout, $redirect_max, $ua, $outfp)
    {
        $connect_timeout = 3;
        $connect_try = 3;
        $method = 'GET';
        $readsize = 4096;
        $ssl = '';
        $getSize = null;
        $headers = '';
        $arr = parse_url($url);
        if (!$arr) {
            // Bad request
            return false;
        }
        if ($arr['scheme'] === 'https') {
            $ssl = 'ssl://';
        }
        // query
        $arr['query'] = isset($arr['query']) ? '?' . $arr['query'] : '';
        // port
        $arr['port'] = isset($arr['port']) ? $arr['port'] : ($ssl ? 443 : 80);
        $url_base = $arr['scheme'] . '://' . $arr['host'] . ':' . $arr['port'];
        $url_path = isset($arr['path']) ? $arr['path'] : '/';
        $uri = $url_path . $arr['query'];
        $query = $method . ' ' . $uri . " HTTP/1.0\r\n";
        $query .= "Host: " . $arr['host'] . "\r\n";
        $query .= "Accept: */*\r\n";
        $query .= "Connection: close\r\n";
        if (!empty($ua)) {
            $query .= "User-Agent: " . $ua . "\r\n";
        }
        if (!is_null($getSize)) {
            $query .= 'Range: bytes=0-' . ($getSize - 1) . "\r\n";
        }
        $query .= $headers;
        $query .= "\r\n";
        $fp = $connect_try_count = 0;
        while (!$fp && $connect_try_count < $connect_try) {
            $errno = 0;
            $errstr = "";
            $fp = fsockopen($ssl . $arr['host'], $arr['port'], $errno, $errstr, $connect_timeout);
            if ($fp) {
                break;
            }
            $connect_try_count++;
            if (connection_aborted()) {
                exit;
            }
            sleep(1);
            // wait 1sec
        }
        $fwrite = 0;
        for ($written = 0; $written < strlen($query); $written += $fwrite) {
            $fwrite = fwrite($fp, substr($query, $written));
            if (!$fwrite) {
                break;
            }
        }
        $response = '';
        if ($timeout) {
            socket_set_timeout($fp, $timeout);
        }
        $_response = '';
        $header = '';
        while ($_response !== "\r\n") {
            $_response = fgets($fp, $readsize);
            $header .= $_response;
        }
        $rccd = array_pad(explode(' ', $header, 2), 2, '');
        // array('HTTP/1.1','200')
        $rc = (int) $rccd[1];
        $ret = false;
        // Redirect
        switch ($rc) {
            case 307:
                // Temporary Redirect
            // Temporary Redirect
            case 303:
                // See Other
            // See Other
            case 302:
                // Moved Temporarily
            // Moved Temporarily
            case 301:
                // Moved Permanently
                $matches = array();
                if (preg_match('/^Location: (.+?)(#.+)?$/im', $header, $matches) && --$redirect_max > 0) {
                    $_url = $url;
                    $url = trim($matches[1]);
                    $hash = isset($matches[2]) ? trim($matches[2]) : '';
                    if (!preg_match('/^https?:\\//', $url)) {
                        // no scheme
                        if ($url[0] != '/') {
                            // Relative path
                            // to Absolute path
                            $url = substr($url_path, 0, strrpos($url_path, '/')) . '/' . $url;
                        }
                        // add sheme,host
                        $url = $url_base . $url;
                    }
                    if ($_url !== $url) {
                        fclose($fp);
                        return $this->fsock_get_contents($url, $timeout, $redirect_max, $ua, $outfp);
                    }
                }
                break;
            case 200:
                $ret = true;
        }
        if (!$ret) {
            fclose($fp);
            return false;
        }
        $body = '';
        if (!$outfp) {
            $outfp = fopen('php://temp', 'rwb');
            $body = true;
        }
        while (fwrite($outfp, fread($fp, $readsize))) {
            if ($timeout) {
                $_status = socket_get_status($fp);
                if ($_status['timed_out']) {
                    fclose($outfp);
                    fclose($fp);
                    return false;
                    // Request Time-out
                }
            }
        }
        if ($body) {
            rewind($outfp);
            $body = stream_get_contents($outfp);
            fclose($outfp);
            $outfp = null;
        }
        fclose($fp);
        return $outfp ? $outfp : $body;
        // Data
    }