setHeader($key, $value); $auth = false; } continue; } $headers[] = $hdr; $client->setHeader($key, $value); } $headers = implode("\n", $headers); return $auth; } function setCookies($client, $cs) { if (!empty($cs)) { $cookies = $client->getCookies(); $tmp = explode( "\n", $cs ); foreach( $tmp as $c ) { $c = trim( $c ); if( empty( $c ) ) { continue; } list( $key, $value ) = explode('=', $c); $cookies[$key] = $value; } foreach ($cookies as $cookieKey => $cookieValue) { $client->setCookie( $cookieKey, $cookieValue ); } } } class RestClient { private $server; private $port; private $proxyHost; private $proxyPort; private $socket; private $responseState; private $responseHeader; private $responseBody; private $requestHeader; private $header = array(); private $cookies = array(); public function __construct( $server, $port = 80 ) { $this->server = $server; $this->port = $port; $this->responseState = array(); $this->responseHeader = array(); $this->responseBody = null; } public function setProxy( $proxyHost = null, $proxyPort = 3128 ) { $this->proxyHost = $proxyHost; $this->proxyPort = $proxyPort; } public function getHeaders() { return $this->header; } public function setHeader($name, $value) { return $this->header[$name] = $value; } public function getCookies() { return $this->cookies; } public function setCookie($name, $value) { $this->cookies[$name] = $value; return true; } public function getResponseState() { return $this->responseState; } public function getResponseHeader() { return $this->responseHeader; } public function getResponseBody() { return $this->responseBody; } public function getRequestHeader() { return $this->requestHeader; } public function get( $path = '/' ) { if( !$this->connect() ) { return false; } $this->writeHeader( 'GET', $path ); $this->ParseResponse(); $this->disconnect(); return true; } public function post( $path = '/', $body = '' ) { if( !$this->connect() ) { return false; } $header = array( 'Content-Length' => strlen( $body ) ); $this->writeHeader( 'POST', $path, $header ); $this->write( $body ); $this->parseResponse(); $this->disconnect(); return true; } public function put( $path = '/', $body = '' ) { if( !$this->connect() ) { return false; } $header = array( 'Content-Length' => strlen( $body ) ); $this->writeHeader( 'PUT', $path, $header ); $this->write( $body ); $this->parseResponse(); $this->disconnect(); return true; } public function delete( $path = '/' ) { if( !$this->connect() ) { return false; } $this->writeHeader( 'DELETE', $path ); $this->parseResponse(); $this->disconnect(); return true; } /** * */ private function parseResponse() { $this->responseState = array(); $this->responseHeader = array(); $this->responseBody = ''; $header = ''; $body = ''; $response = ''; while (!feof($this->socket)) { $response .= fgets($this->socket, 128); } $split = preg_split('/\r\n/', $response); // check state line $state = explode(' ', array_shift($split)); // ignore "continue" and use next line... if ($state[1] == '100') { $state = explode( ' ', array_shift( $split ) ); } $this->responseState['protocol'] = array_shift($state); $this->responseState['code'] = array_shift($state); $this->responseState['message'] = implode(' ', $state); // parse header while (true) { $line = array_shift($split); if (empty($line)) { break; } preg_match('/^(.*):\s+(.*)$/', $line, $match); // multiple header if (isset($this->responseHeader[$match[1]])) { $this->responseHeader[$match[1]] = array($this->responseHeader[$match[1]]); array_push($this->responseHeader[$match[1]], $match[2]); continue; } $this->responseHeader[$match[1]] = $match[2]; } // keep cookies if (isset($this->responseHeader['Set-Cookie'])) { $cookies = $this->responseHeader['Set-Cookie']; if (!is_array( $cookies)) { $cookies = array($cookies); } foreach ($cookies as $cookie) { $c = explode(';', $cookie); $c = explode('=', $c[0]); $this->cookies[$c[0]] = $c[1]; } } // parse body if (isset($this->responseHeader['Transfer-Encoding'] ) && $this->responseHeader['Transfer-Encoding'] == 'chunked') { while (!empty($split)) { $length = hexdec(array_shift($split)); // reached end of boddy if ($length == 0) { break; } $this->responseBody .= array_shift($split); } } else { $this->responseBody = implode( "\r\n", $split ); } if (!isset($this->responseHeader['Content-Encoding'])) { return true; } if ($this->responseHeader['Content-Encoding'] == 'gzip') { $tmp = tempnam(sys_get_temp_dir(), 'http'); file_put_contents($tmp, $this->responseBody); $stream = gzopen($tmp, 'r'); $this->responseBody = stream_get_contents($stream); return true; } if ($this->responseHeader['Content-Encoding'] == 'deflate') { $this->responseBody = gzinflate($this->responseBody); } return true; } /** * connect socket * * @return bool true on success */ private function connect( ) { // direct connect if( empty( $this->proxyHost ) ) { $this->socket = fsockopen( $this->server, $this->port ); } else { $this->socket = fsockopen( $this->proxyHost, $this->proxyPort ); } if( !$this->socket ) { return false; } return true; } /** * disconnect * */ private function disconnect( ) { fclose( $this->socket ); } /** * write HTTP header * * @param string $method * @param string $path * @param array $header */ private function writeHeader($method, $path, $header = array()) { $url = $path; if (!empty($this->proxyHost)) { $url = 'http://' . $this->server . $url; } $this->requestHeader = array(); $this->requestHeader[] = $method . ' '. $url . ' HTTP/1.1'; $this->requestHeader[] = 'Host: ' . $this->server; $this->requestHeader[] = 'Connection: Close'; if (strlen($this->credentials)) { $this->requestHeader[] = 'Authorization: ' . $this->credentials; } // add cookies $cookies = array(); foreach ($this->cookies as $key => $value) { array_push($cookies, $key . '=' . urlencode($value)); } unset($this->header['Cookie']); if (!empty($cookies )) { $this->header['Cookie'] = implode('; ', $cookies); } // additional header $header = array_merge($this->header, $header); foreach ($header as $name => $value) { $this->requestHeader[] = $name . ': ' . $value; } foreach ($this->requestHeader as $hdr) { $this->write($hdr); } $this->write(); } /** * write HTTP linse * * @param string $line */ private function write($line = '') { fwrite($this->socket, $line . "\r\n"); } } ?>