UriScheme.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. /**
  3. * League.Uri (https://uri.thephpleague.com)
  4. *
  5. * (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. declare(strict_types=1);
  11. namespace League\Uri;
  12. use ValueError;
  13. /*
  14. * Supported schemes and corresponding default port.
  15. *
  16. * @see https://github.com/python-hyper/hyperlink/blob/master/src/hyperlink/_url.py for the curating list definition
  17. * @see https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
  18. * @see https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
  19. */
  20. enum UriScheme: string
  21. {
  22. case About = 'about';
  23. case Acap = 'acap';
  24. case Bitcoin = 'bitcoin';
  25. case Geo = 'geo';
  26. case Blob = 'blob';
  27. case Afp = 'afp';
  28. case Data = 'data';
  29. case Dict = 'dict';
  30. case Dns = 'dns';
  31. case File = 'file';
  32. case Ftp = 'ftp';
  33. case Git = 'git';
  34. case Gopher = 'gopher';
  35. case Http = 'http';
  36. case Https = 'https';
  37. case Imap = 'imap';
  38. case Imaps = 'imaps';
  39. case Ipp = 'ipp';
  40. case Ipps = 'ipps';
  41. case Irc = 'irc';
  42. case Ircs = 'ircs';
  43. case Javascript = 'javascript';
  44. case Ldap = 'ldap';
  45. case Ldaps = 'ldaps';
  46. case Magnet = 'magnet';
  47. case Mailto = 'mailto';
  48. case Mms = 'mms';
  49. case Msrp = 'msrp';
  50. case Msrps = 'msrps';
  51. case Mtqp = 'mtqp';
  52. case News = 'news';
  53. case Nfs = 'nfs';
  54. case Nntp = 'nntp';
  55. case Nntps = 'nntps';
  56. case Pkcs11 = 'pkcs11';
  57. case Pop = 'pop';
  58. case Prospero = 'prospero';
  59. case Redis = 'redis';
  60. case Rsync = 'rsync';
  61. case Rtsp = 'rtsp';
  62. case Rtsps = 'rtsps';
  63. case Rtspu = 'rtspu';
  64. case Sftp = 'sftp';
  65. case Wss = 'wss';
  66. case Ws = 'ws';
  67. case Sip = 'sip';
  68. case Sips = 'sips';
  69. case Smb = 'smb';
  70. case Smtp = 'smtp';
  71. case Snmp = 'snmp';
  72. case Ssh = 'ssh';
  73. case Steam = 'steam';
  74. case Svn = 'svn';
  75. case Tel = 'tel';
  76. case Telnet = 'telnet';
  77. case Tn3270 = 'tn3270';
  78. case Urn = 'urn';
  79. case Ventrilo = 'ventrilo';
  80. case Vnc = 'vnc';
  81. case Wais = 'wais';
  82. case Xmpp = 'xmpp';
  83. public function port(): ?int
  84. {
  85. return match ($this) {
  86. self::Acap => 674,
  87. self::Afp => 548,
  88. self::Dict => 2628,
  89. self::Dns => 53,
  90. self::Ftp => 21,
  91. self::Http, self::Ws => 80,
  92. self::Https, self::Wss => 443,
  93. self::Git => 9418,
  94. self::Gopher => 70,
  95. self::Imap => 143,
  96. self::Imaps => 993,
  97. self::Ipp, self::Ipps => 631,
  98. self::Irc => 194,
  99. self::Ircs => 6697,
  100. self::Ldap => 389,
  101. self::Ldaps => 636,
  102. self::Mms => 1755,
  103. self::Msrp, self::Msrps => 2855,
  104. self::Mtqp => 1038,
  105. self::Nfs => 111,
  106. self::Nntp => 119,
  107. self::Nntps => 563,
  108. self::Pop => 110,
  109. self::Prospero => 1525,
  110. self::Redis => 6379,
  111. self::Rsync => 873,
  112. self::Rtsp => 554,
  113. self::Rtsps => 322,
  114. self::Rtspu => 5005,
  115. self::Sftp, self::Ssh => 22,
  116. self::Smb => 445,
  117. self::Smtp => 25,
  118. self::Snmp => 161,
  119. self::Svn => 3690,
  120. self::Telnet, self::Tn3270 => 23,
  121. self::Ventrilo => 3784,
  122. self::Vnc => 5900,
  123. self::Wais => 210,
  124. self::Xmpp => 80,
  125. default => null,
  126. };
  127. }
  128. public function type(): SchemeType
  129. {
  130. return match ($this) {
  131. self::Urn,
  132. self::About,
  133. self::Bitcoin,
  134. self::Blob,
  135. self::Data,
  136. self::Geo,
  137. self::Javascript,
  138. self::Magnet,
  139. self::Mailto,
  140. self::Pkcs11,
  141. self::Sip,
  142. self::Sips,
  143. self::Tel => SchemeType::Opaque,
  144. self::File => SchemeType::Hierarchical,
  145. self::News => SchemeType::Unknown,
  146. default => match (true) {
  147. null !== $this->port() => SchemeType::Hierarchical,
  148. default => SchemeType::Unknown,
  149. },
  150. };
  151. }
  152. public function isWhatWgSpecial(): bool
  153. {
  154. return match ($this) {
  155. self::Ftp,
  156. self::Http,
  157. self::Https,
  158. self::Ws,
  159. self::Wss => true,
  160. default => false,
  161. };
  162. }
  163. /**
  164. * @return list<self>
  165. */
  166. public static function fromPort(?int $port): array
  167. {
  168. null === $port || 0 <= $port || throw new ValueError('The submitted port cannot be negative.');
  169. static $reverse = [];
  170. if ([] === $reverse) {
  171. foreach (self::cases() as $case) {
  172. $defaultPort = $case->port();
  173. if (null === $defaultPort) {
  174. continue;
  175. }
  176. $reverse[$defaultPort] ??= [];
  177. $reverse[$defaultPort][] = $case;
  178. }
  179. }
  180. return $reverse[$port] ?? [];
  181. }
  182. public function builder(): Builder
  183. {
  184. return new Builder(scheme: $this);
  185. }
  186. }