From 926fff0e6a679da63ae351c9180cff463f79794e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Nied=C5=BAwiedzi=C5=84ski?= Date: Mon, 12 Oct 2020 20:48:21 +0200 Subject: [PATCH 01/28] Remove basedir check (#101) --- config/config.go | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/config/config.go b/config/config.go index bf534cc..33a2b4e 100644 --- a/config/config.go +++ b/config/config.go @@ -62,12 +62,7 @@ func Init() error { configDir = amforaAppData } else { // Unix / POSIX system - if basedir.ConfigHome == "" { - // Default to ~/.config/amfora - configDir = filepath.Join(home, ".config", "amfora") - } else { - configDir = filepath.Join(basedir.ConfigHome, "amfora") - } + configDir = filepath.Join(basedir.ConfigHome, "amfora") } configPath = filepath.Join(configDir, "config.toml") @@ -84,12 +79,7 @@ func Init() error { tofuDBDir = amforaAppData } else { // XDG cache dir on POSIX systems - if basedir.CacheHome == "" { - // Default to ~/.cache/amfora - tofuDBDir = filepath.Join(home, ".cache", "amfora") - } else { - tofuDBDir = filepath.Join(basedir.CacheHome, "amfora") - } + tofuDBDir = filepath.Join(basedir.CacheHome, "amfora") } tofuDBPath = filepath.Join(tofuDBDir, "tofu.toml") @@ -99,12 +89,7 @@ func Init() error { bkmkDir = amforaAppData } else { // XDG data dir on POSIX systems - if basedir.DataHome == "" { - // Default to ~/.local/share/amfora - bkmkDir = filepath.Join(home, ".local", "share", "amfora") - } else { - bkmkDir = filepath.Join(basedir.DataHome, "amfora") - } + bkmkDir = filepath.Join(basedir.DataHome, "amfora") } bkmkPath = filepath.Join(bkmkDir, "bookmarks.toml") From 80b1d1837574c61b6af38a6a15d16048e7c2099c Mon Sep 17 00:00:00 2001 From: makeworld Date: Mon, 12 Oct 2020 14:49:21 -0400 Subject: [PATCH 02/28] =?UTF-8?q?=F0=9F=93=9D=20Add=20#101=20to=20changelo?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d4592c..4bf6a95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated [go-isemoji](https://github.com/makeworld-the-better-one/go-isemoji) to v1.1.0 to support Emoji 13.1 for favicons - The web browser code doesn't check for Xorg anymore, just display variables (#93) - Bookmarks can be made to non-gemini URLs (#94) +- Remove pointless directory fallbacks (#101) ### Fixed - XDG user dir file is parsed instead of looking for XDG env vars (#97, #100) From 9292d86c45a54e3e2d3edfdf3822eb239b6be3da Mon Sep 17 00:00:00 2001 From: makeworld Date: Sat, 24 Oct 2020 12:22:41 -0400 Subject: [PATCH 03/28] =?UTF-8?q?=F0=9F=93=9D=20Show=20build=20status=20fo?= =?UTF-8?q?r=20master=20branch=20only?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 949336b..cee35bc 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@
Image modified from: amphora by Alvaro Cabrera from the Noun Project
-[![travis build status](https://img.shields.io/travis/com/makeworld-the-better-one/amfora)](https://https://travis-ci.com/github/makeworld-the-better-one/amfora) +[![travis build status](https://img.shields.io/travis/com/makeworld-the-better-one/amfora/master?label=master)](https://travis-ci.com/github/makeworld-the-better-one/amfora) [![go reportcard](https://goreportcard.com/badge/github.com/makeworld-the-better-one/amfora)](https://goreportcard.com/report/github.com/makeworld-the-better-one/amfora) [![license GPLv3](https://img.shields.io/github/license/makeworld-the-better-one/amfora)](https://www.gnu.org/licenses/gpl-3.0.en.html) From d917ed817949d4b7f557fb1eb4ec8407162be455 Mon Sep 17 00:00:00 2001 From: makeworld Date: Fri, 30 Oct 2020 10:47:24 -0400 Subject: [PATCH 04/28] =?UTF-8?q?=F0=9F=93=9D=20Install=20amfora=20from=20?= =?UTF-8?q?Arch=20pkgs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cee35bc..dfd6434 100644 --- a/README.md +++ b/README.md @@ -42,10 +42,10 @@ Make sure to click "Watch" > "Releases only" in the top right to get notified ab ### Arch Linux -Arch Linux users can install Amfora from AUR. It has the package name `amfora`, and is maintained by @pboyd. +Arch Linux users can install Amfora using pacman. ``` -yay -S amfora +sudo pacman -S amfora ``` ### Homebrew From 132191a9d246fb31909730ebf5f21e931cafc61b Mon Sep 17 00:00:00 2001 From: makeworld Date: Mon, 2 Nov 2020 18:46:37 -0500 Subject: [PATCH 05/28] =?UTF-8?q?=F0=9F=91=B7=20Switch=20to=20GitHub=20Act?= =?UTF-8?q?ions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/actions/test.yml | 30 ++++++++++++++++++++++++++++++ .travis.yml | 35 ----------------------------------- 2 files changed, 30 insertions(+), 35 deletions(-) create mode 100644 .github/actions/test.yml delete mode 100644 .travis.yml diff --git a/.github/actions/test.yml b/.github/actions/test.yml new file mode 100644 index 0000000..1b02251 --- /dev/null +++ b/.github/actions/test.yml @@ -0,0 +1,30 @@ +on: [push, pull_request] +name: Test + +jobs: + test: + strategy: + matrix: + go-version: ['1.13', '1.14', '1.15'] + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go-version }} + - name: Install make on Windows + if: matrix.os == 'windows-latest' + run: choco install make + - name: Checkout code + uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - name: Test + run: | + go test -race ./... + make diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6af09e9..0000000 --- a/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -language: go - -go: - #- "1.11" # Debian Stable golang version, fails - see below - #- "1.12" # Also fails due to progressbar Millisecond requirement - - "1.13" - - "1.14" - - "1.15" - -os: - - linux - - osx - - windows - -before_install: - - if [ "$TRAVIS_OS_NAME" = "windows" ]; then choco install make; fi - -script: - - go test -race ./... - - make - -env: - GO111MODULE=on - -cache: - directories: - - $GOCACHE - - $GOPATH/pkg/mod - -# TODO: GitHub Releases deploy - -notifications: - email: - on_success: never - on_failure: always From e4e9c234115c8246966568198594fe0a97afcf6e Mon Sep 17 00:00:00 2001 From: makeworld Date: Mon, 2 Nov 2020 18:48:25 -0500 Subject: [PATCH 06/28] =?UTF-8?q?=F0=9F=91=B7=20Move=20GitHub=20actions=20?= =?UTF-8?q?to=20correct=20dir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/{actions => workflows}/test.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{actions => workflows}/test.yml (100%) diff --git a/.github/actions/test.yml b/.github/workflows/test.yml similarity index 100% rename from .github/actions/test.yml rename to .github/workflows/test.yml From 4e26a51741f207a34314395774a04b9393001f66 Mon Sep 17 00:00:00 2001 From: Trevor Slocum Date: Wed, 4 Nov 2020 13:37:00 -0800 Subject: [PATCH 07/28] Allow specifying a client certificate (#112) --- CHANGELOG.md | 1 + client/client.go | 68 ++++++++++++++++++++++++++++++++++++++++++--- config/default.go | 12 ++++++++ default-config.toml | 12 ++++++++ go.mod | 2 +- go.sum | 4 +-- 6 files changed, 92 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bf6a95..0c7a586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Edit current URL with e (#87) - If `emoji_favicons` is enabled, new bookmarks will have the domain's favicon prepended (#69, #90) - The `BROWSER` env var is now also checked when opening web links on Unix (#93) +- Allow specifying a client certificate ### Changed - Disabling the `color` config setting also disables ANSI colors in pages (#79, #86) diff --git a/client/client.go b/client/client.go index 4bc1557..f5d4b99 100644 --- a/client/client.go +++ b/client/client.go @@ -2,23 +2,74 @@ package client import ( + "io/ioutil" "net" "net/url" "github.com/makeworld-the-better-one/go-gemini" + "github.com/mitchellh/go-homedir" + "github.com/spf13/viper" ) +var certCache = make(map[string][][]byte) + +func clientCert(host string) ([]byte, []byte) { + if cert := certCache[host]; cert != nil { + return cert[0], cert[1] + } + + // Expand paths staring with ~/ + certPath, err := homedir.Expand(viper.GetString("auth.certs." + host)) + if err != nil { + certPath = viper.GetString("auth.certs." + host) + } + keyPath, err := homedir.Expand(viper.GetString("auth.keys." + host)) + if err != nil { + keyPath = viper.GetString("auth.keys." + host) + } + if certPath == "" && keyPath == "" { + certCache[host] = [][]byte{nil, nil} + return nil, nil + } + + cert, err := ioutil.ReadFile(certPath) + if err != nil { + certCache[host] = [][]byte{nil, nil} + return nil, nil + } + key, err := ioutil.ReadFile(keyPath) + if err != nil { + certCache[host] = [][]byte{nil, nil} + return nil, nil + } + + certCache[host] = [][]byte{cert, key} + return cert, key +} + +// HasClientCert returns whether or not a client certificate exists for a host. +func HasClientCert(host string) bool { + cert, _ := clientCert(host) + return cert != nil +} + // Fetch returns response data and an error. // The error text is human friendly and should be displayed. func Fetch(u string) (*gemini.Response, error) { + parsed, _ := url.Parse(u) + cert, key := clientCert(parsed.Host) - res, err := gemini.Fetch(u) + var res *gemini.Response + var err error + if cert != nil { + res, err = gemini.FetchWithCert(u, cert, key) + } else { + res, err = gemini.Fetch(u) + } if err != nil { return nil, err } - parsed, _ := url.Parse(u) - ok := handleTofu(parsed.Hostname(), parsed.Port(), res.Cert) if !ok { return res, ErrTofu @@ -29,7 +80,16 @@ func Fetch(u string) (*gemini.Response, error) { // FetchWithProxy is the same as Fetch, but uses a proxy. func FetchWithProxy(proxyHostname, proxyPort, u string) (*gemini.Response, error) { - res, err := gemini.FetchWithHost(net.JoinHostPort(proxyHostname, proxyPort), u) + parsed, _ := url.Parse(u) + cert, key := clientCert(parsed.Host) + + var res *gemini.Response + var err error + if cert != nil { + res, err = gemini.FetchWithHostAndCert(net.JoinHostPort(proxyHostname, proxyPort), u, cert, key) + } else { + res, err = gemini.FetchWithHost(net.JoinHostPort(proxyHostname, proxyPort), u) + } if err != nil { return nil, err } diff --git a/config/default.go b/config/default.go index 11cc1ef..cac1ad8 100644 --- a/config/default.go +++ b/config/default.go @@ -59,6 +59,18 @@ page_max_time = 10 emoji_favicons = false +[auth] +# Authentication settings + +[auth.certs] +# Client certificates +# "example.com" = "mycert.crt" + +[auth.keys] +# Client certificate keys +# "example.com" = "mycert.key" + + [keybindings] # In the future there will be more settings here. diff --git a/default-config.toml b/default-config.toml index 4242bb1..4256091 100644 --- a/default-config.toml +++ b/default-config.toml @@ -56,6 +56,18 @@ page_max_time = 10 emoji_favicons = false +[auth] +# Authentication settings + +[auth.certs] +# Client certificates +# "example.com" = "mycert.crt" + +[auth.keys] +# Client certificate keys +# "example.com" = "mycert.key" + + [keybindings] # In the future there will be more settings here. diff --git a/go.mod b/go.mod index a94d5e1..61549ab 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/gdamore/tcell v1.3.1-0.20200608133353-cb1e5d6fa606 github.com/google/go-cmp v0.5.0 // indirect - github.com/makeworld-the-better-one/go-gemini v0.8.4 + github.com/makeworld-the-better-one/go-gemini v0.9.0 github.com/makeworld-the-better-one/go-isemoji v1.1.0 github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index 8639569..2ce1789 100644 --- a/go.sum +++ b/go.sum @@ -125,8 +125,8 @@ github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tW github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/makeworld-the-better-one/go-gemini v0.8.4 h1:ntsQ9HnlJCmC9PDqXp/f1SCALjBMwh69BbT4BhFRFaw= -github.com/makeworld-the-better-one/go-gemini v0.8.4/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4= +github.com/makeworld-the-better-one/go-gemini v0.9.0 h1:Iz4ywRDrfsyoR8xZOkSKGXXftMR2spIV6ibVuhrKvSw= +github.com/makeworld-the-better-one/go-gemini v0.9.0/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4= github.com/makeworld-the-better-one/go-isemoji v1.1.0 h1:wZBHOKB5zAIgaU2vaWnXFDDhatebB8TySrNVxjVV84g= github.com/makeworld-the-better-one/go-isemoji v1.1.0/go.mod h1:FBjkPl9rr0G4vlZCc+Mr+QcnOfGCTbGWYW8/1sp06I0= github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f h1:YEUlTs5gb35UlBLTgqrub9axWTYB3d7/8TxrkJDZpRI= From 424ce099ddedeb3ed9d17c3e4ba8562952146511 Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 16:45:34 -0500 Subject: [PATCH 08/28] =?UTF-8?q?=F0=9F=93=9D=20Update=20changelog=20and?= =?UTF-8?q?=20config=20for=20#112?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 +- README.md | 11 ++++++----- client/client.go | 2 +- config/default.go | 2 ++ default-config.toml | 2 ++ 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c7a586..09e3423 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Edit current URL with e (#87) - If `emoji_favicons` is enabled, new bookmarks will have the domain's favicon prepended (#69, #90) - The `BROWSER` env var is now also checked when opening web links on Unix (#93) -- Allow specifying a client certificate +- Support client certificates through config (#112) ### Changed - Disabling the `color` config setting also disables ANSI colors in pages (#79, #86) diff --git a/README.md b/README.md index dfd6434..632a959 100644 --- a/README.md +++ b/README.md @@ -121,15 +121,16 @@ Features in *italics* are in the master branch, but not in the latest release. - Disabled by default, enable in config - [x] Proxying - Schemes like Gopher or HTTP can be proxied through a Gemini server +- [x] *Client certificate support* + - [ ] Full client certificate UX within the client + - Create transient and permanent certs within the client, per domain + - Manage and browse them + - Similar to [Kristall](https://github.com/MasterQ32/kristall) + - https://lists.orbitalfox.eu/archives/gemini/2020/001400.html - [ ] Subscribe to RSS and Atom feeds and display them - Subscribing to page changes, similar to how Spacewalk works, will also be supported - *In progress on `feeds` branch* - [ ] Stream support -- [ ] Full client certificate UX within the client - - Create transient and permanent certs within the client, per domain - - Manage and browse them - - Similar to [Kristall](https://github.com/MasterQ32/kristall) - - https://lists.orbitalfox.eu/archives/gemini/2020/001400.html - [ ] Table of contents for pages - [ ] Search in pages with Ctrl-F - [ ] Support Markdown rendering diff --git a/client/client.go b/client/client.go index f5d4b99..2ec65d5 100644 --- a/client/client.go +++ b/client/client.go @@ -18,7 +18,7 @@ func clientCert(host string) ([]byte, []byte) { return cert[0], cert[1] } - // Expand paths staring with ~/ + // Expand paths starting with ~/ certPath, err := homedir.Expand(viper.GetString("auth.certs." + host)) if err != nil { certPath = viper.GetString("auth.certs." + host) diff --git a/config/default.go b/config/default.go index cac1ad8..4d0e854 100644 --- a/config/default.go +++ b/config/default.go @@ -64,10 +64,12 @@ emoji_favicons = false [auth.certs] # Client certificates +# Set domain name equal to path to client cert # "example.com" = "mycert.crt" [auth.keys] # Client certificate keys +# Set domain name equal to path to key for the client cert above # "example.com" = "mycert.key" diff --git a/default-config.toml b/default-config.toml index 4256091..900fcbe 100644 --- a/default-config.toml +++ b/default-config.toml @@ -61,10 +61,12 @@ emoji_favicons = false [auth.certs] # Client certificates +# Set domain name equal to path to client cert # "example.com" = "mycert.crt" [auth.keys] # Client certificate keys +# Set domain name equal to path to key for the client cert above # "example.com" = "mycert.key" From b3482d3a0917ee0e59a5ace7f424fe9eb65da838 Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 18:35:56 -0500 Subject: [PATCH 09/28] =?UTF-8?q?=F0=9F=90=9B=20Fixes=20#77?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + config/config.go | 12 ++++++++++++ config/default.go | 16 +++++++++++++--- default-config.toml | 16 +++++++++++++--- display/private.go | 35 ++++++++++++++++++++++------------- 5 files changed, 61 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09e3423..b8ebd26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - XDG user dir file is parsed instead of looking for XDG env vars (#97, #100) +- Support paths in HTTP(S) browser config setting (#77) ## [v1.5.0] - 2020-09-01 diff --git a/config/config.go b/config/config.go index 33a2b4e..17f0273 100644 --- a/config/config.go +++ b/config/config.go @@ -38,6 +38,9 @@ var bkmkPath string var DownloadsDir string +// Command for opening HTTP(S) URLs in the browser, from "a-general.http" in config. +var HttpCommand []string + //nolint:golint,goerr113 func Init() error { @@ -237,5 +240,14 @@ func Init() error { cview.Styles.PrimitiveBackgroundColor = GetColor("bg") } // Otherwise it's black by default + // Parse HTTP command + HttpCommand = viper.GetStringSlice("a-general.http") + if len(HttpCommand) == 0 { + // Not a string array, interpret as a string instead + // Split on spaces to maintain compatibility with old versions + // The new better way to is to just define a string array in config + HttpCommand = strings.Fields(viper.GetString("a-general.http")) + } + return nil } diff --git a/config/default.go b/config/default.go index 4d0e854..3ba1e7c 100644 --- a/config/default.go +++ b/config/default.go @@ -21,10 +21,20 @@ home = "gemini://gemini.circumlunar.space" # If set to false, a prompt will be shown before following redirects. auto_redirect = false -# What command to run to open a HTTP(S) URL. Set to "default" to try to guess the browser, -# or set to "off" to not open HTTP(S) URLs. +# What command to run to open a HTTP(S) URL. +# Set to "default" to try to guess the browser, or set to "off" to not open HTTP(S) URLs. # If a command is set, than the URL will be added (in quotes) to the end of the command. -# A space will be prepended if necessary. +# A space will be prepended to the URL. +# +# The best to define a command is using a string array. +# Examples: +# http = ["firefox"] +# http = ["custom-browser", "--flag", "--option=2"] +# http = ["/path/with spaces/in it/firefox"] +# +# Using just a string will also work, but it is deprecated, +# and will degrade if you use paths with spaces. + http = "default" # Any URL that will accept a query string can be put here diff --git a/default-config.toml b/default-config.toml index 900fcbe..aeb22cf 100644 --- a/default-config.toml +++ b/default-config.toml @@ -18,10 +18,20 @@ home = "gemini://gemini.circumlunar.space" # If set to false, a prompt will be shown before following redirects. auto_redirect = false -# What command to run to open a HTTP(S) URL. Set to "default" to try to guess the browser, -# or set to "off" to not open HTTP(S) URLs. +# What command to run to open a HTTP(S) URL. +# Set to "default" to try to guess the browser, or set to "off" to not open HTTP(S) URLs. # If a command is set, than the URL will be added (in quotes) to the end of the command. -# A space will be prepended if necessary. +# A space will be prepended to the URL. +# +# The best to define a command is using a string array. +# Examples: +# http = ["firefox"] +# http = ["custom-browser", "--flag", "--option=2"] +# http = ["/path/with spaces/in it/firefox"] +# +# Using just a string will also work, but it is deprecated, +# and will degrade if you use paths with spaces. + http = "default" # Any URL that will accept a query string can be put here diff --git a/display/private.go b/display/private.go index d2a341b..dc73f35 100644 --- a/display/private.go +++ b/display/private.go @@ -146,24 +146,33 @@ func setPage(t *tab, p *structs.Page) { // handleHTTP is used by handleURL. // It opens HTTP links and displays Info and Error modals. func handleHTTP(u string, showInfo bool) { - switch strings.TrimSpace(viper.GetString("a-general.http")) { - case "", "off": - Error("HTTP Error", "Opening HTTP URLs is turned off.") - case "default": - s, err := webbrowser.Open(u) - if err != nil { - Error("Webbrowser Error", err.Error()) - } else if showInfo { - Info(s) + if len(config.HttpCommand) == 1 { + // Possibly a non-command + + switch strings.TrimSpace(config.HttpCommand[0]) { + case "", "off": + Error("HTTP Error", "Opening HTTP URLs is turned off.") + case "default": + s, err := webbrowser.Open(u) + if err != nil { + Error("Webbrowser Error", err.Error()) + } else if showInfo { + Info(s) + } + } + } else { + // Custom command + var err error = nil + if len(config.HttpCommand) > 1 { + err = exec.Command(config.HttpCommand[0], append(config.HttpCommand[1:], u)...).Start() + } else { + err = exec.Command(config.HttpCommand[0], u).Start() } - default: - // The config has a custom command to execute for HTTP URLs - fields := strings.Fields(viper.GetString("a-general.http")) - err := exec.Command(fields[0], append(fields[1:], u)...).Start() if err != nil { Error("HTTP Error", "Error executing custom browser command: "+err.Error()) } } + App.Draw() } From 72e38e8b8de61cb39346449a6444bfbf6459ab9b Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 18:38:08 -0500 Subject: [PATCH 10/28] =?UTF-8?q?=F0=9F=93=9D=20Update=20changelog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8ebd26..8ec875b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- **Support client certificates** through config (#112) - `ansi` config setting, to disable ANSI colors in pages (#79, #86) - Edit current URL with e (#87) - If `emoji_favicons` is enabled, new bookmarks will have the domain's favicon prepended (#69, #90) - The `BROWSER` env var is now also checked when opening web links on Unix (#93) -- Support client certificates through config (#112) ### Changed - Disabling the `color` config setting also disables ANSI colors in pages (#79, #86) @@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - XDG user dir file is parsed instead of looking for XDG env vars (#97, #100) -- Support paths in HTTP(S) browser config setting (#77) +- Support paths with spaces in HTTP browser config setting (#77) ## [v1.5.0] - 2020-09-01 From 5adb676a686cc7816eb9f9eb12ff042314be900b Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 18:47:27 -0500 Subject: [PATCH 11/28] =?UTF-8?q?=F0=9F=9A=A8=20Make=20linter=20happy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/config.go | 8 ++++---- display/private.go | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/config/config.go b/config/config.go index 17f0273..85e946d 100644 --- a/config/config.go +++ b/config/config.go @@ -39,7 +39,7 @@ var bkmkPath string var DownloadsDir string // Command for opening HTTP(S) URLs in the browser, from "a-general.http" in config. -var HttpCommand []string +var HTTPCommand []string //nolint:golint,goerr113 func Init() error { @@ -241,12 +241,12 @@ func Init() error { } // Otherwise it's black by default // Parse HTTP command - HttpCommand = viper.GetStringSlice("a-general.http") - if len(HttpCommand) == 0 { + HTTPCommand = viper.GetStringSlice("a-general.http") + if len(HTTPCommand) == 0 { // Not a string array, interpret as a string instead // Split on spaces to maintain compatibility with old versions // The new better way to is to just define a string array in config - HttpCommand = strings.Fields(viper.GetString("a-general.http")) + HTTPCommand = strings.Fields(viper.GetString("a-general.http")) } return nil diff --git a/display/private.go b/display/private.go index dc73f35..474d998 100644 --- a/display/private.go +++ b/display/private.go @@ -146,10 +146,10 @@ func setPage(t *tab, p *structs.Page) { // handleHTTP is used by handleURL. // It opens HTTP links and displays Info and Error modals. func handleHTTP(u string, showInfo bool) { - if len(config.HttpCommand) == 1 { + if len(config.HTTPCommand) == 1 { // Possibly a non-command - switch strings.TrimSpace(config.HttpCommand[0]) { + switch strings.TrimSpace(config.HTTPCommand[0]) { case "", "off": Error("HTTP Error", "Opening HTTP URLs is turned off.") case "default": @@ -163,10 +163,10 @@ func handleHTTP(u string, showInfo bool) { } else { // Custom command var err error = nil - if len(config.HttpCommand) > 1 { - err = exec.Command(config.HttpCommand[0], append(config.HttpCommand[1:], u)...).Start() + if len(config.HTTPCommand) > 1 { + err = exec.Command(config.HTTPCommand[0], append(config.HTTPCommand[1:], u)...).Start() } else { - err = exec.Command(config.HttpCommand[0], u).Start() + err = exec.Command(config.HTTPCommand[0], u).Start() } if err != nil { Error("HTTP Error", "Error executing custom browser command: "+err.Error()) From 4fbaa978d4ae8477900e73179235591e43a11231 Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 19:40:34 -0500 Subject: [PATCH 12/28] =?UTF-8?q?=E2=9C=A8=20Don't=20cache=20client=20cert?= =?UTF-8?q?=20domains?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/config.go | 2 +- display/private.go | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/config/config.go b/config/config.go index 85e946d..0ea7967 100644 --- a/config/config.go +++ b/config/config.go @@ -1,6 +1,7 @@ // Package config initializes all files required for Amfora, even those used by // other packages. It also reads in the config file and initializes a Viper and // the theme +//nolint:golint,goerr113 package config import ( @@ -41,7 +42,6 @@ var DownloadsDir string // Command for opening HTTP(S) URLs in the browser, from "a-general.http" in config. var HTTPCommand []string -//nolint:golint,goerr113 func Init() error { // *** Set paths *** diff --git a/display/private.go b/display/private.go index 474d998..a189931 100644 --- a/display/private.go +++ b/display/private.go @@ -458,7 +458,12 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) { } page.Width = termW - go cache.AddPage(page) + + if !client.HasClientCert(parsed.Host) { + // Don't cache pages with client certs + go cache.AddPage(page) + } + setPage(t, page) return ret(u, true) } From eb10c265990b3f3fdda2ef55e70a263c6f094b5b Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 19:54:58 -0500 Subject: [PATCH 13/28] =?UTF-8?q?=F0=9F=90=9B=20Fixes=20#91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + display/bookmarks.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ec875b..2cf9e34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - XDG user dir file is parsed instead of looking for XDG env vars (#97, #100) - Support paths with spaces in HTTP browser config setting (#77) +- Clicking "Change" on an existing bookmark without changing the text no longer removes it (#91) ## [v1.5.0] - 2020-09-01 diff --git a/display/bookmarks.go b/display/bookmarks.go index 8541751..70cd5a1 100644 --- a/display/bookmarks.go +++ b/display/bookmarks.go @@ -88,7 +88,7 @@ func openBkmkModal(name string, exists bool, favicon string) (string, int) { if favicon != "" && !exists { name = favicon + " " + name } - bkmkModalText = "" + bkmkModalText = name bkmkModal.GetForm().AddInputField("Name: ", name, 0, nil, func(text string) { // Store for use later From b7efbdaeeaeebc34e19ad79c8dab23f994dcdc11 Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 20:01:11 -0500 Subject: [PATCH 14/28] =?UTF-8?q?=F0=9F=90=9B=20Fixes=20#81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + display/download.go | 10 ++++++---- display/private.go | 33 ++++++++++++++++++++------------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cf9e34..23724c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - XDG user dir file is parsed instead of looking for XDG env vars (#97, #100) - Support paths with spaces in HTTP browser config setting (#77) - Clicking "Change" on an existing bookmark without changing the text no longer removes it (#91) +- Display HTTP Error if "Open In Portal" fails (#81) ## [v1.5.0] - 2020-09-01 diff --git a/display/download.go b/display/download.go index a150166..6a30b4e 100644 --- a/display/download.go +++ b/display/download.go @@ -117,10 +117,12 @@ func dlChoice(text, u string, resp *gemini.Response) { portalURL = parsed.String() + "%3F" + query } portalURL = strings.TrimPrefix(portalURL, "gemini://") + "?raw=1" - handleHTTP("https://portal.mozz.us/gemini/"+portalURL, false) - tabPages.SwitchToPage(strconv.Itoa(curTab)) - App.SetFocus(tabs[curTab].view) - App.Draw() + ok := handleHTTP("https://portal.mozz.us/gemini/"+portalURL, false) + if ok { + tabPages.SwitchToPage(strconv.Itoa(curTab)) + App.SetFocus(tabs[curTab].view) + App.Draw() + } return } tabPages.SwitchToPage(strconv.Itoa(curTab)) diff --git a/display/private.go b/display/private.go index a189931..936d9c0 100644 --- a/display/private.go +++ b/display/private.go @@ -145,35 +145,42 @@ func setPage(t *tab, p *structs.Page) { // handleHTTP is used by handleURL. // It opens HTTP links and displays Info and Error modals. -func handleHTTP(u string, showInfo bool) { +// Returns false if there was an error. +func handleHTTP(u string, showInfo bool) bool { if len(config.HTTPCommand) == 1 { // Possibly a non-command switch strings.TrimSpace(config.HTTPCommand[0]) { case "", "off": Error("HTTP Error", "Opening HTTP URLs is turned off.") + return false case "default": s, err := webbrowser.Open(u) if err != nil { Error("Webbrowser Error", err.Error()) - } else if showInfo { + return false + } + if showInfo { Info(s) } - } - } else { - // Custom command - var err error = nil - if len(config.HTTPCommand) > 1 { - err = exec.Command(config.HTTPCommand[0], append(config.HTTPCommand[1:], u)...).Start() - } else { - err = exec.Command(config.HTTPCommand[0], u).Start() - } - if err != nil { - Error("HTTP Error", "Error executing custom browser command: "+err.Error()) + return true } } + // Custom command + var err error = nil + if len(config.HTTPCommand) > 1 { + err = exec.Command(config.HTTPCommand[0], append(config.HTTPCommand[1:], u)...).Start() + } else { + err = exec.Command(config.HTTPCommand[0], u).Start() + } + if err != nil { + Error("HTTP Error", "Error executing custom browser command: "+err.Error()) + return false + } + App.Draw() + return true } // handleOther is used by handleURL. From 819023daec1b5f207c8713ecc884936808610c3f Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 20:31:04 -0500 Subject: [PATCH 15/28] =?UTF-8?q?=F0=9F=90=9B=20Support=20ANSI=20color=20c?= =?UTF-8?q?odes=20in=20preformatted=20blocks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + config/default.go | 2 +- default-config.toml | 2 +- renderer/renderer.go | 37 ++++++++++++++++++++++++++----------- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23724c1..e878a78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support paths with spaces in HTTP browser config setting (#77) - Clicking "Change" on an existing bookmark without changing the text no longer removes it (#91) - Display HTTP Error if "Open In Portal" fails (#81) +- Support ANSI color codes again, but only in preformatted blocks (#59) ## [v1.5.0] - 2020-09-01 diff --git a/config/default.go b/config/default.go index 3ba1e7c..6329539 100644 --- a/config/default.go +++ b/config/default.go @@ -43,7 +43,7 @@ search = "gemini://gus.guru/search" # Whether colors will be used in the terminal color = true -# Whether ANSI codes from the page content should be rendered +# Whether ANSI color codes from the page content should be rendered ansi = true # Whether to replace list asterisks with unicode bullets diff --git a/default-config.toml b/default-config.toml index aeb22cf..9ac0d21 100644 --- a/default-config.toml +++ b/default-config.toml @@ -40,7 +40,7 @@ search = "gemini://gus.guru/search" # Whether colors will be used in the terminal color = true -# Whether ANSI codes from the page content should be rendered +# Whether ANSI color codes from the page content should be rendered ansi = true # Whether to replace list asterisks with unicode bullets diff --git a/renderer/renderer.go b/renderer/renderer.go index 3b1e6eb..eabc715 100644 --- a/renderer/renderer.go +++ b/renderer/renderer.go @@ -283,11 +283,6 @@ func convertRegularGemini(s string, numLinks, width int, proxied bool) (string, // If it's not a gemini:// page, set this to true. func RenderGemini(s string, width, leftMargin int, proxied bool) (string, []string) { s = cview.Escape(s) - if viper.GetBool("a-general.color") && viper.GetBool("a-general.ansi") { - s = cview.TranslateANSI(s) - } else { - s = ansiRegex.ReplaceAllString(s, "") - } lines := strings.Split(s, "\n") @@ -302,13 +297,22 @@ func RenderGemini(s string, width, leftMargin int, proxied bool) (string, []stri if pre { // In a preformatted block, so add the text as is // Don't add the current line with backticks - rendered += tagLines( - buf, - fmt.Sprintf("[%s]", config.GetColorString("preformatted_text")), - "[-]", - ) + + // Support ANSI color codes in preformatted blocks - see #59 + if viper.GetBool("a-general.color") && viper.GetBool("a-general.ansi") { + buf = cview.TranslateANSI(buf) + } else { + buf = ansiRegex.ReplaceAllString(buf, "") + } + + rendered += fmt.Sprintf("[%s]", config.GetColorString("preformatted_text")) + + buf + "[-]" } else { // Not preformatted, regular text + + // ANSI not allowed in regular text - see #59 + buf = ansiRegex.ReplaceAllString(buf, "") + ren, lks := convertRegularGemini(buf, len(links), width, proxied) links = append(links, lks...) rendered += ren @@ -323,10 +327,21 @@ func RenderGemini(s string, width, leftMargin int, proxied bool) (string, []stri // Gone through all the lines, but there still is likely a block in the buffer if pre { // File ended without closing the preformatted block - rendered += buf + // Same code as in the loop above + + if viper.GetBool("a-general.color") && viper.GetBool("a-general.ansi") { + buf = cview.TranslateANSI(buf) + } else { + buf = ansiRegex.ReplaceAllString(buf, "") + } + rendered += fmt.Sprintf("[%s]", config.GetColorString("preformatted_text")) + + buf + "[-]" } else { // Not preformatted, regular text // Same code as in the loop above + + buf = ansiRegex.ReplaceAllString(buf, "") + ren, lks := convertRegularGemini(buf, len(links), width, proxied) links = append(links, lks...) rendered += ren From fb47eff23ea0f9a63b14a3054622075147f4284d Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 20:41:09 -0500 Subject: [PATCH 16/28] =?UTF-8?q?=F0=9F=90=9B=20Make=20..=20command=20work?= =?UTF-8?q?=20like=20in=20v1.4.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + display/display.go | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e878a78..9ca876b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Clicking "Change" on an existing bookmark without changing the text no longer removes it (#91) - Display HTTP Error if "Open In Portal" fails (#81) - Support ANSI color codes again, but only in preformatted blocks (#59) +- Make the `..` command work lke it used to in v1.4.0 ## [v1.5.0] - 2020-09-01 diff --git a/display/display.go b/display/display.go index 0f08676..d2b6921 100644 --- a/display/display.go +++ b/display/display.go @@ -133,6 +133,13 @@ func Init() { // This shouldn't occur return } + + if query == ".." && tabs[tab].page.URL[len(tabs[tab].page.URL)-1] != '/' { + // Support what ".." used to work like + // If on /dir/doc.gmi, got to /dir/ + query = "./" + } + target, err := current.Parse(query) if err != nil { // Invalid relative url From 6993c24470031ed9d138c67f4e3b92cfba18da39 Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 20:42:30 -0500 Subject: [PATCH 17/28] =?UTF-8?q?=F0=9F=94=A5=20Remove=20unused=20func?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- renderer/renderer.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/renderer/renderer.go b/renderer/renderer.go index eabc715..8f41fdd 100644 --- a/renderer/renderer.go +++ b/renderer/renderer.go @@ -80,17 +80,6 @@ func wrapLine(line string, width int, prefix, suffix string, includeFirst bool) return ret } -// tagLines splits a string into lines and adds a the given -// string to the start and another to the end. -// It is used for adding cview color tags. -func tagLines(s, start, end string) string { - lines := strings.Split(s, "\n") - for i := range lines { - lines[i] = start + lines[i] + end - } - return strings.Join(lines, "\n") -} - // convertRegularGemini converts non-preformatted blocks of text/gemini // into a cview-compatible format. // Since this only works on non-preformatted blocks, RenderGemini From 277cc91881da0814e15e994c53b31b1d35a845df Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 20:55:34 -0500 Subject: [PATCH 18/28] =?UTF-8?q?=E2=9C=A8=20More=20fine-grained=20error?= =?UTF-8?q?=20codes,=20support=20client=20cert=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + display/private.go | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ca876b..18a536f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Edit current URL with e (#87) - If `emoji_favicons` is enabled, new bookmarks will have the domain's favicon prepended (#69, #90) - The `BROWSER` env var is now also checked when opening web links on Unix (#93) +- More accurate error messages based on server response code ### Changed - Disabling the `color` config setting also disables ANSI colors in pages (#79, #86) diff --git a/display/private.go b/display/private.go index 936d9c0..f213455 100644 --- a/display/private.go +++ b/display/private.go @@ -478,8 +478,8 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) { // Could be a non 20 (or 21) status code, or a different kind of document // Handle each status code - switch gemini.SimplifyStatus(res.Status) { - case 10: + switch res.Status { + case 10, 11: userInput, ok := Input(res.Meta) if ok { // Make another request with the query string added @@ -492,7 +492,7 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) { return ret(handleURL(t, parsed.String(), 0)) } return ret("", false) - case 30: + case 30, 31: parsedMeta, err := url.Parse(res.Meta) if err != nil { Error("Redirect Error", "Invalid URL: "+err.Error()) @@ -520,13 +520,44 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) { case 40: Error("Temporary Failure", cview.Escape(res.Meta)) return ret("", false) + case 41: + Error("Server Unavailable", cview.Escape(res.Meta)) + return ret("", false) + case 42: + Error("CGI Error", cview.Escape(res.Meta)) + return ret("", false) + case 43: + Error("Proxy Failure", cview.Escape(res.Meta)) + return ret("", false) + case 44: + Error("Slow Down", "You should wait "+cview.Escape(res.Meta)+" seconds before making another request.") + return ret("", false) case 50: Error("Permanent Failure", cview.Escape(res.Meta)) return ret("", false) + case 51: + Error("Not Found", cview.Escape(res.Meta)) + return ret("", false) + case 52: + Error("Gone", cview.Escape(res.Meta)) + return ret("", false) + case 53: + Error("Proxy Request Refused", cview.Escape(res.Meta)) + return ret("", false) + case 59: + Error("Bad Request", cview.Escape(res.Meta)) + return ret("", false) case 60: - Info("The server requested a certificate. Cert handling is coming to Amfora soon!") + Error("Client Certificate Required", cview.Escape(res.Meta)) + return ret("", false) + case 61: + Error("Certificate Not Authorised", cview.Escape(res.Meta)) + return ret("", false) + case 62: + Error("Certificate Not Valid", cview.Escape(res.Meta)) return ret("", false) } + // Status code 20, but not a document that can be displayed go dlChoice("That file could not be displayed. What would you like to do?", u, res) return ret("", false) From b05885e7100a18fb7afae5d388173b7795c274ec Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 21:11:33 -0500 Subject: [PATCH 19/28] =?UTF-8?q?=E2=9C=A8=20Disable=20cache=20for=20redir?= =?UTF-8?q?ects=20-=20fixes=20#114?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + display/private.go | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18a536f..aea2dc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The web browser code doesn't check for Xorg anymore, just display variables (#93) - Bookmarks can be made to non-gemini URLs (#94) - Remove pointless directory fallbacks (#101) +- Don't load page from cache when redirected to it (#114) ### Fixed - XDG user dir file is parsed instead of looking for XDG env vars (#97, #100) diff --git a/display/private.go b/display/private.go index f213455..71db998 100644 --- a/display/private.go +++ b/display/private.go @@ -383,11 +383,14 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) { // Gemini URL, or one with a Gemini proxy available - // Load page from cache if possible - page, ok := cache.GetPage(u) - if ok { - setPage(t, page) - return ret(u, true) + // Load page from cache if it exists, + // and this isn't a page that was redirected to by the server (indicates dynamic content) + if numRedirects == 0 { + page, ok := cache.GetPage(u) + if ok { + setPage(t, page) + return ret(u, true) + } } // Otherwise download it bottomBar.SetText("Loading...") From 445be96e467a959aff6dc8aaf75ca8751ce6f2d7 Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 21:31:08 -0500 Subject: [PATCH 20/28] =?UTF-8?q?=F0=9F=94=96=20Ready=20for=20v1.6.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 +- README.md | 3 +-- THANKS.md | 13 +++++++++++++ amfora.go | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 THANKS.md diff --git a/CHANGELOG.md b/CHANGELOG.md index aea2dc2..d1e46be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [v1.6.0] - 2020-11-04 ### Added - **Support client certificates** through config (#112) - `ansi` config setting, to disable ANSI colors in pages (#79, #86) diff --git a/README.md b/README.md index 632a959..cea0ac0 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ Features in *italics* are in the master branch, but not in the latest release. - Disabled by default, enable in config - [x] Proxying - Schemes like Gopher or HTTP can be proxied through a Gemini server -- [x] *Client certificate support* +- [x] Client certificate support - [ ] Full client certificate UX within the client - Create transient and permanent certs within the client, per domain - Manage and browse them @@ -144,7 +144,6 @@ On Windows, the file is in `%APPDATA%\amfora\config.toml`, which usually expands ## Known Bugs - Pasting on Windows is truncated, the full paste content won't be added. ([#43](https://github.com/makeworld-the-better-one/amfora/issues/43)) -- ANSI codes aren't displaying properly ([#59](https://github.com/makeworld-the-better-one/amfora/issues/59)) You can also check out [all the issues with the bug label](https://github.com/makeworld-the-better-one/amfora/issues?q=is%3Aopen+is%3Aissue+label%3Abug). diff --git a/THANKS.md b/THANKS.md new file mode 100644 index 0000000..0e093f4 --- /dev/null +++ b/THANKS.md @@ -0,0 +1,13 @@ +# THANKS + +Thank you to the following contributors, who have helped make Amfora great. FOSS projects are a community effort, and we would be worse off without you. + +- Sotiris Papatheodorou (@sotpapathe) +- Chloe Kudryavtsev (@CosmicToast) +- Adrian Hesketh (@a-h) +- Jansen Price (@sumpygump) +- Alex Wennerberg (@alexwennerberg) +- Timur Ismagilov (@bouncepaw) +- Matt Caroll (@ohiolab) +- Patryk Niedźwiedziński (@pniedzwiedzinski) +- Trevor Slocum (@tsclocum) \ No newline at end of file diff --git a/amfora.go b/amfora.go index 80d6115..8c58a73 100644 --- a/amfora.go +++ b/amfora.go @@ -9,7 +9,7 @@ import ( ) var ( - version = "1.5.0" + version = "v1.6.0" commit = "unknown" builtBy = "unknown" ) From adf03b9aed792a6124f2058a3968db572fb4c437 Mon Sep 17 00:00:00 2001 From: makeworld Date: Wed, 4 Nov 2020 22:18:43 -0500 Subject: [PATCH 21/28] =?UTF-8?q?=F0=9F=93=9D=20Add=20client=20cert=20gen?= =?UTF-8?q?=20command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index cea0ac0..84890c0 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,16 @@ The config file is written in the intuitive [TOML](https://github.com/toml-lang/ On Windows, the file is in `%APPDATA%\amfora\config.toml`, which usually expands to `C:\Users\\AppData\Roaming\amfora\config.toml`. +## Client Certificates + +Amfora has early support for client certs. Eventually Amfora will be able to generate them itself, but for you can do it by using OpenSSL (not Windows friendly): + +```shell +openssl req -new -subj "/CN=username" -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -out cert.pem -keyout key.pem +``` + +This will create a certificate and key file, that can be renamed and moved as you like. See the configuration section above for how to edit your config file to tell Amfora about them. + ## Known Bugs - Pasting on Windows is truncated, the full paste content won't be added. ([#43](https://github.com/makeworld-the-better-one/amfora/issues/43)) From 383d8bcee0e94562362738ec732b6de7fb30da05 Mon Sep 17 00:00:00 2001 From: makeworld Date: Thu, 5 Nov 2020 10:38:40 -0500 Subject: [PATCH 22/28] =?UTF-8?q?=F0=9F=90=9B=20Remove=20newlines=20from?= =?UTF-8?q?=20META=20error=20strings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- display/private.go | 26 +++++++++++++------------- display/util.go | 7 +++++++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/display/private.go b/display/private.go index 71db998..dc353d9 100644 --- a/display/private.go +++ b/display/private.go @@ -521,43 +521,43 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) { } return ret("", false) case 40: - Error("Temporary Failure", cview.Escape(res.Meta)) + Error("Temporary Failure", escapeMeta(res.Meta)) return ret("", false) case 41: - Error("Server Unavailable", cview.Escape(res.Meta)) + Error("Server Unavailable", escapeMeta(res.Meta)) return ret("", false) case 42: - Error("CGI Error", cview.Escape(res.Meta)) + Error("CGI Error", escapeMeta(res.Meta)) return ret("", false) case 43: - Error("Proxy Failure", cview.Escape(res.Meta)) + Error("Proxy Failure", escapeMeta(res.Meta)) return ret("", false) case 44: - Error("Slow Down", "You should wait "+cview.Escape(res.Meta)+" seconds before making another request.") + Error("Slow Down", "You should wait "+escapeMeta(res.Meta)+" seconds before making another request.") return ret("", false) case 50: - Error("Permanent Failure", cview.Escape(res.Meta)) + Error("Permanent Failure", escapeMeta(res.Meta)) return ret("", false) case 51: - Error("Not Found", cview.Escape(res.Meta)) + Error("Not Found", escapeMeta(res.Meta)) return ret("", false) case 52: - Error("Gone", cview.Escape(res.Meta)) + Error("Gone", escapeMeta(res.Meta)) return ret("", false) case 53: - Error("Proxy Request Refused", cview.Escape(res.Meta)) + Error("Proxy Request Refused", escapeMeta(res.Meta)) return ret("", false) case 59: - Error("Bad Request", cview.Escape(res.Meta)) + Error("Bad Request", escapeMeta(res.Meta)) return ret("", false) case 60: - Error("Client Certificate Required", cview.Escape(res.Meta)) + Error("Client Certificate Required", escapeMeta(res.Meta)) return ret("", false) case 61: - Error("Certificate Not Authorised", cview.Escape(res.Meta)) + Error("Certificate Not Authorised", escapeMeta(res.Meta)) return ret("", false) case 62: - Error("Certificate Not Valid", cview.Escape(res.Meta)) + Error("Certificate Not Valid", escapeMeta(res.Meta)) return ret("", false) } diff --git a/display/util.go b/display/util.go index e03fdd6..4ea8e91 100644 --- a/display/util.go +++ b/display/util.go @@ -3,12 +3,19 @@ package display import ( "errors" "net/url" + "strings" "github.com/spf13/viper" + "gitlab.com/tslocum/cview" ) // This file contains funcs that are small, self-contained utilities. +// escapeMeta santizes a META string for use within a cview modal. +func escapeMeta(meta string) string { + return cview.Escape(strings.ReplaceAll(meta, "\n", "")) +} + // isValidTab indicates whether the passed tab is still being used, even if it's not currently displayed. func isValidTab(t *tab) bool { tempTabs := tabs From 81fee446d4ea8f582c1e9a604f894098f8c04ef6 Mon Sep 17 00:00:00 2001 From: makeworld Date: Thu, 5 Nov 2020 10:42:07 -0500 Subject: [PATCH 23/28] =?UTF-8?q?=F0=9F=9A=91=20Remove=20unused=20import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Whoops --- display/private.go | 1 - 1 file changed, 1 deletion(-) diff --git a/display/private.go b/display/private.go index dc353d9..8686fd7 100644 --- a/display/private.go +++ b/display/private.go @@ -20,7 +20,6 @@ import ( "github.com/makeworld-the-better-one/go-gemini" "github.com/makeworld-the-better-one/go-isemoji" "github.com/spf13/viper" - "gitlab.com/tslocum/cview" ) // This file contains the functions that aren't part of the public API. From 99c117589b6ddc0c0062354428584b1e1749a1ec Mon Sep 17 00:00:00 2001 From: makeworld Date: Thu, 5 Nov 2020 11:09:37 -0500 Subject: [PATCH 24/28] =?UTF-8?q?=F0=9F=93=9D=20Add=205=20year=20expiry=20?= =?UTF-8?q?to=20openssl=20demo=20cmd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 84890c0..4d626a2 100644 --- a/README.md +++ b/README.md @@ -143,10 +143,10 @@ On Windows, the file is in `%APPDATA%\amfora\config.toml`, which usually expands ## Client Certificates -Amfora has early support for client certs. Eventually Amfora will be able to generate them itself, but for you can do it by using OpenSSL (not Windows friendly): +Amfora has early support for client certs. Eventually Amfora will be able to generate them itself, but for you can do it by using OpenSSL: ```shell -openssl req -new -subj "/CN=username" -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -out cert.pem -keyout key.pem +openssl req -new -subj "/CN=username" -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -days 1825 -nodes -out cert.pem -keyout key.pem ``` This will create a certificate and key file, that can be renamed and moved as you like. See the configuration section above for how to edit your config file to tell Amfora about them. From b314053f48e9189d3301a245e0af5ed77d71cfb9 Mon Sep 17 00:00:00 2001 From: makeworld Date: Fri, 6 Nov 2020 00:00:07 -0500 Subject: [PATCH 25/28] =?UTF-8?q?=F0=9F=93=9D=20Remove=20'v's=20from=20cha?= =?UTF-8?q?ngelog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1e46be..325c48d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [v1.6.0] - 2020-11-04 +## [1.6.0] - 2020-11-04 ### Added - **Support client certificates** through config (#112) - `ansi` config setting, to disable ANSI colors in pages (#79, #86) @@ -30,7 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Make the `..` command work lke it used to in v1.4.0 -## [v1.5.0] - 2020-09-01 +## [1.5.0] - 2020-09-01 ### Added - **Proxy support** - see the `[proxies]` section in the config (#66, #80) - **Emoji favicons** can now be seen if `emoji_favicons` is enabled in the config (#62) From 1839b7be9e9a05d4a513fabd267a4ee36f6293bb Mon Sep 17 00:00:00 2001 From: makeworld Date: Tue, 10 Nov 2020 14:53:54 -0500 Subject: [PATCH 26/28] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20go-gemini=20v0.9.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support for CN-only wildcard certs --- CHANGELOG.md | 5 +++++ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 325c48d..5e1f7a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Changed +- Updated [go-gemini](https://github.com/makeworld-the-better-one/go-gemini) to v0.9.1 to support CN-only wildcard certs + + ## [1.6.0] - 2020-11-04 ### Added - **Support client certificates** through config (#112) diff --git a/go.mod b/go.mod index 61549ab..e633377 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/gdamore/tcell v1.3.1-0.20200608133353-cb1e5d6fa606 github.com/google/go-cmp v0.5.0 // indirect - github.com/makeworld-the-better-one/go-gemini v0.9.0 + github.com/makeworld-the-better-one/go-gemini v0.9.1 github.com/makeworld-the-better-one/go-isemoji v1.1.0 github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index 2ce1789..1bf7e3f 100644 --- a/go.sum +++ b/go.sum @@ -125,8 +125,8 @@ github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tW github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/makeworld-the-better-one/go-gemini v0.9.0 h1:Iz4ywRDrfsyoR8xZOkSKGXXftMR2spIV6ibVuhrKvSw= -github.com/makeworld-the-better-one/go-gemini v0.9.0/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4= +github.com/makeworld-the-better-one/go-gemini v0.9.1 h1:/Vc6Y4Y1aOi4lZIBA1wDe+4N2xAI8EQ0CIjip2NUQkk= +github.com/makeworld-the-better-one/go-gemini v0.9.1/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4= github.com/makeworld-the-better-one/go-isemoji v1.1.0 h1:wZBHOKB5zAIgaU2vaWnXFDDhatebB8TySrNVxjVV84g= github.com/makeworld-the-better-one/go-isemoji v1.1.0/go.mod h1:FBjkPl9rr0G4vlZCc+Mr+QcnOfGCTbGWYW8/1sp06I0= github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f h1:YEUlTs5gb35UlBLTgqrub9axWTYB3d7/8TxrkJDZpRI= From 8a1a845ab2755e342cdc7f402be0ec0ea9a7ad6a Mon Sep 17 00:00:00 2001 From: Lokesh Krishna Date: Fri, 13 Nov 2020 08:23:42 +0530 Subject: [PATCH 27/28] Add the Nord theme (#118) --- contrib/themes/nord.toml | 111 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 contrib/themes/nord.toml diff --git a/contrib/themes/nord.toml b/contrib/themes/nord.toml new file mode 100644 index 0000000..ec2bf7b --- /dev/null +++ b/contrib/themes/nord.toml @@ -0,0 +1,111 @@ +[theme] +# This section is for changing the COLORS used in Amfora. +# These colors only apply if 'color' is enabled above. +# Colors can be set using a W3C color name, or a hex value such as "#ffffff". + +# Note that not all colors will work on terminals that do not have truecolor support. +# If you want to stick to the standard 16 or 256 colors, you can get +# a list of those here: https://jonasjacek.github.io/colors/ +# DO NOT use the names from that site, just the hex codes. + +# Definitions: +# bg = background +# fg = foreground +# dl = download +# btn = button +# hdg = heading +# bkmk = bookmark +# modal = a popup window/box in the middle of the screen + +# EXAMPLES: +# hdg_1 = "green" +# hdg_2 = "#5f0000" + +# Available keys to set: + +# bg: background for pages, tab row, app in general +# tab_num: The number/highlight of the tabs at the top +# tab_divider: The color of the divider character between tab numbers: | +# bottombar_label: The color of the prompt that appears when you press space +# bottombar_text: The color of the text you type +# bottombar_bg +bg = "#2e3440" +fg = "#eceff4" +tab_num = "#88c0d0" +tab_divider = "#eceff4" +bottombar_bg = "#3b4252" +bottombar_text = "#eceff4" +bottombar_label = "#88c0d0" + +# hdg_1 +# hdg_2 +# hdg_3 +# amfora_link: A link that Amfora supports viewing. For now this is only gemini:// +# foreign_link: HTTP(S), Gopher, etc +# link_number: The silver number that appears to the left of a link +# regular_text: Normal gemini text, and plaintext documents +# quote_text +# preformatted_text +# list_text +hdg_1 = "#5e81ac" +hdg_2 = "#81a1c1" +hdg_3 = "#8fbcbb" +amfora_link = "#88c0d0" +foreign_link = "#b48ead" +link_number = "#a3be8c" +regular_text = "#eceff4" +quote_text = "#8fbcbb" +preformatted_text = "#eceff4" +list_text = "#eceff4" + +# btn_bg: The bg color for all modal buttons +# btn_text: The text color for all modal buttons +btn_bg = "#4c566a" +btn_text = "#eceff4" + +# dl_choice_modal_bg +# dl_choice_modal_text +# dl_modal_bg +# dl_modal_text +# info_modal_bg +# info_modal_text +# error_modal_bg +# error_modal_text +# yesno_modal_bg +# yesno_modal_text +# tofu_modal_bg +# tofu_modal_text + +dl_choice_modal_bg = "#3b4252" +dl_choice_modal_text = "#eceff4" +dl_modal_bg = "#3b4252" +dl_modal_text = "#eceff4" +info_modal_bg = "#3b4252" +info_modal_text = "#eceff4" +error_modal_bg = "#bf616a" +error_modal_text = "#2e3440" +yesno_modal_bg = "#3b4252" +yesno_modal_text = "#eceff4" +tofu_modal_bg = "#3b4252" +tofu_modal_text = "#eceff4" + +# input_modal_bg +# input_modal_text +# input_modal_field_bg: The bg of the input field, where you type the text +# input_modal_field_text: The color of the text you type +input_modal_bg = "#3b4252" +input_modal_text = "#eceff4" +input_modal_field_bg = "#4c566a" +input_modal_field_text ="#eceff4" + +# bkmk_modal_bg +# bkmk_modal_text +# bkmk_modal_label +# bkmk_modal_field_bg +# bkmk_modal_field_text + +bkmk_modal_bg = "#3b4252" +bkmk_modal_text = "#eceff4" +bkmk_modal_label = "#88c0d0" +bkmk_modal_field_bg = "#4c566a" +bkmk_modal_field_text = "#eceff4" From 524dee963559a31b639c3d11ca8d893d0374efbe Mon Sep 17 00:00:00 2001 From: makeworld Date: Mon, 16 Nov 2020 18:20:53 -0500 Subject: [PATCH 28/28] =?UTF-8?q?=F0=9F=92=84=20Preformatted=20text=20grey?= =?UTF-8?q?=20by=20default?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + config/theme.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e1f7a1..4547b95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed - Updated [go-gemini](https://github.com/makeworld-the-better-one/go-gemini) to v0.9.1 to support CN-only wildcard certs +- Preformatted text is now grey by default ## [1.6.0] - 2020-11-04 diff --git a/config/theme.go b/config/theme.go index 6c021cc..a7177b6 100644 --- a/config/theme.go +++ b/config/theme.go @@ -58,7 +58,7 @@ var theme = map[string]tcell.Color{ "link_number": tcell.ColorSilver, "regular_text": tcell.ColorWhite, "quote_text": tcell.ColorWhite, - "preformatted_text": tcell.ColorWhite, + "preformatted_text": tcell.ColorGrey, "list_text": tcell.ColorWhite, }