1
0
Fork 0

fix for #103: Simple handling of local (file://) urls (#117)

Co-authored-by: Mattias Jadelius <mattias.jadelius>
This commit is contained in:
Mattias Jadelius 2020-11-22 22:25:20 +01:00 committed by GitHub
parent a04c281ae0
commit 51fd32e1ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 129 additions and 2 deletions

116
display/file.go Normal file
View File

@ -0,0 +1,116 @@
package display
import (
"fmt"
"io/ioutil"
"mime"
"net/url"
"os"
"path/filepath"
"strings"
"github.com/makeworld-the-better-one/amfora/renderer"
"github.com/makeworld-the-better-one/amfora/structs"
"github.com/spf13/viper"
)
// handleFile handles urls using file:// protocol
func handleFile(u string) (*structs.Page, bool) {
page := &structs.Page{}
uri, err := url.ParseRequestURI(u)
if err != nil {
Error("File Error", "Cannot parse URI: "+err.Error())
return page, false
}
fi, err := os.Stat(uri.Path)
if err != nil {
Error("File Error", "Cannot open local file: "+err.Error())
return page, false
}
switch mode := fi.Mode(); {
case mode.IsDir():
return createDirectoryListing(u)
case mode.IsRegular():
if fi.Size() > viper.GetInt64("a-general.page_max_size") {
Error("File Error", "Cannot open local file, exceeds page max size")
return page, false
}
mimetype := mime.TypeByExtension(filepath.Ext(uri.Path))
if strings.HasSuffix(u, ".gmi") || strings.HasSuffix(u, ".gemini") {
mimetype = "text/gemini"
}
if !strings.HasPrefix(mimetype, "text/") {
Error("File Error", "Cannot open file, not recognized as text.")
return page, false
}
content, err := ioutil.ReadFile(uri.Path)
if err != nil {
Error("File Error", "Cannot open local file: "+err.Error())
return page, false
}
if mimetype == "text/gemini" {
rendered, links := renderer.RenderGemini(string(content), textWidth(), leftMargin(), false)
page = &structs.Page{
Mediatype: structs.TextGemini,
URL: u,
Raw: string(content),
Content: rendered,
Links: links,
Width: termW,
}
} else {
page = &structs.Page{
Mediatype: structs.TextPlain,
URL: u,
Raw: string(content),
Content: renderer.RenderPlainText(string(content), leftMargin()),
Links: []string{},
Width: termW,
}
}
}
return page, true
}
// createDirectoryListing creates a text/gemini page for a directory
// that lists all the files as links.
func createDirectoryListing(u string) (*structs.Page, bool) {
page := &structs.Page{}
uri, err := url.ParseRequestURI(u)
if err != nil {
Error("Directory Error", "Cannot parse URI: "+err.Error())
}
files, err := ioutil.ReadDir(uri.Path)
if err != nil {
Error("Directory error", "Cannot open local directory: "+err.Error())
return page, false
}
content := "Index of " + uri.Path + "\n"
content += "=> ../ ../\n"
for _, f := range files {
separator := ""
if f.IsDir() {
separator = "/"
}
content += fmt.Sprintf("=> %s%s %s%s\n", f.Name(), separator, f.Name(), separator)
}
rendered, links := renderer.RenderGemini(content, textWidth(), leftMargin(), false)
page = &structs.Page{
Mediatype: structs.TextGemini,
URL: u,
Raw: content,
Content: rendered,
Links: links,
Width: termW,
}
return page, true
}

View File

@ -78,7 +78,9 @@ func reformatPage(p *structs.Page) {
case structs.TextGemini:
// Links are not recorded because they won't change
proxied := true
if strings.HasPrefix(p.URL, "gemini") || strings.HasPrefix(p.URL, "about") {
if strings.HasPrefix(p.URL, "gemini") ||
strings.HasPrefix(p.URL, "about") ||
strings.HasPrefix(p.URL, "file") {
proxied = false
}
rendered, _ = renderer.RenderGemini(p.Raw, textWidth(), leftMargin(), proxied)
@ -370,7 +372,16 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
usingProxy = true
}
if !strings.HasPrefix(u, "http") && !strings.HasPrefix(u, "gemini") {
if strings.HasPrefix(u, "file") {
page, ok := handleFile(u)
if !ok {
return ret("", false)
}
setPage(t, page)
return ret(u, true)
}
if !strings.HasPrefix(u, "http") && !strings.HasPrefix(u, "gemini") && !strings.HasPrefix(u, "file") {
// Not a Gemini URL
if proxy == "" || proxy == "off" {
// No proxy available