@@ -785,12 +785,19 @@ public function getSelfURL(): string
785785 $ cur_path = realpath ($ _SERVER ['SCRIPT_FILENAME ' ]);
786786 // make sure we got a string from realpath()
787787 $ cur_path = is_string ($ cur_path ) ? $ cur_path : '' ;
788+
788789 // find the path to the current script relative to the public/ directory of SimpleSAMLphp
789790 $ rel_path = str_replace ($ baseDir . 'public ' . DIRECTORY_SEPARATOR , '' , $ cur_path );
790- // convert that relative path to an HTTP query
791+
791792 $ url_path = str_replace (DIRECTORY_SEPARATOR , '/ ' , $ rel_path );
792- // find where the relative path starts in the current request URI
793- $ uri_pos = (!empty ($ url_path )) ? strpos ($ _SERVER ['REQUEST_URI ' ] ?? '' , $ url_path ) : false ;
793+
794+ $ requestUri = (string )($ _SERVER ['REQUEST_URI ' ] ?? '' );
795+ $ requestPath = (string )parse_url ($ requestUri , PHP_URL_PATH );
796+ $ requestQuery = (string )parse_url ($ requestUri , PHP_URL_QUERY );
797+ $ requestFragment = (string )parse_url ($ requestUri , PHP_URL_FRAGMENT );
798+
799+ // Match script-relative path only against the path part of the request
800+ $ uri_pos = (!empty ($ url_path )) ? strpos ($ requestPath , $ url_path ) : false ;
794801
795802 if ($ cur_path == $ rel_path || $ uri_pos === false ) {
796803 /*
@@ -799,12 +806,13 @@ public function getSelfURL(): string
799806 * - $_SERVER['SCRIPT_FILENAME'] points to a script that doesn't exist. E.g. functional testing. In this
800807 * case, realpath() returns false and str_replace an empty string, so we compare them loosely.
801808 *
802- * - The URI requested does not belong to a script in the public/ directory of SimpleSAMLphp. In that case,
803- * removing SimpleSAMLphp's base dir from the current path yields the same path, so $cur_path and
809+ * - The script is not located under the public/ directory of SimpleSAMLphp. In that case, removing
810+ * SimpleSAMLphp's base dir and public/ from the current path yields the same path, so $cur_path and
804811 * $rel_path are equal.
805812 *
806- * - The request URI does not match the current script. Even if the current script is located in the
807- * public/ directory of SimpleSAMLphp, the URI does not contain its relative path, and $uri_pos is false.
813+ * - The request path does not match the current script. Even if the current script is located in the
814+ * public/ directory of SimpleSAMLphp, the request path (without query string) does not contain its
815+ * relative path, and $uri_pos is false.
808816 *
809817 * It doesn't matter which one of those cases we have. We just know we can't apply our base URL to the
810818 * current URI, so we need to build it back from the PHP environment, unless we have a base URL specified
@@ -814,20 +822,33 @@ public function getSelfURL(): string
814822 $ appurl = ($ appcfg !== null ) ? $ appcfg ->getOptionalString ('baseURL ' , null ) : null ;
815823
816824 if (!empty ($ appurl )) {
817- $ protocol = parse_url ($ appurl , PHP_URL_SCHEME );
818- $ hostname = parse_url ($ appurl , PHP_URL_HOST );
819- $ port = parse_url ($ appurl , PHP_URL_PORT );
820- $ port = !empty ($ port ) ? ': ' . $ port : '' ;
825+ $ protocol = ( string ) parse_url ($ appurl , PHP_URL_SCHEME );
826+ $ hostname = ( string ) parse_url ($ appurl , PHP_URL_HOST );
827+ $ portNum = parse_url ($ appurl , PHP_URL_PORT );
828+ $ port = !empty ($ portNum ) ? ': ' . $ portNum : '' ;
821829 } else {
822830 // no base URL specified for app, just use the current URL
823831 $ protocol = $ this ->getServerHTTPS () ? 'https ' : 'http ' ;
824832 $ hostname = $ this ->getServerHost ();
825833 $ port = $ this ->getServerPort ();
826834 }
835+
827836 return $ protocol . ':// ' . $ hostname . $ port . $ _SERVER ['REQUEST_URI ' ];
828837 }
829838
830- return $ this ->getBaseURL () . $ url_path . substr ($ _SERVER ['REQUEST_URI ' ], $ uri_pos + strlen ($ url_path ));
839+ // Normal case: baseURL + script-relative path + remaining path, plus query if present
840+ $ suffix = substr ($ requestPath , $ uri_pos + strlen ($ url_path ));
841+ $ url = $ this ->getBaseURL () . $ url_path . $ suffix ;
842+
843+ if ($ requestQuery !== '' ) {
844+ $ url .= '? ' . $ requestQuery ;
845+ }
846+
847+ if ($ requestFragment !== '' ) {
848+ $ url .= '# ' . $ requestFragment ;
849+ }
850+
851+ return $ url ;
831852 }
832853
833854
0 commit comments