DirectAdmin\LetsEncrypt\Lib\HTTPSocket::query PHP Метод

query() публичный Метод

Query the server
public query ( $request, $content = '', $doSpeedCheck )
    function query($request, $content = '', $doSpeedCheck = 0)
    {
        $this->error = $this->warn = array();
        $this->result_status_code = NULL;
        // 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('ssl://' . $location['host'], $location['port']);
            } else {
                $this->connect($location['host'], $location['port']);
            }
            $this->set_login($location['user'], $location['pass']);
            $request = $location['path'];
            $content = $location['query'];
            if (strlen($request) < 1) {
                $request = '/';
            }
        }
        $array_headers = array('User-Agent' => "HTTPSocket/{$this->version}", '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;
        // instance connection
        if ($this->bind_host) {
            $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
            socket_bind($socket, $this->bind_host);
            if (!@socket_connect($socket, $this->remote_host, $this->remote_port)) {
                $OK = FALSE;
            }
        } else {
            $context = stream_context_create(array('ssl' => array('verify_peer' => false, 'verify_peer_name' => false)));
            $socket = stream_socket_client($this->remote_host . ':' . $this->remote_port, $sock_errno, $sock_errstr, 10, STREAM_CLIENT_CONNECT, $context);
        }
        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 {
            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;
            $prevSecond = 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) {
            //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']);
            }
        }
    }

Usage Example

Пример #1
0
 /**
  * Apply certificates to DirectAdmin
  *
  * @return bool
  * @throws \Exception
  */
 public function applyCertificates()
 {
     $sock = new HTTPSocket();
     $sock->connect('127.0.0.1', 2222);
     $sock->set_login('admin');
     $sock->set_method('POST');
     $sock->query('/CMD_API_SSL', ['domain' => $this->getHostname(), 'action' => 'save', 'type' => 'paste', 'certificate' => $this->domainKeys->getPrivate() . PHP_EOL . $this->getCertificate(), 'submit' => 'Save']);
     $result = $sock->fetch_parsed_body();
     if ($result['error'] != 0) {
         throw new \Exception('Error while executing first API request: ' . $result['details']);
     }
     $sock = new HTTPSocket();
     $sock->connect('127.0.0.1', 2222);
     $sock->set_login('admin');
     $sock->set_method('POST');
     $sock->query('/CMD_API_SSL', ['domain' => $this->getHostname(), 'action' => 'save', 'type' => 'cacert', 'active' => 'yes', 'cacert' => implode("\n", $this->getCertificateAuthorityCertificates()), 'submit' => 'Save']);
     $result = $sock->fetch_parsed_body();
     if ($result['error'] != 0) {
         throw new \Exception('Error while executing second API request: ' . $result['details']);
     }
     return true;
 }