From 93942f4e0cb4eed8124736b3229fad3fcfa48973 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Wed, 17 Oct 2018 07:38:21 -0700 Subject: [PATCH] give stop signals to servers --- src/croc/recipient.go | 4 +-- src/croc/sender.go | 4 +++ src/croc/sending.go | 5 ++++ src/relay/hub.go | 4 +++ src/relay/relay.go | 27 ++++++++++++++++-- src/win/main.go | 65 +++++++++++++++++++++++-------------------- 6 files changed, 74 insertions(+), 35 deletions(-) diff --git a/src/croc/recipient.go b/src/croc/recipient.go index 66abddfc..e3c0d08e 100644 --- a/src/croc/recipient.go +++ b/src/croc/recipient.go @@ -13,9 +13,8 @@ import ( "sync" "time" - humanize "github.com/dustin/go-humanize" - log "github.com/cihub/seelog" + humanize "github.com/dustin/go-humanize" "github.com/gorilla/websocket" "github.com/schollz/croc/src/comm" "github.com/schollz/croc/src/compress" @@ -73,6 +72,7 @@ func (cr *Croc) receive(forceSend int, serverAddress string, tcpPorts []string, spin.Writer = os.Stderr spin.Suffix = " performing PAKE..." spin.Start() + defer spin.Stop() // pick an elliptic curve curve := siec.SIEC255() diff --git a/src/croc/sender.go b/src/croc/sender.go index 9d334c4a..9cd2d775 100644 --- a/src/croc/sender.go +++ b/src/croc/sender.go @@ -38,6 +38,9 @@ func (cr *Croc) startSender(forceSend int, serverAddress string, tcpPorts []stri if !strings.HasPrefix(err.Error(), "websocket: close 100") { fmt.Fprintf(os.Stderr, "\n"+err.Error()) } + cr.StateString = err.Error() + } else { + cr.StateString = "File transfer completed." } done <- struct{}{} @@ -89,6 +92,7 @@ func (cr *Croc) send(forceSend int, serverAddress string, tcpPorts []string, isL // start a spinner spin := spinner.New(spinner.CharSets[9], 100*time.Millisecond) spin.Writer = os.Stderr + defer spin.Stop() // pick an elliptic curve curve := siec.SIEC255() diff --git a/src/croc/sending.go b/src/croc/sending.go index fbec7834..74d972e2 100644 --- a/src/croc/sending.go +++ b/src/croc/sending.go @@ -18,6 +18,7 @@ import ( // Send the file func (c *Croc) Send(fname, codephrase string) (err error) { + defer log.Flush() log.Debugf("sending %s", fname) errChan := make(chan error) @@ -36,6 +37,10 @@ func (c *Croc) Send(fname, codephrase string) (err error) { // use local relay if !c.NoLocal { + defer func() { + log.Debug("sending relay stop signal") + relay.Stop() + }() go func() { // start own relay and connect to it go relay.Run(c.RelayWebsocketPort, c.RelayTCPPorts) diff --git a/src/relay/hub.go b/src/relay/hub.go index 86d2aca9..bbb11b37 100644 --- a/src/relay/hub.go +++ b/src/relay/hub.go @@ -47,6 +47,10 @@ var h = hub{ func (h *hub) run() { for { + if stop { + log.Debug("stopping hub") + return + } select { case s := <-h.register: log.Debugf("adding connection to %s", s.room) diff --git a/src/relay/relay.go b/src/relay/relay.go index e713e446..951a1ea5 100644 --- a/src/relay/relay.go +++ b/src/relay/relay.go @@ -1,8 +1,10 @@ package relay import ( + "context" "fmt" "net/http" + "time" log "github.com/cihub/seelog" "github.com/schollz/croc/src/logger" @@ -10,6 +12,12 @@ import ( ) var DebugLevel string +var stop bool + +func Stop() { + log.Debug("got stop signal") + stop = true +} // Run is the async operation for running a server func Run(port string, tcpPorts []string) (err error) { @@ -23,12 +31,25 @@ func Run(port string, tcpPorts []string) (err error) { go h.run() log.Debug("running relay on " + port) - http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { + m := http.NewServeMux() + s := http.Server{Addr: ":" + port, Handler: m} + m.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { serveWs(w, r) }) - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "ok") }) - err = http.ListenAndServe(":"+port, nil) + go func() { + for { + if stop { + s.Shutdown(context.Background()) + log.Debug("stopping http server") + return + } + time.Sleep(10 * time.Millisecond) + } + }() + s.ListenAndServe() + log.Debug("finished") return } diff --git a/src/win/main.go b/src/win/main.go index 24f03e0d..f7dc9e04 100644 --- a/src/win/main.go +++ b/src/win/main.go @@ -32,7 +32,7 @@ func main() { window := widgets.NewQMainWindow(nil, 0) window.SetFixedSize2(300, 200) - window.SetWindowTitle("croc - secure data transfer") + window.SetWindowTitle("🐊📦 croc") widget := widgets.NewQWidget(nil, 0) widget.SetLayout(widgets.NewQVBoxLayout()) @@ -45,7 +45,8 @@ func main() { widget.Layout().AddWidget(label) labels[i] = label } - labels[0].SetText("Click 'Send' or 'Receive' to start") + labels[0].SetText("secure data transfer") + labels[1].SetText("Click 'Send' or 'Receive' to start") button := widgets.NewQPushButton2("Send file", nil) button.ConnectClicked(func(bool) { @@ -53,51 +54,55 @@ func main() { dialog("Can only do one send or receive at a time") return } - defer func() { - isWorking = false - }() + isWorking = true var fileDialog = widgets.NewQFileDialog2(nil, "Open file to send...", "", "") fileDialog.SetAcceptMode(widgets.QFileDialog__AcceptOpen) fileDialog.SetFileMode(widgets.QFileDialog__AnyFile) if fileDialog.Exec() != int(widgets.QDialog__Accepted) { + isWorking = false return } var fn = fileDialog.SelectedFiles()[0] if len(fn) == 0 { dialog(fmt.Sprintf("No file selected")) + isWorking = false return } - cr := croc.Init(false) - done := make(chan bool) go func() { + cr := croc.Init(false) + done := make(chan bool) codePhrase := utils.GetRandomName() _, fname := filepath.Split(fn) - labels[0].SetText(fmt.Sprintf("Sending '%'", fname)) - labels[1].SetText(fmt.Sprintf("Code phrase: %s", codePhrase)) + labels[0].UpdateTextFromGoroutine(fmt.Sprintf("Sending '%s'", fname)) + labels[1].UpdateTextFromGoroutine(fmt.Sprintf("Code phrase: %s", codePhrase)) + + go func(done chan bool) { + for { + fmt.Println(cr.FileInfo, cr.Bar) + if cr.FileInfo.SentName != "" { + labels[0].UpdateTextFromGoroutine(fmt.Sprintf("Sending %s", cr.FileInfo.SentName)) + } + if cr.Bar != nil { + barState := cr.Bar.State() + labels[1].UpdateTextFromGoroutine(fmt.Sprintf("%2.1f%% [%2.0f:%2.0f]", barState.CurrentPercent*100, barState.SecondsSince, barState.SecondsLeft)) + } + labels[2].UpdateTextFromGoroutine(cr.StateString) + time.Sleep(100 * time.Millisecond) + select { + case _ = <-done: + labels[2].UpdateTextFromGoroutine(cr.StateString) + return + default: + continue + } + } + }(done) + cr.Send(fn, codePhrase) done <- true - }() - - go func() { - for { - fmt.Println(cr.FileInfo, cr.Bar) - if cr.FileInfo.SentName != "" { - labels[0].UpdateTextFromGoroutine(fmt.Sprintf("%s", cr.FileInfo.SentName)) - } - if cr.Bar != nil { - barState := cr.Bar.State() - labels[1].UpdateTextFromGoroutine(fmt.Sprintf("%2.1f", barState.CurrentPercent)) - } - time.Sleep(100 * time.Millisecond) - select { - case _ = <-done: - break - default: - continue - } - } + isWorking = false }() // for i, label := range labels { @@ -144,7 +149,7 @@ func main() { os.Chdir(fn) defer os.Chdir(cwd) - cr := croc.Init(false) + cr := croc.Init(true) done := make(chan bool) go func() { cr.Receive(codePhrase)