From b2a8e7dba5dded073e678b8b783063550f978f13 Mon Sep 17 00:00:00 2001 From: sloumdrone Date: Sun, 6 Oct 2019 19:59:46 -0700 Subject: [PATCH] Adds basic finger protocol support to Bombadillo --- client.go | 15 +++++++++++++++ finger/finger.go | 31 +++++++++++++++++++++++++++++++ url.go | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 finger/finger.go diff --git a/client.go b/client.go index a8b7b2f..1e7c93d 100644 --- a/client.go +++ b/client.go @@ -12,6 +12,7 @@ import ( "tildegit.org/sloum/bombadillo/cmdparse" "tildegit.org/sloum/bombadillo/cui" + "tildegit.org/sloum/bombadillo/finger" "tildegit.org/sloum/bombadillo/gemini" "tildegit.org/sloum/bombadillo/gopher" "tildegit.org/sloum/bombadillo/http" @@ -966,6 +967,20 @@ func (c *client) Visit(url string) { c.SetMessage("'openhttp' is not set to true, cannot open web link", false) c.DrawMessage() } + case "finger": + content, err := finger.Finger(u.Host, u.Port, u.Resource) + if err != nil { + c.SetMessage(err.Error(), true) + c.DrawMessage() + return + } + pg := MakePage(u, content, []string{}) + pg.WrapContent(c.Width - 1) + c.PageState.Add(pg) + c.SetPercentRead() + c.ClearMessage() + c.SetHeaderUrl() + c.Draw() default: c.SetMessage(fmt.Sprintf("%q is not a supported protocol", u.Scheme), true) c.DrawMessage() diff --git a/finger/finger.go b/finger/finger.go new file mode 100644 index 0000000..d02a1b1 --- /dev/null +++ b/finger/finger.go @@ -0,0 +1,31 @@ +package finger + +import ( + "fmt" + "net" + "io/ioutil" + "time" +) + +func Finger(host, port, resource string) (string, error) { + addr := fmt.Sprintf("%s:%s", host, port) + + timeOut := time.Duration(3) * time.Second + conn, err := net.DialTimeout("tcp", addr, timeOut) + if err != nil { + return "", err + } + + defer conn.Close() + + _, err = conn.Write([]byte(resource + "\r\n")) + if err != nil { + return "", err + } + + result, err := ioutil.ReadAll(conn) + if err != nil { + return "", err + } + return string(result), nil +} diff --git a/url.go b/url.go index 73b5226..0588ab1 100644 --- a/url.go +++ b/url.go @@ -36,6 +36,13 @@ type Url struct { // representation of a url and returns a Url struct and // an error (or nil). func MakeUrl(u string) (Url, error) { + if len(u) < 1 { + return Url{}, fmt.Errorf("Invalid url, unable to parse") + } + if strings.HasPrefix(u, "finger://") { + return parseFinger(u) + } + var out Url re := regexp.MustCompile(`^((?P[a-zA-Z]+):\/\/)?(?P[\w\-\.\d]+)(?::(?P\d+)?)?(?:/(?P[01345679gIhisp])?)?(?P.*)?$`) match := re.FindStringSubmatch(u) @@ -106,3 +113,32 @@ func MakeUrl(u string) (Url, error) { return out, nil } + +func parseFinger(u string) (Url, error) { + var out Url + out.Scheme = "finger" + if len(u) < 10 { + return out, fmt.Errorf("Invalid finger address") + } + u = u[9:] + userPlusAddress := strings.Split(u, "@") + if len(userPlusAddress) > 1 { + out.Resource = userPlusAddress[0] + u = userPlusAddress[1] + } + hostPort := strings.Split(u, ":") + if len(hostPort) < 2 { + out.Port = "79" + } else { + out.Port = hostPort[1] + } + out.Host = hostPort[0] + resource := "" + if out.Resource != "" { + resource = out.Resource + "@" + } + out.Full = fmt.Sprintf("%s://%s%s:%s", out.Scheme, resource, out.Host, out.Port) + return out, nil +} + +