123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- #region License
- /*
- * EndPointManager.cs
- *
- * This code is derived from EndPointManager.cs (System.Net) of Mono
- * (http://www.mono-project.com).
- *
- * The MIT License
- *
- * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
- * Copyright (c) 2012-2020 sta.blockhead
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
- #endregion
- #region Authors
- /*
- * Authors:
- * - Gonzalo Paniagua Javier <gonzalo@ximian.com>
- */
- #endregion
- #region Contributors
- /*
- * Contributors:
- * - Liryna <liryna.stark@gmail.com>
- */
- #endregion
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Net;
- namespace WebSocketSharp.Net
- {
- internal sealed class EndPointManager
- {
- #region Private Fields
- private static readonly Dictionary<IPEndPoint, EndPointListener> _endpoints;
- #endregion
- #region Static Constructor
- static EndPointManager ()
- {
- _endpoints = new Dictionary<IPEndPoint, EndPointListener> ();
- }
- #endregion
- #region Private Constructors
- private EndPointManager ()
- {
- }
- #endregion
- #region Private Methods
- private static void addPrefix (string uriPrefix, HttpListener listener)
- {
- var pref = new HttpListenerPrefix (uriPrefix, listener);
- var addr = convertToIPAddress (pref.Host);
- if (addr == null) {
- var msg = "The URI prefix includes an invalid host.";
- throw new HttpListenerException (87, msg);
- }
- if (!addr.IsLocal ()) {
- var msg = "The URI prefix includes an invalid host.";
- throw new HttpListenerException (87, msg);
- }
- int port;
- if (!Int32.TryParse (pref.Port, out port)) {
- var msg = "The URI prefix includes an invalid port.";
- throw new HttpListenerException (87, msg);
- }
- if (!port.IsPortNumber ()) {
- var msg = "The URI prefix includes an invalid port.";
- throw new HttpListenerException (87, msg);
- }
- var path = pref.Path;
- if (path.IndexOf ('%') != -1) {
- var msg = "The URI prefix includes an invalid path.";
- throw new HttpListenerException (87, msg);
- }
- if (path.IndexOf ("//", StringComparison.Ordinal) != -1) {
- var msg = "The URI prefix includes an invalid path.";
- throw new HttpListenerException (87, msg);
- }
- var endpoint = new IPEndPoint (addr, port);
- EndPointListener lsnr;
- if (_endpoints.TryGetValue (endpoint, out lsnr)) {
- if (lsnr.IsSecure ^ pref.IsSecure) {
- var msg = "The URI prefix includes an invalid scheme.";
- throw new HttpListenerException (87, msg);
- }
- }
- else {
- lsnr = new EndPointListener (
- endpoint,
- pref.IsSecure,
- listener.CertificateFolderPath,
- listener.SslConfiguration,
- listener.ReuseAddress
- );
- _endpoints.Add (endpoint, lsnr);
- }
- lsnr.AddPrefix (pref);
- }
- private static IPAddress convertToIPAddress (string hostname)
- {
- if (hostname == "*")
- return IPAddress.Any;
- if (hostname == "+")
- return IPAddress.Any;
- return hostname.ToIPAddress ();
- }
- private static void removePrefix (string uriPrefix, HttpListener listener)
- {
- var pref = new HttpListenerPrefix (uriPrefix, listener);
- var addr = convertToIPAddress (pref.Host);
- if (addr == null)
- return;
- if (!addr.IsLocal ())
- return;
- int port;
- if (!Int32.TryParse (pref.Port, out port))
- return;
- if (!port.IsPortNumber ())
- return;
- var path = pref.Path;
- if (path.IndexOf ('%') != -1)
- return;
- if (path.IndexOf ("//", StringComparison.Ordinal) != -1)
- return;
- var endpoint = new IPEndPoint (addr, port);
- EndPointListener lsnr;
- if (!_endpoints.TryGetValue (endpoint, out lsnr))
- return;
- if (lsnr.IsSecure ^ pref.IsSecure)
- return;
- lsnr.RemovePrefix (pref);
- }
- #endregion
- #region Internal Methods
- internal static bool RemoveEndPoint (IPEndPoint endpoint)
- {
- lock (((ICollection) _endpoints).SyncRoot)
- return _endpoints.Remove (endpoint);
- }
- #endregion
- #region Public Methods
- public static void AddListener (HttpListener listener)
- {
- var added = new List<string> ();
- lock (((ICollection) _endpoints).SyncRoot) {
- try {
- foreach (var pref in listener.Prefixes) {
- addPrefix (pref, listener);
- added.Add (pref);
- }
- }
- catch {
- foreach (var pref in added)
- removePrefix (pref, listener);
- throw;
- }
- }
- }
- public static void AddPrefix (string uriPrefix, HttpListener listener)
- {
- lock (((ICollection) _endpoints).SyncRoot)
- addPrefix (uriPrefix, listener);
- }
- public static void RemoveListener (HttpListener listener)
- {
- lock (((ICollection) _endpoints).SyncRoot) {
- foreach (var pref in listener.Prefixes)
- removePrefix (pref, listener);
- }
- }
- public static void RemovePrefix (string uriPrefix, HttpListener listener)
- {
- lock (((ICollection) _endpoints).SyncRoot)
- removePrefix (uriPrefix, listener);
- }
- #endregion
- }
- }
|