private static async void ProcessAccept(SocketAsyncEventArgs args) { HttpEndPointListener epl = (HttpEndPointListener)args.UserToken; if (epl._closed) { return; } // http://msdn.microsoft.com/en-us/library/system.net.sockets.acceptSocket.acceptasync%28v=vs.110%29.aspx // Under certain conditions ConnectionReset can occur // Need to attept to re-accept var socketError = args.SocketError; var accepted = args.AcceptSocket; epl.Accept(args); if (socketError == SocketError.ConnectionReset) { epl._logger.LogError("SocketError.ConnectionReset reported. Attempting to re-accept."); return; } if (accepted == null) { return; } if (epl._secure && epl._cert == null) { TryClose(accepted); return; } try { var remoteEndPointString = accepted.RemoteEndPoint == null ? string.Empty : accepted.RemoteEndPoint.ToString(); var localEndPointString = accepted.LocalEndPoint == null ? string.Empty : accepted.LocalEndPoint.ToString(); //_logger.LogInformation("HttpEndPointListener Accepting connection from {0} to {1} secure connection requested: {2}", remoteEndPointString, localEndPointString, _secure); HttpConnection conn = new HttpConnection(epl._logger, accepted, epl, epl._secure, epl._cert, epl._cryptoProvider, epl._streamHelper, epl._textEncoding, epl._fileSystem, epl._environment); await conn.Init().ConfigureAwait(false); //_logger.LogDebug("Adding unregistered connection to {0}. Id: {1}", accepted.RemoteEndPoint, connectionId); lock (epl._unregisteredConnections) { epl._unregisteredConnections[conn] = conn; } conn.BeginReadRequest(); } catch (Exception ex) { epl._logger.LogError(ex, "Error in ProcessAccept"); TryClose(accepted); epl.Accept(); return; } }
private static void Accept(Socket socket, SocketAsyncEventArgs acceptEventArg, ref Socket accepted) { // acceptSocket must be cleared since the context object is being reused acceptEventArg.AcceptSocket = null; try { bool willRaiseEvent = socket.AcceptAsync(acceptEventArg); if (!willRaiseEvent) { ProcessAccept(acceptEventArg); } } catch (ObjectDisposedException) { if (accepted != null) { TryCloseAndDispose(accepted); } } catch (Exception ex) { HttpEndPointListener epl = (HttpEndPointListener)acceptEventArg.UserToken; epl._logger.ErrorException("Error in socket.AcceptAsync", ex); if (accepted != null) { TryClose(accepted); accepted = null; } } }
private void Accept(SocketAsyncEventArgs acceptEventArg) { // acceptSocket must be cleared since the context object is being reused acceptEventArg.AcceptSocket = null; try { bool willRaiseEvent = _socket.AcceptAsync(acceptEventArg); if (!willRaiseEvent) { ProcessAccept(acceptEventArg); } } catch (ObjectDisposedException) { // TODO Investigate or properly fix. } catch (Exception ex) { HttpEndPointListener epl = (HttpEndPointListener)acceptEventArg.UserToken; epl._logger.LogError(ex, "Error in socket.AcceptAsync"); } }
private static void Accept(Socket socket, HttpEndPointListener epl) { var acceptEventArg = new SocketAsyncEventArgs(); acceptEventArg.UserToken = epl; acceptEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(OnAccept); Socket dummy = null; Accept(socket, acceptEventArg, ref dummy); }
public static void RemoveEndPoint(HttpEndPointListener epl, IPEndPoint ep) { lock ((s_ipEndPoints as ICollection).SyncRoot) { Dictionary <int, HttpEndPointListener> p = null; p = s_ipEndPoints[ep.Address]; p.Remove(ep.Port); if (p.Count == 0) { s_ipEndPoints.Remove(ep.Address); } epl.Close(); } }
private 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; } HttpEndPointListener epl = GetEPListener(logger, lp.Host, lp.Port, listener, lp.Secure); epl.RemovePrefix(lp, listener); }
public HttpConnection(ILogger logger, Socket socket, HttpEndPointListener epl, bool secure, X509Certificate cert, ICryptoProvider cryptoProvider, IStreamHelper streamHelper, IFileSystem fileSystem, IEnvironmentInfo environment) { _logger = logger; this._socket = socket; this._epl = epl; this.secure = secure; this.cert = cert; _cryptoProvider = cryptoProvider; _streamHelper = streamHelper; _fileSystem = fileSystem; _environment = environment; if (secure == false) { _stream = new SocketStream(_socket, false); } else { ssl_stream = new SslStream(new SocketStream(_socket, false), false, (t, c, ch, e) => { if (c == null) { return(true); } //var c2 = c as X509Certificate2; //if (c2 == null) //{ // c2 = new X509Certificate2(c.GetRawCertData()); //} //_clientCert = c2; //_clientCertErrors = new int[] { (int)e }; return(true); }); _stream = ssl_stream; } }
private static async void ProcessAccept(SocketAsyncEventArgs args) { HttpEndPointListener epl = (HttpEndPointListener)args.UserToken; if (epl._closed) { return; } var acceptSocket = args.AcceptSocket; // http://msdn.microsoft.com/en-us/library/system.net.sockets.acceptSocket.acceptasync%28v=vs.110%29.aspx // Under certain conditions ConnectionReset can occur // Need to attept to re-accept if (args.SocketError == SocketError.ConnectionReset) { epl._logger.Error("SocketError.ConnectionReset reported. Attempting to re-accept."); TryClose(acceptSocket); Accept(epl._socket, epl); return; } if (acceptSocket != null) { try { await epl.ProcessAccept(acceptSocket).ConfigureAwait(false); } catch (Exception ex) { epl._logger.ErrorException("Error in ProcessAccept", ex); TryClose(acceptSocket); Accept(epl._socket, epl); return; } } // Accept the next connection request Accept(epl._socket, args, ref acceptSocket); }
private static void AddPrefixInternal(ILogger logger, string p, HttpListener listener) { int start = p.IndexOf(':') + 3; int colon = p.IndexOf(':', start); if (colon != -1) { // root can't be -1 here, since we've already checked for ending '/' in ListenerPrefix. int root = p.IndexOf('/', colon, p.Length - colon); string portString = p.Substring(colon + 1, root - colon - 1); int port; if (!int.TryParse(portString, out port) || port <= 0 || port >= 65536) { throw new HttpListenerException((int)HttpStatusCode.BadRequest, "net_invalid_port"); } } ListenerPrefix lp = new ListenerPrefix(p); if (lp.Host != "*" && lp.Host != "+" && Uri.CheckHostName(lp.Host) == UriHostNameType.Unknown) { throw new HttpListenerException((int)HttpStatusCode.BadRequest, "net_listener_host"); } if (lp.Path.IndexOf('%') != -1) { throw new HttpListenerException((int)HttpStatusCode.BadRequest, "net_invalid_path"); } if (lp.Path.IndexOf("//", StringComparison.Ordinal) != -1) { throw new HttpListenerException((int)HttpStatusCode.BadRequest, "net_invalid_path"); } // listens on all the interfaces if host name cannot be parsed by IPAddress. HttpEndPointListener epl = GetEPListener(logger, lp.Host, lp.Port, listener, lp.Secure); epl.AddPrefix(lp, listener); }
private static HttpEndPointListener GetEPListener(ILogger logger, string host, int port, HttpListener listener, bool secure) { IPAddress addr; if (host == "*" || host == "+") { addr = GetIpAnyAddress(listener); } else { const int NotSupportedErrorCode = 50; try { addr = Dns.GetHostAddresses(host)[0]; } catch { // Throw same error code as windows, request is not supported. throw new HttpListenerException(NotSupportedErrorCode, "net_listener_not_supported"); } if (IPAddress.Any.Equals(addr)) { // Don't support listening to 0.0.0.0, match windows behavior. throw new HttpListenerException(NotSupportedErrorCode, "net_listener_not_supported"); } } Dictionary <int, HttpEndPointListener> p = null; if (s_ipEndPoints.ContainsKey(addr)) { p = s_ipEndPoints[addr]; } else { p = new Dictionary <int, HttpEndPointListener>(); s_ipEndPoints[addr] = p; } HttpEndPointListener epl = null; if (p.ContainsKey(port)) { epl = p[port]; } else { try { epl = new HttpEndPointListener(listener, addr, port, secure, listener.Certificate, logger, listener.CryptoProvider, listener.SocketFactory, listener.MemoryStreamFactory, listener.TextEncoding, listener.FileSystem, listener.EnvironmentInfo); } catch (SocketException ex) { throw new HttpListenerException(ex.ErrorCode, ex.Message); } p[port] = epl; } return(epl); }