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