diff --git a/cmd/robots2policy/robots2policy_test.go b/cmd/robots2policy/robots2policy_test.go index e9d90e62..523d69a7 100644 --- a/cmd/robots2policy/robots2policy_test.go +++ b/cmd/robots2policy/robots2policy_test.go @@ -22,9 +22,9 @@ type TestCase struct { type TestOptions struct { format string action string - crawlDelayWeight int policyName string deniedAction string + crawlDelayWeight int } func TestDataFileConversion(t *testing.T) { diff --git a/decaymap/decaymap.go b/decaymap/decaymap.go index dd3ea41f..37997e1a 100644 --- a/decaymap/decaymap.go +++ b/decaymap/decaymap.go @@ -13,13 +13,13 @@ func Zilch[T any]() T { // Impl is a lazy key->value map. It's a wrapper around a map and a mutex. If values exceed their time-to-live, they are pruned at Get time. type Impl[K comparable, V any] struct { data map[K]decayMapEntry[V] - lock sync.RWMutex // deleteCh receives decay-deletion requests from readers. deleteCh chan deleteReq[K] // stopCh stops the background cleanup worker. stopCh chan struct{} wg sync.WaitGroup + lock sync.RWMutex } type decayMapEntry[V any] struct { diff --git a/internal/ogtags/ogtags.go b/internal/ogtags/ogtags.go index 1d6cafc2..872931bf 100644 --- a/internal/ogtags/ogtags.go +++ b/internal/ogtags/ogtags.go @@ -23,21 +23,21 @@ const ( ) type OGTagCache struct { - cache store.JSON[map[string]string] - targetURL *url.URL - client *http.Client - transport *http.Transport + ogOverride map[string]string + targetURL *url.URL + client *http.Client + transport *http.Transport + cache store.JSON[map[string]string] // Pre-built strings for optimization unixPrefix string // "http://unix" - approvedTags []string - approvedPrefixes []string - ogTimeToLive time.Duration - ogCacheConsiderHost bool - ogPassthrough bool - ogOverride map[string]string - targetHost string targetSNI string + targetHost string + approvedPrefixes []string + approvedTags []string + ogTimeToLive time.Duration + ogPassthrough bool + ogCacheConsiderHost bool targetSNIAuto bool insecureSkipVerify bool } diff --git a/lib/anubis.go b/lib/anubis.go index 33a6b530..68dd9bc5 100644 --- a/lib/anubis.go +++ b/lib/anubis.go @@ -68,14 +68,14 @@ var ( type Server struct { next http.Handler + store store.Interface mux *http.ServeMux policy *policy.ParsedConfig OGTags *ogtags.OGTagCache + logger *slog.Logger + opts Options ed25519Priv ed25519.PrivateKey hs512Secret []byte - opts Options - store store.Interface - logger *slog.Logger } func (s *Server) getTokenKeyfunc() jwt.Keyfunc { diff --git a/lib/anubis_test.go b/lib/anubis_test.go index 320589de..6df8fc4b 100644 --- a/lib/anubis_test.go +++ b/lib/anubis_test.go @@ -154,8 +154,8 @@ func handleChallengeZeroDifficulty(t *testing.T, ts *httptest.Server, cli *http. type loggingCookieJar struct { t *testing.T - lock sync.Mutex cookies map[string][]*http.Cookie + lock sync.Mutex } func (lcj *loggingCookieJar) Cookies(u *url.URL) []*http.Cookie { @@ -747,9 +747,9 @@ func TestStripBasePrefixFromRequest(t *testing.T) { testCases := []struct { name string basePrefix string - stripBasePrefix bool requestPath string expectedPath string + stripBasePrefix bool }{ { name: "strip disabled - no change", diff --git a/lib/challenge/challenge.go b/lib/challenge/challenge.go index ef9a86f0..d0cfbf77 100644 --- a/lib/challenge/challenge.go +++ b/lib/challenge/challenge.go @@ -4,12 +4,12 @@ import "time" // Challenge is the metadata about a single challenge issuance. type Challenge struct { - ID string `json:"id"` // UUID identifying the challenge - Method string `json:"method"` // Challenge method - RandomData string `json:"randomData"` // The random data the client processes - IssuedAt time.Time `json:"issuedAt"` // When the challenge was issued - Metadata map[string]string `json:"metadata"` // Challenge metadata such as IP address and user agent - Spent bool `json:"spent"` // Has the challenge already been solved? - Difficulty int `json:"difficulty,omitempty"` // Difficulty that was in effect when issued - PolicyRuleHash string `json:"policyRuleHash,omitempty"` // Hash of the policy rule that issued this challenge + IssuedAt time.Time `json:"issuedAt"` + Metadata map[string]string `json:"metadata"` + ID string `json:"id"` + Method string `json:"method"` + RandomData string `json:"randomData"` + PolicyRuleHash string `json:"policyRuleHash,omitempty"` + Difficulty int `json:"difficulty,omitempty"` + Spent bool `json:"spent"` } diff --git a/lib/http_test.go b/lib/http_test.go index 4bd353e7..255344f3 100644 --- a/lib/http_test.go +++ b/lib/http_test.go @@ -13,9 +13,9 @@ import ( func TestSetCookie(t *testing.T) { for _, tt := range []struct { name string - options Options host string cookieName string + options Options }{ { name: "basic", diff --git a/lib/policy/config/asn_test.go b/lib/policy/config/asn_test.go index 4967d2c0..9653a465 100644 --- a/lib/policy/config/asn_test.go +++ b/lib/policy/config/asn_test.go @@ -8,9 +8,9 @@ import ( func TestASNsValid(t *testing.T) { for _, tt := range []struct { - name string - input *ASNs err error + input *ASNs + name string }{ { name: "basic valid", diff --git a/lib/policy/config/config.go b/lib/policy/config/config.go index 6b5946ae..577470a2 100644 --- a/lib/policy/config/config.go +++ b/lib/policy/config/config.go @@ -62,13 +62,14 @@ type BotConfig struct { Expression *ExpressionOrList `json:"expression,omitempty" yaml:"expression,omitempty"` Challenge *ChallengeRules `json:"challenge,omitempty" yaml:"challenge,omitempty"` Weight *Weight `json:"weight,omitempty" yaml:"weight,omitempty"` - Name string `json:"name" yaml:"name"` - Action Rule `json:"action" yaml:"action"` - RemoteAddr []string `json:"remote_addresses,omitempty" yaml:"remote_addresses,omitempty"` // Thoth features GeoIP *GeoIP `json:"geoip,omitempty"` ASNs *ASNs `json:"asns,omitempty"` + + Name string `json:"name" yaml:"name"` + Action Rule `json:"action" yaml:"action"` + RemoteAddr []string `json:"remote_addresses,omitempty" yaml:"remote_addresses,omitempty"` } func (b BotConfig) Zero() bool { @@ -324,13 +325,13 @@ func (sc StatusCodes) Valid() error { } type fileConfig struct { - Bots []BotOrImport `json:"bots"` - DNSBL bool `json:"dnsbl"` OpenGraph openGraphFileConfig `json:"openGraph,omitempty"` Impressum *Impressum `json:"impressum,omitempty"` - StatusCodes StatusCodes `json:"status_codes"` Store *Store `json:"store"` + Bots []BotOrImport `json:"bots"` Thresholds []Threshold `json:"thresholds"` + StatusCodes StatusCodes `json:"status_codes"` + DNSBL bool `json:"dnsbl"` } func (c *fileConfig) Valid() error { @@ -462,13 +463,13 @@ func Load(fin io.Reader, fname string) (*Config, error) { } type Config struct { + Impressum *Impressum + Store *Store + OpenGraph OpenGraph Bots []BotConfig Thresholds []Threshold - DNSBL bool - Impressum *Impressum - OpenGraph OpenGraph StatusCodes StatusCodes - Store *Store + DNSBL bool } func (c Config) Valid() error { diff --git a/lib/policy/config/config_test.go b/lib/policy/config/config_test.go index 3a96c9c9..c35ceefb 100644 --- a/lib/policy/config/config_test.go +++ b/lib/policy/config/config_test.go @@ -15,9 +15,9 @@ func p[V any](v V) *V { return &v } func TestBotValid(t *testing.T) { var tests = []struct { + bot BotConfig err error name string - bot BotConfig }{ { name: "simple user agent", diff --git a/lib/policy/config/expressionorlist_test.go b/lib/policy/config/expressionorlist_test.go index a09baf3e..91d46709 100644 --- a/lib/policy/config/expressionorlist_test.go +++ b/lib/policy/config/expressionorlist_test.go @@ -11,10 +11,10 @@ import ( func TestExpressionOrListMarshalJSON(t *testing.T) { for _, tt := range []struct { - name string - input *ExpressionOrList - output []byte err error + input *ExpressionOrList + name string + output []byte }{ { name: "single expression", @@ -74,10 +74,10 @@ func TestExpressionOrListMarshalJSON(t *testing.T) { func TestExpressionOrListMarshalYAML(t *testing.T) { for _, tt := range []struct { - name string - input *ExpressionOrList - output []byte err error + input *ExpressionOrList + name string + output []byte }{ { name: "single expression", @@ -217,8 +217,8 @@ func TestExpressionOrListUnmarshalJSON(t *testing.T) { func TestExpressionOrListString(t *testing.T) { for _, tt := range []struct { name string - in ExpressionOrList out string + in ExpressionOrList }{ { name: "single expression", diff --git a/lib/policy/config/geoip_test.go b/lib/policy/config/geoip_test.go index c20310fa..739ada55 100644 --- a/lib/policy/config/geoip_test.go +++ b/lib/policy/config/geoip_test.go @@ -7,9 +7,9 @@ import ( func TestGeoIPValid(t *testing.T) { for _, tt := range []struct { - name string - input *GeoIP err error + input *GeoIP + name string }{ { name: "basic valid", diff --git a/lib/policy/config/impressum_test.go b/lib/policy/config/impressum_test.go index 91424b52..1844ce53 100644 --- a/lib/policy/config/impressum_test.go +++ b/lib/policy/config/impressum_test.go @@ -8,9 +8,9 @@ import ( func TestImpressumValid(t *testing.T) { for _, cs := range []struct { - name string - inp Impressum err error + inp Impressum + name string }{ { name: "basic happy path", diff --git a/lib/policy/config/opengraph.go b/lib/policy/config/opengraph.go index 544647ec..087d046c 100644 --- a/lib/policy/config/opengraph.go +++ b/lib/policy/config/opengraph.go @@ -13,17 +13,17 @@ var ( ) type openGraphFileConfig struct { + Override map[string]string `json:"override,omitempty" yaml:"override,omitempty"` + TimeToLive string `json:"ttl" yaml:"ttl"` Enabled bool `json:"enabled" yaml:"enabled"` ConsiderHost bool `json:"considerHost" yaml:"enabled"` - TimeToLive string `json:"ttl" yaml:"ttl"` - Override map[string]string `json:"override,omitempty" yaml:"override,omitempty"` } type OpenGraph struct { - Enabled bool `json:"enabled" yaml:"enabled"` - ConsiderHost bool `json:"considerHost" yaml:"enabled"` Override map[string]string `json:"override,omitempty" yaml:"override,omitempty"` TimeToLive time.Duration `json:"ttl" yaml:"ttl"` + Enabled bool `json:"enabled" yaml:"enabled"` + ConsiderHost bool `json:"considerHost" yaml:"enabled"` } func (og *openGraphFileConfig) Valid() error { diff --git a/lib/policy/config/opengraph_test.go b/lib/policy/config/opengraph_test.go index 639549ad..27250ff6 100644 --- a/lib/policy/config/opengraph_test.go +++ b/lib/policy/config/opengraph_test.go @@ -7,9 +7,9 @@ import ( func TestOpenGraphFileConfigValid(t *testing.T) { for _, tt := range []struct { - name string - input *openGraphFileConfig err error + input *openGraphFileConfig + name string }{ { name: "basic happy path", diff --git a/lib/policy/config/store_test.go b/lib/policy/config/store_test.go index 1c1556e7..227b06bf 100644 --- a/lib/policy/config/store_test.go +++ b/lib/policy/config/store_test.go @@ -12,9 +12,9 @@ import ( func TestStoreValid(t *testing.T) { for _, tt := range []struct { + err error name string input config.Store - err error }{ { name: "no backend", diff --git a/lib/policy/config/threshold.go b/lib/policy/config/threshold.go index d9a0ed05..dd828925 100644 --- a/lib/policy/config/threshold.go +++ b/lib/policy/config/threshold.go @@ -31,10 +31,10 @@ var ( ) type Threshold struct { - Name string `json:"name" yaml:"name"` Expression *ExpressionOrList `json:"expression" yaml:"expression"` - Action Rule `json:"action" yaml:"action"` Challenge *ChallengeRules `json:"challenge" yaml:"challenge"` + Name string `json:"name" yaml:"name"` + Action Rule `json:"action" yaml:"action"` } func (t Threshold) Valid() error { diff --git a/lib/policy/config/threshold_test.go b/lib/policy/config/threshold_test.go index 1c668b2b..fce15d05 100644 --- a/lib/policy/config/threshold_test.go +++ b/lib/policy/config/threshold_test.go @@ -10,9 +10,9 @@ import ( func TestThresholdValid(t *testing.T) { for _, tt := range []struct { - name string - input *Threshold err error + input *Threshold + name string }{ { name: "basic allow", diff --git a/lib/policy/expressions/environment_test.go b/lib/policy/expressions/environment_test.go index 4e7d7960..75b05323 100644 --- a/lib/policy/expressions/environment_test.go +++ b/lib/policy/expressions/environment_test.go @@ -14,11 +14,11 @@ func TestBotEnvironment(t *testing.T) { t.Run("missingHeader", func(t *testing.T) { tests := []struct { + headers map[string]string name string expression string - headers map[string]string - expected types.Bool description string + expected types.Bool }{ { name: "missing-header", @@ -167,10 +167,10 @@ func TestBotEnvironment(t *testing.T) { t.Run("invalid", func(t *testing.T) { for _, tt := range []struct { + env any name string description string expression string - env any wantFailCompile bool wantFailEval bool }{ @@ -244,11 +244,11 @@ func TestThresholdEnvironment(t *testing.T) { } tests := []struct { + variables map[string]interface{} name string expression string - variables map[string]interface{} - expected types.Bool description string + expected types.Bool shouldCompile bool }{ { diff --git a/lib/policy/expressions/loadavg.go b/lib/policy/expressions/loadavg.go index 72b08788..cfbb2ae3 100644 --- a/lib/policy/expressions/loadavg.go +++ b/lib/policy/expressions/loadavg.go @@ -10,8 +10,8 @@ import ( ) type loadAvg struct { - lock sync.RWMutex data *load.AvgStat + lock sync.RWMutex } func (l *loadAvg) updateThread(ctx context.Context) { diff --git a/lib/policy/policy.go b/lib/policy/policy.go index 5493d8dd..27bd6661 100644 --- a/lib/policy/policy.go +++ b/lib/policy/policy.go @@ -29,16 +29,15 @@ var ( ) type ParsedConfig struct { - orig *config.Config - - Bots []Bot - Thresholds []*Threshold - DNSBL bool + Store store.Interface + orig *config.Config Impressum *config.Impressum OpenGraph config.OpenGraph - DefaultDifficulty int + Bots []Bot + Thresholds []*Threshold StatusCodes config.StatusCodes - Store store.Interface + DefaultDifficulty int + DNSBL bool } func newParsedConfig(orig *config.Config) *ParsedConfig { diff --git a/lib/redirect_security_test.go b/lib/redirect_security_test.go index e16206a3..2bc16907 100644 --- a/lib/redirect_security_test.go +++ b/lib/redirect_security_test.go @@ -13,7 +13,7 @@ import ( func TestRedirectSecurity(t *testing.T) { tests := []struct { - name string + reqHost string testType string // "constructRedirectURL", "serveHTTPNext", "renderIndex" // For constructRedirectURL tests @@ -23,17 +23,16 @@ func TestRedirectSecurity(t *testing.T) { // For serveHTTPNext tests redirParam string - reqHost string + name string + + errorContains string + expectedStatus int // For renderIndex tests returnHTTPStatusOnly bool - - // Expected results - expectedStatus int - shouldError bool - shouldNotRedirect bool - shouldBlock bool - errorContains string + shouldError bool + shouldNotRedirect bool + shouldBlock bool }{ // constructRedirectURL tests - X-Forwarded-Proto validation { diff --git a/lib/store/bbolt/factory_test.go b/lib/store/bbolt/factory_test.go index babc9f2b..ac90e5a6 100644 --- a/lib/store/bbolt/factory_test.go +++ b/lib/store/bbolt/factory_test.go @@ -17,9 +17,9 @@ func TestFactoryValid(t *testing.T) { t.Run("invalid config", func(t *testing.T) { for _, tt := range []struct { + err error name string cfg Config - err error }{ { name: "missing path", diff --git a/lib/store/s3api/factory.go b/lib/store/s3api/factory.go index 34ac10bb..cfed5350 100644 --- a/lib/store/s3api/factory.go +++ b/lib/store/s3api/factory.go @@ -88,8 +88,8 @@ func (Factory) Valid(data json.RawMessage) error { } type Config struct { - PathStyle bool `json:"pathStyle"` BucketName string `json:"bucketName"` + PathStyle bool `json:"pathStyle"` } func (c Config) Valid() error { diff --git a/lib/store/s3api/s3api_test.go b/lib/store/s3api/s3api_test.go index 80309dc4..5b7a9c6b 100644 --- a/lib/store/s3api/s3api_test.go +++ b/lib/store/s3api/s3api_test.go @@ -17,10 +17,10 @@ import ( // mockS3 is an in-memory mock of the methods we use. type mockS3 struct { - mu sync.RWMutex - bucket string data map[string][]byte meta map[string]map[string]string + bucket string + mu sync.RWMutex } func (m *mockS3) PutObject(ctx context.Context, in *s3.PutObjectInput, _ ...func(*s3.Options)) (*s3.PutObjectOutput, error) { diff --git a/lib/store/storetest/storetest.go b/lib/store/storetest/storetest.go index f04ce8a9..db7da90b 100644 --- a/lib/store/storetest/storetest.go +++ b/lib/store/storetest/storetest.go @@ -21,9 +21,9 @@ func Common(t *testing.T, f store.Factory, config json.RawMessage) { } for _, tt := range []struct { - name string - doer func(t *testing.T, s store.Interface) error err error + doer func(t *testing.T, s store.Interface) error + name string }{ { name: "basic get set delete",