summaryrefslogtreecommitdiffstats
path: root/modules/monitoring/library/Monitoring/Web/Rest/RestRequest.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules/monitoring/library/Monitoring/Web/Rest/RestRequest.php')
-rw-r--r--modules/monitoring/library/Monitoring/Web/Rest/RestRequest.php297
1 files changed, 297 insertions, 0 deletions
diff --git a/modules/monitoring/library/Monitoring/Web/Rest/RestRequest.php b/modules/monitoring/library/Monitoring/Web/Rest/RestRequest.php
new file mode 100644
index 0000000..fcbe0ca
--- /dev/null
+++ b/modules/monitoring/library/Monitoring/Web/Rest/RestRequest.php
@@ -0,0 +1,297 @@
+<?php
+/* Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */
+
+namespace Icinga\Module\Monitoring\Web\Rest;
+
+use Exception;
+use Icinga\Application\Logger;
+use Icinga\Util\Json;
+use Icinga\Module\Monitoring\Exception\CurlException;
+
+/**
+ * REST Request
+ */
+class RestRequest
+{
+ /**
+ * Request URI
+ *
+ * @var string
+ */
+ protected $uri;
+
+ /**
+ * Request method
+ *
+ * @var string
+ */
+ protected $method;
+
+ /**
+ * Request content type
+ *
+ * @var string
+ */
+ protected $contentType;
+
+ /**
+ * Whether to authenticate with basic auth
+ *
+ * @var bool
+ */
+ protected $hasBasicAuth;
+
+ /**
+ * Auth username
+ *
+ * @var string
+ */
+ protected $username;
+
+ /**
+ * Auth password
+ *
+ * @var string
+ */
+ protected $password;
+
+ /**
+ * Request payload
+ *
+ * @var mixed
+ */
+ protected $payload;
+
+ /**
+ * Whether strict SSL is enabled
+ *
+ * @var bool
+ */
+ protected $strictSsl = true;
+
+ /**
+ * Request timeout
+ *
+ * @var int
+ */
+ protected $timeout = 30;
+
+ /**
+ * Create a GET REST request
+ *
+ * @param string $uri
+ *
+ * @return static
+ */
+ public static function get($uri)
+ {
+ $request = new static;
+ $request->uri = $uri;
+ $request->method = 'GET';
+ return $request;
+ }
+
+ /**
+ * Create a POST REST request
+ *
+ * @param string $uri
+ *
+ * @return static
+ */
+ public static function post($uri)
+ {
+ $request = new static;
+ $request->uri = $uri;
+ $request->method = 'POST';
+ return $request;
+ }
+
+ /**
+ * Send content type JSON
+ *
+ * @return $this
+ */
+ public function sendJson()
+ {
+ $this->contentType = 'application/json';
+
+ return $this;
+ }
+
+ /**
+ * Set basic auth credentials
+ *
+ * @param string $username
+ * @param string $password
+ *
+ * @return $this
+ */
+ public function authenticateWith($username, $password)
+ {
+ $this->hasBasicAuth = true;
+ $this->username = $username;
+ $this->password = $password;
+
+ return $this;
+ }
+
+ /**
+ * Set request payload
+ *
+ * @param mixed $payload
+ *
+ * @return $this
+ */
+ public function setPayload($payload)
+ {
+ $this->payload = $payload;
+
+ return $this;
+ }
+
+ /**
+ * Disable strict SSL
+ *
+ * @return $this
+ */
+ public function noStrictSsl()
+ {
+ $this->strictSsl = false;
+
+ return $this;
+ }
+
+ /**
+ * Serialize payload according to content type
+ *
+ * @param mixed $payload
+ * @param string $contentType
+ *
+ * @return string
+ */
+ public function serializePayload($payload, $contentType)
+ {
+ switch ($contentType) {
+ case 'application/json':
+ $payload = Json::encode($payload);
+ break;
+ }
+
+ return $payload;
+ }
+
+ /**
+ * Send the request
+ *
+ * @return mixed
+ *
+ * @throws Exception
+ */
+ public function send()
+ {
+ $defaults = array(
+ 'host' => 'localhost',
+ 'path' => '/'
+ );
+
+ $url = array_merge($defaults, parse_url($this->uri));
+
+ if (isset($url['port'])) {
+ $url['host'] .= sprintf(':%u', $url['port']);
+ }
+
+ if (isset($url['query'])) {
+ $url['path'] .= sprintf('?%s', $url['query']);
+ }
+
+ $headers = array(
+ "{$this->method} {$url['path']} HTTP/1.1",
+ "Host: {$url['host']}",
+ "Content-Type: {$this->contentType}",
+ 'Accept: application/json',
+ // Bypass "Expect: 100-continue" timeouts
+ 'Expect:'
+ );
+
+ $options = array(
+ CURLOPT_URL => $this->uri,
+ CURLOPT_TIMEOUT => $this->timeout,
+ // Ignore proxy settings
+ CURLOPT_PROXY => '',
+ CURLOPT_CUSTOMREQUEST => $this->method
+ );
+
+ // Record cURL command line for debugging
+ $curlCmd = array('curl', '-s', '-X', $this->method, '-H', escapeshellarg('Accept: application/json'));
+
+ if ($this->strictSsl) {
+ $options[CURLOPT_SSL_VERIFYHOST] = 2;
+ $options[CURLOPT_SSL_VERIFYPEER] = true;
+ } else {
+ $options[CURLOPT_SSL_VERIFYHOST] = false;
+ $options[CURLOPT_SSL_VERIFYPEER] = false;
+ $curlCmd[] = '-k';
+ }
+
+ if ($this->hasBasicAuth) {
+ $options[CURLOPT_USERPWD] = sprintf('%s:%s', $this->username, $this->password);
+ $curlCmd[] = sprintf('-u %s:%s', escapeshellarg($this->username), escapeshellarg($this->password));
+ }
+
+ if (! empty($this->payload)) {
+ $payload = $this->serializePayload($this->payload, $this->contentType);
+ $options[CURLOPT_POSTFIELDS] = $payload;
+ $curlCmd[] = sprintf('-d %s', escapeshellarg($payload));
+ }
+
+ $options[CURLOPT_HTTPHEADER] = $headers;
+
+ $stream = null;
+ $logger = Logger::getInstance();
+ if ($logger !== null && $logger->getLevel() === Logger::DEBUG) {
+ $stream = fopen('php://temp', 'w');
+ $options[CURLOPT_VERBOSE] = true;
+ $options[CURLOPT_STDERR] = $stream;
+ }
+
+ Logger::debug(
+ 'Executing %s %s',
+ implode(' ', $curlCmd),
+ escapeshellarg($this->uri)
+ );
+
+ $result = $this->curlExec($options);
+
+ if (is_resource($stream)) {
+ rewind($stream);
+ Logger::debug(stream_get_contents($stream));
+ fclose($stream);
+ }
+
+ return Json::decode($result, true);
+ }
+
+ /**
+ * Set up a new cURL handle with the given options and call {@link curl_exec()}
+ *
+ * @param array $options
+ *
+ * @return string The response
+ *
+ * @throws CurlException
+ */
+ protected function curlExec(array $options)
+ {
+ $ch = curl_init();
+ $options[CURLOPT_RETURNTRANSFER] = true;
+ curl_setopt_array($ch, $options);
+ $result = curl_exec($ch);
+
+ if ($result === false) {
+ throw new CurlException('%s', curl_error($ch));
+ }
+
+ curl_close($ch);
+ return $result;
+ }
+}