You've already forked armbian-router
mirror of
https://github.com/armbian/armbian-router.git
synced 2026-01-06 10:37:03 -08:00
Fix golint issues
This commit is contained in:
34
check.go
34
check.go
@@ -15,19 +15,27 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrHttpsRedirect = errors.New("unexpected forced https redirect")
|
||||
ErrHttpRedirect = errors.New("unexpected redirect to insecure url")
|
||||
ErrCertExpired = errors.New("certificate is expired")
|
||||
// ErrHTTPSRedirect is an error thrown when the webserver returns
|
||||
// an https redirect for an http url.
|
||||
ErrHTTPSRedirect = errors.New("unexpected forced https redirect")
|
||||
|
||||
// ErrHTTPRedirect is an error thrown when the webserver returns
|
||||
// a redirect to a non-https url from an https request.
|
||||
ErrHTTPRedirect = errors.New("unexpected redirect to insecure url")
|
||||
|
||||
// ErrCertExpired is a fatal error thrown when the webserver's
|
||||
// certificate is expired.
|
||||
ErrCertExpired = errors.New("certificate is expired")
|
||||
)
|
||||
|
||||
func (r *Redirector) checkHttp(scheme string) ServerCheck {
|
||||
func (r *Redirector) checkHTTP(scheme string) ServerCheck {
|
||||
return func(server *Server, logFields log.Fields) (bool, error) {
|
||||
return r.checkHttpScheme(server, scheme, logFields)
|
||||
return r.checkHTTPScheme(server, scheme, logFields)
|
||||
}
|
||||
}
|
||||
|
||||
// checkHttp checks a URL for validity, and checks redirects
|
||||
func (r *Redirector) checkHttpScheme(server *Server, scheme string, logFields log.Fields) (bool, error) {
|
||||
// checkHTTPScheme checks a URL for validity, and checks redirects
|
||||
func (r *Redirector) checkHTTPScheme(server *Server, scheme string, logFields log.Fields) (bool, error) {
|
||||
u := &url.URL{
|
||||
Scheme: scheme,
|
||||
Host: server.Host,
|
||||
@@ -82,7 +90,7 @@ func (r *Redirector) checkHttpScheme(server *Server, scheme string, logFields lo
|
||||
}
|
||||
|
||||
func (r *Redirector) checkProtocol(server *Server, scheme string) {
|
||||
res, err := r.checkHttpScheme(server, scheme, log.Fields{})
|
||||
res, err := r.checkHTTPScheme(server, scheme, log.Fields{})
|
||||
|
||||
if !res || err != nil {
|
||||
return
|
||||
@@ -95,16 +103,16 @@ func (r *Redirector) checkProtocol(server *Server, scheme string) {
|
||||
|
||||
// checkRedirect parses a location header response and checks the scheme
|
||||
func (r *Redirector) checkRedirect(originatingScheme, locationHeader string) (bool, error) {
|
||||
newUrl, err := url.Parse(locationHeader)
|
||||
newURL, err := url.Parse(locationHeader)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if newUrl.Scheme == "https" {
|
||||
return false, ErrHttpsRedirect
|
||||
} else if originatingScheme == "https" && newUrl.Scheme == "http" {
|
||||
return false, ErrHttpRedirect
|
||||
if newURL.Scheme == "https" {
|
||||
return false, ErrHTTPSRedirect
|
||||
} else if originatingScheme == "https" && newURL.Scheme == "http" {
|
||||
return false, ErrHTTPRedirect
|
||||
}
|
||||
|
||||
return true, nil
|
||||
|
||||
@@ -92,7 +92,7 @@ var _ = Describe("Check suite", func() {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
res, err := r.checkHttpScheme(server, "http", log.Fields{})
|
||||
res, err := r.checkHTTPScheme(server, "http", log.Fields{})
|
||||
|
||||
Expect(res).To(BeTrue())
|
||||
Expect(err).To(BeNil())
|
||||
@@ -146,11 +146,11 @@ var _ = Describe("Check suite", func() {
|
||||
|
||||
logFields := log.Fields{}
|
||||
|
||||
res, err := r.checkHttpScheme(server, "https", logFields)
|
||||
res, err := r.checkHTTPScheme(server, "https", logFields)
|
||||
|
||||
Expect(logFields["url"]).ToNot(BeEmpty())
|
||||
Expect(logFields["url"]).ToNot(Equal(httpServer.URL))
|
||||
Expect(err).To(Equal(ErrHttpRedirect))
|
||||
Expect(err).To(Equal(ErrHTTPRedirect))
|
||||
Expect(res).To(BeFalse())
|
||||
})
|
||||
})
|
||||
|
||||
50
config.go
50
config.go
@@ -17,17 +17,39 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Config represents our application's configuration.
|
||||
type Config struct {
|
||||
BindAddress string `mapstructure:"bind"`
|
||||
GeoDBPath string `mapstructure:"geodb"`
|
||||
ASNDBPath string `mapstructure:"asndb"`
|
||||
MapFile string `mapstructure:"dl_map"`
|
||||
CacheSize int `mapstructure:"cacheSize"`
|
||||
TopChoices int `mapstructure:"topChoices"`
|
||||
ReloadToken string `mapstructure:"reloadToken"`
|
||||
ServerList []ServerConfig `mapstructure:"servers"`
|
||||
ReloadFunc func()
|
||||
RootCAs *x509.CertPool
|
||||
// BindAddress is the address to bind our webserver to.
|
||||
BindAddress string `mapstructure:"bind"`
|
||||
|
||||
// GeoDBPath is the path to the MaxMind GeoLite2 City DB.
|
||||
GeoDBPath string `mapstructure:"geodb"`
|
||||
|
||||
// ASNDBPath is the path to the GeoLite2 ASN DB.
|
||||
ASNDBPath string `mapstructure:"asndb"`
|
||||
|
||||
// MapFile is a file used to map download urls via redirect.
|
||||
MapFile string `mapstructure:"dl_map"`
|
||||
|
||||
// CacheSize is the number of items to keep in the LRU cache.
|
||||
CacheSize int `mapstructure:"cacheSize"`
|
||||
|
||||
// TopChoices is the number of servers to use in a rotation.
|
||||
// With the default being 3, the top 3 servers will be rotated based on weight.
|
||||
TopChoices int `mapstructure:"topChoices"`
|
||||
|
||||
// ReloadToken is a secret token used for web-based reload.
|
||||
ReloadToken string `mapstructure:"reloadToken"`
|
||||
|
||||
// ServerList is a list of ServerConfig structs, which gets parsed into servers.
|
||||
ServerList []ServerConfig `mapstructure:"servers"`
|
||||
|
||||
// ReloadFunc is called when a reload is done via http api.
|
||||
ReloadFunc func()
|
||||
|
||||
// RootCAs is a list of CA certificates, which we parse from Mozilla directly.
|
||||
RootCAs *x509.CertPool
|
||||
|
||||
checkClient *http.Client
|
||||
}
|
||||
|
||||
@@ -51,8 +73,11 @@ func (c *Config) SetRootCAs(cas *x509.CertPool) {
|
||||
}
|
||||
}
|
||||
|
||||
// ASNList is a list of Autonomous System Numbers (in int)
|
||||
// It can be used to include or exclude specific ASNs from requests.
|
||||
type ASNList []uint
|
||||
|
||||
// Contains checks if an ASN is in the list.
|
||||
func (a ASNList) Contains(value uint) bool {
|
||||
for _, val := range a {
|
||||
if value == val {
|
||||
@@ -63,8 +88,10 @@ func (a ASNList) Contains(value uint) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ProtocolList is a list of supported protocols.
|
||||
type ProtocolList []string
|
||||
|
||||
// Contains checks if the specified protocol exists in the list.
|
||||
func (p ProtocolList) Contains(value string) bool {
|
||||
for _, val := range p {
|
||||
if value == val {
|
||||
@@ -75,10 +102,12 @@ func (p ProtocolList) Contains(value string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Append adds a supported protocol to the list.
|
||||
func (p ProtocolList) Append(value string) ProtocolList {
|
||||
return append(p, value)
|
||||
}
|
||||
|
||||
// Remove a specific protocol from the list.
|
||||
func (p ProtocolList) Remove(value string) ProtocolList {
|
||||
index := -1
|
||||
|
||||
@@ -97,6 +126,7 @@ func (p ProtocolList) Remove(value string) ProtocolList {
|
||||
return p[:len(p)-1]
|
||||
}
|
||||
|
||||
// ReloadConfig is called to reload the server's configuration.
|
||||
func (r *Redirector) ReloadConfig() error {
|
||||
log.Info("Loading configuration...")
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package redirector
|
||||
|
||||
import (
|
||||
// embed is a blank import for Go's embedding, used for image files.
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
@@ -25,6 +25,7 @@ var (
|
||||
})
|
||||
)
|
||||
|
||||
// Redirector is our application instance.
|
||||
type Redirector struct {
|
||||
config *Config
|
||||
db *maxminddb.Reader
|
||||
@@ -39,6 +40,8 @@ type Redirector struct {
|
||||
checkClient *http.Client
|
||||
}
|
||||
|
||||
// LocationLookup is a specific GeoIP lookup on the maxminddb side,
|
||||
// used for finding the closest servers.
|
||||
type LocationLookup struct {
|
||||
Location struct {
|
||||
Latitude float64 `maxminddb:"latitude"`
|
||||
@@ -46,7 +49,8 @@ type LocationLookup struct {
|
||||
} `maxminddb:"location"`
|
||||
}
|
||||
|
||||
// City represents a MaxmindDB city
|
||||
// City represents a MaxmindDB city, used only when loading servers,
|
||||
// or returning a GeoIP response.
|
||||
type City struct {
|
||||
Continent struct {
|
||||
Code string `maxminddb:"code" json:"code"`
|
||||
@@ -76,6 +80,8 @@ type ASN struct {
|
||||
AutonomousSystemOrganization string `maxminddb:"autonomous_system_organization"`
|
||||
}
|
||||
|
||||
// ServerConfig is a configuration struct holding basic server configuration.
|
||||
// This is used for initial loading of server information before parsing into Server.
|
||||
type ServerConfig struct {
|
||||
Server string `mapstructure:"server" yaml:"server"`
|
||||
Latitude float64 `mapstructure:"latitude" yaml:"latitude"`
|
||||
@@ -92,13 +98,15 @@ func New(config *Config) *Redirector {
|
||||
}
|
||||
|
||||
r.checks = []ServerCheck{
|
||||
r.checkHttp("http"),
|
||||
r.checkHTTP("http"),
|
||||
r.checkTLS,
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// Start registers the routes, loggers, and server checks,
|
||||
// then returns the http.Handler.
|
||||
func (r *Redirector) Start() http.Handler {
|
||||
if err := r.ReloadConfig(); err != nil {
|
||||
log.WithError(err).Fatalln("Unable to load configuration")
|
||||
|
||||
@@ -27,6 +27,7 @@ type Server struct {
|
||||
LastChange time.Time `json:"lastChange"`
|
||||
}
|
||||
|
||||
// ServerCheck is a check function which can return information about a status.
|
||||
type ServerCheck func(server *Server, logFields log.Fields) (bool, error)
|
||||
|
||||
// checkStatus runs all status checks against a server
|
||||
@@ -70,8 +71,12 @@ func (server *Server) checkStatus(checks []ServerCheck) {
|
||||
}
|
||||
}
|
||||
|
||||
// ServerList is a wrapper for a Server slice.
|
||||
// It implements features like server checks.
|
||||
type ServerList []*Server
|
||||
|
||||
// checkLoop is a loop function which checks server statuses
|
||||
// every 60 seconds.
|
||||
func (s ServerList) checkLoop(checks []ServerCheck) {
|
||||
t := time.NewTicker(60 * time.Second)
|
||||
|
||||
|
||||
1
util.go
1
util.go
@@ -4,6 +4,7 @@ import "math/rand"
|
||||
|
||||
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
|
||||
// RandomSequence is an insecure, but "good enough" random generator.
|
||||
func RandomSequence(n int) string {
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
|
||||
@@ -11,6 +11,7 @@ const (
|
||||
defaultDownloadURL = "https://github.com/mozilla/gecko-dev/blob/master/security/nss/lib/ckfw/builtins/certdata.txt?raw=true"
|
||||
)
|
||||
|
||||
// LoadCACerts loads the certdata from Mozilla and parses it into a CertPool.
|
||||
func LoadCACerts() (*x509.CertPool, error) {
|
||||
res, err := http.Get(defaultDownloadURL)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user