Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
eb5c44e1c3 | ||
![]() |
6b75e17f48 | ||
![]() |
8a0465a0f4 | ||
![]() |
c3b16f3981 |
20
README.adoc
Normal file
20
README.adoc
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
= ClientInfo
|
||||||
|
r00t^2 <brent.saner@gmail.com>
|
||||||
|
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!**
|
7
TODO
Normal file
7
TODO
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
- suggest browser, OS alternatives (again)
|
||||||
|
- 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
|
@ -20,3 +20,17 @@
|
|||||||
# * "<Client IP>:<Client Port>" (IPv4)
|
# * "<Client IP>:<Client Port>" (IPv4)
|
||||||
# * "[<Client IP>]:<Client Port>" (IPv6)
|
# * "[<Client IP>]:<Client Port>" (IPv6)
|
||||||
#CINFO_URI="http://127.0.0.1:1234"
|
#CINFO_URI="http://127.0.0.1:1234"
|
||||||
|
|
||||||
|
# The permissions mode for the socket file, if using UDS.
|
||||||
|
#CINFO_FMODE=0o0600
|
||||||
|
|
||||||
|
# The permissiosn mode for the socket file directory, if using UDS.
|
||||||
|
#CINFO_DMODE=0o0700
|
||||||
|
|
||||||
|
# The GID or group name of the group to chown the socket to.
|
||||||
|
# Uses the runtime user UID if not specified.
|
||||||
|
#CINFO_FGRP=http
|
||||||
|
|
||||||
|
# The GID or group name of the group to chown the socket directory to.
|
||||||
|
# Uses the primary group of the runtime user if not specified.
|
||||||
|
#CINFO_DGRP=http
|
||||||
|
@ -9,7 +9,7 @@ Description=Return Client Request Information
|
|||||||
Type=notify
|
Type=notify
|
||||||
# These may also be "httpd", "nginx", etc.
|
# These may also be "httpd", "nginx", etc.
|
||||||
User=http
|
User=http
|
||||||
Group=htttp
|
Group=http
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=10
|
RestartSec=10
|
||||||
# Not required, but you may create this file and specify the associated commandline argument env vars.
|
# Not required, but you may create this file and specify the associated commandline argument env vars.
|
||||||
@ -17,6 +17,7 @@ RestartSec=10
|
|||||||
# See clientinfo.env for an example.
|
# See clientinfo.env for an example.
|
||||||
EnvironmentFile=-/etc/default/clientinfo
|
EnvironmentFile=-/etc/default/clientinfo
|
||||||
ExecStart=/usr/local/bin/clientinfo
|
ExecStart=/usr/local/bin/clientinfo
|
||||||
|
RuntimeDirectory=clientinfo
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
@ -79,10 +79,15 @@ var (
|
|||||||
mediaJSON: json.MarshalIndent,
|
mediaJSON: json.MarshalIndent,
|
||||||
mediaXML: xml.MarshalIndent,
|
mediaXML: xml.MarshalIndent,
|
||||||
}
|
}
|
||||||
|
// valid MIMEs.
|
||||||
okAcceptMime []string = []string{
|
okAcceptMime []string = []string{
|
||||||
mediaJSON,
|
mediaJSON,
|
||||||
mediaXML,
|
mediaXML,
|
||||||
mediaYAML,
|
mediaYAML,
|
||||||
mediaHTML,
|
mediaHTML,
|
||||||
}
|
}
|
||||||
|
// These are actually HTML.
|
||||||
|
htmlOverride map[string]bool = map[string]bool{
|
||||||
|
"Links": true,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
sysd "github.com/coreos/go-systemd/daemon"
|
sysd "github.com/coreos/go-systemd/daemon"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
`github.com/goccy/go-yaml`
|
`github.com/goccy/go-yaml`
|
||||||
|
`r00t2.io/clientinfo/version`
|
||||||
"r00t2.io/goutils/multierr"
|
"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))
|
s.log.Debug("server.Server.handleDefault: Handling request:\n%s", spew.Sdump(req))
|
||||||
|
|
||||||
|
resp.Header().Set("ClientInfo-Version", version.Ver.Short())
|
||||||
|
|
||||||
page = &Page{
|
page = &Page{
|
||||||
Info: &R00tInfo{
|
Info: &R00tInfo{
|
||||||
Client: nil,
|
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)
|
http.Error(resp, fmt.Sprintf("ERROR: Failed to parse 'User-Agent' '%s'", ua), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if parsedUA.Name != nil && htmlOverride[*parsedUA.Name] {
|
||||||
|
parsedUA.IsDesktop = true
|
||||||
|
}
|
||||||
page.Info.Client = append(page.Info.Client, parsedUA)
|
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))
|
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")
|
resp.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
|
||||||
if err = tpl.ExecuteTemplate(resp, "about", renderPage); err != nil {
|
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))
|
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")
|
resp.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
|
||||||
if err = tpl.ExecuteTemplate(resp, "usage", renderPage); err != nil {
|
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)
|
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)
|
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
|
var b []byte
|
||||||
|
|
||||||
|
resp.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
if page.DoIndent {
|
if page.DoIndent {
|
||||||
if b, err = json.MarshalIndent(page.Info, "", page.Indent); err != nil {
|
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)
|
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)
|
s.log.Err("server.Server.renderHTML: Failed to render to '%s': %v", *page.RawFmt, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
page.Raw = new(string)
|
if b != nil {
|
||||||
*page.Raw = string(b)
|
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 {
|
if err = tpl.ExecuteTemplate(resp, "index", page); err != nil {
|
||||||
s.log.Err("server.Server.renderHTML: Failed to render template: %v", err)
|
s.log.Err("server.Server.renderHTML: Failed to render template: %v", err)
|
||||||
http.Error(resp, "ERROR: Failed to render HTML", http.StatusInternalServerError)
|
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
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resp.Header().Set("Content-Type", "application/xml; charset=utf-8")
|
||||||
|
|
||||||
if _, err = resp.Write(b); err != nil {
|
if _, err = resp.Write(b); err != nil {
|
||||||
s.log.Err("server.Server.renderXML: Failed to send XML: %v", err)
|
s.log.Err("server.Server.renderXML: Failed to send XML: %v", err)
|
||||||
return
|
return
|
||||||
@ -609,6 +627,8 @@ func (s *Server) renderYML(page *Page, resp http.ResponseWriter) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resp.Header().Set("Content-Type", "application/yaml")
|
||||||
|
|
||||||
if _, err = resp.Write(b); err != nil {
|
if _, err = resp.Write(b); err != nil {
|
||||||
s.log.Err("server.Server.renderJSON: Failed to send JSON: %v", err)
|
s.log.Err("server.Server.renderJSON: Failed to send JSON: %v", err)
|
||||||
return
|
return
|
||||||
|
@ -46,8 +46,8 @@ Accept: text/html
|
|||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Note that <a href="https://lynx.invisible-island.net/">Lynx</a> and <a href="http://elinks.or.cz/">Elinks</a> are considered "graphical"
|
Note that <a href="http://links.twibright.com/">Links</a>, <a href="https://lynx.invisible-island.net/">Lynx</a>, <a href="http://elinks.or.cz/">Elinks</a>,
|
||||||
browsers by this program as they are HTML-centric.
|
and <a href="https://w3m.sourceforge.net/">W3M</a> are considered "graphical" browsers by this program as they are HTML-centric.
|
||||||
</p>
|
</p>
|
||||||
<p id="usage_params_mod">
|
<p id="usage_params_mod">
|
||||||
The following parameters control/modify behavior.<a href="#usage_params_mod">{{ $linkico }}</a>
|
The following parameters control/modify behavior.<a href="#usage_params_mod">{{ $linkico }}</a>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user