@@ -120,7 +120,14 @@ public function __toString(): string
120120 }
121121
122122 if ($ this ->path !== '' ) {
123- $ this ->cache .= $ authority ? '/ ' . ltrim ($ this ->path , '/ ' ) : $ this ->path ;
123+ if ($ authority === '' ) {
124+ // If the path is starting with more than one "/" and no authority is present,
125+ // the starting slashes MUST be reduced to one.
126+ $ this ->cache .= $ this ->path [0 ] === '/ ' ? '/ ' . ltrim ($ this ->path , '/ ' ) : $ this ->path ;
127+ } else {
128+ // If the path is rootless and an authority is present, the path MUST be prefixed by "/".
129+ $ this ->cache .= $ this ->path [0 ] === '/ ' ? $ this ->path : '/ ' . $ this ->path ;
130+ }
124131 }
125132
126133 if ($ this ->query !== '' ) {
@@ -193,7 +200,16 @@ public function getPort(): ?int
193200 */
194201 public function getPath (): string
195202 {
196- return $ this ->path ;
203+ if ($ this ->path === '' || $ this ->path === '/ ' ) {
204+ return $ this ->path ;
205+ }
206+
207+ if ($ this ->path [0 ] !== '/ ' ) {
208+ // If the path is rootless and an authority is present, the path MUST be prefixed by "/".
209+ return $ this ->host === '' ? $ this ->path : '/ ' . $ this ->path ;
210+ }
211+
212+ return '/ ' . ltrim ($ this ->path , '/ ' );
197213 }
198214
199215 /**
@@ -438,8 +454,7 @@ private function normalizePath(string $path): string
438454 return $ path ;
439455 }
440456
441- $ path = $ this ->encode ($ path , '/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/ ' );
442- return $ path === '' ? '' : (($ path [0 ] === '/ ' ) ? '/ ' . ltrim ($ path , '/ ' ) : $ path );
457+ return $ this ->encode ($ path , '/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/ ' );
443458 }
444459
445460 /**
@@ -490,7 +505,6 @@ private function normalizeFragment(string $fragment): string
490505 * @param string $string
491506 * @param string $pattern
492507 * @return string
493- * @psalm-suppress MixedArgument
494508 */
495509 private function encode (string $ string , string $ pattern ): string
496510 {
0 commit comments