UriNormalizerTest.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. namespace GuzzleHttp\Tests\Psr7;
  3. use GuzzleHttp\Psr7\Uri;
  4. use GuzzleHttp\Psr7\UriNormalizer;
  5. /**
  6. * @covers GuzzleHttp\Psr7\UriNormalizer
  7. */
  8. class UriNormalizerTest extends BaseTest
  9. {
  10. public function testCapitalizePercentEncoding()
  11. {
  12. $actualEncoding = 'a%c2%7A%5eb%25%fa%fA%Fa';
  13. $expectEncoding = 'a%C2%7A%5Eb%25%FA%FA%FA';
  14. $uri = (new Uri())->withPath("/$actualEncoding")->withQuery($actualEncoding);
  15. $this->assertSame("/$actualEncoding?$actualEncoding", (string) $uri, 'Not normalized automatically beforehand');
  16. $normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::CAPITALIZE_PERCENT_ENCODING);
  17. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  18. $this->assertSame("/$expectEncoding?$expectEncoding", (string) $normalizedUri);
  19. }
  20. /**
  21. * @dataProvider getUnreservedCharacters
  22. */
  23. public function testDecodeUnreservedCharacters($char)
  24. {
  25. $percentEncoded = '%'.bin2hex($char);
  26. // Add encoded reserved characters to test that those are not decoded and include the percent-encoded
  27. // unreserved character both in lower and upper case to test the decoding is case-insensitive.
  28. $encodedChars = $percentEncoded.'%2F%5B'.strtoupper($percentEncoded);
  29. $uri = (new Uri())->withPath("/$encodedChars")->withQuery($encodedChars);
  30. $this->assertSame("/$encodedChars?$encodedChars", (string) $uri, 'Not normalized automatically beforehand');
  31. $normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::DECODE_UNRESERVED_CHARACTERS);
  32. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  33. $this->assertSame("/$char%2F%5B$char?$char%2F%5B$char", (string) $normalizedUri);
  34. }
  35. public function getUnreservedCharacters()
  36. {
  37. $unreservedChars = array_merge(range('a', 'z'), range('A', 'Z'), range('0', '9'), ['-', '.', '_', '~']);
  38. return array_map(function ($char) {
  39. return [$char];
  40. }, $unreservedChars);
  41. }
  42. /**
  43. * @dataProvider getEmptyPathTestCases
  44. */
  45. public function testConvertEmptyPath($uri, $expected)
  46. {
  47. $normalizedUri = UriNormalizer::normalize(new Uri($uri), UriNormalizer::CONVERT_EMPTY_PATH);
  48. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  49. $this->assertSame($expected, (string) $normalizedUri);
  50. }
  51. public function getEmptyPathTestCases()
  52. {
  53. return [
  54. ['http://example.org', 'http://example.org/'],
  55. ['https://example.org', 'https://example.org/'],
  56. ['urn://example.org', 'urn://example.org'],
  57. ];
  58. }
  59. public function testRemoveDefaultHost()
  60. {
  61. $uri = new Uri('file://localhost/myfile');
  62. $normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DEFAULT_HOST);
  63. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  64. $this->assertSame('file:///myfile', (string) $normalizedUri);
  65. }
  66. public function testRemoveDefaultPort()
  67. {
  68. $uri = $this->getMockBuilder('Psr\Http\Message\UriInterface')->getMock();
  69. $uri->expects($this->any())->method('getScheme')->will($this->returnValue('http'));
  70. $uri->expects($this->any())->method('getPort')->will($this->returnValue(80));
  71. $uri->expects($this->once())->method('withPort')->with(null)->will($this->returnValue(new Uri('http://example.org')));
  72. $normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DEFAULT_PORT);
  73. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  74. $this->assertNull($normalizedUri->getPort());
  75. }
  76. public function testRemoveDotSegments()
  77. {
  78. $uri = new Uri('http://example.org/../a/b/../c/./d.html');
  79. $normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DOT_SEGMENTS);
  80. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  81. $this->assertSame('http://example.org/a/c/d.html', (string) $normalizedUri);
  82. }
  83. public function testRemoveDotSegmentsOfAbsolutePathReference()
  84. {
  85. $uri = new Uri('/../a/b/../c/./d.html');
  86. $normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DOT_SEGMENTS);
  87. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  88. $this->assertSame('/a/c/d.html', (string) $normalizedUri);
  89. }
  90. public function testRemoveDotSegmentsOfRelativePathReference()
  91. {
  92. $uri = new Uri('../c/./d.html');
  93. $normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DOT_SEGMENTS);
  94. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  95. $this->assertSame('../c/./d.html', (string) $normalizedUri);
  96. }
  97. public function testRemoveDuplicateSlashes()
  98. {
  99. $uri = new Uri('http://example.org//foo///bar/bam.html');
  100. $normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DUPLICATE_SLASHES);
  101. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  102. $this->assertSame('http://example.org/foo/bar/bam.html', (string) $normalizedUri);
  103. }
  104. public function testSortQueryParameters()
  105. {
  106. $uri = new Uri('?lang=en&article=fred');
  107. $normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::SORT_QUERY_PARAMETERS);
  108. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  109. $this->assertSame('?article=fred&lang=en', (string) $normalizedUri);
  110. }
  111. public function testSortQueryParametersWithSameKeys()
  112. {
  113. $uri = new Uri('?a=b&b=c&a=a&a&b=a&b=b&a=d&a=c');
  114. $normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::SORT_QUERY_PARAMETERS);
  115. $this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri);
  116. $this->assertSame('?a&a=a&a=b&a=c&a=d&b=a&b=b&b=c', (string) $normalizedUri);
  117. }
  118. /**
  119. * @dataProvider getEquivalentTestCases
  120. */
  121. public function testIsEquivalent($uri1, $uri2, $expected)
  122. {
  123. $equivalent = UriNormalizer::isEquivalent(new Uri($uri1), new Uri($uri2));
  124. $this->assertSame($expected, $equivalent);
  125. }
  126. public function getEquivalentTestCases()
  127. {
  128. return [
  129. ['http://example.org', 'http://example.org', true],
  130. ['hTTp://eXaMpLe.org', 'http://example.org', true],
  131. ['http://example.org/path?#', 'http://example.org/path', true],
  132. ['http://example.org:80', 'http://example.org/', true],
  133. ['http://example.org/../a/.././p%61th?%7a=%5e', 'http://example.org/path?z=%5E', true],
  134. ['https://example.org/', 'http://example.org/', false],
  135. ['https://example.org/', '//example.org/', false],
  136. ['//example.org/', '//example.org/', true],
  137. ['file:/myfile', 'file:///myfile', true],
  138. ['file:///myfile', 'file://localhost/myfile', true],
  139. ];
  140. }
  141. }