@@ -305,4 +305,90 @@ public function testAllowsHttpAndHttpsRedirects(): void
305305
306306 $ this ->assertEquals (200 , $ response ->getStatusCode ());
307307 }
308+
309+ public function testNormalizesRelativePathWithDotDotSegments (): void
310+ {
311+ // Current URL: https://example.com/path/to/feed.xml
312+ // Redirect to: ../newpath/feed.xml
313+ // Should resolve to: https://example.com/path/newpath/feed.xml
314+
315+ $ redirectResponse = new PsrResponse (301 , ['Location ' => '../newpath/feed.xml ' ]);
316+ $ finalResponse = new PsrResponse (200 , [], 'content ' );
317+
318+ $ requestCount = 0 ;
319+ $ this ->psrClient
320+ ->expects ($ this ->exactly (2 ))
321+ ->method ('sendRequest ' )
322+ ->willReturnCallback (function (RequestInterface $ request ) use ($ redirectResponse , $ finalResponse , &$ requestCount ) {
323+ $ requestCount ++;
324+
325+ if ($ requestCount === 1 ) {
326+ $ this ->assertEquals ('https://example.com/path/to/feed.xml ' , (string ) $ request ->getUri ());
327+ return $ redirectResponse ;
328+ }
329+
330+ // Verify the path was properly normalized
331+ $ this ->assertEquals ('https://example.com/path/newpath/feed.xml ' , (string ) $ request ->getUri ());
332+ return $ finalResponse ;
333+ });
334+
335+ $ response = $ this ->client ->getResponse ('https://example.com/path/to/feed.xml ' );
336+ $ this ->assertEquals (200 , $ response ->getStatusCode ());
337+ }
338+
339+ public function testNormalizesAbsolutePathWithDotDotSegments (): void
340+ {
341+ // Redirect to: /path/../other/feed.xml
342+ // Should resolve to: /other/feed.xml
343+
344+ $ redirectResponse = new PsrResponse (301 , ['Location ' => '/path/../other/feed.xml ' ]);
345+ $ finalResponse = new PsrResponse (200 , [], 'content ' );
346+
347+ $ requestCount = 0 ;
348+ $ this ->psrClient
349+ ->expects ($ this ->exactly (2 ))
350+ ->method ('sendRequest ' )
351+ ->willReturnCallback (function (RequestInterface $ request ) use ($ redirectResponse , $ finalResponse , &$ requestCount ) {
352+ $ requestCount ++;
353+
354+ if ($ requestCount === 1 ) {
355+ return $ redirectResponse ;
356+ }
357+
358+ // Verify the path was properly normalized
359+ $ this ->assertEquals ('https://example.com/other/feed.xml ' , (string ) $ request ->getUri ());
360+ return $ finalResponse ;
361+ });
362+
363+ $ response = $ this ->client ->getResponse ('https://example.com/some/path.xml ' );
364+ $ this ->assertEquals (200 , $ response ->getStatusCode ());
365+ }
366+
367+ public function testNormalizesPathWithDotSegments (): void
368+ {
369+ // Redirect to: /path/./to/./feed.xml
370+ // Should resolve to: /path/to/feed.xml
371+
372+ $ redirectResponse = new PsrResponse (301 , ['Location ' => '/path/./to/./feed.xml ' ]);
373+ $ finalResponse = new PsrResponse (200 , [], 'content ' );
374+
375+ $ requestCount = 0 ;
376+ $ this ->psrClient
377+ ->expects ($ this ->exactly (2 ))
378+ ->method ('sendRequest ' )
379+ ->willReturnCallback (function (RequestInterface $ request ) use ($ redirectResponse , $ finalResponse , &$ requestCount ) {
380+ $ requestCount ++;
381+
382+ if ($ requestCount === 1 ) {
383+ return $ redirectResponse ;
384+ }
385+
386+ // Verify the path was properly normalized
387+ $ this ->assertEquals ('https://example.com/path/to/feed.xml ' , (string ) $ request ->getUri ());
388+ return $ finalResponse ;
389+ });
390+
391+ $ response = $ this ->client ->getResponse ('https://example.com/old.xml ' );
392+ $ this ->assertEquals (200 , $ response ->getStatusCode ());
393+ }
308394}
0 commit comments