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 }}