示例#1
0
文件: Program.cs 项目: gfody/WebRelay
            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);
            }
示例#2
0
文件: Program.cs 项目: gfody/WebRelay
        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");
            }
        }
示例#3
0
        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();
            }
        }