ListenerPrefix.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. using System;
  2. using System.Net;
  3. using MediaBrowser.Model.Net;
  4. namespace SocketHttpListener.Net
  5. {
  6. sealed class ListenerPrefix
  7. {
  8. string original;
  9. string host;
  10. ushort port;
  11. string path;
  12. bool secure;
  13. IpAddressInfo[] addresses;
  14. public HttpListener Listener;
  15. public ListenerPrefix(string prefix)
  16. {
  17. this.original = prefix;
  18. Parse(prefix);
  19. }
  20. public override string ToString()
  21. {
  22. return original;
  23. }
  24. public IpAddressInfo[] Addresses
  25. {
  26. get { return addresses; }
  27. set { addresses = value; }
  28. }
  29. public bool Secure
  30. {
  31. get { return secure; }
  32. }
  33. public string Host
  34. {
  35. get { return host; }
  36. }
  37. public int Port
  38. {
  39. get { return (int)port; }
  40. }
  41. public string Path
  42. {
  43. get { return path; }
  44. }
  45. // Equals and GetHashCode are required to detect duplicates in HttpListenerPrefixCollection.
  46. public override bool Equals(object o)
  47. {
  48. ListenerPrefix other = o as ListenerPrefix;
  49. if (other == null)
  50. return false;
  51. return (original == other.original);
  52. }
  53. public override int GetHashCode()
  54. {
  55. return original.GetHashCode();
  56. }
  57. void Parse(string uri)
  58. {
  59. ushort default_port = 80;
  60. if (uri.StartsWith("https://"))
  61. {
  62. default_port = 443;
  63. secure = true;
  64. }
  65. int length = uri.Length;
  66. int start_host = uri.IndexOf(':') + 3;
  67. if (start_host >= length)
  68. throw new ArgumentException("No host specified.");
  69. int colon = uri.IndexOf(':', start_host, length - start_host);
  70. int root;
  71. if (colon > 0)
  72. {
  73. host = uri.Substring(start_host, colon - start_host);
  74. root = uri.IndexOf('/', colon, length - colon);
  75. port = (ushort)Int32.Parse(uri.Substring(colon + 1, root - colon - 1));
  76. path = uri.Substring(root);
  77. }
  78. else
  79. {
  80. root = uri.IndexOf('/', start_host, length - start_host);
  81. host = uri.Substring(start_host, root - start_host);
  82. port = default_port;
  83. path = uri.Substring(root);
  84. }
  85. if (path.Length != 1)
  86. path = path.Substring(0, path.Length - 1);
  87. }
  88. public static void CheckUri(string uri)
  89. {
  90. if (uri == null)
  91. throw new ArgumentNullException("uriPrefix");
  92. if (!uri.StartsWith("http://") && !uri.StartsWith("https://"))
  93. throw new ArgumentException("Only 'http' and 'https' schemes are supported.");
  94. int length = uri.Length;
  95. int start_host = uri.IndexOf(':') + 3;
  96. if (start_host >= length)
  97. throw new ArgumentException("No host specified.");
  98. int colon = uri.IndexOf(':', start_host, length - start_host);
  99. if (start_host == colon)
  100. throw new ArgumentException("No host specified.");
  101. int root;
  102. if (colon > 0)
  103. {
  104. root = uri.IndexOf('/', colon, length - colon);
  105. if (root == -1)
  106. throw new ArgumentException("No path specified.");
  107. try
  108. {
  109. int p = Int32.Parse(uri.Substring(colon + 1, root - colon - 1));
  110. if (p <= 0 || p >= 65536)
  111. throw new Exception();
  112. }
  113. catch
  114. {
  115. throw new ArgumentException("Invalid port.");
  116. }
  117. }
  118. else
  119. {
  120. root = uri.IndexOf('/', start_host, length - start_host);
  121. if (root == -1)
  122. throw new ArgumentException("No path specified.");
  123. }
  124. if (uri[uri.Length - 1] != '/')
  125. throw new ArgumentException("The prefix must end with '/'");
  126. }
  127. }
  128. }