forked from sloum/bombadillo
Merges updates from develop into file-mode so that merge into develop can happen
This commit is contained in:
commit
4a8c9cd074
|
@ -50,7 +50,6 @@ func (b *Bookmarks) ToggleOpen() {
|
||||||
b.IsFocused = true
|
b.IsFocused = true
|
||||||
} else {
|
} else {
|
||||||
b.IsFocused = false
|
b.IsFocused = false
|
||||||
cui.Clear("screen")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
74
client.go
74
client.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -12,6 +13,7 @@ import (
|
||||||
|
|
||||||
"tildegit.org/sloum/bombadillo/cmdparse"
|
"tildegit.org/sloum/bombadillo/cmdparse"
|
||||||
"tildegit.org/sloum/bombadillo/cui"
|
"tildegit.org/sloum/bombadillo/cui"
|
||||||
|
"tildegit.org/sloum/bombadillo/finger"
|
||||||
"tildegit.org/sloum/bombadillo/gemini"
|
"tildegit.org/sloum/bombadillo/gemini"
|
||||||
"tildegit.org/sloum/bombadillo/gopher"
|
"tildegit.org/sloum/bombadillo/gopher"
|
||||||
"tildegit.org/sloum/bombadillo/http"
|
"tildegit.org/sloum/bombadillo/http"
|
||||||
|
@ -36,7 +38,6 @@ type client struct {
|
||||||
Certs gemini.TofuDigest
|
Certs gemini.TofuDigest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------\\
|
//------------------------------------------------\\
|
||||||
// + + + R E C E I V E R S + + + \\
|
// + + + R E C E I V E R S + + + \\
|
||||||
//--------------------------------------------------\\
|
//--------------------------------------------------\\
|
||||||
|
@ -83,18 +84,18 @@ func (c *client) GetSize() {
|
||||||
|
|
||||||
func (c *client) Draw() {
|
func (c *client) Draw() {
|
||||||
var screen strings.Builder
|
var screen strings.Builder
|
||||||
screen.Grow(c.Height * c.Width + c.Width)
|
screen.Grow(c.Height*c.Width + c.Width)
|
||||||
screen.WriteString("\033[0m")
|
screen.WriteString("\033[0m")
|
||||||
screen.WriteString(c.TopBar.Render(c.Width, c.Options["theme"]))
|
screen.WriteString(c.TopBar.Render(c.Width, c.Options["theme"]))
|
||||||
screen.WriteString("\n")
|
screen.WriteString("\n")
|
||||||
pageContent := c.PageState.Render(c.Height, c.Width - 1)
|
pageContent := c.PageState.Render(c.Height, c.Width-1)
|
||||||
if c.Options["theme"] == "inverse" {
|
if c.Options["theme"] == "inverse" {
|
||||||
screen.WriteString("\033[7m")
|
screen.WriteString("\033[7m")
|
||||||
}
|
}
|
||||||
if c.BookMarks.IsOpen {
|
if c.BookMarks.IsOpen {
|
||||||
bm := c.BookMarks.Render(c.Width, c.Height)
|
bm := c.BookMarks.Render(c.Width, c.Height)
|
||||||
bmWidth := len([]rune(bm[0]))
|
bmWidth := len([]rune(bm[0]))
|
||||||
for i := 0; i < c.Height - 3; i++ {
|
for i := 0; i < c.Height-3; i++ {
|
||||||
if c.Width > bmWidth {
|
if c.Width > bmWidth {
|
||||||
contentWidth := c.Width - bmWidth
|
contentWidth := c.Width - bmWidth
|
||||||
if i < len(pageContent) {
|
if i < len(pageContent) {
|
||||||
|
@ -122,9 +123,9 @@ func (c *client) Draw() {
|
||||||
screen.WriteString("\n")
|
screen.WriteString("\n")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for i := 0; i < c.Height - 3; i++ {
|
for i := 0; i < c.Height-3; i++ {
|
||||||
if i < len(pageContent) {
|
if i < len(pageContent) {
|
||||||
screen.WriteString(fmt.Sprintf("%-*.*s", c.Width - 1, c.Width - 1, pageContent[i]))
|
screen.WriteString(fmt.Sprintf("%-*.*s", c.Width-1, c.Width-1, pageContent[i]))
|
||||||
screen.WriteString("\n")
|
screen.WriteString("\n")
|
||||||
} else {
|
} else {
|
||||||
screen.WriteString(fmt.Sprintf("%-*.*s", c.Width, c.Width, " "))
|
screen.WriteString(fmt.Sprintf("%-*.*s", c.Width, c.Width, " "))
|
||||||
|
@ -138,7 +139,7 @@ func (c *client) Draw() {
|
||||||
screen.WriteString("\n") // for the input line
|
screen.WriteString("\n") // for the input line
|
||||||
screen.WriteString(c.FootBar.Render(c.Width, c.PageState.Position, c.Options["theme"]))
|
screen.WriteString(c.FootBar.Render(c.Width, c.PageState.Position, c.Options["theme"]))
|
||||||
// cui.Clear("screen")
|
// cui.Clear("screen")
|
||||||
cui.MoveCursorTo(0,0)
|
cui.MoveCursorTo(0, 0)
|
||||||
fmt.Print(screen.String())
|
fmt.Print(screen.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,12 +169,12 @@ func (c *client) TakeControlInput() {
|
||||||
case 'd':
|
case 'd':
|
||||||
// scroll down 75%
|
// scroll down 75%
|
||||||
c.ClearMessage()
|
c.ClearMessage()
|
||||||
distance := c.Height - c.Height / 4
|
distance := c.Height - c.Height/4
|
||||||
c.Scroll(distance)
|
c.Scroll(distance)
|
||||||
case 'u':
|
case 'u':
|
||||||
// scroll up 75%
|
// scroll up 75%
|
||||||
c.ClearMessage()
|
c.ClearMessage()
|
||||||
distance := c.Height - c.Height / 4
|
distance := c.Height - c.Height/4
|
||||||
c.Scroll(-distance)
|
c.Scroll(-distance)
|
||||||
case 'b':
|
case 'b':
|
||||||
// go back
|
// go back
|
||||||
|
@ -249,7 +250,6 @@ func (c *client) TakeControlInput() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (c *client) routeCommandInput(com *cmdparse.Command) error {
|
func (c *client) routeCommandInput(com *cmdparse.Command) error {
|
||||||
var err error
|
var err error
|
||||||
switch com.Type {
|
switch com.Type {
|
||||||
|
@ -345,7 +345,7 @@ func (c *client) doCommand(action string, values []string) {
|
||||||
fns := strings.Split(u.Resource, "/")
|
fns := strings.Split(u.Resource, "/")
|
||||||
var fn string
|
var fn string
|
||||||
if len(fns) > 0 {
|
if len(fns) > 0 {
|
||||||
fn = strings.Trim(fns[len(fns) - 1], "\t\r\n \a\f\v")
|
fn = strings.Trim(fns[len(fns)-1], "\t\r\n \a\f\v")
|
||||||
} else {
|
} else {
|
||||||
fn = "index"
|
fn = "index"
|
||||||
}
|
}
|
||||||
|
@ -413,6 +413,9 @@ func (c *client) doCommandAs(action string, values []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.Options[values[0]] = lowerCaseOpt(values[0], val)
|
c.Options[values[0]] = lowerCaseOpt(values[0], val)
|
||||||
|
if values[0] == "tlskey" || values[0] == "tlscertificate" {
|
||||||
|
c.Certs.LoadCertificate(c.Options["tlscertificate"], c.Options["tlskey"])
|
||||||
|
}
|
||||||
err := saveConfig()
|
err := saveConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.SetMessage("Value set, but error saving config to file", true)
|
c.SetMessage("Value set, but error saving config to file", true)
|
||||||
|
@ -471,7 +474,7 @@ func (c *client) doLinkCommandAs(action, target string, values []string) {
|
||||||
c.Draw()
|
c.Draw()
|
||||||
}
|
}
|
||||||
case "WRITE", "W":
|
case "WRITE", "W":
|
||||||
out := make([]string, 0, len(values) + 1)
|
out := make([]string, 0, len(values)+1)
|
||||||
out = append(out, links[num])
|
out = append(out, links[num])
|
||||||
out = append(out, values...)
|
out = append(out, values...)
|
||||||
c.doCommandAs(action, out)
|
c.doCommandAs(action, out)
|
||||||
|
@ -480,7 +483,6 @@ func (c *client) doLinkCommandAs(action, target string, values []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (c *client) getCurrentPageUrl() (string, error) {
|
func (c *client) getCurrentPageUrl() (string, error) {
|
||||||
if c.PageState.Length < 1 {
|
if c.PageState.Length < 1 {
|
||||||
return "", fmt.Errorf("There are no pages in history")
|
return "", fmt.Errorf("There are no pages in history")
|
||||||
|
@ -516,10 +518,11 @@ func (c *client) saveFile(u Url, name string) {
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
savePath := c.Options["savelocation"] + name
|
|
||||||
|
savePath := filepath.Join(c.Options["savelocation"], name)
|
||||||
err = ioutil.WriteFile(savePath, file, 0644)
|
err = ioutil.WriteFile(savePath, file, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.SetMessage("Error writing file to disk", true)
|
c.SetMessage("Error writing file: "+err.Error(), true)
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -532,10 +535,11 @@ func (c *client) saveFileFromData(d, name string) {
|
||||||
data := []byte(d)
|
data := []byte(d)
|
||||||
c.SetMessage(fmt.Sprintf("Saving %s ...", name), false)
|
c.SetMessage(fmt.Sprintf("Saving %s ...", name), false)
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
savePath := c.Options["savelocation"] + name
|
|
||||||
|
savePath := filepath.Join(c.Options["savelocation"], name)
|
||||||
err := ioutil.WriteFile(savePath, data, 0644)
|
err := ioutil.WriteFile(savePath, data, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.SetMessage("Error writing file to disk", true)
|
c.SetMessage("Error writing file: "+err.Error(), true)
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -551,7 +555,6 @@ func (c *client) doLinkCommand(action, target string) {
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case "DELETE", "D":
|
case "DELETE", "D":
|
||||||
msg, err := c.BookMarks.Delete(num)
|
msg, err := c.BookMarks.Delete(num)
|
||||||
|
@ -589,7 +592,7 @@ func (c *client) doLinkCommand(action, target string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
link := links[num]
|
link := links[num]
|
||||||
c.SetMessage(fmt.Sprintf("[%d] %s", num + 1, link), false)
|
c.SetMessage(fmt.Sprintf("[%d] %s", num+1, link), false)
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
case "WRITE", "W":
|
case "WRITE", "W":
|
||||||
links := c.PageState.History[c.PageState.Position].Links
|
links := c.PageState.History[c.PageState.Position].Links
|
||||||
|
@ -607,7 +610,7 @@ func (c *client) doLinkCommand(action, target string) {
|
||||||
fns := strings.Split(u.Resource, "/")
|
fns := strings.Split(u.Resource, "/")
|
||||||
var fn string
|
var fn string
|
||||||
if len(fns) > 0 {
|
if len(fns) > 0 {
|
||||||
fn = strings.Trim(fns[len(fns) - 1], "\t\r\n \a\f\v")
|
fn = strings.Trim(fns[len(fns)-1], "\t\r\n \a\f\v")
|
||||||
} else {
|
} else {
|
||||||
fn = "index"
|
fn = "index"
|
||||||
}
|
}
|
||||||
|
@ -655,11 +658,11 @@ func (c *client) search(query, url, question string) {
|
||||||
}
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "gopher":
|
case "gopher":
|
||||||
go c.Visit(fmt.Sprintf("%s\t%s",u.Full,entry))
|
go c.Visit(fmt.Sprintf("%s\t%s", u.Full, entry))
|
||||||
case "gemini":
|
case "gemini":
|
||||||
// TODO url escape the entry variable
|
// TODO url escape the entry variable
|
||||||
escapedEntry := entry
|
escapedEntry := entry
|
||||||
go c.Visit(fmt.Sprintf("%s?%s",u.Full,escapedEntry))
|
go c.Visit(fmt.Sprintf("%s?%s", u.Full, escapedEntry))
|
||||||
case "http", "https":
|
case "http", "https":
|
||||||
c.Visit(u.Full)
|
c.Visit(u.Full)
|
||||||
default:
|
default:
|
||||||
|
@ -717,10 +720,10 @@ func (c *client) Scroll(amount int) {
|
||||||
|
|
||||||
c.PageState.History[c.PageState.Position].ScrollPosition = newScrollPosition
|
c.PageState.History[c.PageState.Position].ScrollPosition = newScrollPosition
|
||||||
|
|
||||||
if len(page.WrappedContent) < c.Height - 3 {
|
if len(page.WrappedContent) < c.Height-3 {
|
||||||
percentRead = 100
|
percentRead = 100
|
||||||
} else {
|
} else {
|
||||||
percentRead = int(float32(newScrollPosition + c.Height - 3) / float32(len(page.WrappedContent)) * 100.0)
|
percentRead = int(float32(newScrollPosition+c.Height-3) / float32(len(page.WrappedContent)) * 100.0)
|
||||||
}
|
}
|
||||||
c.FootBar.SetPercentRead(percentRead)
|
c.FootBar.SetPercentRead(percentRead)
|
||||||
}
|
}
|
||||||
|
@ -730,10 +733,10 @@ func (c *client) Scroll(amount int) {
|
||||||
func (c *client) SetPercentRead() {
|
func (c *client) SetPercentRead() {
|
||||||
page := c.PageState.History[c.PageState.Position]
|
page := c.PageState.History[c.PageState.Position]
|
||||||
var percentRead int
|
var percentRead int
|
||||||
if len(page.WrappedContent) < c.Height - 3 {
|
if len(page.WrappedContent) < c.Height-3 {
|
||||||
percentRead = 100
|
percentRead = 100
|
||||||
} else {
|
} else {
|
||||||
percentRead = int(float32(page.ScrollPosition + c.Height - 3) / float32(len(page.WrappedContent)) * 100.0)
|
percentRead = int(float32(page.ScrollPosition+c.Height-3) / float32(len(page.WrappedContent)) * 100.0)
|
||||||
}
|
}
|
||||||
c.FootBar.SetPercentRead(percentRead)
|
c.FootBar.SetPercentRead(percentRead)
|
||||||
}
|
}
|
||||||
|
@ -840,7 +843,7 @@ func (c *client) Visit(url string) {
|
||||||
case "gopher":
|
case "gopher":
|
||||||
if u.DownloadOnly {
|
if u.DownloadOnly {
|
||||||
nameSplit := strings.Split(u.Resource, "/")
|
nameSplit := strings.Split(u.Resource, "/")
|
||||||
filename := nameSplit[len(nameSplit) - 1]
|
filename := nameSplit[len(nameSplit)-1]
|
||||||
filename = strings.Trim(filename, " \t\r\n\v\f\a")
|
filename = strings.Trim(filename, " \t\r\n\v\f\a")
|
||||||
if filename == "" {
|
if filename == "" {
|
||||||
filename = "gopherfile"
|
filename = "gopherfile"
|
||||||
|
@ -934,7 +937,7 @@ func (c *client) Visit(url string) {
|
||||||
c.Draw()
|
c.Draw()
|
||||||
case 'w':
|
case 'w':
|
||||||
nameSplit := strings.Split(u.Resource, "/")
|
nameSplit := strings.Split(u.Resource, "/")
|
||||||
filename := nameSplit[len(nameSplit) - 1]
|
filename := nameSplit[len(nameSplit)-1]
|
||||||
c.saveFileFromData(capsule.Content, filename)
|
c.saveFileFromData(capsule.Content, filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -990,6 +993,20 @@ func (c *client) Visit(url string) {
|
||||||
c.ClearMessage()
|
c.ClearMessage()
|
||||||
c.SetHeaderUrl()
|
c.SetHeaderUrl()
|
||||||
c.Draw()
|
c.Draw()
|
||||||
|
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:
|
default:
|
||||||
c.SetMessage(fmt.Sprintf("%q is not a supported protocol", u.Scheme), true)
|
c.SetMessage(fmt.Sprintf("%q is not a supported protocol", u.Scheme), true)
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
|
@ -1020,4 +1037,3 @@ func MakeClient(name string) *client {
|
||||||
c := client{0, 0, defaultOptions, "", false, MakePages(), MakeBookmarks(), MakeHeadbar(name), MakeFootbar(), gemini.MakeTofuDigest()}
|
c := client{0, 0, defaultOptions, "", false, MakePages(), MakeBookmarks(), MakeHeadbar(name), MakeFootbar(), gemini.MakeTofuDigest()}
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,5 +21,7 @@ var defaultOptions = map[string]string{
|
||||||
"configlocation": userinfo.HomeDir,
|
"configlocation": userinfo.HomeDir,
|
||||||
"theme": "normal", // "normal", "inverted"
|
"theme": "normal", // "normal", "inverted"
|
||||||
"terminalonly": "true",
|
"terminalonly": "true",
|
||||||
|
"tlscertificate": "",
|
||||||
|
"tlskey": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ type Capsule struct {
|
||||||
|
|
||||||
type TofuDigest struct {
|
type TofuDigest struct {
|
||||||
certs map[string]string
|
certs map[string]string
|
||||||
|
ClientCert tls.Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +31,15 @@ type TofuDigest struct {
|
||||||
// + + + R E C E I V E R S + + + \\
|
// + + + R E C E I V E R S + + + \\
|
||||||
//--------------------------------------------------\\
|
//--------------------------------------------------\\
|
||||||
|
|
||||||
|
func (t *TofuDigest) LoadCertificate(cert, key string) {
|
||||||
|
certificate, err := tls.LoadX509KeyPair(cert, key)
|
||||||
|
if err != nil {
|
||||||
|
t.ClientCert = tls.Certificate{}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.ClientCert = certificate
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TofuDigest) Purge(host string) error {
|
func (t *TofuDigest) Purge(host string) error {
|
||||||
host = strings.ToLower(host)
|
host = strings.ToLower(host)
|
||||||
if host == "*" {
|
if host == "*" {
|
||||||
|
@ -144,6 +154,10 @@ func Retrieve(host, port, resource string, td *TofuDigest) (string, error) {
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conf.GetClientCertificate = func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
|
||||||
|
return &td.ClientCert, nil
|
||||||
|
}
|
||||||
|
|
||||||
conn, err := tls.Dial("tcp", addr, conf)
|
conn, err := tls.Dial("tcp", addr, conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -383,5 +397,5 @@ func MakeCapsule() Capsule {
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeTofuDigest() TofuDigest {
|
func MakeTofuDigest() TofuDigest {
|
||||||
return TofuDigest{make(map[string]string)}
|
return TofuDigest{make(map[string]string), tls.Certificate{}}
|
||||||
}
|
}
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -1,3 +1,5 @@
|
||||||
module tildegit.org/sloum/bombadillo
|
module tildegit.org/sloum/bombadillo
|
||||||
|
|
||||||
go 1.10
|
go 1.12
|
||||||
|
|
||||||
|
require tildegit.org/sloum/mailcap v0.0.0-20190706214029-b787a49e9db2
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
tildegit.org/sloum/mailcap v0.0.0-20190706214029-b787a49e9db2 h1:tAPIFBpXwOq1Ytxk8aGsDjCutnwUC01BVkK77QS1bdU=
|
||||||
|
tildegit.org/sloum/mailcap v0.0.0-20190706214029-b787a49e9db2/go.mod h1:m4etAw9DbXsdanDUNS8oERhL+7y4II82ZLHWzw2yibg=
|
3
main.go
3
main.go
|
@ -138,6 +138,9 @@ func initClient() error {
|
||||||
bombadillo = MakeClient(" ((( Bombadillo ))) ")
|
bombadillo = MakeClient(" ((( Bombadillo ))) ")
|
||||||
cui.SetCharMode()
|
cui.SetCharMode()
|
||||||
err := loadConfig()
|
err := loadConfig()
|
||||||
|
if bombadillo.Options["tlscertificate"] != "" && bombadillo.Options["tlskey"] != "" {
|
||||||
|
bombadillo.Certs.LoadCertificate(bombadillo.Options["tlscertificate"], bombadillo.Options["tlskey"])
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
35
url.go
35
url.go
|
@ -38,6 +38,13 @@ type Url struct {
|
||||||
// representation of a url and returns a Url struct and
|
// representation of a url and returns a Url struct and
|
||||||
// an error (or nil).
|
// an error (or nil).
|
||||||
func MakeUrl(u string) (Url, error) {
|
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
|
var out Url
|
||||||
if local := strings.HasPrefix(u, "local://"); u[0] == '/' || u[0] == '.' || u[0] == '~' || local {
|
if local := strings.HasPrefix(u, "local://"); u[0] == '/' || u[0] == '.' || u[0] == '~' || local {
|
||||||
if local && len(u) > 8 {
|
if local && len(u) > 8 {
|
||||||
|
@ -131,3 +138,31 @@ func MakeUrl(u string) (Url, error) {
|
||||||
return out, nil
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue