ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
HTTP.php
Go to the documentation of this file.
1<?php
2namespace SimpleSAML\Utils;
3
6
12class HTTP
13{
14
27 {
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}
An exception for terminatinating execution or to throw for unit testing.
static warning($string)
Definition: Logger.php:177
static getModuleURL($resource, array $parameters=array())
Get absolute URL to a specified module resource.
Definition: Module.php:220
static aesEncrypt($data)
Encrypt data using AES-256-CBC and the system-wide secret salt as key.
Definition: Crypto.php:146
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
static getServerPort()
Retrieve the port number from $_SERVER environment variables.
Definition: HTTP.php:109
static getServerHTTPS()
Retrieve HTTPS status from $_SERVER environment variables.
Definition: HTTP.php:84
static getServerHost()
Retrieve Host value from $_SERVER environment variables.
Definition: HTTP.php:54
static savePOSTData(\SimpleSAML_Session $session, $destination, $data)
Save the given HTTP POST data and the destination where it should be posted to a given session.
Definition: HTTP.php:217
static redirect($url, $parameters=array())
This function redirects the user to the specified address.
Definition: HTTP.php:147
static getSessionFromRequest()
Retrieves the current session.
Definition: Session.php:241
$code
Definition: example_050.php:99
if(!array_key_exists('StateId', $_REQUEST)) $id
$destination
$info
Definition: index.php:5
static http()
Fetches the global http state from ILIAS.
$session
$url
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
$data
Definition: bench.php:6