- Collect: replace WalkDir with ReadDir to avoid subdirectory recursion
and the risk of duplicate filenames silently overwriting each other
- shmigrate: check scanner.Err() after reading migrations log
- shmigrate: shell-quote all paths in generated scripts to prevent
shell injection via migration filenames
- shmigrate: wrap errors with ErrQueryApplied sentinel for consistency
with DB backends
- mustInit: remove stale err check that could never fire
- mustInit: fix swapped error messages (read vs create)
Rename net/ipgate to net/ippolicy and compose independently refreshed
whitelist and blacklist sources into one IP decision policy.
- rename slog group and error prefixes from ipgate to ippolicy
- delete unused ParseDomainSet and RecordReader from domainsetcsv.go
- rewrite README to match the actual Config API
- document nil-whitelist behavior on New()
- bump iplist dependency to v0.8.5
- go mod tidy: remove stale ipgate and iplist entries
Add net/iplist for shared IP-policy source loading.
- Accept local TSV/CSV file paths or HTTP(S) URLs (including Google Sheets).
- Auto-detect TSV vs CSV format from file content.
- Send Accept: text/tab-separated-values header for content negotiation.
- Parse the first column and ignore comments (#) and optional "network" header.
- Expand nested list URLs up to MaxNestedSources (2) levels.
- Support Basic Auth from URL userinfo without sending credentials in the URL.
- Persist cached URL responses across restarts via httpcache.
- Refresh periodically and preserve the known-good cache on fetch or parse failure.
- Validate entries as IP address, CIDR range, or domain name (Validate()).
- Use golib/https.NewInternalClient() through httpcache.NewWith.
- Add README with usage examples and entry format documentation.
Add non-breaking context-aware and custom-HTTP-client variants of the
existing reader and fetch functions:
- NewReaderFromContext / NewReaderFromContextWith
- NewReaderFromURLContext / NewReaderFromURLWith
- NewReaderFromIDsContext
- GetSheetContext
All existing function signatures are unchanged. The shared response
handling is extracted into newReaderFromResponse, and the legacy GetSheet
path is refactored through getSheetWithGet for clarity.
Ensure cohort is never nil:
- NewDomainSet stores an empty Cohort before rebuildCohort, so a parse
failure leaves an empty (non-nil) cohort instead of nil
- Contains uses CompareAndSwap to lazily self-initialise a zero-value
struct, making nil impossible after first access — no explicit nil
check needed
Extract the cache-validity check into a testable cachedCohortValid()
helper and add filesPresent() to detect when data files exist on disk.
Use strings.Builder in commaify() for efficiency.
Tests:
- TestPrefixSetContainsZeroValue: zero-value self-heals via CAS,
cohort is non-nil after first Contains call
- TestCachedCohortValidRequiresFiles: cache invalidation logic
Add tests for AuthorizationSchemes ["*"] accepting any scheme and
for unaccepted schemes returning ErrNoCredentials without falling
through to cookies. These fill pre-existing test gaps unrelated to
the TokenCookies feature.