ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
HTTP.php
Go to the documentation of this file.
1 <?php
2 namespace SimpleSAML\Utils;
3 
6 
12 class HTTP
13 {
14 
26  private static function getSecurePOSTRedirectURL($destination, $data)
27  {
29  $id = self::savePOSTData($session, $destination, $data);
30 
31  // get the session ID
32  $session_id = $session->getSessionId();
33  if (is_null($session_id)) {
34  // this is a transient session, it is pointless to continue
35  throw new \SimpleSAML_Error_Exception('Cannot save POST data to a transient session.');
36  }
37 
38  // encrypt the session ID and the random ID
39  $info = base64_encode(Crypto::aesEncrypt($session_id.':'.$id));
40 
41  $url = Module::getModuleURL('core/postredirect.php', array('RedirInfo' => $info));
42  return preg_replace('#^https:#', 'http:', $url);
43  }
44 
45 
54  private static function getServerHost()
55  {
56  if (array_key_exists('HTTP_HOST', $_SERVER)) {
57  $current = $_SERVER['HTTP_HOST'];
58  } elseif (array_key_exists('SERVER_NAME', $_SERVER)) {
59  $current = $_SERVER['SERVER_NAME'];
60  } else {
61  // almost certainly not what you want, but...
62  $current = 'localhost';
63  }
64 
65  if (strstr($current, ":")) {
66  $decomposed = explode(":", $current);
67  $port = array_pop($decomposed);
68  if (!is_numeric($port)) {
69  array_push($decomposed, $port);
70  }
71  $current = implode(":", $decomposed);
72  }
73  return $current;
74  }
75 
76 
84  public static function getServerHTTPS()
85  {
86  if (!array_key_exists('HTTPS', $_SERVER)) {
87  // not an https-request
88  return false;
89  }
90 
91  if ($_SERVER['HTTPS'] === 'off') {
92  // IIS with HTTPS off
93  return false;
94  }
95 
96  // otherwise, HTTPS will be non-empty
97  return !empty($_SERVER['HTTPS']);
98  }
99 
100 
109  public static function getServerPort()
110  {
111  $default_port = self::getServerHTTPS() ? '443' : '80';
112  $port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : $default_port;
113 
114  // Take care of edge-case where SERVER_PORT is an integer
115  $port = strval($port);
116 
117  if ($port !== $default_port) {
118  return ':'.$port;
119  }
120  return '';
121  }
122 
123 
147  private static function redirect($url, $parameters = array())
148  {
149  if (!is_string($url) || empty($url) || !is_array($parameters)) {
150  throw new \InvalidArgumentException('Invalid input parameters.');
151  }
152  if (!empty($parameters)) {
153  $url = self::addURLParameters($url, $parameters);
154  }
155 
156  /* Set the HTTP result code. This is either 303 See Other or
157  * 302 Found. HTTP 303 See Other is sent if the HTTP version
158  * is HTTP/1.1 and the request type was a POST request.
159  */
160  if ($_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1' &&
161  $_SERVER['REQUEST_METHOD'] === 'POST'
162  ) {
163  $code = 303;
164  } else {
165  $code = 302;
166  }
167 
168  if (strlen($url) > 2048) {
169  Logger::warning('Redirecting to a URL longer than 2048 bytes.');
170  }
171 
172  if (!headers_sent()) {
173  // set the location header
174  header('Location: '.$url, true, $code);
175 
176  // disable caching of this response
177  header('Pragma: no-cache');
178  header('Cache-Control: no-cache, no-store, must-revalidate');
179  }
180 
181  // show a minimal web page with a clickable link to the URL
182  echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";
183  echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"';
184  echo ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'."\n";
185  echo '<html xmlns="http://www.w3.org/1999/xhtml">'."\n";
186  echo " <head>\n";
187  echo ' <meta http-equiv="content-type" content="text/html; charset=utf-8">'."\n";
188  echo ' <meta http-equiv="refresh" content="0;URL=\''.htmlspecialchars($url).'\'">'."\n";
189  echo " <title>Redirect</title>\n";
190  echo " </head>\n";
191  echo " <body>\n";
192  echo " <h1>Redirect</h1>\n";
193  echo ' <p>You were redirected to: <a id="redirlink" href="'.htmlspecialchars($url).'">';
194  echo htmlspecialchars($url)."</a>\n";
195  echo ' <script type="text/javascript">document.getElementById("redirlink").focus();</script>'."\n";
196  echo " </p>\n";
197  echo " </body>\n";
198  echo '</html>';
199 
200  // end script execution
201  exit;
202  }
203 
204 
217  private static function savePOSTData(\SimpleSAML_Session $session, $destination, $data)
218  {
219  // generate a random ID to avoid replay attacks
220  $id = Random::generateID();
221  $postData = array(
222  'post' => $data,
223  'url' => $destination,
224  );
225 
226  // save the post data to the session, tied to the random ID
227  $session->setData('core_postdatalink', $id, $postData);
228 
229  return $id;
230  }
231 
232 
246  public static function addURLParameters($url, $parameters)
247  {
248  if (!is_string($url) || !is_array($parameters)) {
249  throw new \InvalidArgumentException('Invalid input parameters.');
250  }
251 
252  $queryStart = strpos($url, '?');
253  if ($queryStart === false) {
254  $oldQuery = array();
255  $url .= '?';
256  } else {
258  $oldQuery = substr($url, $queryStart + 1);
259  if ($oldQuery === false) {
260  $oldQuery = array();
261  } else {
262  $oldQuery = self::parseQueryString($oldQuery);
263  }
264  $url = substr($url, 0, $queryStart + 1);
265  }
266 
268  $query = array_merge($oldQuery, $parameters);
269  $url .= http_build_query($query, '', '&');
270 
271  return $url;
272  }
273 
274 
286  public static function checkSessionCookie($retryURL = null)
287  {
288  if (!is_null($retryURL) && !is_string($retryURL)) {
289  throw new \InvalidArgumentException('Invalid input parameters.');
290  }
291 
292  $session = \SimpleSAML_Session::getSessionFromRequest();
293  if ($session->hasSessionCookie()) {
294  return;
295  }
296 
297  // we didn't have a session cookie. Redirect to the no-cookie page
298 
299  $url = Module::getModuleURL('core/no_cookie.php');
300  if ($retryURL !== null) {
301  $url = self::addURLParameters($url, array('retryURL' => $retryURL));
302  }
303  self::redirectTrustedURL($url);
304  }
305 
306 
321  public static function checkURLAllowed($url, array $trustedSites = null)
322  {
323  if (empty($url)) {
324  return '';
325  }
326  $url = self::normalizeURL($url);
327 
328  if (filter_var($url, FILTER_VALIDATE_URL) === false) {
329  throw new \SimpleSAML_Error_Exception('Invalid URL: '.$url);
330  }
331 
332  // get the white list of domains
333  if ($trustedSites === null) {
334  $trustedSites = \SimpleSAML_Configuration::getInstance()->getValue('trusted.url.domains', array());
335  }
336 
337  // validates the URL's host is among those allowed
338  if (is_array($trustedSites)) {
339  assert(is_array($trustedSites));
340  $components = parse_url($url);
341  $hostname = $components['host'];
342 
343  // check for userinfo
344  if ((isset($components['user']) && strpos($components['user'], '\\') !== false) ||
345  (isset($components['pass']) && strpos($components['pass'], '\\') !== false)
346  ) {
347  throw new \SimpleSAML_Error_Exception('Invalid URL: '.$url);
348  }
349 
350  // allow URLs with standard ports specified (non-standard ports must then be allowed explicitly)
351  if (isset($components['port']) &&
352  (($components['scheme'] === 'http' && $components['port'] !== 80) ||
353  ($components['scheme'] === 'https' && $components['port'] !== 443))
354  ) {
355  $hostname = $hostname.':'.$components['port'];
356  }
357 
358  $self_host = self::getSelfHostWithNonStandardPort();
359 
360  $trustedRegex = \SimpleSAML_Configuration::getInstance()->getValue('trusted.url.regex', false);
361 
362  $trusted = false;
363  if ($trustedRegex) {
364  // add self host to the white list
365  $trustedSites[] = preg_quote($self_host);
366  foreach ($trustedSites as $regex) {
367  // Add start and end delimiters.
368  $regex = "@^{$regex}$@";
369  if (preg_match($regex, $hostname)) {
370  $trusted = true;
371  break;
372  }
373  }
374  } else {
375  // add self host to the white list
376  $trustedSites[] = $self_host;
377  $trusted = in_array($hostname, $trustedSites, true);
378  }
379 
380  // throw exception due to redirection to untrusted site
381  if (!$trusted) {
382  throw new \SimpleSAML_Error_Exception('URL not allowed: '.$url);
383  }
384  }
385  return $url;
386  }
387 
388 
408  public static function fetch($url, $context = array(), $getHeaders = false)
409  {
410  if (!is_string($url)) {
411  throw new \InvalidArgumentException('Invalid input parameters.');
412  }
413 
414  $config = \SimpleSAML_Configuration::getInstance();
415 
416  $proxy = $config->getString('proxy', null);
417  if ($proxy !== null) {
418  if (!isset($context['http']['proxy'])) {
419  $context['http']['proxy'] = $proxy;
420  }
421  $proxy_auth = $config->getString('proxy.auth', false);
422  if ($proxy_auth !== false) {
423  $context['http']['header'] = "Proxy-Authorization: Basic ".base64_encode($proxy_auth);
424  }
425  if (!isset($context['http']['request_fulluri'])) {
426  $context['http']['request_fulluri'] = true;
427  }
428  /*
429  * If the remote endpoint over HTTPS uses the SNI extension (Server Name Indication RFC 4366), the proxy
430  * could introduce a mismatch between the names in the Host: HTTP header and the SNI_server_name in TLS
431  * negotiation (thanks to Cristiano Valli @ GARR-IDEM to have pointed this problem).
432  * See: https://bugs.php.net/bug.php?id=63519
433  * These controls will force the same value for both fields.
434  * Marco Ferrante (marco@csita.unige.it), Nov 2012
435  */
436  if (preg_match('#^https#i', $url)
437  && defined('OPENSSL_TLSEXT_SERVER_NAME')
438  && OPENSSL_TLSEXT_SERVER_NAME
439  ) {
440  // extract the hostname
441  $hostname = parse_url($url, PHP_URL_HOST);
442  if (!empty($hostname)) {
443  $context['ssl'] = array(
444  'SNI_server_name' => $hostname,
445  'SNI_enabled' => true,
446  );
447  } else {
448  Logger::warning('Invalid URL format or local URL used through a proxy');
449  }
450  }
451  }
452 
453  $context = stream_context_create($context);
454  $data = @file_get_contents($url, false, $context);
455  if ($data === false) {
456  $error = error_get_last();
457  throw new \SimpleSAML_Error_Exception('Error fetching '.var_export($url, true).':'.
458  (is_array($error) ? $error['message'] : 'no error available'));
459  }
460 
461  // data and headers
462  if ($getHeaders) {
463  if (isset($http_response_header)) {
464  $headers = array();
465  foreach ($http_response_header as $h) {
466  if (preg_match('@^HTTP/1\.[01]\s+\d{3}\s+@', $h)) {
467  $headers = array(); // reset
468  $headers[0] = $h;
469  continue;
470  }
471  $bits = explode(':', $h, 2);
472  if (count($bits) === 2) {
473  $headers[strtolower($bits[0])] = trim($bits[1]);
474  }
475  }
476  } else {
477  // no HTTP headers, probably a different protocol, e.g. file
478  $headers = null;
479  }
480  return array($data, $headers);
481  }
482 
483  return $data;
484  }
485 
486 
498  public static function getAcceptLanguage()
499  {
500  if (!array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
501  // no Accept-Language header, return an empty set
502  return array();
503  }
504 
505  $languages = explode(',', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']));
506 
507  $ret = array();
508 
509  foreach ($languages as $l) {
510  $opts = explode(';', $l);
511 
512  $l = trim(array_shift($opts)); // the language is the first element
513 
514  $q = 1.0;
515 
516  // iterate over all options, and check for the quality option
517  foreach ($opts as $o) {
518  $o = explode('=', $o);
519  if (count($o) < 2) {
520  // skip option with no value
521  continue;
522  }
523 
524  $name = trim($o[0]);
525  $value = trim($o[1]);
526 
527  if ($name === 'q') {
528  $q = (float) $value;
529  }
530  }
531 
532  // remove the old key to ensure that the element is added to the end
533  unset($ret[$l]);
534 
535  // set the quality in the result
536  $ret[$l] = $q;
537 
538  if (strpos($l, '-')) {
539  // the language includes a region part
540 
541  // extract the language without the region
542  $l = explode('-', $l);
543  $l = $l[0];
544 
545  // add this language to the result (unless it is defined already)
546  if (!array_key_exists($l, $ret)) {
547  $ret[$l] = $q;
548  }
549  }
550  }
551  return $ret;
552  }
553 
554 
562  public static function guessBasePath()
563  {
564  if (!array_key_exists('REQUEST_URI', $_SERVER) || !array_key_exists('SCRIPT_FILENAME', $_SERVER)) {
565  return '/';
566  }
567  // get the name of the current script
568  $path = explode('/', $_SERVER['SCRIPT_FILENAME']);
569  $script = array_pop($path);
570 
571  // get the portion of the URI up to the script, i.e.: /simplesaml/some/directory/script.php
572  if (!preg_match('#^/(?:[^/]+/)*'.$script.'#', $_SERVER['REQUEST_URI'], $matches)) {
573  return '/';
574  }
575  $uri_s = explode('/', $matches[0]);
576  $file_s = explode('/', $_SERVER['SCRIPT_FILENAME']);
577 
578  // compare both arrays from the end, popping elements matching out of them
579  while ($uri_s[count($uri_s) - 1] === $file_s[count($file_s) - 1]) {
580  array_pop($uri_s);
581  array_pop($file_s);
582  }
583  // we are now left with the minimum part of the URI that does not match anything in the file system, use it
584  return join('/', $uri_s).'/';
585  }
586 
587 
597  public static function getBaseURL()
598  {
599  $globalConfig = \SimpleSAML_Configuration::getInstance();
600  $baseURL = $globalConfig->getString('baseurlpath', 'simplesaml/');
601 
602  if (preg_match('#^https?://.*/?$#D', $baseURL, $matches)) {
603  // full URL in baseurlpath, override local server values
604  return rtrim($baseURL, '/').'/';
605  } elseif ((preg_match('#^/?([^/]?.*/)$#D', $baseURL, $matches)) ||
606  (preg_match('#^\*(.*)/$#D', $baseURL, $matches)) ||
607  ($baseURL === '')
608  ) {
609  // get server values
610  $protocol = 'http';
611  $protocol .= (self::getServerHTTPS()) ? 's' : '';
612  $protocol .= '://';
613 
614  $hostname = self::getServerHost();
615  $port = self::getServerPort();
616  $path = $globalConfig->getBasePath();
617 
618  return $protocol.$hostname.$port.$path;
619  } else {
620  /*
621  * Invalid 'baseurlpath'. We cannot recover from this, so throw a critical exception and try to be graceful
622  * with the configuration. Use a guessed base path instead of the one provided.
623  */
624  $c = $globalConfig->toArray();
625  $c['baseurlpath'] = self::guessBasePath();
626  throw new \SimpleSAML\Error\CriticalConfigurationError(
627  'Invalid value for \'baseurlpath\' in config.php. Valid format is in the form: '.
628  '[(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/]. It must end with a \'/\'.',
629  null,
630  $c
631  );
632  }
633  }
634 
635 
645  public static function getFirstPathElement($trailingslash = true)
646  {
647  if (preg_match('|^/(.*?)/|', $_SERVER['SCRIPT_NAME'], $matches)) {
648  return ($trailingslash ? '/' : '').$matches[1];
649  }
650  return '';
651  }
652 
653 
666  public static function getPOSTRedirectURL($destination, $data)
667  {
668  if (!is_string($destination) || !is_array($data)) {
669  throw new \InvalidArgumentException('Invalid input parameters.');
670  }
671 
672  $config = \SimpleSAML_Configuration::getInstance();
673  $allowed = $config->getBoolean('enable.http_post', false);
674 
675  if ($allowed && preg_match("#^http:#", $destination) && self::isHTTPS()) {
676  // we need to post the data to HTTP
677  $url = self::getSecurePOSTRedirectURL($destination, $data);
678  } else { // post the data directly
679  $session = \SimpleSAML_Session::getSessionFromRequest();
680  $id = self::savePOSTData($session, $destination, $data);
681  $url = Module::getModuleURL('core/postredirect.php', array('RedirId' => $id));
682  }
683 
684  return $url;
685  }
686 
687 
697  public static function getSelfHost()
698  {
699  $decomposed = explode(':', self::getSelfHostWithNonStandardPort());
700  return array_shift($decomposed);
701  }
702 
715  public static function getSelfHostWithNonStandardPort()
716  {
717  $url = self::getBaseURL();
718 
720  $colon = strpos($url, '://');
721  $start = $colon + 3;
722  $length = strcspn($url, '/', $start);
723 
724  return substr($url, $start, $length);
725  }
726 
736  public static function getSelfHostWithPath()
737  {
738  $baseurl = explode("/", self::getBaseURL());
739  $elements = array_slice($baseurl, 3 - count($baseurl), count($baseurl) - 4);
740  $path = implode("/", $elements);
741  return self::getSelfHostWithNonStandardPort()."/".$path;
742  }
743 
744 
760  public static function getSelfURL()
761  {
762  $cfg = \SimpleSAML_Configuration::getInstance();
763  $baseDir = $cfg->getBaseDir();
764  $cur_path = realpath($_SERVER['SCRIPT_FILENAME']);
765  // make sure we got a string from realpath()
766  $cur_path = is_string($cur_path) ? $cur_path : '';
767  // find the path to the current script relative to the www/ directory of SimpleSAMLphp
768  $rel_path = str_replace($baseDir.'www'.DIRECTORY_SEPARATOR, '', $cur_path);
769  // convert that relative path to an HTTP query
770  $url_path = str_replace(DIRECTORY_SEPARATOR, '/', $rel_path);
771  // find where the relative path starts in the current request URI
772  $uri_pos = (!empty($url_path)) ? strpos($_SERVER['REQUEST_URI'], $url_path) : false;
773 
774  if ($cur_path == $rel_path || $uri_pos === false) {
775  /*
776  * We were accessed from an external script. This can happen in the following cases:
777  *
778  * - $_SERVER['SCRIPT_FILENAME'] points to a script that doesn't exist. E.g. functional testing. In this
779  * case, realpath() returns false and str_replace an empty string, so we compare them loosely.
780  *
781  * - The URI requested does not belong to a script in the www/ directory of SimpleSAMLphp. In that case,
782  * removing SimpleSAMLphp's base dir from the current path yields the same path, so $cur_path and
783  * $rel_path are equal.
784  *
785  * - The request URI does not match the current script. Even if the current script is located in the www/
786  * directory of SimpleSAMLphp, the URI does not contain its relative path, and $uri_pos is false.
787  *
788  * It doesn't matter which one of those cases we have. We just know we can't apply our base URL to the
789  * current URI, so we need to build it back from the PHP environment, unless we have a base URL specified
790  * for this case in the configuration. First, check if that's the case.
791  */
792 
794  $appcfg = $cfg->getConfigItem('application', null);
795  $appurl = ($appcfg instanceof \SimpleSAML_Configuration) ? $appcfg->getString('baseURL', '') : '';
796  if (!empty($appurl)) {
797  $protocol = parse_url($appurl, PHP_URL_SCHEME);
798  $hostname = parse_url($appurl, PHP_URL_HOST);
799  $port = parse_url($appurl, PHP_URL_PORT);
800  $port = !empty($port) ? ':'.$port : '';
801  } else { // no base URL specified for app, just use the current URL
802  $protocol = 'http';
803  $protocol .= (self::getServerHTTPS()) ? 's' : '';
804  $hostname = self::getServerHost();
805  $port = self::getServerPort();
806  }
807  return $protocol.'://'.$hostname.$port.$_SERVER['REQUEST_URI'];
808  }
809 
810  return self::getBaseURL().$url_path.substr($_SERVER['REQUEST_URI'], $uri_pos + strlen($url_path));
811  }
812 
813 
823  public static function getSelfURLHost()
824  {
825  $url = self::getSelfURL();
826 
828  $colon = strpos($url, '://');
829  $start = $colon + 3;
830  $length = strcspn($url, '/', $start) + $start;
831  return substr($url, 0, $length);
832  }
833 
834 
843  public static function getSelfURLNoQuery()
844  {
845  $url = self::getSelfURL();
846  $pos = strpos($url, '?');
847  if (!$pos) {
848  return $url;
849  }
850  return substr($url, 0, $pos);
851  }
852 
853 
862  public static function isHTTPS()
863  {
864  return strpos(self::getSelfURL(), 'https://') === 0;
865  }
866 
867 
880  public static function normalizeURL($url)
881  {
882  if (!is_string($url)) {
883  throw new \InvalidArgumentException('Invalid input parameters.');
884  }
885 
886  $url = self::resolveURL($url, self::getSelfURL());
887 
888  // verify that the URL is to a http or https site
889  if (!preg_match('@^https?://@i', $url)) {
890  throw new \InvalidArgumentException('Invalid URL: '.$url);
891  }
892 
893  return $url;
894  }
895 
896 
912  public static function parseQueryString($query_string)
913  {
914  if (!is_string($query_string)) {
915  throw new \InvalidArgumentException('Invalid input parameters.');
916  }
917 
918  $res = array();
919  if (empty($query_string)) {
920  return $res;
921  }
922 
923  foreach (explode('&', $query_string) as $param) {
924  $param = explode('=', $param);
925  $name = urldecode($param[0]);
926  if (count($param) === 1) {
927  $value = '';
928  } else {
929  $value = urldecode($param[1]);
930  }
931  $res[$name] = $value;
932  }
933  return $res;
934  }
935 
936 
959  public static function redirectTrustedURL($url, $parameters = array())
960  {
961  if (!is_string($url) || !is_array($parameters)) {
962  throw new \InvalidArgumentException('Invalid input parameters.');
963  }
964 
965  $url = self::normalizeURL($url);
966  self::redirect($url, $parameters);
967  }
968 
969 
991  public static function redirectUntrustedURL($url, $parameters = array())
992  {
993  if (!is_string($url) || !is_array($parameters)) {
994  throw new \InvalidArgumentException('Invalid input parameters.');
995  }
996 
997  $url = self::checkURLAllowed($url);
998  self::redirect($url, $parameters);
999  }
1000 
1001 
1023  public static function resolveURL($url, $base = null)
1024  {
1025  if ($base === null) {
1026  $base = self::getBaseURL();
1027  }
1028 
1029  if (!is_string($url) || !is_string($base)) {
1030  throw new \InvalidArgumentException('Invalid input parameters.');
1031  }
1032 
1033  if (!preg_match('/^((((\w+:)\/\/[^\/]+)(\/[^?#]*))(?:\?[^#]*)?)(?:#.*)?/', $base, $baseParsed)) {
1034  throw new \InvalidArgumentException('Unable to parse base url: '.$base);
1035  }
1036 
1037  $baseDir = dirname($baseParsed[5].'filename');
1038  $baseScheme = $baseParsed[4];
1039  $baseHost = $baseParsed[3];
1040  $basePath = $baseParsed[2];
1041  $baseQuery = $baseParsed[1];
1042 
1043  if (preg_match('$^\w+:$', $url)) {
1044  return $url;
1045  }
1046 
1047  if (substr($url, 0, 2) === '//') {
1048  return $baseScheme.$url;
1049  }
1050 
1051  if ($url[0] === '/') {
1052  return $baseHost.$url;
1053  }
1054  if ($url[0] === '?') {
1055  return $basePath.$url;
1056  }
1057  if ($url[0] === '#') {
1058  return $baseQuery.$url;
1059  }
1060 
1061  // we have a relative path. Remove query string/fragment and save it as $tail
1062  $queryPos = strpos($url, '?');
1063  $fragmentPos = strpos($url, '#');
1064  if ($queryPos !== false || $fragmentPos !== false) {
1065  if ($queryPos === false) {
1066  $tailPos = $fragmentPos;
1067  } elseif ($fragmentPos === false) {
1068  $tailPos = $queryPos;
1069  } elseif ($queryPos < $fragmentPos) {
1070  $tailPos = $queryPos;
1071  } else {
1072  $tailPos = $fragmentPos;
1073  }
1074 
1075  $tail = substr($url, $tailPos);
1076  $dir = substr($url, 0, $tailPos);
1077  } else {
1078  $dir = $url;
1079  $tail = '';
1080  }
1081 
1082  $dir = System::resolvePath($dir, $baseDir);
1083 
1084  return $baseHost.$dir.$tail;
1085  }
1086 
1087 
1104  public static function setCookie($name, $value, $params = null, $throw = true)
1105  {
1106  if (!(is_string($name) && // $name must be a string
1107  (is_string($value) || is_null($value)) && // $value can be a string or null
1108  (is_array($params) || is_null($params)) && // $params can be an array or null
1109  is_bool($throw)) // $throw must be boolean
1110  ) {
1111  throw new \InvalidArgumentException('Invalid input parameters.');
1112  }
1113 
1114  $default_params = array(
1115  'lifetime' => 0,
1116  'expire' => null,
1117  'path' => '/',
1118  'domain' => null,
1119  'secure' => false,
1120  'httponly' => true,
1121  'raw' => false,
1122  );
1123 
1124  if ($params !== null) {
1125  $params = array_merge($default_params, $params);
1126  } else {
1127  $params = $default_params;
1128  }
1129 
1130  // Do not set secure cookie if not on HTTPS
1131  if ($params['secure'] && !self::isHTTPS()) {
1132  if ($throw) {
1133  throw new \SimpleSAML\Error\CannotSetCookie(
1134  'Setting secure cookie on plain HTTP is not allowed.',
1135  \SimpleSAML\Error\CannotSetCookie::SECURE_COOKIE
1136  );
1137  }
1138  Logger::warning('Error setting cookie: setting secure cookie on plain HTTP is not allowed.');
1139  return;
1140  }
1141 
1142  if ($value === null) {
1143  $expire = time() - 365 * 24 * 60 * 60;
1144  } elseif (isset($params['expire'])) {
1145  $expire = $params['expire'];
1146  } elseif ($params['lifetime'] === 0) {
1147  $expire = 0;
1148  } else {
1149  $expire = time() + $params['lifetime'];
1150  }
1151 
1152  if ($params['raw']) {
1153  $success = @setrawcookie(
1154  $name,
1155  $value,
1156  $expire,
1157  $params['path'],
1158  $params['domain'],
1159  $params['secure'],
1160  $params['httponly']
1161  );
1162  } else {
1163  $success = @setcookie(
1164  $name,
1165  $value,
1166  $expire,
1167  $params['path'],
1168  $params['domain'],
1169  $params['secure'],
1170  $params['httponly']
1171  );
1172  }
1173 
1174  if (!$success) {
1175  if ($throw) {
1176  throw new \SimpleSAML\Error\CannotSetCookie(
1177  'Headers already sent.',
1178  \SimpleSAML\Error\CannotSetCookie::HEADERS_SENT
1179  );
1180  }
1181  Logger::warning('Error setting cookie: headers already sent.');
1182  }
1183  }
1184 
1185 
1202  public static function submitPOSTData($destination, $data)
1203  {
1204  if (!is_string($destination) || !is_array($data)) {
1205  throw new \InvalidArgumentException('Invalid input parameters.');
1206  }
1207 
1208  $config = \SimpleSAML_Configuration::getInstance();
1209  $allowed = $config->getBoolean('enable.http_post', false);
1210 
1211  if ($allowed && preg_match("#^http:#", $destination) && self::isHTTPS()) {
1212  // we need to post the data to HTTP
1213  self::redirect(self::getSecurePOSTRedirectURL($destination, $data));
1214  }
1215 
1216  $p = new \SimpleSAML_XHTML_Template($config, 'post.php');
1217  $p->data['destination'] = $destination;
1218  $p->data['post'] = $data;
1219  $p->show();
1220  exit(0);
1221  }
1222 }
static redirect($url, $parameters=array())
This function redirects the user to the specified address.
Definition: HTTP.php:147
static getServerHost()
Retrieve Host value from $_SERVER environment variables.
Definition: HTTP.php:54
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
static getServerHTTPS()
Retrieve HTTPS status from $_SERVER environment variables.
Definition: HTTP.php:84
static aesEncrypt($data)
Encrypt data using AES-256-CBC and the system-wide secret salt as key.
Definition: Crypto.php:146
$code
Definition: example_050.php:99
$session
$destination
if(!array_key_exists('StateId', $_REQUEST)) $id
if(! $in) print Initializing normalization quick check tables n
static getModuleURL($resource, array $parameters=array())
Get absolute URL to a specified module resource.
Definition: Module.php:220
static http()
Fetches the global http state from ILIAS.
static warning($string)
Definition: Logger.php:177
static getServerPort()
Retrieve the port number from $_SERVER environment variables.
Definition: HTTP.php:109
static getSecurePOSTRedirectURL($destination, $data)
Obtain a URL where we can redirect to securely post a form with the given data to a specific destinat...
Definition: HTTP.php:26
$url
$info
Definition: index.php:5
static getSessionFromRequest()
Retrieves the current session.
Definition: Session.php:241
$data
Definition: bench.php:6