From e85a6b1c934d1070e40d11ad94b3ad4d79bdc9b2 Mon Sep 17 00:00:00 2001 From: Feuerfuchs Date: Sun, 17 Nov 2019 10:14:58 +0100 Subject: Report template errors, add support for start page --- gopherproxy.go | 97 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 28 deletions(-) (limited to 'gopherproxy.go') diff --git a/gopherproxy.go b/gopherproxy.go index 751cebf..2a6358c 100644 --- a/gopherproxy.go +++ b/gopherproxy.go @@ -177,9 +177,19 @@ func parseGeminiDocument(body *bytes.Buffer, uri string, hostport string) (items return } -func DefaultHandler(tpl *template.Template, uri string) http.HandlerFunc { +func DefaultHandler(tpl *template.Template, startpagetext string, assetList AssetList) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { - http.Redirect(w, req, "/"+uri, http.StatusFound) + if err := tpl.Execute(w, struct { + Title string + URI string + Assets AssetList + RawText string + Lines []Item + Error bool + Protocol string + }{"Gopher/Gemini proxy", "", assetList, startpagetext, nil, false, "startpage"}); err != nil { + log.Println("Template error: " + err.Error()) + } } } @@ -188,7 +198,7 @@ func DefaultHandler(tpl *template.Template, uri string) http.HandlerFunc { // to the request path and renders the content using the provided template. // The optional robots parameters points to a robotstxt.RobotsData struct // to test user agents against a configurable robotst.txt file. -func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, assetList AssetList, robotsdebug bool, uri string) http.HandlerFunc { +func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, assetList AssetList, robotsdebug bool) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { agent := req.UserAgent() path := strings.TrimPrefix(req.URL.Path, "/gopher/") @@ -201,7 +211,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass hostport := parts[0] if len(hostport) == 0 { - http.Redirect(w, req, "/"+uri, http.StatusFound) + http.Redirect(w, req, "/", http.StatusFound) return } @@ -215,7 +225,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass uri, err := url.QueryUnescape(strings.Join(parts[1:], "/")) if err != nil { - tpl.Execute(w, struct { + if e := tpl.Execute(w, struct { Title string URI string Assets AssetList @@ -223,7 +233,10 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass Lines []Item Error bool Protocol string - }{title, hostport, assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}) + }{title, hostport, assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}); e != nil { + log.Println("Template error: " + e.Error()) + log.Println(err.Error()) + } return } @@ -241,7 +254,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass ) if err != nil { - tpl.Execute(w, struct { + if e := tpl.Execute(w, struct { Title string URI string Assets AssetList @@ -249,7 +262,9 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass Lines []Item Error bool Protocol string - }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}) + }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}); e != nil { + log.Println("Template error: " + e.Error()) + } return } @@ -259,7 +274,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass } else if strings.HasPrefix(parts[1], "0") && !strings.HasSuffix(uri, ".xml") && !strings.HasSuffix(uri, ".asc") { buf := new(bytes.Buffer) buf.ReadFrom(res.Body) - tpl.Execute(w, struct { + if err := tpl.Execute(w, struct { Title string URI string Assets AssetList @@ -267,7 +282,9 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass Lines []Item Error bool Protocol string - }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, buf.String(), nil, false, "gopher"}) + }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, buf.String(), nil, false, "gopher"}); err != nil { + log.Println("Template error: " + err.Error()) + } } else if strings.HasPrefix(parts[1], "T") { _, _, err = vips.NewTransform(). Load(res.Body). @@ -281,7 +298,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass } } else { if err := renderGopherDirectory(w, tpl, assetList, uri, hostport, res.Dir); err != nil { - tpl.Execute(w, struct { + if e := tpl.Execute(w, struct { Title string URI string Assets AssetList @@ -289,13 +306,16 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass Lines []Item Error bool Protocol string - }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}) + }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}); e != nil { + log.Println("Template error: " + e.Error()) + log.Println(e.Error()) + } } } } } -func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, assetList AssetList, robotsdebug bool, uri string) http.HandlerFunc { +func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, assetList AssetList, robotsdebug bool) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { agent := req.UserAgent() path := strings.TrimPrefix(req.URL.Path, "/gemini/") @@ -308,7 +328,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass hostport := parts[0] if len(hostport) == 0 { - http.Redirect(w, req, "/"+uri, http.StatusFound) + http.Redirect(w, req, "/", http.StatusFound) return } @@ -322,7 +342,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass uri, err := url.QueryUnescape(strings.Join(parts[1:], "/")) if err != nil { - tpl.Execute(w, struct { + if e := tpl.Execute(w, struct { Title string URI string Assets AssetList @@ -330,7 +350,10 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass Lines []Item Error bool Protocol string - }{title, hostport, assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}) + }{title, hostport, assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}); e != nil { + log.Println("Template error: " + e.Error()) + log.Println(err.Error()) + } return } @@ -348,7 +371,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass ) if err != nil { - tpl.Execute(w, struct { + if e := tpl.Execute(w, struct { Title string URI string Assets AssetList @@ -356,7 +379,10 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass Lines []Item Error bool Protocol string - }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}) + }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}); e != nil { + log.Println("Template error: " + e.Error()) + log.Println(err.Error()) + } return } @@ -367,7 +393,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass uri, )) if err != nil { - tpl.Execute(w, struct { + if e := tpl.Execute(w, struct { Title string URI string Assets AssetList @@ -375,7 +401,10 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass Lines []Item Error bool Protocol string - }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}) + }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}); e != nil { + log.Println("Template error: " + e.Error()) + log.Println(err.Error()) + } return } @@ -384,7 +413,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass } if int(res.Header.Status/10) != 2 { - tpl.Execute(w, struct { + if err := tpl.Execute(w, struct { Title string URI string Assets AssetList @@ -392,7 +421,9 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass Lines []Item Error bool Protocol string - }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error %d: %s", res.Header.Status, res.Header.Meta), nil, true, "gemini"}) + }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error %d: %s", res.Header.Status, res.Header.Meta), nil, true, "gemini"}); err != nil { + log.Println("Template error: " + err.Error()) + } return } @@ -423,7 +454,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass rawText = buf.String() } - tpl.Execute(w, struct { + if err := tpl.Execute(w, struct { Title string URI string Assets AssetList @@ -431,7 +462,9 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass Lines []Item Error bool Protocol string - }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, rawText, items, false, "gemini"}) + }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, rawText, items, false, "gemini"}); err != nil { + log.Println("Template error: " + err.Error()) + } } else { io.Copy(w, res.Body) } @@ -506,7 +539,7 @@ func FontHandler(woff2 bool, fontdata []byte) http.HandlerFunc { // specified by the request. The robots argument is a pointer to // a robotstxt.RobotsData struct for testing user agents against // a configurable robots.txt file. -func ListenAndServe(bind, robotsfile string, robotsdebug bool, vipsconcurrency int, uri string) error { +func ListenAndServe(bind, robotsfile string, robotsdebug bool, vipsconcurrency int) error { var ( tpl *template.Template robotsdata *robotstxt.RobotsData @@ -567,6 +600,12 @@ func ListenAndServe(bind, robotsfile string, robotsdebug bool, vipsconcurrency i favicondata = []byte{} } + startpagedata, err := ioutil.ReadFile("startpage.txt") + if err != nil { + startpagedata = []byte{} + } + startpagetext := string(startpagedata) + tpldata, err := ioutil.ReadFile(".template") if err == nil { tpltext = string(tpldata) @@ -622,9 +661,11 @@ func ListenAndServe(bind, robotsfile string, robotsdebug bool, vipsconcurrency i ConcurrencyLevel: vipsconcurrency, }) - http.Handle("/", gziphandler.GzipHandler(DefaultHandler(tpl, uri))) - http.Handle("/gopher/", gziphandler.GzipHandler(GopherHandler(tpl, robotsdata, AssetList{styleAsset, jsAsset, fontwAsset, fontw2Asset, propfontwAsset, propfontw2Asset}, robotsdebug, uri))) - http.Handle("/gemini/", gziphandler.GzipHandler(GeminiHandler(tpl, robotsdata, AssetList{styleAsset, jsAsset, fontwAsset, fontw2Asset, propfontwAsset, propfontw2Asset}, robotsdebug, uri))) + assets := AssetList{styleAsset, jsAsset, fontwAsset, fontw2Asset, propfontwAsset, propfontw2Asset} + + http.Handle("/", gziphandler.GzipHandler(DefaultHandler(tpl, startpagetext, assets))) + http.Handle("/gopher/", gziphandler.GzipHandler(GopherHandler(tpl, robotsdata, assets, robotsdebug))) + http.Handle("/gemini/", gziphandler.GzipHandler(GeminiHandler(tpl, robotsdata, assets, robotsdebug))) http.Handle("/robots.txt", gziphandler.GzipHandler(RobotsTxtHandler(robotstxtdata))) http.Handle("/favicon.ico", gziphandler.GzipHandler(FaviconHandler(favicondata))) http.Handle(styleAsset, gziphandler.GzipHandler(StyleHandler(styledata))) -- cgit v1.2.3-54-g00ecf