Last active
July 24, 2020 17:39
-
-
Save Quacky2200/74d280bf828fcd68f326a4b5aab603c3 to your computer and use it in GitHub Desktop.
Revisions
-
Quacky2200 revised this gist
Jan 2, 2020 . 1 changed file with 0 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -140,8 +140,6 @@ public function makeRequest($uri = "/", $params = null, $method = "GET", $mime = $uri .= "?" . http_build_query($params); } $opts = array( 'http' => array( 'header' => $this->combineHeaders($this->headers, 'string'), -
Quacky2200 revised this gist
Jan 2, 2020 . 1 changed file with 6 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,7 +18,7 @@ class Request { public $defaultMime = 'application/json'; /** * Creates a Request object */ public function __construct($protocol = null, $host = null, $path = null) { $this->protocol = $protocol ?: 'https'; @@ -66,8 +66,8 @@ public function makeRequest($uri = "/", $params = null, $method = "GET", $mime = $uri = $this->protocol . "://" . $this->host . $this->path . $uri; $this->headers += array( "Accept" => $mime, "User-Agent" => $this->userAgent ); if ($this->authorize) { @@ -140,11 +140,13 @@ public function makeRequest($uri = "/", $params = null, $method = "GET", $mime = $uri .= "?" . http_build_query($params); } var_dump($this->combineHeaders($this->headers, 'string')); $opts = array( 'http' => array( 'header' => $this->combineHeaders($this->headers, 'string'), 'method' => $method, 'user_agent' => $this->userAgent, 'proxy' => $this->proxyURL, 'timeout' => 5, ), -
Quacky2200 renamed this gist
Jan 2, 2020 . 1 changed file with 163 additions and 38 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,30 +3,32 @@ * REST test scripts * @license MIT */ class Request { public $protocol; public $host; public $path; public $proxyURL; public $decoders; public $userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"; public $allowInsecure = false; public $headers = array(); // set to Basic for user/pass authorization public $authorize = null; public $defaultMime = 'application/json'; /** * Creates a RESTRequest object */ public function __construct($protocol = null, $host = null, $path = null) { $this->protocol = $protocol ?: 'https'; $this->host = $host ?: 'localhost'; $this->path = $path ?: ''; $this->decoders = array( "application/xml" => function($res) { // Decode an XML response return json_decode(json_encode((array)simplexml_load_string($res)), true); }, "application/json" => function($res) { // Decode a JSON response @@ -42,41 +44,63 @@ public function __construct($username, $password) { // return $result; // }, ); } /** * Make a request to the API with the following information. * * You can use params to contain uri query information, but you cannot use * both $uri and $params to create GET query parameters. It's probably best * to stick to $params so that it will be easier to manage them. * * @param string $uri The endpoint * @param array $params Extra data for the request (GET/POST data) * @param string $method The request type (GET/POST/PUT/DELETE) * @param string $format The response format (JSON/XML) * @return Array */ public function makeRequest($uri = "/", $params = null, $method = "GET", $mime = null) { // Build URL $uri = $this->protocol . "://" . $this->host . $this->path . $uri; $this->headers += array( "Accept", $mime, "User-Agent", $this->userAgent ); if ($this->authorize) { $this->headers['Authorization'] = $this->authorize; } $params = $params ?: array(); if ($params !== null && !is_array($params)) { throw new \Exception( 'Invalid type ' . gettype($mime) . ', expected array for request parameters' ); } $mime = $mime ?: $this->defaultMime; if ($mime !== null && !is_string($mime)) { throw new \Exception( 'Invalid type ' . gettype($mime) . ', expected string for mime' ); } if (function_exists('curl_init')) { $opts = array( CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HEADER => false, CURLOPT_HTTPHEADER => $this->combineHeaders($this->headers, 'array'), CURLOPT_FAILONERROR => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_PROXY => $this->proxyURL, CURLOPT_TIMEOUT => 10, CURLOPT_CONNECTTIMEOUT => 5, ); if ($this->allowInsecure) { @@ -105,18 +129,20 @@ public function makeRequest($uri = "/", $params = array(), $method = "GET", $mim if (curl_setopt_array($ch, $opts) === false || ($data = curl_exec($ch)) === false) { $err = curl_error($ch); curl_close($ch); throw new RuntimeException("{$err} \"{$uri}\""); } } elseif (ini_get('allow_url_fopen')) { if (in_array(strtoupper($method), array("PUT", "POST"))) { $this->headers["Content-Type"] = "application/x-www-form-urlencoded"; $opts['http']['content'] = http_build_query($request, '', '&'); } else if (strpos($uri, '?') === false) { $uri .= "?" . http_build_query($params); } $opts = array( 'http' => array( 'header' => $this->combineHeaders($this->headers, 'string'), 'method' => $method, 'user_agent' => $agent, 'proxy' => $this->proxyURL, @@ -131,13 +157,6 @@ public function makeRequest($uri = "/", $params = array(), $method = "GET", $mim ); } $context = stream_context_create($opts); if (($data = @file_get_contents($uri, false, $context)) === false) { @@ -167,13 +186,120 @@ public function makeRequest($uri = "/", $params = array(), $method = "GET", $mim return $decoded; } /** * Combines headers into a string * @param array $headers Dictionary of header keys and values * @param string $type Return type * @return mixed String or Array containing combined KVPs */ public function combineHeaders($headers, $type = 'string') { foreach($headers as $key => &$value) { if (is_string($key)) { $value = "$key: $value"; } } if ($type == 'string') { // returns 'User-Agent: Chrome\nHost: localhost\n' etc... return implode(array_values($headers), "\n"); } else if ($type == 'array') { // returns array('User-Agent: Chrome', 'Host: localhost'), etc... return array_values($headers); } else { throw new \Exception('Invalid combineHeaders type'); } } /** * Parse headers from a string into an array. * Not yet implemented * @return [type] [description] */ public function parseHeaders() { // TODO? throw new \Exception('Not yet implemented'); } /** * Adds a KVP to the headers for future requests. * @param string $key Header key * @param string $value Header value */ public function addHeader($key, $value) { $this->headers[$key] = $value; return $this; } /** * Remove a KVP from the headers for future requests. * @param string $key Header key * @param string $value Header value */ public function removeHeader($key) { if (isset($this->headers[$key])) { unset($this->headers[$key]); } return $this; } /** * This removes any authorization header currently being used. * @return $this */ public function removeAuthorization() { $this->authorize = null; return $this; } /** * Sets basic authorization for username and password * @param string $username User's Username * @param string $password User's password * @return $this */ public function setBasicAuthorization($username, $password) { $this->authorize = "Basic " . base64_encode("{$username}:{$password}"); return $this; } /** * Set authorization header with authorization string (e.g. token) * @param string $auth authorization string * @return $this */ public function setOtherAuthorization($auth) { $this->authorize = $auth; return $this; } /** * Sets the default mime type. * @param string $mime Default mime * @return $this */ public function setDefaultMime($mime) { if (is_string($mime)) { $this->defaultMime = $mime; } return $this; } /** * Adds a decoding mechanism to the supported list of decoders * @param string $mime The mime type in the format of <MIME_type/MIME_subtype> * @param closure $decodeLamda The decoding mechanism to support the mime type * @return $this */ public function addDecoder($mime, $decodeLamda){ $this->decoders[$mime] = $decodeLamda; return $this; } /** @@ -253,5 +379,4 @@ function arrayMergeRecursiveDistinct(array &$array1, array &$array2, $dynamicKey } return $merged; } } -
Quacky2200 revised this gist
Jan 2, 2020 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -25,7 +25,7 @@ public function __construct($username, $password) { $this->decoders = array( "application/xml" => function($res) { // Decode an XML response return simplexml_load_string($res); //return json_decode(json_encode((array)simplexml_load_string($res)), true); }, "application/json" => function($res) { -
Quacky2200 created this gist
Jan 2, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,257 @@ <?php /** * REST test scripts * @license MIT */ class RESTRequest { const PROTOCOL = "https"; const HOST = "localhost"; const API_PATH = "/api/v1"; public $username; public $password; public $proxyURL; public $decoders; public $userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"; public $allowInsecure = false; /** * Creates a RESTRequest object */ public function __construct($username, $password) { $this->username = $username; $this->password = $password; $this->decoders = array( "application/xml" => function($res) { // Decode an XML response return simplexml_load_string($res); //return json_decode(json_encode((array)simplexml_load_string($res)), true); }, "application/json" => function($res) { // Decode a JSON response return json_decode($res, true); }, "application/vnd.php.serialized" => function($res) { // Deserialize a PHP object return unserialize($res); }, // "application/x-www-form-urlencoded" => function($res) { // // Decode a url encoded string // $result = $this->parseUrl(urldecode($res)); // return $result; // }, ); } /** * Make a request to the API with the following information * @param string $uri The endpoint * @param array $params Extra data for the request (GET/POST data) * @param string $method The request type (GET/POST/PUT/DELETE) * @param string $format The response format (JSON/XML) * @return Array */ public function makeRequest($uri = "/", $params = array(), $method = "GET", $mime = "application/json") { $authorisation = null; if ($this->authorisation) { $authorisation = "{$this->username}:{$this->password}"; } // Build URL $uri = self::PROTOCOL . "://" . self::HOST . self::API_PATH . "{$uri}"; if (function_exists('curl_init')) { $opts = array( CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HEADER => false, CURLOPT_HTTPHEADER => array( "Accept: {$mime}", "User-Agent: {$this->userAgent}" ), CURLOPT_FAILONERROR => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_PROXY => $this->proxyURL, CURLOPT_TIMEOUT => 10, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_USERPWD => $authorisation ); if ($this->allowInsecure) { $opts += array( CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, ); } // Only send content in PUT and POST requests if (in_array(strtoupper($method), array("PUT", "POST"))){ $opts[CURLOPT_POSTFIELDS] = http_build_query($params, '', '&'); } else { $uri .= "?" . http_build_query($params); } // Start the connection $ch = curl_init($uri); // Make sure we can connect if (($ch = curl_init($uri)) === false) { throw new RuntimeException("Cannot connect to HOST: {$uri}"); } // Try to make the request and get data out if (curl_setopt_array($ch, $opts) === false || ($data = curl_exec($ch)) === false) { $err = curl_error($ch); curl_close($ch); throw new RuntimeException("Error: {$err} with URL \"{$uri}\""); } } elseif (ini_get('allow_url_fopen')) { if ($authorisation) { $authorisation = "Authorization: Basic " . base64_encode("{$this->username}:{$this->password}") . "\n"; } $accept = "Accept: {$mime}"; $opts = array( 'http' => array( 'header' => $authorisation . $accept, 'method' => $method, 'user_agent' => $agent, 'proxy' => $this->proxyURL, 'timeout' => 5, ), ); if ($this->allowInsecure) { $opts['ssl'] = array( "verify_peer" => false, "verify_peer_name" => false, ); } if (in_array(strtoupper($method), array("PUT", "POST"))) { $opts['http']['header'] .= "\nContent-Type: application/x-www-form-urlencoded"; $opts['http']['content'] = http_build_query($request, '', '&'); } else { $uri .= "?" . http_build_query($params); } $context = stream_context_create($opts); if (($data = @file_get_contents($uri, false, $context)) === false) { $error = error_get_last()['message']; preg_match("/(?:HTTP request failed! HTTP\/[0-9].[0-9] ([0-9a-zA-Z ]+))/", $error, $specific); $error = (@$specific[1] ?: $error); throw new RuntimeException("Cannot connect to HOST as $error: {$uri}"); } } else { throw new RuntimeException('No means of communication with REST API, please enable CURL or HTTP Stream Wrappers'); } if (!$data) { throw RuntimeException("The response was empty"); } $decoder = $this->getDecoder($mime); if (!$decoder) { throw new RuntimeException("No decoder is present for mime type {$mime}"); } $decoded = $decoder($data); if (!$decoded) { throw new RuntimeException("The response cannot be decoded into the mime type {$mime}. Response: {$data}"); } return $decoded; } /** * Adds a decoding mechanism to the supported list of decoders * @param string $mime The mime type in the format of <MIME_type/MIME_subtype> * @param closure $decodeLamda The decoding mechanism to support the mime type */ public function addDecoder($mime, $decodeLamda){ $this->decoders[$mime] = $decodeLamda; } /** * Gets a decoding lamda mechanism for a known mime type * @param string $mime The mime type in the format of <MIME_type/MIME_subtype> * @return closure The decoding mechanism */ public function getDecoder($mime) { if (array_key_exists($mime, $this->decoders)){ return $this->decoders[$mime]; } else { return null; } } /** * Returns all known mime types supported by the REST API * @return array list of <MIME_type/MIME_subtype> */ public function getMimeTypes(){ return array_keys($this->decoders); } // @see https://gist.github.com/rubo77/6821632 to skip max_input_vars error /** * @param $string * @return array|bool */ function parseUrl($string) { if($string==='') { return false; } $result = array(); // Find the pairs "name=value" $pairs = explode('&', $string); foreach ($pairs as $pair) { $dynamicKey = (false !== strpos($pair, '[]=')) || (false !== strpos($pair, '%5B%5D=')); // use the original parse_str() on each element parse_str($pair, $params); $k = key($params); if (!isset($result[$k])) { $result += $params; } else { $result[$k] = $this->arrayMergeRecursiveDistinct($result[$k], $params[$k], $dynamicKey); } } return $result; } /** * @param array $array1 * @param array $array2 * @param $dynamicKey * @return array */ function arrayMergeRecursiveDistinct(array &$array1, array &$array2, $dynamicKey) { $merged = $array1; foreach ($array2 as $key => &$value) { if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) { $merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value, $dynamicKey); } else { if ($dynamicKey) { if (!isset( $merged[$key])) { $merged[$key] = $value; } else { if (is_array($merged[$key])) { $merged[$key] = array_merge_recursive($merged[$key], $value); } else { $merged[] = $value; } } } else { $merged[$key] = $value; } } } return $merged; } } ?>