From 6b75e17f480323454f7099a5a2dfacfea635732c Mon Sep 17 00:00:00 2001 From: brent saner Date: Thu, 19 Dec 2024 02:27:53 -0500 Subject: [PATCH] BUGFIX: Content-Type, Nil Raw Body Edge Case, Links FIXES: * There was an edge case where a raw body for HTML would potentially result in a nil byte slice exception. This has been fixed. (I don't even know if it was possible, I just made sure it wasn't.) * The links browser is now explicitly returned as HTML and properly detected as a "browser". * Hyperlinks for links, w3m added to Usage page. * Content-Type is now always set correctly; there were cases where it was improperly returning e.g. text/plain for JSON. --- README.adoc | 20 ++++++++++++++++++++ TODO | 8 ++++++-- server/consts.go | 5 +++++ server/funcs_server.go | 24 ++++++++++++++++++++++-- server/tpl/usage.html.tpl | 4 ++-- 5 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 README.adoc diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000..7b909c9 --- /dev/null +++ b/README.adoc @@ -0,0 +1,20 @@ += ClientInfo +r00t^2 +Last rendered {localdatetime} +:doctype: book +:docinfo: shared +:data-uri: +:imagesdir: images +:sectlinks: +:sectnums: +:sectnumlevels: 7 +:toc: preamble +:toc2: left +:idprefix: +:toclevels: 7 +//:toclevels: 4 +:source-highlighter: rouge +:docinfo: shared + +== DOCS +**TODO!** diff --git a/TODO b/TODO index f292f90..01e1cac 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,7 @@ - suggest browser, OS alternatives (again) -- link to ipinfo.io for client IP (again) --- or just implement myself +- implement ipinfo.io equiv. myself? +- also link to https://www.useragentstring.com/ +-- or maybe https://www.whatsmyua.info/ +-- see https://www.useragentstring.com/pages/api.php +- note that though lynx and elinks are "graphical", links is considered text. w3m is considered graphical. +- fix the text/plain issue for the json (et. al.) renderer diff --git a/server/consts.go b/server/consts.go index 4b72431..41832d8 100644 --- a/server/consts.go +++ b/server/consts.go @@ -79,10 +79,15 @@ var ( mediaJSON: json.MarshalIndent, mediaXML: xml.MarshalIndent, } + // valid MIMEs. okAcceptMime []string = []string{ mediaJSON, mediaXML, mediaYAML, mediaHTML, } + // These are actually HTML. + htmlOverride map[string]bool = map[string]bool{ + "Links": true, + } ) diff --git a/server/funcs_server.go b/server/funcs_server.go index af1c251..8273ea1 100644 --- a/server/funcs_server.go +++ b/server/funcs_server.go @@ -19,6 +19,7 @@ import ( sysd "github.com/coreos/go-systemd/daemon" "github.com/davecgh/go-spew/spew" `github.com/goccy/go-yaml` + `r00t2.io/clientinfo/version` "r00t2.io/goutils/multierr" ) @@ -280,6 +281,8 @@ func (s *Server) handleDefault(resp http.ResponseWriter, req *http.Request) { s.log.Debug("server.Server.handleDefault: Handling request:\n%s", spew.Sdump(req)) + resp.Header().Set("ClientInfo-Version", version.Ver.Short()) + page = &Page{ Info: &R00tInfo{ Client: nil, @@ -327,6 +330,9 @@ func (s *Server) handleDefault(resp http.ResponseWriter, req *http.Request) { http.Error(resp, fmt.Sprintf("ERROR: Failed to parse 'User-Agent' '%s'", ua), http.StatusInternalServerError) return } + if parsedUA.Name != nil && htmlOverride[*parsedUA.Name] { + parsedUA.IsDesktop = true + } page.Info.Client = append(page.Info.Client, parsedUA) } } @@ -470,6 +476,7 @@ func (s *Server) handleAbout(resp http.ResponseWriter, req *http.Request) { s.log.Debug("server.Server.handleAbout: Handling request:\n%s", spew.Sdump(req)) + resp.Header().Set("ClientInfo-Version", version.Ver.Short()) resp.Header().Set("Content-Type", "text/html; charset=utf-8") if err = tpl.ExecuteTemplate(resp, "about", renderPage); err != nil { @@ -495,7 +502,9 @@ func (s *Server) handleUsage(resp http.ResponseWriter, req *http.Request) { s.log.Debug("server.Server.handleUsage: Handling request:\n%s", spew.Sdump(req)) + resp.Header().Set("ClientInfo-Version", version.Ver.Short()) resp.Header().Set("Content-Type", "text/html; charset=utf-8") + if err = tpl.ExecuteTemplate(resp, "usage", renderPage); err != nil { s.log.Err("server.Server.handleAbout: Failed to execute template for '%s': %v", req.RemoteAddr, err) http.Error(resp, "ERROR: Failed to render HTML", http.StatusInternalServerError) @@ -511,6 +520,8 @@ func (s *Server) renderJSON(page *Page, resp http.ResponseWriter) (err error) { var b []byte + resp.Header().Set("Content-Type", "application/json") + if page.DoIndent { if b, err = json.MarshalIndent(page.Info, "", page.Indent); err != nil { s.log.Err("server.Server.renderJSON: Failed to render to indented JSON: %v", err) @@ -561,10 +572,14 @@ func (s *Server) renderHTML(page *Page, resp http.ResponseWriter) (err error) { s.log.Err("server.Server.renderHTML: Failed to render to '%s': %v", *page.RawFmt, err) } } - page.Raw = new(string) - *page.Raw = string(b) + if b != nil { + page.Raw = new(string) + *page.Raw = string(b) + } } + resp.Header().Set("Content-Type", "text/html; charset=utf-8") + if err = tpl.ExecuteTemplate(resp, "index", page); err != nil { s.log.Err("server.Server.renderHTML: Failed to render template: %v", err) http.Error(resp, "ERROR: Failed to render HTML", http.StatusInternalServerError) @@ -591,6 +606,9 @@ func (s *Server) renderXML(page *Page, resp http.ResponseWriter) (err error) { return } } + + resp.Header().Set("Content-Type", "application/xml; charset=utf-8") + if _, err = resp.Write(b); err != nil { s.log.Err("server.Server.renderXML: Failed to send XML: %v", err) return @@ -609,6 +627,8 @@ func (s *Server) renderYML(page *Page, resp http.ResponseWriter) (err error) { return } + resp.Header().Set("Content-Type", "application/yaml") + if _, err = resp.Write(b); err != nil { s.log.Err("server.Server.renderJSON: Failed to send JSON: %v", err) return diff --git a/server/tpl/usage.html.tpl b/server/tpl/usage.html.tpl index 18a443d..e9e6e46 100644 --- a/server/tpl/usage.html.tpl +++ b/server/tpl/usage.html.tpl @@ -46,8 +46,8 @@ Accept: text/html

- Note that Lynx and Elinks are considered "graphical" - browsers by this program as they are HTML-centric. + Note that Linksa>, Lynx, Elinks, + and W3M are considered "graphical" browsers by this program as they are HTML-centric.

The following parameters control/modify behavior.{{ $linkico }}