public static ServerAddress FromUrl(string url) { url = url ?? string.Empty; int delimiterStart1 = url.IndexOf("://", StringComparison.Ordinal); if (delimiterStart1 < 0) { return null; } int delimiterEnd1 = delimiterStart1 + "://".Length; int delimiterStart3 = url.IndexOf("/", delimiterEnd1, StringComparison.Ordinal); if (delimiterStart3 < 0) { delimiterStart3 = url.Length; } int delimiterStart2 = url.LastIndexOf(":", delimiterStart3 - 1, delimiterStart3 - delimiterEnd1, StringComparison.Ordinal); int delimiterEnd2 = delimiterStart2 + ":".Length; if (delimiterStart2 < 0) { delimiterStart2 = delimiterStart3; delimiterEnd2 = delimiterStart3; } var serverAddress = new ServerAddress(); serverAddress.Scheme = url.Substring(0, delimiterStart1); string portString = url.Substring(delimiterEnd2, delimiterStart3 - delimiterEnd2); int portNumber; if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portNumber)) { serverAddress.Host = url.Substring(delimiterEnd1, delimiterStart2 - delimiterEnd1); serverAddress.Port = portNumber; } else { if (string.Equals(serverAddress.Scheme, "http", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 80; } else if (string.Equals(serverAddress.Scheme, "https", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 443; } else { serverAddress.Port = 0; } serverAddress.Host = url.Substring(delimiterEnd1, delimiterStart3 - delimiterEnd1); } serverAddress.Path = url.Substring(delimiterStart3); return serverAddress; }
public IDisposable CreateServer(ServerAddress address) { var listeners = new List<IDisposable>(); var usingPipes = address.IsUnixPipe; try { var pipeName = (Libuv.IsWindows ? @"\\.\pipe\kestrel_" : "/tmp/kestrel_") + Guid.NewGuid().ToString("n"); var single = Threads.Count == 1; var first = true; foreach (var thread in Threads) { if (single) { var listener = usingPipes ? (Listener) new PipeListener(this) : new TcpListener(this); listeners.Add(listener); listener.StartAsync(address, thread).Wait(); } else if (first) { var listener = usingPipes ? (ListenerPrimary) new PipeListenerPrimary(this) : new TcpListenerPrimary(this); listeners.Add(listener); listener.StartAsync(pipeName, address, thread).Wait(); } else { var listener = usingPipes ? (ListenerSecondary) new PipeListenerSecondary(this) : new TcpListenerSecondary(this); listeners.Add(listener); listener.StartAsync(pipeName, address, thread).Wait(); } first = false; } return new Disposable(() => { foreach (var listener in listeners) { listener.Dispose(); } }); } catch { foreach (var listener in listeners) { listener.Dispose(); } throw; } }
public static ServerAddress FromUrl(string url) { url = url ?? string.Empty; int schemeDelimiterStart = url.IndexOf("://", StringComparison.Ordinal); if (schemeDelimiterStart < 0) { int port; if (int.TryParse(url, NumberStyles.None, CultureInfo.InvariantCulture, out port)) { return new ServerAddress() { Scheme = "http", Host = "+", Port = port, Path = "/" }; } return null; } int schemeDelimiterEnd = schemeDelimiterStart + "://".Length; var isUnixPipe = url.IndexOf(Constants.UnixPipeHostPrefix, schemeDelimiterEnd, StringComparison.Ordinal) == schemeDelimiterEnd; int pathDelimiterStart; int pathDelimiterEnd; if (!isUnixPipe) { pathDelimiterStart = url.IndexOf("/", schemeDelimiterEnd, StringComparison.Ordinal); pathDelimiterEnd = pathDelimiterStart; } else { pathDelimiterStart = url.IndexOf(":", schemeDelimiterEnd + Constants.UnixPipeHostPrefix.Length, StringComparison.Ordinal); pathDelimiterEnd = pathDelimiterStart + ":".Length; } if (pathDelimiterStart < 0) { pathDelimiterStart = pathDelimiterEnd = url.Length; } var serverAddress = new ServerAddress(); serverAddress.Scheme = url.Substring(0, schemeDelimiterStart); var hasSpecifiedPort = false; if (!isUnixPipe) { int portDelimiterStart = url.LastIndexOf(":", pathDelimiterStart - 1, pathDelimiterStart - schemeDelimiterEnd, StringComparison.Ordinal); if (portDelimiterStart >= 0) { int portDelimiterEnd = portDelimiterStart + ":".Length; string portString = url.Substring(portDelimiterEnd, pathDelimiterStart - portDelimiterEnd); int portNumber; if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portNumber)) { hasSpecifiedPort = true; serverAddress.Host = url.Substring(schemeDelimiterEnd, portDelimiterStart - schemeDelimiterEnd); serverAddress.Port = portNumber; } } if (!hasSpecifiedPort) { if (string.Equals(serverAddress.Scheme, "http", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 80; } else if (string.Equals(serverAddress.Scheme, "https", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 443; } } } if (!hasSpecifiedPort) { serverAddress.Host = url.Substring(schemeDelimiterEnd, pathDelimiterStart - schemeDelimiterEnd); } serverAddress.Path = url.Substring(pathDelimiterEnd); return serverAddress; }
public IDisposable Start(IFeatureCollection serverFeatures, Func <IFeatureCollection, Task> application) { var disposables = new Stack <IDisposable>(); var disposer = new Disposable(() => { foreach (var disposable in disposables) { disposable.Dispose(); } }); try { var information = (KestrelServerInformation)serverFeatures.Get <IKestrelServerInformation>(); var dateHeaderValueManager = new DateHeaderValueManager(); var engine = new KestrelEngine(_libraryManager, new ServiceContext { AppShutdown = _appShutdownService, Log = new KestrelTrace(_logger), DateHeaderValueManager = dateHeaderValueManager }); disposables.Push(engine); disposables.Push(dateHeaderValueManager); if (information.ThreadCount < 0) { throw new ArgumentOutOfRangeException(nameof(information.ThreadCount), information.ThreadCount, "ThreadCount cannot be negative"); } engine.Start(information.ThreadCount == 0 ? 1 : information.ThreadCount); bool atLeastOneListener = false; foreach (var address in information.Addresses) { var parsedAddress = ServerAddress.FromUrl(address); if (parsedAddress == null) { throw new FormatException("Unrecognized listening address: " + address); } else { atLeastOneListener = true; disposables.Push(engine.CreateServer( parsedAddress.Scheme, parsedAddress.Host, parsedAddress.Port, async frame => { var request = new ServerRequest(frame); await application.Invoke(request.Features).ConfigureAwait(false); })); } } if (!atLeastOneListener) { throw new InvalidOperationException("No recognized listening addresses were configured."); } return(disposer); } catch { disposer.Dispose(); throw; } }
public static ServerAddress FromUrl(string url) { url = url ?? string.Empty; int schemeDelimiterStart = url.IndexOf("://", StringComparison.Ordinal); if (schemeDelimiterStart < 0) { int port; if (int.TryParse(url, NumberStyles.None, CultureInfo.InvariantCulture, out port)) { return(new ServerAddress() { Scheme = "http", Host = "+", Port = port, PathBase = "/" }); } return(null); } int schemeDelimiterEnd = schemeDelimiterStart + "://".Length; var isUnixPipe = url.IndexOf(Constants.UnixPipeHostPrefix, schemeDelimiterEnd, StringComparison.Ordinal) == schemeDelimiterEnd; int pathDelimiterStart; int pathDelimiterEnd; if (!isUnixPipe) { pathDelimiterStart = url.IndexOf("/", schemeDelimiterEnd, StringComparison.Ordinal); pathDelimiterEnd = pathDelimiterStart; } else { pathDelimiterStart = url.IndexOf(":", schemeDelimiterEnd + Constants.UnixPipeHostPrefix.Length, StringComparison.Ordinal); pathDelimiterEnd = pathDelimiterStart + ":".Length; } if (pathDelimiterStart < 0) { pathDelimiterStart = pathDelimiterEnd = url.Length; } var serverAddress = new ServerAddress(); serverAddress.Scheme = url.Substring(0, schemeDelimiterStart); var hasSpecifiedPort = false; if (!isUnixPipe) { int portDelimiterStart = url.LastIndexOf(":", pathDelimiterStart - 1, pathDelimiterStart - schemeDelimiterEnd, StringComparison.Ordinal); if (portDelimiterStart >= 0) { int portDelimiterEnd = portDelimiterStart + ":".Length; string portString = url.Substring(portDelimiterEnd, pathDelimiterStart - portDelimiterEnd); int portNumber; if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portNumber)) { hasSpecifiedPort = true; serverAddress.Host = url.Substring(schemeDelimiterEnd, portDelimiterStart - schemeDelimiterEnd); serverAddress.Port = portNumber; } } if (!hasSpecifiedPort) { if (string.Equals(serverAddress.Scheme, "http", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 80; } else if (string.Equals(serverAddress.Scheme, "https", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 443; } } } if (!hasSpecifiedPort) { serverAddress.Host = url.Substring(schemeDelimiterEnd, pathDelimiterStart - schemeDelimiterEnd); } // Path should not end with a / since it will be used as PathBase later if (url[url.Length - 1] == '/') { serverAddress.PathBase = url.Substring(pathDelimiterEnd, url.Length - pathDelimiterEnd - 1); } else { serverAddress.PathBase = url.Substring(pathDelimiterEnd); } return(serverAddress); }
public IDisposable CreateServer(ServerAddress address) { var listeners = new List <IDisposable>(); var usingPipes = address.IsUnixPipe; try { var pipeName = (Libuv.IsWindows ? @"\\.\pipe\kestrel_" : "/tmp/kestrel_") + Guid.NewGuid().ToString("n"); var single = Threads.Count == 1; var first = true; foreach (var thread in Threads) { if (single) { var listener = usingPipes ? (Listener) new PipeListener(this) : new TcpListener(this); listeners.Add(listener); listener.StartAsync(address, thread).Wait(); } else if (first) { var listener = usingPipes ? (ListenerPrimary) new PipeListenerPrimary(this) : new TcpListenerPrimary(this); listeners.Add(listener); listener.StartAsync(pipeName, address, thread).Wait(); } else { var listener = usingPipes ? (ListenerSecondary) new PipeListenerSecondary(this) : new TcpListenerSecondary(this); listeners.Add(listener); listener.StartAsync(pipeName, address, thread).Wait(); } first = false; } return(new Disposable(() => { foreach (var listener in listeners) { listener.Dispose(); } })); } catch { foreach (var listener in listeners) { listener.Dispose(); } throw; } }