108 lines
4.6 KiB
Go
108 lines
4.6 KiB
Go
package server
|
|
|
|
import (
|
|
`encoding/xml`
|
|
`net`
|
|
`net/http`
|
|
`net/url`
|
|
`os`
|
|
|
|
`github.com/mileusna/useragent`
|
|
`r00t2.io/clientinfo/args`
|
|
`r00t2.io/goutils/logging`
|
|
)
|
|
|
|
type outerRenderer func(page *Page, resp http.ResponseWriter) (err error)
|
|
type XmlHeaders map[string][]string
|
|
|
|
// R00tInfo is the structure of data returned to the client.
|
|
type R00tInfo struct {
|
|
// XMLName is the element name/namespace of this object ("info").
|
|
XMLName xml.Name `json:"-" xml:"info" yaml:"-"`
|
|
// Client is the UA/Client info, if any passed by the client.
|
|
Client []*R00tClient `json:"ua,omitempty" xml:"ua,omitempty" yaml:"Client/User Agent,omitempty"`
|
|
// IP is the client IP address.
|
|
IP net.IP `json:"ip" xml:"ip,attr" yaml:"Client IP Address"`
|
|
// Port is the client's port number.
|
|
Port uint16 `json:"port" xml:"port,attr" yaml:"Client Port"`
|
|
// Headers are the collection of the request headers sent by the client.
|
|
Headers XmlHeaders `json:"headers" xml:"reqHeaders" yaml:"Request Headers"`
|
|
// Req contains the original request. It is not rendered but may be used for templating.
|
|
Req *http.Request `json:"-" xml:"-" yaml:"-"`
|
|
}
|
|
|
|
// R00tClient is the UA/Client info, if any passed by the client.
|
|
type R00tClient struct {
|
|
// XMLName is the element name/namespace of this object ("ua").
|
|
XMLName xml.Name `json:"-" xml:"ua" yaml:"-" uaField:"-" renderName:"-"`
|
|
// String contains the entire UA string.
|
|
String *string `json:"str,omitempty" xml:",chardata" yaml:"String"`
|
|
// ClientVer is a parsed version structure of the client version (see ClientVerStr for the combined string).
|
|
ClientVer *Ver `json:"ver,omitempty" xml:"version,omitempty" yaml:"Client Version,omitempty" uaField:"VersionNo" renderName:"-"`
|
|
// OSVer is the parsed OS version info of the client (see OsVersionStr for the combined string).
|
|
OSVer *Ver `json:"os_ver,omitempty" xml:"osVersion,omitempty" yaml:"Operating System Version,omitempty" uaField:"OSVersionNo" renderName:"-"`
|
|
// URL, if any, is the URL of the client.
|
|
URL *string `json:"url,omitempty" xml:"url,attr,omitempty" yaml:"URL,omitempty"`
|
|
// Name is the client software name.
|
|
Name *string `json:"name,omitempty" xml:"name,attr,omitempty" yaml:"Program/Name,omitempty"`
|
|
// ClientVerStr contains the full version as a string (see also Clientversion).
|
|
ClientVerStr *string `json:"ver_str,omitempty" xml:"verStr,attr,omitempty" yaml:"Client Version String,omitempty" uaField:"Version" renderName:"Client Version"`
|
|
// OS is the operating system of the client.
|
|
OS *string `json:"os,omitempty" xml:"os,attr,omitempty" yaml:"Operating System,omitempty"`
|
|
// OsVerStr is the version of the operating system of the client.
|
|
OsVerStr *string `json:"os_ver_str,omitempty" xml:"osVerStr,attr,omitempty" yaml:"Operating System Version String,omitempty" uaField:"OSVersion" renderName:"Operating System Version"`
|
|
// Dev is the device type.
|
|
Dev *string `json:"dev,omitempty" xml:"dev,attr,omitempty" yaml:"Device,omitempty" uaField:"Device"`
|
|
// IsMobile is true if this is a mobile device.
|
|
IsMobile bool `json:"mobile" xml:"mobile,attr" yaml:"Is Mobile" uaField:"Mobile"`
|
|
// sTablet is true if this is a tablet.
|
|
IsTablet bool `json:"tablet" xml:"tablet,attr" yaml:"Is Tablet" uaField:"Tablet"`
|
|
// IsDesktop is true if this is a desktop/laptop.
|
|
IsDesktop bool `json:"desktop" xml:"desktop,attr" yaml:"Is Desktop" uaField:"Desktop"`
|
|
// IsBot is true if this is a bot.
|
|
IsBot bool `json:"bot" xml:"bot,attr" yaml:"Is Bot" uaField:"Bot"`
|
|
ua *useragent.UserAgent
|
|
}
|
|
|
|
type Ver struct {
|
|
// XMLName xml.Name `json:"-" xml:"version" yaml:"-"`
|
|
Major int `json:"major" xml:"maj,attr" yaml:"Major"`
|
|
Minor int `json:"minor" xml:"min,attr" yaml:"Minor"`
|
|
Patch int `json:"patch" xml:"patch,attr" yaml:"Patch"`
|
|
}
|
|
|
|
// Page is only used for HTML rendering.
|
|
type Page struct {
|
|
Info *R00tInfo
|
|
// e.g. "index.html.tpl"; populated by handler
|
|
PageType string
|
|
// Nil unless `?include=` specified, otherwise a block of text to be wrapped in <code>...</code>.
|
|
Raw *string
|
|
// RawFmt is the MIME type for Raw, if `?include=` enabled/specified.
|
|
RawFmt *string
|
|
// Indent specifies the indentation string.
|
|
Indent string
|
|
// DoIndent indicates if indenting was enabled.
|
|
DoIndent bool
|
|
}
|
|
|
|
type Server struct {
|
|
log logging.Logger
|
|
args *args.Args
|
|
listenUri *url.URL
|
|
isHttp bool
|
|
mux *http.ServeMux
|
|
sock net.Listener
|
|
doneChan chan bool
|
|
stopChan chan os.Signal
|
|
reloadChan chan os.Signal
|
|
isStopping bool
|
|
}
|
|
|
|
// https://www.iana.org/assignments/media-types/media-types.xhtml
|
|
type parsedMIME struct {
|
|
MIME string
|
|
Weight float32 // Technically a param (q; "qualifier"?), but copied and converted here for easier sorting.
|
|
Params map[string]string
|
|
}
|