Resolved merge conflict
This commit is contained in:
commit
64590f53e7
|
@ -59,7 +59,7 @@ Displaying web content directly in \fBbombadillo\fP requires lynx, w3m or elinks
|
||||||
These commands work as a single keypress anytime \fBbombadillo\fP is not taking in a line based command or when the user is being prompted for action. This is the default command mode of \fBbombadillo\fP.
|
These commands work as a single keypress anytime \fBbombadillo\fP is not taking in a line based command or when the user is being prompted for action. This is the default command mode of \fBbombadillo\fP.
|
||||||
.TP
|
.TP
|
||||||
.B
|
.B
|
||||||
b
|
b, h
|
||||||
Navigate back one place in your document history.
|
Navigate back one place in your document history.
|
||||||
.TP
|
.TP
|
||||||
.B
|
.B
|
||||||
|
@ -71,7 +71,7 @@ d
|
||||||
Scroll down an amount corresponding to 75% of your terminal window height in the current document.
|
Scroll down an amount corresponding to 75% of your terminal window height in the current document.
|
||||||
.TP
|
.TP
|
||||||
.B
|
.B
|
||||||
f
|
f, l
|
||||||
Navigate forward one place in your document history.
|
Navigate forward one place in your document history.
|
||||||
.TP
|
.TP
|
||||||
.B
|
.B
|
||||||
|
@ -95,6 +95,7 @@ n
|
||||||
Jump to next found text item.
|
Jump to next found text item.
|
||||||
.TP
|
.TP
|
||||||
.B
|
.B
|
||||||
|
N
|
||||||
Jump to previous found text item.
|
Jump to previous found text item.
|
||||||
.TP
|
.TP
|
||||||
.B
|
.B
|
||||||
|
|
14
client.go
14
client.go
|
@ -168,15 +168,15 @@ func (c *client) TakeControlInput() {
|
||||||
} else {
|
} else {
|
||||||
c.goToLink(string(input))
|
c.goToLink(string(input))
|
||||||
}
|
}
|
||||||
case 'j', 'J':
|
case 'j':
|
||||||
// scroll down one line
|
// scroll down one line
|
||||||
c.ClearMessage()
|
c.ClearMessage()
|
||||||
c.Scroll(1)
|
c.Scroll(1)
|
||||||
case 'k', 'K':
|
case 'k':
|
||||||
// scroll up one line
|
// scroll up one line
|
||||||
c.ClearMessage()
|
c.ClearMessage()
|
||||||
c.Scroll(-1)
|
c.Scroll(-1)
|
||||||
case 'q', 'Q':
|
case 'q':
|
||||||
// quit bombadillo
|
// quit bombadillo
|
||||||
cui.Exit(0, "")
|
cui.Exit(0, "")
|
||||||
case 'g':
|
case 'g':
|
||||||
|
@ -197,7 +197,7 @@ func (c *client) TakeControlInput() {
|
||||||
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', 'h':
|
||||||
// go back
|
// go back
|
||||||
c.ClearMessage()
|
c.ClearMessage()
|
||||||
err := c.PageState.NavigateHistory(-1)
|
err := c.PageState.NavigateHistory(-1)
|
||||||
|
@ -222,7 +222,7 @@ func (c *client) TakeControlInput() {
|
||||||
// open the bookmarks browser
|
// open the bookmarks browser
|
||||||
c.BookMarks.ToggleOpen()
|
c.BookMarks.ToggleOpen()
|
||||||
c.Draw()
|
c.Draw()
|
||||||
case 'f', 'F':
|
case 'f', 'l':
|
||||||
// go forward
|
// go forward
|
||||||
c.ClearMessage()
|
c.ClearMessage()
|
||||||
err := c.PageState.NavigateHistory(1)
|
err := c.PageState.NavigateHistory(1)
|
||||||
|
@ -711,11 +711,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))
|
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))
|
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:
|
||||||
|
|
|
@ -49,8 +49,8 @@ func (t *TofuDigest) Purge(host string) error {
|
||||||
return fmt.Errorf("Invalid host %q", host)
|
return fmt.Errorf("Invalid host %q", host)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TofuDigest) Add(host, hash string) {
|
func (t *TofuDigest) Add(host, hash string, time int64) {
|
||||||
t.certs[strings.ToLower(host)] = hash
|
t.certs[strings.ToLower(host)] = fmt.Sprintf("%s|%d", hash, time)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TofuDigest) Exists(host string) bool {
|
func (t *TofuDigest) Exists(host string) bool {
|
||||||
|
@ -67,12 +67,11 @@ func (t *TofuDigest) Find(host string) (string, error) {
|
||||||
return "", fmt.Errorf("Invalid hostname, no key saved")
|
return "", fmt.Errorf("Invalid hostname, no key saved")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TofuDigest) Match(host string, cState *tls.ConnectionState) error {
|
func (t *TofuDigest) Match(host, localCert string, cState *tls.ConnectionState) error {
|
||||||
host = strings.ToLower(host)
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
for _, cert := range cState.PeerCertificates {
|
for _, cert := range cState.PeerCertificates {
|
||||||
if t.certs[host] != hashCert(cert.Raw) {
|
if localCert != hashCert(cert.Raw) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,13 +117,40 @@ func (t *TofuDigest) newCert(host string, cState *tls.ConnectionState) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Add(host, hashCert(cert.Raw))
|
t.Add(host, hashCert(cert.Raw), cert.NotAfter.Unix())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf(reasons.String())
|
return fmt.Errorf(reasons.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TofuDigest) GetCertAndTimestamp(host string) (string, int64, error) {
|
||||||
|
certTs, err := t.Find(host)
|
||||||
|
if err != nil {
|
||||||
|
return "", -1, err
|
||||||
|
}
|
||||||
|
certTsSplit := strings.SplitN(certTs, "|", -1)
|
||||||
|
if len(certTsSplit) < 2 {
|
||||||
|
_ = t.Purge(host)
|
||||||
|
return certTsSplit[0], -1, fmt.Errorf("Invalid certstring, no delimiter")
|
||||||
|
}
|
||||||
|
ts, err := strconv.ParseInt(certTsSplit[1], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
_ = t.Purge(host)
|
||||||
|
return certTsSplit[0], -1, err
|
||||||
|
}
|
||||||
|
now := time.Now()
|
||||||
|
if ts < now.Unix() {
|
||||||
|
// Ignore error return here since an error would indicate
|
||||||
|
// the host does not exist and we have already checked for
|
||||||
|
// that and the desired outcome of the action is that the
|
||||||
|
// host will no longer exist, so we are good either way
|
||||||
|
_ = t.Purge(host)
|
||||||
|
return "", -1, fmt.Errorf("Expired cert")
|
||||||
|
}
|
||||||
|
return certTsSplit[0], ts, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TofuDigest) IniDump() string {
|
func (t *TofuDigest) IniDump() string {
|
||||||
if len(t.certs) < 1 {
|
if len(t.certs) < 1 {
|
||||||
return ""
|
return ""
|
||||||
|
@ -176,9 +202,11 @@ func Retrieve(host, port, resource string, td *TofuDigest) (string, error) {
|
||||||
return "", fmt.Errorf("Insecure, no certificates offered by server")
|
return "", fmt.Errorf("Insecure, no certificates offered by server")
|
||||||
}
|
}
|
||||||
|
|
||||||
if td.Exists(host) {
|
localCert, localTs, err := td.GetCertAndTimestamp(host)
|
||||||
|
|
||||||
|
if localTs > 0 {
|
||||||
// See if we have a matching cert
|
// See if we have a matching cert
|
||||||
err := td.Match(host, &connState)
|
err := td.Match(host, localCert, &connState)
|
||||||
if err != nil && err.Error() != "EXP" {
|
if err != nil && err.Error() != "EXP" {
|
||||||
// If there is no match and it isnt because of an expiration
|
// If there is no match and it isnt because of an expiration
|
||||||
// just return the error
|
// just return the error
|
||||||
|
|
17
main.go
17
main.go
|
@ -25,8 +25,10 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"tildegit.org/sloum/bombadillo/config"
|
"tildegit.org/sloum/bombadillo/config"
|
||||||
"tildegit.org/sloum/bombadillo/cui"
|
"tildegit.org/sloum/bombadillo/cui"
|
||||||
|
@ -132,7 +134,20 @@ func loadConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range settings.Certs {
|
for _, v := range settings.Certs {
|
||||||
bombadillo.Certs.Add(v.Key, v.Value)
|
// Remove expired certs
|
||||||
|
vals := strings.SplitN(v.Value, "|", -1)
|
||||||
|
if len(vals) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ts, err := strconv.ParseInt(vals[1], 10, 64)
|
||||||
|
now := time.Now()
|
||||||
|
if err != nil || now.Unix() > ts {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Satisfied that the cert is not expired
|
||||||
|
// or malformed: add to the current client
|
||||||
|
// instance
|
||||||
|
bombadillo.Certs.Add(v.Key, vals[0], ts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
page.go
10
page.go
|
@ -70,7 +70,9 @@ func (p *Page) WrapContent(width int, color bool) {
|
||||||
p.RenderImage(width)
|
p.RenderImage(width)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
width = min(width, 100)
|
||||||
counter := 0
|
counter := 0
|
||||||
|
spacer := " "
|
||||||
var content strings.Builder
|
var content strings.Builder
|
||||||
var esc strings.Builder
|
var esc strings.Builder
|
||||||
escape := false
|
escape := false
|
||||||
|
@ -124,7 +126,6 @@ func (p *Page) WrapContent(width int, color bool) {
|
||||||
content.WriteRune('\n')
|
content.WriteRune('\n')
|
||||||
counter = 0
|
counter = 0
|
||||||
if p.Location.Mime == "1" {
|
if p.Location.Mime == "1" {
|
||||||
spacer := " "
|
|
||||||
content.WriteString(spacer)
|
content.WriteString(spacer)
|
||||||
counter += len(spacer)
|
counter += len(spacer)
|
||||||
}
|
}
|
||||||
|
@ -188,3 +189,10 @@ func MakePage(url Url, content string, links []string) Page {
|
||||||
p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0, "", 40, false}
|
p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0, "", 40, false}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func min(a, b int) int {
|
||||||
|
if a < b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue