예제 #1
0
        private static HttpListener matchFromList(
            string host, string path, List <HttpListenerPrefix> list, out HttpListenerPrefix prefix)
        {
            prefix = null;
            if (list == null)
            {
                return(null);
            }

            HttpListener bestMatch = null;
            var          bestLen   = -1;

            foreach (var pref in list)
            {
                var ppath = pref.Path;
                if (ppath.Length < bestLen)
                {
                    continue;
                }

                if (path.StartsWith(ppath))
                {
                    bestLen   = ppath.Length;
                    bestMatch = pref.Listener;
                    prefix    = pref;
                }
            }

            return(bestMatch);
        }
예제 #2
0
        public void AddPrefix(HttpListenerPrefix prefix, HttpListener listener)
        {
            List <HttpListenerPrefix> current, future;

            if (prefix.Host == "*")
            {
                do
                {
                    current = _unhandled;
                    future  = current != null
                   ? new List <HttpListenerPrefix> (current)
                   : new List <HttpListenerPrefix> ();

                    prefix.Listener = listener;
                    addSpecial(future, prefix);
                }while (Interlocked.CompareExchange(ref _unhandled, future, current) != current);

                return;
            }

            if (prefix.Host == "+")
            {
                do
                {
                    current = _all;
                    future  = current != null
                   ? new List <HttpListenerPrefix> (current)
                   : new List <HttpListenerPrefix> ();

                    prefix.Listener = listener;
                    addSpecial(future, prefix);
                }while (Interlocked.CompareExchange(ref _all, future, current) != current);

                return;
            }

            Dictionary <HttpListenerPrefix, HttpListener> prefs, prefs2;

            do
            {
                prefs = _prefixes;
                if (prefs.ContainsKey(prefix))
                {
                    if (prefs[prefix] != listener)
                    {
                        throw new HttpListenerException(
                                  400, String.Format("There's another listener for {0}.", prefix)); // TODO: Code?
                    }
                    return;
                }

                prefs2         = new Dictionary <HttpListenerPrefix, HttpListener> (prefs);
                prefs2[prefix] = listener;
            }while (Interlocked.CompareExchange(ref _prefixes, prefs2, prefs) != prefs);
        }
예제 #3
0
 private void init()
 {
     _chunked       = false;
     _context       = new HttpListenerContext(this);
     _inputState    = InputState.RequestLine;
     _inputStream   = null;
     _lineState     = LineState.None;
     _outputStream  = null;
     _position      = 0;
     _prefix        = null;
     _requestBuffer = new MemoryStream();
 }
예제 #4
0
    private static void addPrefix (string uriPrefix, HttpListener listener)
    {
      var pref = new HttpListenerPrefix (uriPrefix);
      if (pref.Path.IndexOf ('%') != -1)
        throw new HttpListenerException (400, "Invalid path."); // TODO: Code?

      if (pref.Path.IndexOf ("//", StringComparison.Ordinal) != -1)
        throw new HttpListenerException (400, "Invalid path."); // TODO: Code?

      // Listens on all the interfaces if host name cannot be parsed by IPAddress.
      var lsnr = getEndPointListener (pref.Host, pref.Port, listener, pref.IsSecure);
      lsnr.AddPrefix (pref, listener);
    }
예제 #5
0
        private static void addSpecial(List <HttpListenerPrefix> prefixes, HttpListenerPrefix prefix)
        {
            var path = prefix.Path;

            foreach (var pref in prefixes)
            {
                if (pref.Path == path)
                {
                    throw new HttpListenerException(400, "The prefix is already in use."); // TODO: Code?
                }
            }
            prefixes.Add(prefix);
        }
예제 #6
0
        /// <summary>
        /// Adds the specified <paramref name="uriPrefix"/> to the collection.
        /// </summary>
        /// <param name="uriPrefix">
        /// A <see cref="string"/> that represents the URI prefix to add. The prefix must be
        /// a well-formed URI prefix with http or https scheme, and must end with a <c>'/'</c>.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="uriPrefix"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="uriPrefix"/> is invalid.
        /// </exception>
        /// <exception cref="ObjectDisposedException">
        /// The <see cref="HttpListener"/> associated with this collection is closed.
        /// </exception>
        public void Add(string uriPrefix)
        {
            _listener.CheckDisposed();
            HttpListenerPrefix.CheckPrefix(uriPrefix);
            if (_prefixes.Contains(uriPrefix))
            {
                return;
            }

            _prefixes.Add(uriPrefix);
            if (_listener.IsListening)
            {
                EndPointManager.AddPrefix(uriPrefix, _listener);
            }
        }
예제 #7
0
        private static bool removeSpecial(List <HttpListenerPrefix> prefixes, HttpListenerPrefix prefix)
        {
            var path = prefix.Path;
            var cnt  = prefixes.Count;

            for (var i = 0; i < cnt; i++)
            {
                if (prefixes[i].Path == path)
                {
                    prefixes.RemoveAt(i);
                    return(true);
                }
            }

            return(false);
        }
예제 #8
0
        private static void addPrefix(string uriPrefix, HttpListener listener)
        {
            var pref = new HttpListenerPrefix(uriPrefix);

            if (pref.Path.IndexOf('%') != -1)
            {
                throw new HttpListenerException(400, "Invalid path."); // TODO: Code?
            }
            if (pref.Path.IndexOf("//", StringComparison.Ordinal) != -1)
            {
                throw new HttpListenerException(400, "Invalid path."); // TODO: Code?
            }
            // Listens on all the interfaces if host name cannot be parsed by IPAddress.
            var lsnr = getEndPointListener(pref.Host, pref.Port, listener, pref.IsSecure);

            lsnr.AddPrefix(pref, listener);
        }
예제 #9
0
        private static void removePrefix(string uriPrefix, HttpListener listener)
        {
            var pref = new HttpListenerPrefix(uriPrefix);

            if (pref.Path.IndexOf('%') != -1)
            {
                return;
            }

            if (pref.Path.IndexOf("//", StringComparison.Ordinal) != -1)
            {
                return;
            }

            var lsnr = getEndPointListener(pref.Host, pref.Port, listener, pref.IsSecure);

            lsnr.RemovePrefix(pref, listener);
        }
예제 #10
0
    public void RemovePrefix (HttpListenerPrefix prefix, HttpListener listener)
    {
      List<HttpListenerPrefix> current, future;
      if (prefix.Host == "*") {
        do {
          current = _unhandled;
          if (current == null)
            break;

          future = new List<HttpListenerPrefix> (current);
          if (!removeSpecial (future, prefix))
            break; // The prefix wasn't found.
        }
        while (Interlocked.CompareExchange (ref _unhandled, future, current) != current);

        checkIfRemove ();
        return;
      }

      if (prefix.Host == "+") {
        do {
          current = _all;
          if (current == null)
            break;

          future = new List<HttpListenerPrefix> (current);
          if (!removeSpecial (future, prefix))
            break; // The prefix wasn't found.
        }
        while (Interlocked.CompareExchange (ref _all, future, current) != current);

        checkIfRemove ();
        return;
      }

      Dictionary<HttpListenerPrefix, HttpListener> prefs, prefs2;
      do {
        prefs = _prefixes;
        if (!prefs.ContainsKey (prefix))
          break;

        prefs2 = new Dictionary<HttpListenerPrefix, HttpListener> (prefs);
        prefs2.Remove (prefix);
      }
      while (Interlocked.CompareExchange (ref _prefixes, prefs2, prefs) != prefs);

      checkIfRemove ();
    }
예제 #11
0
    public void AddPrefix (HttpListenerPrefix prefix, HttpListener listener)
    {
      List<HttpListenerPrefix> current, future;
      if (prefix.Host == "*") {
        do {
          current = _unhandled;
          future = current != null
                   ? new List<HttpListenerPrefix> (current)
                   : new List<HttpListenerPrefix> ();

          prefix.Listener = listener;
          addSpecial (future, prefix);
        }
        while (Interlocked.CompareExchange (ref _unhandled, future, current) != current);

        return;
      }

      if (prefix.Host == "+") {
        do {
          current = _all;
          future = current != null
                   ? new List<HttpListenerPrefix> (current)
                   : new List<HttpListenerPrefix> ();

          prefix.Listener = listener;
          addSpecial (future, prefix);
        }
        while (Interlocked.CompareExchange (ref _all, future, current) != current);

        return;
      }

      Dictionary<HttpListenerPrefix, HttpListener> prefs, prefs2;
      do {
        prefs = _prefixes;
        if (prefs.ContainsKey (prefix)) {
          if (prefs[prefix] != listener)
            throw new HttpListenerException (
              400, String.Format ("There's another listener for {0}.", prefix)); // TODO: Code?

          return;
        }

        prefs2 = new Dictionary<HttpListenerPrefix, HttpListener> (prefs);
        prefs2[prefix] = listener;
      }
      while (Interlocked.CompareExchange (ref _prefixes, prefs2, prefs) != prefs);
    }
예제 #12
0
    private HttpListener searchListener (Uri uri, out HttpListenerPrefix prefix)
    {
      prefix = null;
      if (uri == null)
        return null;

      var host = uri.Host;
      var port = uri.Port;
      var path = HttpUtility.UrlDecode (uri.AbsolutePath);
      var pathSlash = path[path.Length - 1] == '/' ? path : path + "/";

      HttpListener bestMatch = null;
      var bestLen = -1;
      if (host != null && host.Length > 0) {
        foreach (var pref in _prefixes.Keys) {
          var ppath = pref.Path;
          if (ppath.Length < bestLen)
            continue;

          if (pref.Host != host || pref.Port != port)
            continue;

          if (path.StartsWith (ppath) || pathSlash.StartsWith (ppath)) {
            bestLen = ppath.Length;
            bestMatch = _prefixes[pref];
            prefix = pref;
          }
        }

        if (bestLen != -1)
          return bestMatch;
      }

      var list = _unhandled;
      bestMatch = matchFromList (host, path, list, out prefix);
      if (path != pathSlash && bestMatch == null)
        bestMatch = matchFromList (host, pathSlash, list, out prefix);

      if (bestMatch != null)
        return bestMatch;

      list = _all;
      bestMatch = matchFromList (host, path, list, out prefix);
      if (path != pathSlash && bestMatch == null)
        bestMatch = matchFromList (host, pathSlash, list, out prefix);

      if (bestMatch != null)
        return bestMatch;

      return null;
    }
예제 #13
0
    private static bool removeSpecial (List<HttpListenerPrefix> prefixes, HttpListenerPrefix prefix)
    {
      var path = prefix.Path;
      var cnt = prefixes.Count;
      for (var i = 0; i < cnt; i++) {
        if (prefixes[i].Path == path) {
          prefixes.RemoveAt (i);
          return true;
        }
      }

      return false;
    }
예제 #14
0
    private static HttpListener matchFromList (
      string host, string path, List<HttpListenerPrefix> list, out HttpListenerPrefix prefix)
    {
      prefix = null;
      if (list == null)
        return null;

      HttpListener bestMatch = null;
      var bestLen = -1;
      foreach (var pref in list) {
        var ppath = pref.Path;
        if (ppath.Length < bestLen)
          continue;

        if (path.StartsWith (ppath)) {
          bestLen = ppath.Length;
          bestMatch = pref.Listener;
          prefix = pref;
        }
      }

      return bestMatch;
    }
예제 #15
0
    private static void addSpecial (List<HttpListenerPrefix> prefixes, HttpListenerPrefix prefix)
    {
      var path = prefix.Path;
      foreach (var pref in prefixes)
        if (pref.Path == path)
          throw new HttpListenerException (400, "The prefix is already in use."); // TODO: Code?

      prefixes.Add (prefix);
    }
예제 #16
0
 private void init ()
 {
   _chunked = false;
   _context = new HttpListenerContext (this);
   _inputState = InputState.RequestLine;
   _inputStream = null;
   _lineState = LineState.None;
   _outputStream = null;
   _position = 0;
   _prefix = null;
   _requestBuffer = new MemoryStream ();
 }
예제 #17
0
        private HttpListener searchListener(Uri uri, out HttpListenerPrefix prefix)
        {
            prefix = null;
            if (uri == null)
            {
                return(null);
            }

            var host      = uri.Host;
            var port      = uri.Port;
            var path      = HttpUtility.UrlDecode(uri.AbsolutePath);
            var pathSlash = path[path.Length - 1] == '/' ? path : path + "/";

            HttpListener bestMatch = null;
            var          bestLen   = -1;

            if (host != null && host.Length > 0)
            {
                foreach (var pref in _prefixes.Keys)
                {
                    var ppath = pref.Path;
                    if (ppath.Length < bestLen)
                    {
                        continue;
                    }

                    if (pref.Host != host || pref.Port != port)
                    {
                        continue;
                    }

                    if (path.StartsWith(ppath) || pathSlash.StartsWith(ppath))
                    {
                        bestLen   = ppath.Length;
                        bestMatch = _prefixes[pref];
                        prefix    = pref;
                    }
                }

                if (bestLen != -1)
                {
                    return(bestMatch);
                }
            }

            var list = _unhandled;

            bestMatch = matchFromList(host, path, list, out prefix);
            if (path != pathSlash && bestMatch == null)
            {
                bestMatch = matchFromList(host, pathSlash, list, out prefix);
            }

            if (bestMatch != null)
            {
                return(bestMatch);
            }

            list      = _all;
            bestMatch = matchFromList(host, path, list, out prefix);
            if (path != pathSlash && bestMatch == null)
            {
                bestMatch = matchFromList(host, pathSlash, list, out prefix);
            }

            if (bestMatch != null)
            {
                return(bestMatch);
            }

            return(null);
        }
예제 #18
0
        public void RemovePrefix(HttpListenerPrefix prefix, HttpListener listener)
        {
            List <HttpListenerPrefix> current, future;

            if (prefix.Host == "*")
            {
                do
                {
                    current = _unhandled;
                    if (current == null)
                    {
                        break;
                    }

                    future = new List <HttpListenerPrefix> (current);
                    if (!removeSpecial(future, prefix))
                    {
                        break; // The prefix wasn't found.
                    }
                }while (Interlocked.CompareExchange(ref _unhandled, future, current) != current);

                checkIfRemove();
                return;
            }

            if (prefix.Host == "+")
            {
                do
                {
                    current = _all;
                    if (current == null)
                    {
                        break;
                    }

                    future = new List <HttpListenerPrefix> (current);
                    if (!removeSpecial(future, prefix))
                    {
                        break; // The prefix wasn't found.
                    }
                }while (Interlocked.CompareExchange(ref _all, future, current) != current);

                checkIfRemove();
                return;
            }

            Dictionary <HttpListenerPrefix, HttpListener> prefs, prefs2;

            do
            {
                prefs = _prefixes;
                if (!prefs.ContainsKey(prefix))
                {
                    break;
                }

                prefs2 = new Dictionary <HttpListenerPrefix, HttpListener> (prefs);
                prefs2.Remove(prefix);
            }while (Interlocked.CompareExchange(ref _prefixes, prefs2, prefs) != prefs);

            checkIfRemove();
        }
예제 #19
0
    private static void removePrefix (string uriPrefix, HttpListener listener)
    {
      var pref = new HttpListenerPrefix (uriPrefix);
      if (pref.Path.IndexOf ('%') != -1)
        return;

      if (pref.Path.IndexOf ("//", StringComparison.Ordinal) != -1)
        return;

      var lsnr = getEndPointListener (pref.Host, pref.Port, listener, pref.IsSecure);
      lsnr.RemovePrefix (pref, listener);
    }