From 80bdbb642dbf2ed38634f3c2e6f8022d514e8f1b Mon Sep 17 00:00:00 2001 From: sloum Date: Mon, 29 Jun 2020 21:45:24 -0700 Subject: [PATCH 1/2] Adds timeout to tls for gemini and increases gopher timeout --- gemini/gemini.go | 4 +++- gopher/gopher.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gemini/gemini.go b/gemini/gemini.go index 44c8545..ae5af8e 100644 --- a/gemini/gemini.go +++ b/gemini/gemini.go @@ -6,6 +6,7 @@ import ( "crypto/tls" "fmt" "io/ioutil" + "net" "net/url" "strconv" "strings" @@ -26,6 +27,7 @@ type TofuDigest struct { } var BlockBehavior = "block" +var TlsTimeout = time.Duration(15) * time.Second //------------------------------------------------\\ // + + + R E C E I V E R S + + + \\ @@ -189,7 +191,7 @@ func Retrieve(host, port, resource string, td *TofuDigest) (string, error) { return &td.ClientCert, nil } - conn, err := tls.Dial("tcp", addr, conf) + conn, err := tls.DialWithDialer(&net.Dialer{Timeout: TlsTimeout}, "tcp", addr, conf) if err != nil { return "", fmt.Errorf("TLS Dial Error: %s", err.Error()) } diff --git a/gopher/gopher.go b/gopher/gopher.go index 20e76e9..68721d3 100644 --- a/gopher/gopher.go +++ b/gopher/gopher.go @@ -49,7 +49,7 @@ var types = map[string]string{ // be better. func Retrieve(host, port, resource string) ([]byte, error) { nullRes := make([]byte, 0) - timeOut := time.Duration(5) * time.Second + timeOut := time.Duration(15) * time.Second if host == "" || port == "" { return nullRes, errors.New("Incomplete request url") From 185c62f27200a85bd8a7bbb63be1a36217c181e4 Mon Sep 17 00:00:00 2001 From: sloum Date: Mon, 29 Jun 2020 22:19:14 -0700 Subject: [PATCH 2/2] Adds timeout config option --- bombadillo.1 | 4 ++++ client.go | 15 +++++++++++++++ defaults.go | 3 ++- gemini/gemini.go | 4 ++-- gopher/gopher.go | 5 +++-- main.go | 10 ++++++++++ 6 files changed, 36 insertions(+), 5 deletions(-) diff --git a/bombadillo.1 b/bombadillo.1 index c8b19a0..ea650b2 100644 --- a/bombadillo.1 +++ b/bombadillo.1 @@ -257,6 +257,10 @@ theme Can toggle between visual modes. Valid values are \fInormal\fP, \fIcolor\fP, and \fIinverse\fP. When set to inverse, the normal mode colors are inverted. Both normal and inverse modes filter out terminal escape sequences. When set to color, Bombadillo will render terminal escape sequences representing colors when it finds them in documents. .TP .B +timeout +The number of seconds after which connections to gopher or gemini servers should time out if the server has not responded. +.TP +.B tlscertificate A path to a tls certificate file on a user's local filesystem. Defaults to NULL. Both \fItlscertificate\fP and \fItlskey\fP must be set for client certificates to work in gemini. .TP diff --git a/client.go b/client.go index 25d7723..f14565f 100644 --- a/client.go +++ b/client.go @@ -455,6 +455,8 @@ func (c *client) doCommandAs(action string, values []string) { c.Certs.LoadCertificate(c.Options["tlscertificate"], c.Options["tlskey"]) } else if values[0] == "geminiblocks" { gemini.BlockBehavior = c.Options[values[0]] + } else if values[0] == "timeout" { + updateTimeouts(c.Options[values[0]]) } else if values[0] == "configlocation" { c.SetMessage("Cannot set READ ONLY setting 'configlocation'", true) c.DrawMessage() @@ -1195,3 +1197,16 @@ func findAvailableFileName(fpath, fname string) (string, error) { return savePath, nil } + +func updateTimeouts(timeoutString string) error { + sec, err := strconv.Atoi(timeoutString) + if err != nil { + return err + } + timeout := time.Duration(sec) * time.Second + + gopher.Timeout = timeout + gemini.TlsTimeout = timeout + + return nil +} diff --git a/defaults.go b/defaults.go index fc47a64..b0f28a8 100644 --- a/defaults.go +++ b/defaults.go @@ -54,9 +54,10 @@ var defaultOptions = map[string]string{ "showimages": "true", "telnetcommand": "telnet", "theme": "normal", // "normal", "inverted", "color" + "timeout": "15", // connection timeout for gopher/gemini in seconds "tlscertificate": "", "tlskey": "", - "webmode": "none", // "none", "gui", "lynx", "w3m", "elinks" + "webmode": "none", // "none", "gui", "lynx", "w3m", "elinks" } // homePath will return the path to your home directory as a string diff --git a/gemini/gemini.go b/gemini/gemini.go index ae5af8e..a3625f2 100644 --- a/gemini/gemini.go +++ b/gemini/gemini.go @@ -26,8 +26,8 @@ type TofuDigest struct { ClientCert tls.Certificate } -var BlockBehavior = "block" -var TlsTimeout = time.Duration(15) * time.Second +var BlockBehavior string = "block" +var TlsTimeout time.Duration = time.Duration(15) * time.Second //------------------------------------------------\\ // + + + R E C E I V E R S + + + \\ diff --git a/gopher/gopher.go b/gopher/gopher.go index 68721d3..fbe579f 100644 --- a/gopher/gopher.go +++ b/gopher/gopher.go @@ -38,6 +38,8 @@ var types = map[string]string{ "T": "TEL", } +var Timeout time.Duration = time.Duration(15) * time.Second + //------------------------------------------------\\ // + + + F U N C T I O N S + + + \\ //--------------------------------------------------\\ @@ -49,7 +51,6 @@ var types = map[string]string{ // be better. func Retrieve(host, port, resource string) ([]byte, error) { nullRes := make([]byte, 0) - timeOut := time.Duration(15) * time.Second if host == "" || port == "" { return nullRes, errors.New("Incomplete request url") @@ -57,7 +58,7 @@ func Retrieve(host, port, resource string) ([]byte, error) { addr := host + ":" + port - conn, err := net.DialTimeout("tcp", addr, timeOut) + conn, err := net.DialTimeout("tcp", addr, Timeout) if err != nil { return nullRes, err } diff --git a/main.go b/main.go index 28fcf36..a9b5d83 100644 --- a/main.go +++ b/main.go @@ -82,6 +82,14 @@ func validateOpt(opt, val string) bool { } return false } + + if opt == "timeout" { + _, err := strconv.Atoi(val) + if err != nil { + return false + } + } + return true } @@ -126,6 +134,8 @@ func loadConfig() { bombadillo.Options[lowerkey] = v.Value if lowerkey == "geminiblocks" { gemini.BlockBehavior = v.Value + } else if lowerkey == "timeout" { + updateTimeouts(v.Value) } } else { bombadillo.Options[lowerkey] = defaultOptions[lowerkey]