diff Http.inc.php @ 134:b6b4a58c7625

Using .inc.php rather than just .inc for include files.
author Tom Fredrik Blenning <bfg@bfgconsult.no>
date Sun, 22 Jan 2023 19:22:00 +0100
parents Http.inc@51b53cd01080
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Http.inc.php	Sun Jan 22 19:22:00 2023 +0100
@@ -0,0 +1,173 @@
+<?php
+include_once 'ScriptIncludeCache.inc.php';
+
+/// @cond
+$baseDir = dirname(__FILE__);
+$cache = ScriptIncludeCache::instance(__FILE__);
+/// @endcond
+
+/**
+ * Thrown if a request has gone bad
+ */
+class RequestException extends RuntimeException
+{
+  private $_info;
+
+  /**
+   * Constructs a RequestException
+   *
+   * @param $info an info array as defined in http_get, if a key with
+   * name error exist, this will be the error text for the
+   * RuntimeException
+   */
+  function __construct($info)
+  {
+    $this->_info = $info;
+    if (array_key_exists('error', $info)) {
+      parent::__construct($info['error']);
+    }
+  }
+
+  /**
+   * Get the info object associated with this RequestException
+   *
+   * @return $info an info array as defined in http_get
+   */
+  function info()
+  {
+    return $this->_info;
+  }
+}
+
+/**
+ * Http contains a set of functions for retrieving http information
+ */
+class Http
+{
+  /**
+   * Gets the content of a page
+   *
+   * This mimics the file_content with a uri parameter which is often
+   * disabled due to security reasons
+   *
+   * @param $uri The uri to fetch
+   */
+  static function get_uri_contents($uri)
+  {
+    $crl = curl_init();
+    $timeout = 5;
+
+    curl_setopt ($crl, CURLOPT_URL, $uri);
+    curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);
+    curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);
+    $ret = curl_exec($crl);
+    curl_close($crl);
+    return $ret;
+  }
+
+  /**
+   * Splits an http header response into an associative array
+   *
+   * @param $response The headers to parse
+   * @return an Associative array, the key '' refers to the HTTP status header
+   */
+  static function headersToArray($response)
+  {
+    $headers = array();
+    $response = trim($response);
+    $str = explode("\n", $response);
+    $headers[''] = trim($str[0]);
+    foreach($str as $kv) {
+      $p = strpos($kv, ":");
+      if ($p) {
+	$key = substr($kv, 0, $p);
+	$value = trim(substr($kv, $p + 1));
+	$headers[$key] = $value;
+      }
+    }
+    return $headers;
+  }
+
+  /**
+   * Queries a URL for headers
+   *
+   * @param $url the url to query
+   * @param $timeout float number of seconds to wait before timeout
+   * @return an associative array of all headers returned
+   */
+  static function getHeaders($url, $timeout = 1)
+  {
+    //Workaround when getHeaders doesn't work
+    if (false) {
+      $response = http_head($url, array("timeout" => $timeout), $info);
+      if (array_key_exists('error', $info) && $info['error']) {
+	throw new RequestException($info);
+      }
+      return self::headersToArray($response);
+    }
+    elseif (true) {
+      $rp = get_headers($url);
+      $response=array('' =>  array_shift ($rp));
+      foreach($rp as $kv) {
+	if (!str_contains($kv, ':')) {
+	  if (!preg_match("/^HTTP\/\S+\s(\d+)/", $response[''], $re)) {
+	    throw new Exception('Uninteligble header');
+	  }
+	  //FIXME: We should do something with this,
+	  //but now we just assume we have a redirect
+	  $retCode=intval($re[1]);
+	  $response=array('' =>  $kv);
+	}
+	else {
+	  $tmp=array_map('trim', explode(':', $kv, 2));
+	  $response[$tmp[0]]=$tmp[1];
+	}
+      }
+      return $response;
+    }
+    else {
+      return array('' => 'HTTP/1.1 200 OK');
+    }
+
+  }
+
+  /**
+   * Performs a post to an URI for headers
+   *
+   * @param $uri the uri to query
+   * @param $params an associative array of params to post
+   * @param $timeout float number of seconds to wait before timeout
+   * @return an associative array of all headers returned
+   */
+  static function postHeaders($uri, $params, $timeout = 1)
+  {
+    $crl = curl_init();
+
+    $descriptorspec = array(
+			    0 => array("pipe", "r"),
+			    1 => array("pipe", "w"),
+			    //2 => array("file", "/tmp/error-output.txt", "a")
+			    );
+
+    //We use tac, since it buffers, and we don't care about the output
+    //being reordered.
+    $process = proc_open('tac | tac', $descriptorspec, $pipes);
+
+    curl_setopt ($crl, CURLOPT_URL, $uri);
+    curl_setopt ($crl, CURLOPT_WRITEHEADER, $pipes[0]);
+    curl_setopt ($crl, CURLOPT_NOBODY, true);
+    curl_setopt ($crl, CURLOPT_POST, true);
+    curl_setopt ($crl, CURLOPT_POSTFIELDS, $params);
+
+    curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);
+    curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);
+    $ret = curl_exec($crl);
+    curl_close($crl);
+
+    fclose($pipes[0]);
+    $buf = fread($pipes[1], 8192);
+
+    return self::headersToArray($buf);
+  }
+}
+?>
\ No newline at end of file