@@ -62,6 +62,16 @@ class IncomingRequest extends Request
62
62
*/
63
63
public $ uri ;
64
64
65
+ /**
66
+ * The detected path (relative to SCRIPT_NAME).
67
+ * Note: current_url() uses this to build its URI,
68
+ * so this becomes the source for the "current URL"
69
+ * when working with the share request instance.
70
+ *
71
+ * @var string|null
72
+ */
73
+ protected $ path ;
74
+
65
75
/**
66
76
* File collection
67
77
*
@@ -159,12 +169,6 @@ public function __construct($config, URI $uri = null, $body = 'php://input', Use
159
169
160
170
$ this ->detectURI ($ config ->uriProtocol , $ config ->baseURL );
161
171
162
- // Check if the baseURL scheme needs to be coerced into its secure version
163
- if ($ config ->forceGlobalSecureRequests && $ this ->uri ->getScheme () === 'http ' )
164
- {
165
- $ this ->uri ->setScheme ('https ' );
166
- }
167
-
168
172
$ this ->validLocales = $ config ->supportedLocales ;
169
173
170
174
$ this ->detectLocale ($ config );
@@ -613,11 +617,34 @@ public function getFile(string $fileID)
613
617
*/
614
618
protected function detectURI (string $ protocol , string $ baseURL )
615
619
{
616
- $ this ->uri ->setPath ($ this ->detectPath ($ protocol ));
620
+ // Passing the config is unnecessary but left for legacy purposes
621
+ $ config = clone $ this ->config ;
622
+ $ config ->baseURL = $ baseURL ;
623
+
624
+ $ this ->setPath ($ this ->detectPath ($ protocol ), $ config );
625
+ }
626
+
627
+ /**
628
+ * Sets the relative path and updates the URI object.
629
+ * Note: Since current_url() accesses the shared request
630
+ * instance, this can be used to change the "current URL"
631
+ * for testing.
632
+ *
633
+ * @param string $path URI path relative to SCRIPT_NAME
634
+ * @param App $config Optional alternate config to use
635
+ *
636
+ * @return $this
637
+ */
638
+ public function setPath (string $ path , App $ config = null )
639
+ {
640
+ $ this ->path = $ path ;
641
+ $ this ->uri ->setPath ($ path );
642
+
643
+ $ config = $ config ?? $ this ->config ;
617
644
618
645
// It's possible the user forgot a trailing slash on their
619
646
// baseURL, so let's help them out.
620
- $ baseURL = $ baseURL === '' ? $ baseURL : rtrim ($ baseURL , '/ ' ) . '/ ' ;
647
+ $ baseURL = $ config -> baseURL === '' ? $ config -> baseURL : rtrim ($ config -> baseURL , '/ ' ) . '/ ' ;
621
648
622
649
// Based on our baseURL provided by the developer
623
650
// set our current domain name, scheme
@@ -629,23 +656,44 @@ protected function detectURI(string $protocol, string $baseURL)
629
656
630
657
// Ensure we have any query vars
631
658
$ this ->uri ->setQuery ($ _SERVER ['QUERY_STRING ' ] ?? '' );
632
- }
633
- else
634
- {
635
- // @codeCoverageIgnoreStart
636
- if (! is_cli ())
659
+
660
+ // Check if the baseURL scheme needs to be coerced into its secure version
661
+ if ($ config ->forceGlobalSecureRequests && $ this ->uri ->getScheme () === 'http ' )
637
662
{
638
- die ( ' You have an empty or invalid base URL. The baseURL value must be set in Config\App.php, or through the .env file. ' );
663
+ $ this -> uri -> setScheme ( ' https ' );
639
664
}
640
- // @codeCoverageIgnoreEnd
641
665
}
666
+ // @codeCoverageIgnoreStart
667
+ elseif (! is_cli ())
668
+ {
669
+ die ('You have an empty or invalid base URL. The baseURL value must be set in Config\App.php, or through the .env file. ' );
670
+ }
671
+ // @codeCoverageIgnoreEnd
672
+
673
+ return $ this ;
642
674
}
643
675
644
676
//--------------------------------------------------------------------
645
677
646
678
/**
647
- * Based on the URIProtocol Config setting, will attempt to
648
- * detect the path portion of the current URI.
679
+ * Returns the path relative to SCRIPT_NAME,
680
+ * running detection as necessary.
681
+ *
682
+ * @return string
683
+ */
684
+ public function getPath (): string
685
+ {
686
+ if (is_null ($ this ->path ))
687
+ {
688
+ $ this ->detectPath ($ this ->config ->uriProtocol );
689
+ }
690
+
691
+ return $ this ->path ;
692
+ }
693
+
694
+ /**
695
+ * Detects the relative path based on
696
+ * the URIProtocol Config setting.
649
697
*
650
698
* @param string $protocol
651
699
*
@@ -661,18 +709,18 @@ public function detectPath(string $protocol = ''): string
661
709
switch ($ protocol )
662
710
{
663
711
case 'REQUEST_URI ' :
664
- $ path = $ this ->parseRequestURI ();
712
+ $ this -> path = $ this ->parseRequestURI ();
665
713
break ;
666
714
case 'QUERY_STRING ' :
667
- $ path = $ this ->parseQueryString ();
715
+ $ this -> path = $ this ->parseQueryString ();
668
716
break ;
669
717
case 'PATH_INFO ' :
670
718
default :
671
- $ path = $ this ->fetchGlobal ('server ' , $ protocol ) ?? $ this ->parseRequestURI ();
719
+ $ this -> path = $ this ->fetchGlobal ('server ' , $ protocol ) ?? $ this ->parseRequestURI ();
672
720
break ;
673
721
}
674
722
675
- return $ path ;
723
+ return $ this -> path ;
676
724
}
677
725
678
726
//--------------------------------------------------------------------
@@ -731,23 +779,23 @@ protected function parseRequestURI(): string
731
779
$ query = $ parts ['query ' ] ?? '' ;
732
780
$ uri = $ parts ['path ' ] ?? '' ;
733
781
734
- if (isset ($ _SERVER ['SCRIPT_NAME ' ][0 ]) && pathinfo ($ _SERVER ['SCRIPT_NAME ' ], PATHINFO_EXTENSION ) === 'php ' )
782
+ // Strip the SCRIPT_NAME path from the URI
783
+ if ($ uri !== '' && isset ($ _SERVER ['SCRIPT_NAME ' ][0 ]) && pathinfo ($ _SERVER ['SCRIPT_NAME ' ], PATHINFO_EXTENSION ) === 'php ' )
735
784
{
736
- // strip the script name from the beginning of the URI
737
- if (strpos ($ uri , $ _SERVER ['SCRIPT_NAME ' ]) === 0 && strpos ($ uri , '/index.php ' ) === 0 )
738
- {
739
- $ uri = (string ) substr ($ uri , strlen ($ _SERVER ['SCRIPT_NAME ' ]));
740
- }
741
- // if the script is nested, strip the parent folder & script from the URI
742
- elseif (strpos ($ uri , $ _SERVER ['SCRIPT_NAME ' ]) > 0 )
743
- {
744
- $ uri = (string ) substr ($ uri , strpos ($ uri , $ _SERVER ['SCRIPT_NAME ' ]) + strlen ($ _SERVER ['SCRIPT_NAME ' ]));
745
- }
746
- // or if index.php is implied
747
- elseif (strpos ($ uri , dirname ($ _SERVER ['SCRIPT_NAME ' ])) === 0 )
785
+ // Compare each segment, dropping them until there is no match
786
+ $ segments = $ keep = explode ('/ ' , $ uri );
787
+ foreach (explode ('/ ' , $ _SERVER ['SCRIPT_NAME ' ]) as $ i => $ segment )
748
788
{
749
- $ uri = (string ) substr ($ uri , strlen (dirname ($ _SERVER ['SCRIPT_NAME ' ])));
789
+ // If these segments are not the same then we're done
790
+ if ($ segment !== $ segments [$ i ])
791
+ {
792
+ break ;
793
+ }
794
+
795
+ array_shift ($ keep );
750
796
}
797
+
798
+ $ uri = implode ('/ ' , $ keep );
751
799
}
752
800
753
801
// This section ensures that even on servers that require the URI to contain the query string (Nginx) a correct
@@ -763,7 +811,10 @@ protected function parseRequestURI(): string
763
811
$ _SERVER ['QUERY_STRING ' ] = $ query ;
764
812
}
765
813
814
+ // Update our globals for values likely to been have changed
766
815
parse_str ($ _SERVER ['QUERY_STRING ' ], $ _GET );
816
+ $ this ->populateGlobals ('server ' );
817
+ $ this ->populateGlobals ('get ' );
767
818
768
819
$ uri = URI ::removeDotSegments ($ uri );
769
820
@@ -795,7 +846,10 @@ protected function parseQueryString(): string
795
846
$ uri = $ uri [0 ];
796
847
}
797
848
849
+ // Update our globals for values likely to been have changed
798
850
parse_str ($ _SERVER ['QUERY_STRING ' ], $ _GET );
851
+ $ this ->populateGlobals ('server ' );
852
+ $ this ->populateGlobals ('get ' );
799
853
800
854
$ uri = URI ::removeDotSegments ($ uri );
801
855
0 commit comments