protected override void OnStart(string[] args) { server = new RelayServer() { EnableBuiltinWebclient = bool.Parse(ConfigurationManager.AppSettings["enableWebClient"] ?? "true") }; stopping = new TaskCompletionSource <bool>(); task = server.Listen( args.Length > 0 ? args[0] : ConfigurationManager.AppSettings["listenPrefix"] ?? "http://*:80/", int.Parse(ConfigurationManager.AppSettings["maxConnections"] ?? "8"), stopping); base.OnStart(args); }
private static void HandleRelay(Stream stream, Options options) { IRelay relay; string code, urlBase = options.ListenPrefix.Replace("*", HostName).Replace("+", HostName).Replace(":80", ""); var done = new TaskCompletionSource <bool>(); Task <bool> listenTask = null; if (!string.IsNullOrEmpty(options.RemoteHost)) { relay = new SocketRelayClient(); code = (relay as SocketRelayClient).AddRelay(new Uri(options.RemoteHost), stream, options.FinalFilename, options.FinalContentType).Result; urlBase = options.RemoteHost.Replace("ws", "http"); } else if (options.ListenPrefix.AlreadyListening()) { // if something is listening on the requested port, assume it's our service and try to connect to it.. try { relay = new SocketRelayClient(); code = (relay as SocketRelayClient).AddRelay(new Uri(urlBase.Replace("http", "ws")), stream, options.FinalFilename, options.FinalContentType).Result; } catch (Exception e) { throw new Exception($"Another process is already listening on {options.ListenPrefix}\r\n" + "Try a different port or install the service to avoid this error.", e); } } else { relay = new LocalRelay(stream, options.FinalFilename, options.FinalContentType); var server = new RelayServer() { AcceptSocketConnections = false }; code = server.AddRelay(relay); listenTask = server.Listen(options.ListenPrefix, options.MaxConnections.Value, done); if (listenTask.IsFaulted) { throw listenTask.Exception.InnerException; } } int lastLen = Console.BufferWidth - 1; void PrintStatus(string status) { string line = string.Format("Status: {0}", status); int lineLen = line.Length; if (lineLen < lastLen) { line = line.PadRight(lastLen); } lastLen = lineLen; Console.CursorLeft = 0; Console.Write(line); } relay.OnStart += () => PrintStatus("download starting.."); relay.OnComplete += () => { PrintStatus("download complete"); done.TrySetResult(true); }; relay.OnDisconnect += () => PrintStatus("disconnected, waiting for resume.."); relay.OnCancel += () => { PrintStatus("canceled"); done.TrySetResult(false); }; long lastDownloaded = 0; double lastLastBps = 0, lastBps = 0, inverseTotal = (stream.CanSeek && stream.Length > 0) ? 100.0 / stream.Length : 1.0; void ProgressUpdate(long downloaded, long?total) { double bps = downloaded - lastDownloaded; bps = (bps + (lastBps > 0 ? lastBps : bps) + (lastLastBps > 0 ? lastLastBps : bps)) / 3.0; lastLastBps = lastBps; lastBps = bps; lastDownloaded = downloaded; if (total.HasValue) { var remaining = bps > 0 ? TimeSpan.FromSeconds((total.Value - downloaded) / bps).ToString("hh\\:mm\\:ss") : "--:--:--"; PrintStatus($"{downloaded.FormatBytes()} ({downloaded * inverseTotal:0}%) downloaded, time remaining {remaining} (at {((long)bps).FormatBytes()}/sec)"); } else { PrintStatus($"{downloaded.FormatBytes()} downloaded (at {((long)bps).FormatBytes()}/sec)"); } } relay.OnProgress += (transferred, total) => ProgressUpdate(transferred, total); Console.WriteLine($"Download link: {urlBase.TrimEnd('/')}/{code}"); Console.WriteLine($"Press {(Console.IsInputRedirected ? "CTRL+C" : "any key")} to cancel"); Console.WriteLine(); PrintStatus("waiting for connection.."); if (Console.IsInputRedirected) { Console.CancelKeyPress += (e, args) => { done.TrySetResult(false); relay.Cancel(); }; done.Task.Wait(); } else { while (!done.Task.IsCompleted) { Thread.Sleep(100); if (Console.KeyAvailable) { done.TrySetResult(false); relay.Cancel(); } } } if (listenTask != null && listenTask.IsFaulted) { PrintStatus("error"); Console.WriteLine(); throw listenTask.Exception.InnerException; } if (done.Task.Result) { PrintStatus("completed successfully"); } else { PrintStatus("canceled"); } }
private void Application_Startup(object sender, StartupEventArgs e) { bool isAdmin = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); try { if (OneInstance.First()) { OneInstance.OnMessage += AddRelay; } else if (e.Args.Length > 0) { OneInstance.SendMessage(new FileInfo(e.Args[0]).FullName); Shutdown(); return; } if (e.Args.Length == 0) { if (isAdmin) { InstallRegistry(); } if (!stayOpen) { Shutdown(); return; } } urlBase = listenPrefix.Replace("*", hostName).Replace("+", hostName).Replace(":80", ""); var enableWebclient = bool.Parse(ConfigurationManager.AppSettings["enableWebClient"] ?? "true"); var acceptRelays = bool.Parse(ConfigurationManager.AppSettings["acceptRelays"] ?? "true"); var maxConnections = int.Parse(ConfigurationManager.AppSettings["maxConnections"] ?? "8"); if (!string.IsNullOrEmpty(remoteHost)) { remote = true; urlBase = remoteHost.Replace("ws", "http"); } else if (listenPrefix.AlreadyListening()) { remote = true; remoteHost = urlBase.Replace("http", "ws"); } else { remote = false; server = new RelayServer() { EnableBuiltinWebclient = enableWebclient, AcceptSocketConnections = acceptRelays }; stop = new TaskCompletionSource <bool>(); listen = server.Listen(listenPrefix, maxConnections, stop); if (listen.IsFaulted) { throw listen.Exception.InnerException; } server.OnSocketRelay += (file, size, code, relay) => AddRelayStatus(file, size, urlBase + code, relay); } urlBase += urlBase.EndsWith("/") ? "" : "/"; urlBase = Regex.Replace(urlBase, "localhost", hostName, RegexOptions.IgnoreCase); var idleStatus = $"{(remote ? "Relaying to" : "Listening on")} {urlBase}"; if (!remote) { idleStatus += $"\r\n{(acceptRelays ? "Accepting" : "Not accepting")} relays" + $"\r\nWebclient is {(enableWebclient ? "enabled" : "disabled")}" + $"\r\n{maxConnections} max connections"; } relayStatus = new RelayStatus(idleStatus); notifyIcon = (TaskbarIcon)FindResource("NotifyIcon"); notifyIcon.TrayToolTip = relayStatus; notifyIcon.DataContext = relayStatus; if (e.Args.Length > 0) { AddRelay(e.Args[0]); } else { notifyIcon.Icon = appIcon; ShowRelays(); } } catch (System.Net.HttpListenerException ex) when((uint)ex.HResult == 0x80004005) // access denied { if (!isAdmin) { OneInstance.Dispose(); Process.Start(new ProcessStartInfo(Assembly.GetEntryAssembly().Location, e.Args.Length > 0 ? e.Args[0] : "") { Verb = "runas" }); } else { MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } Shutdown(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); Shutdown(); } }