Beispiel #1
0
        private async void AddRelay(string filename)
        {
            try
            {
                IRelay relay;
                var    file   = new FileInfo(filename);
                var    stream = file.OpenRead();
                string code;
                if (remote)
                {
                    relay = new SocketRelayClient();
                    code  = await(relay as SocketRelayClient).AddRelay(new Uri(remoteHost), stream, file.Name);
                }
                else
                {
                    relay = new LocalRelay(stream, file.Name);
                    code  = server.AddRelay(relay);
                }

                relay.OnComplete += () => stream.Close();
                relay.OnCancel   += () => stream.Close();
                AddRelayStatus(file.FullName, file.Length, urlBase + code, relay);
                Clipboard.SetDataObject(urlBase + code, true);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);

                if (relayStatus.Relays.Count == 1 && !stayOpen)
                {
                    Shutdown();
                }
            }
        }
Beispiel #2
0
        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");
            }
        }