123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Net;
- using System.Reflection;
- using System.Threading.Tasks;
- using MediaBrowser.Model.IO;
- using MediaBrowser.Model.Logging;
- using MediaBrowser.Model.Net;
- using SocketHttpListener.Primitives;
- namespace SocketHttpListener.Net
- {
- sealed class EndPointManager
- {
- // Dictionary<IPAddress, Dictionary<int, EndPointListener>>
- static Dictionary<string, Dictionary<int, EndPointListener>> ip_to_endpoints = new Dictionary<string, Dictionary<int, EndPointListener>>();
- private EndPointManager()
- {
- }
- public static void AddListener(ILogger logger, HttpListener listener)
- {
- List<string> added = new List<string>();
- try
- {
- lock (ip_to_endpoints)
- {
- foreach (string prefix in listener.Prefixes)
- {
- AddPrefixInternal(logger, prefix, listener);
- added.Add(prefix);
- }
- }
- }
- catch
- {
- foreach (string prefix in added)
- {
- RemovePrefix(logger, prefix, listener);
- }
- throw;
- }
- }
- public static void AddPrefix(ILogger logger, string prefix, HttpListener listener)
- {
- lock (ip_to_endpoints)
- {
- AddPrefixInternal(logger, prefix, listener);
- }
- }
- static void AddPrefixInternal(ILogger logger, string p, HttpListener listener)
- {
- ListenerPrefix lp = new ListenerPrefix(p);
- if (lp.Path.IndexOf('%') != -1)
- throw new HttpListenerException(400, "Invalid path.");
- if (lp.Path.IndexOf("//", StringComparison.Ordinal) != -1) // TODO: Code?
- throw new HttpListenerException(400, "Invalid path.");
- // listens on all the interfaces if host name cannot be parsed by IPAddress.
- EndPointListener epl = GetEPListener(logger, lp.Host, lp.Port, listener, lp.Secure).Result;
- epl.AddPrefix(lp, listener);
- }
- private static IPAddress GetIpAnyAddress(HttpListener listener)
- {
- return listener.EnableDualMode ? IPAddress.IPv6Any : IPAddress.Any;
- }
- static async Task<EndPointListener> GetEPListener(ILogger logger, string host, int port, HttpListener listener, bool secure)
- {
- var networkManager = listener.NetworkManager;
- IPAddress addr;
- if (host == "*" || host == "+")
- addr = GetIpAnyAddress(listener);
- else if (IPAddress.TryParse(host, out addr) == false)
- {
- try
- {
- var all = (await networkManager.GetHostAddressesAsync(host).ConfigureAwait(false));
- addr = (all.Length == 0 ? null : IPAddress.Parse(all[0].Address)) ??
- GetIpAnyAddress(listener);
- }
- catch
- {
- addr = GetIpAnyAddress(listener);
- }
- }
- Dictionary<int, EndPointListener> p = null; // Dictionary<int, EndPointListener>
- if (!ip_to_endpoints.TryGetValue(addr.ToString(), out p))
- {
- p = new Dictionary<int, EndPointListener>();
- ip_to_endpoints[addr.ToString()] = p;
- }
- EndPointListener epl = null;
- if (p.ContainsKey(port))
- {
- epl = (EndPointListener)p[port];
- }
- else
- {
- epl = new EndPointListener(listener, addr, port, secure, listener.Certificate, logger, listener.CryptoProvider, listener.SocketFactory, listener.MemoryStreamFactory, listener.TextEncoding, listener.FileSystem, listener.EnvironmentInfo);
- p[port] = epl;
- }
- return epl;
- }
- public static void RemoveEndPoint(EndPointListener epl, IPEndPoint ep)
- {
- lock (ip_to_endpoints)
- {
- // Dictionary<int, EndPointListener> p
- Dictionary<int, EndPointListener> p;
- if (ip_to_endpoints.TryGetValue(ep.Address.ToString(), out p))
- {
- p.Remove(ep.Port);
- if (p.Count == 0)
- {
- ip_to_endpoints.Remove(ep.Address.ToString());
- }
- }
- epl.Close();
- }
- }
- public static void RemoveListener(ILogger logger, HttpListener listener)
- {
- lock (ip_to_endpoints)
- {
- foreach (string prefix in listener.Prefixes)
- {
- RemovePrefixInternal(logger, prefix, listener);
- }
- }
- }
- public static void RemovePrefix(ILogger logger, string prefix, HttpListener listener)
- {
- lock (ip_to_endpoints)
- {
- RemovePrefixInternal(logger, prefix, listener);
- }
- }
- static void RemovePrefixInternal(ILogger logger, string prefix, HttpListener listener)
- {
- ListenerPrefix lp = new ListenerPrefix(prefix);
- if (lp.Path.IndexOf('%') != -1)
- return;
- if (lp.Path.IndexOf("//", StringComparison.Ordinal) != -1)
- return;
- EndPointListener epl = GetEPListener(logger, lp.Host, lp.Port, listener, lp.Secure).Result;
- epl.RemovePrefix(lp, listener);
- }
- }
- }
|