mirror of
https://blitiri.com.ar/repos/chasquid
synced 2026-10-28 15:02:28 +00:00
Apply more mechanical simplifications using recent Go features
This is a follow-up on the `go fix` run in commit
0210c5fd92.
That commit recorded the automated updates.
This one applies further simplifications that are mechanical and do not
involve logic changes, but are outside of what `go fix` did.
It also removes some now-obsolete comments and statements.
This commit is contained in:
+10
-13
@@ -58,8 +58,10 @@ package aliases
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"maps"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -376,7 +378,7 @@ func (v *Resolver) AddAliasesFile(domain, path string) (int, error) {
|
||||
v.mu.Unlock()
|
||||
|
||||
aliases, err := v.parseFile(domain, path)
|
||||
if os.IsNotExist(err) {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return 0, nil
|
||||
}
|
||||
if err != nil {
|
||||
@@ -404,7 +406,7 @@ func (v *Resolver) Reload() error {
|
||||
for domain, paths := range v.files {
|
||||
for _, path := range paths {
|
||||
aliases, err := v.parseFile(domain, path)
|
||||
if os.IsNotExist(err) {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
@@ -447,12 +449,12 @@ func (v *Resolver) parseReader(domain string, r io.Reader) (map[string][]Recipie
|
||||
continue
|
||||
}
|
||||
|
||||
sp := strings.SplitN(line, ":", 2)
|
||||
if len(sp) != 2 {
|
||||
addr, rawalias, ok := strings.Cut(line, ":")
|
||||
if !ok {
|
||||
return nil, newParseError(i, "missing ':' in line")
|
||||
}
|
||||
|
||||
addr, rawalias := strings.TrimSpace(sp[0]), strings.TrimSpace(sp[1])
|
||||
addr, rawalias = strings.TrimSpace(addr), strings.TrimSpace(rawalias)
|
||||
if len(addr) == 0 || len(rawalias) == 0 {
|
||||
return nil, newParseError(i, "missing address or alias")
|
||||
}
|
||||
@@ -574,12 +576,7 @@ func removeAllAfter(s, seps string) string {
|
||||
continue
|
||||
}
|
||||
|
||||
i := strings.Index(s, c)
|
||||
if i == -1 {
|
||||
continue
|
||||
}
|
||||
|
||||
s = s[:i]
|
||||
s, _, _ = strings.Cut(s, c)
|
||||
}
|
||||
|
||||
return s
|
||||
@@ -588,7 +585,7 @@ func removeAllAfter(s, seps string) string {
|
||||
// removeChars removes the runes in "chars" from s.
|
||||
func removeChars(s, chars string) string {
|
||||
for c := range strings.SplitSeq(chars, "") {
|
||||
s = strings.Replace(s, c, "", -1)
|
||||
s = strings.ReplaceAll(s, c, "")
|
||||
}
|
||||
|
||||
return s
|
||||
@@ -600,7 +597,7 @@ func (v *Resolver) runResolveHook(tr *trace.Trace, addr string) ([]Recipient, er
|
||||
return nil, nil
|
||||
}
|
||||
// TODO: check if the file is executable.
|
||||
if _, err := os.Stat(v.ResolveHook); os.IsNotExist(err) {
|
||||
if _, err := os.Stat(v.ResolveHook); errors.Is(err, fs.ErrNotExist) {
|
||||
hookResults.Add("resolve:skip", 1)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -214,10 +214,8 @@ func DecodeResponse(response string) (user, domain, passwd string, err error) {
|
||||
|
||||
// Split identity into "user@domain", if possible.
|
||||
user = identity
|
||||
idsp := strings.SplitN(identity, "@", 2)
|
||||
if len(idsp) >= 2 {
|
||||
user = idsp[0]
|
||||
domain = idsp[1]
|
||||
if u, d, ok := strings.Cut(identity, "@"); ok {
|
||||
user, domain = u, d
|
||||
}
|
||||
|
||||
// Normalize the user and domain. This is so users can write the username
|
||||
|
||||
@@ -2,6 +2,8 @@ package courier
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -67,7 +69,7 @@ func TestExitCode(t *testing.T) {
|
||||
// TODO: This can happen when building under unusual circumstances, such
|
||||
// as Debian package building. Are they reasonable enough for us to keep
|
||||
// this?
|
||||
if _, err := os.Stat("../../test/util/exitcode"); os.IsNotExist(err) {
|
||||
if _, err := os.Stat("../../test/util/exitcode"); errors.Is(err, fs.ErrNotExist) {
|
||||
t.Skipf("util/exitcode not found, running from outside repo?")
|
||||
}
|
||||
|
||||
|
||||
@@ -11,12 +11,8 @@ import (
|
||||
|
||||
// Split an user@domain address into user and domain.
|
||||
func Split(addr string) (string, string) {
|
||||
ps := strings.SplitN(addr, "@", 2)
|
||||
if len(ps) != 2 {
|
||||
return addr, ""
|
||||
}
|
||||
|
||||
return ps[0], ps[1]
|
||||
user, domain, _ := strings.Cut(addr, "@")
|
||||
return user, domain
|
||||
}
|
||||
|
||||
// UserOf user@domain returns user.
|
||||
@@ -48,7 +44,7 @@ func AddHeader(data []byte, k, v string) []byte {
|
||||
if v[len(v)-1] == '\n' {
|
||||
v = v[:len(v)-1]
|
||||
}
|
||||
v = strings.Replace(v, "\n", "\n\t", -1)
|
||||
v = strings.ReplaceAll(v, "\n", "\n\t")
|
||||
}
|
||||
|
||||
header := []byte(fmt.Sprintf("%s: %s\n", k, v))
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -90,8 +90,8 @@ func MetricsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
|
||||
// Sort the variables for reproducibility and readability.
|
||||
sort.Slice(vars, func(i, j int) bool {
|
||||
return vars[i].Name < vars[j].Name
|
||||
slices.SortFunc(vars, func(a, b exportedVar) int {
|
||||
return strings.Compare(a.Name, b.Name)
|
||||
})
|
||||
|
||||
for _, v := range vars {
|
||||
|
||||
@@ -128,11 +128,8 @@ func readRequest(r *textproto.Reader) (string, string, error) {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
sp := strings.SplitN(line, " ", 2)
|
||||
if len(sp) == 1 {
|
||||
return sp[0], "", nil
|
||||
}
|
||||
return sp[0], sp[1], nil
|
||||
name, params, _ := strings.Cut(line, " ")
|
||||
return name, params, nil
|
||||
}
|
||||
|
||||
func writeError(tr *trace.Trace, tconn *textproto.Conn, err error) {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"html/template"
|
||||
"math"
|
||||
"net/http"
|
||||
"sort"
|
||||
"slices"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
@@ -156,8 +156,8 @@ func allEvents(tr *trace) []traceAndEvent {
|
||||
evts := appendAllEvents(tr, []traceAndEvent{}, seen, 0)
|
||||
|
||||
// Sort them by time.
|
||||
sort.Slice(evts, func(i, j int) bool {
|
||||
return evts[i].Event.When.Before(evts[j].Event.When)
|
||||
slices.SortFunc(evts, func(a, b traceAndEvent) int {
|
||||
return a.Event.When.Compare(b.Event.When)
|
||||
})
|
||||
|
||||
return evts
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"math/rand/v2"
|
||||
"sort"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -29,11 +29,8 @@ func newID(family string, ts int64) id {
|
||||
}
|
||||
|
||||
func (id id) Family() string {
|
||||
sp := strings.SplitN(string(id), "!", 2)
|
||||
if len(sp) != 2 {
|
||||
return string(id)
|
||||
}
|
||||
return sp[0]
|
||||
family, _, _ := strings.Cut(string(id), "!")
|
||||
return family
|
||||
}
|
||||
|
||||
// Trace represents a single request trace.
|
||||
@@ -433,8 +430,8 @@ func (ft *familyTraces) TracesFor(b int, allgt bool) []*trace {
|
||||
|
||||
// Sort them by start, newer first. This is the order that will be used
|
||||
// when displaying them.
|
||||
sort.Slice(trs, func(i, j int) bool {
|
||||
return trs[i].Start.After(trs[j].Start)
|
||||
slices.SortFunc(trs, func(a, b *trace) int {
|
||||
return b.Start.Compare(a.Start)
|
||||
})
|
||||
return trs
|
||||
}
|
||||
@@ -510,13 +507,9 @@ var (
|
||||
)
|
||||
|
||||
func copyFamilies() map[string]*familyTraces {
|
||||
n := map[string]*familyTraces{}
|
||||
|
||||
familiesMu.Lock()
|
||||
maps.Copy(n, families)
|
||||
familiesMu.Unlock()
|
||||
|
||||
return n
|
||||
defer familiesMu.Unlock()
|
||||
return maps.Clone(families)
|
||||
}
|
||||
|
||||
func findInFamilies(traceID id, refID id) *trace {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
package protoio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -87,7 +89,7 @@ func (s *Store) Put(id string, m proto.Message) error {
|
||||
// Get a message from the store.
|
||||
func (s *Store) Get(id string, m proto.Message) (bool, error) {
|
||||
err := ReadTextMessage(s.idToFname(id), m)
|
||||
if os.IsNotExist(err) {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return false, nil
|
||||
}
|
||||
return err == nil, err
|
||||
|
||||
@@ -88,7 +88,7 @@ type dsnInfo struct {
|
||||
// indent s with the given number of spaces.
|
||||
func indent(sp int, s string) string {
|
||||
pad := strings.Repeat(" ", sp)
|
||||
return strings.Replace(s, "\n", "\n"+pad, -1)
|
||||
return strings.ReplaceAll(s, "\n", "\n"+pad)
|
||||
}
|
||||
|
||||
var dsnTemplate = template.Must(
|
||||
|
||||
@@ -2,7 +2,7 @@ package queue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@@ -182,7 +182,7 @@ func printDiff(print func(s string), expected, got string) {
|
||||
|
||||
// sort the lines, to make it easier to see the differences (this works
|
||||
// ok when there's few, horrible when there's lots).
|
||||
sort.Strings(lines)
|
||||
slices.Sort(lines)
|
||||
|
||||
// print diff of expected vs. got
|
||||
seen := map[string]bool{}
|
||||
|
||||
+12
-14
@@ -252,19 +252,19 @@ func (q *Queue) DumpString() string {
|
||||
defer q.mu.RUnlock()
|
||||
var s strings.Builder
|
||||
s.WriteString("# Queue status\n\n")
|
||||
s.WriteString(fmt.Sprintf("date: %v\n", time.Now()))
|
||||
s.WriteString(fmt.Sprintf("length: %d\n\n", len(q.q)))
|
||||
fmt.Fprintf(&s, "date: %v\n", time.Now())
|
||||
fmt.Fprintf(&s, "length: %d\n\n", len(q.q))
|
||||
|
||||
for id, item := range q.q {
|
||||
s.WriteString(fmt.Sprintf("## Item %s\n", id))
|
||||
fmt.Fprintf(&s, "## Item %s\n", id)
|
||||
item.Lock()
|
||||
s.WriteString(fmt.Sprintf("created at: %s\n", item.CreatedAt))
|
||||
s.WriteString(fmt.Sprintf("from: %s\n", item.From))
|
||||
s.WriteString(fmt.Sprintf("to: %s\n", item.To))
|
||||
fmt.Fprintf(&s, "created at: %s\n", item.CreatedAt)
|
||||
fmt.Fprintf(&s, "from: %s\n", item.From)
|
||||
fmt.Fprintf(&s, "to: %s\n", item.To)
|
||||
for _, rcpt := range item.Rcpt {
|
||||
s.WriteString(fmt.Sprintf("%s %s (%s)\n", rcpt.Status, rcpt.Address, rcpt.Type))
|
||||
s.WriteString(fmt.Sprintf(" original address: %s\n", rcpt.OriginalAddress))
|
||||
s.WriteString(fmt.Sprintf(" last failure: %q\n", rcpt.LastFailureMessage))
|
||||
fmt.Fprintf(&s, "%s %s (%s)\n", rcpt.Status, rcpt.Address, rcpt.Type)
|
||||
fmt.Fprintf(&s, " original address: %s\n", rcpt.OriginalAddress)
|
||||
fmt.Fprintf(&s, " last failure: %q\n", rcpt.LastFailureMessage)
|
||||
}
|
||||
item.Unlock()
|
||||
s.WriteString("\n")
|
||||
@@ -329,8 +329,7 @@ func (item *Item) SendLoop(q *Queue) {
|
||||
continue
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go item.sendOneRcpt(&wg, tr, q, rcpt)
|
||||
wg.Go(func() { item.sendOneRcpt(tr, q, rcpt) })
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
@@ -359,8 +358,7 @@ func (item *Item) SendLoop(q *Queue) {
|
||||
}
|
||||
|
||||
// sendOneRcpt, and update it with the results.
|
||||
func (item *Item) sendOneRcpt(wg *sync.WaitGroup, tr *trace.Trace, q *Queue, rcpt *Recipient) {
|
||||
defer wg.Done()
|
||||
func (item *Item) sendOneRcpt(tr *trace.Trace, q *Queue, rcpt *Recipient) {
|
||||
to := rcpt.Address
|
||||
tr.Debugf("%s sending", to)
|
||||
|
||||
@@ -452,7 +450,7 @@ func rewriteSender(from, originalAddr string) string {
|
||||
// we can't know if the other side will support SMTPUTF8.
|
||||
return fmt.Sprintf("%s+fwd_from=%s@%s",
|
||||
envelope.UserOf(originalAddr),
|
||||
strings.Replace(from, "@", "=", -1),
|
||||
strings.ReplaceAll(from, "@", "="),
|
||||
mustIDNAToASCII(envelope.DomainOf(originalAddr)))
|
||||
}
|
||||
|
||||
|
||||
+15
-22
@@ -9,6 +9,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"math/rand/v2"
|
||||
"net"
|
||||
"net/mail"
|
||||
@@ -343,7 +344,7 @@ loop:
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
if errors.Is(err, io.EOF) {
|
||||
c.tr.Debugf("client closed the connection")
|
||||
} else {
|
||||
c.tr.Errorf("exiting with error: %v", err)
|
||||
@@ -363,7 +364,7 @@ func (c *Conn) HELO(params string) (code int, msg string) {
|
||||
"liquor emporium", "antique weapons outlet", "delicatessen",
|
||||
"jewelers", "quality apparel and accessories", "hardware",
|
||||
"rare books", "lighting store"}
|
||||
t := types[rand.Int()%len(types)]
|
||||
t := types[rand.IntN(len(types))]
|
||||
msg = fmt.Sprintf("Hello my friend, welcome to chasqui's %s!", t)
|
||||
|
||||
return 250, msg
|
||||
@@ -408,7 +409,7 @@ func (c *Conn) RSET(params string) (code int, msg string) {
|
||||
"Your mind releases itself from mundane concerns.",
|
||||
"As your mind turns inward on itself, you forget everything else.",
|
||||
}
|
||||
return 250, "2.0.0 " + msgs[rand.Int()%len(msgs)]
|
||||
return 250, "2.0.0 " + msgs[rand.IntN(len(msgs))]
|
||||
}
|
||||
|
||||
// VRFY SMTP command handler.
|
||||
@@ -455,7 +456,7 @@ func (c *Conn) MAIL(params string) (code int, msg string) {
|
||||
// It should be written "<>", we check for that and remove spaces just to
|
||||
// be more flexible.
|
||||
addr := ""
|
||||
if strings.Replace(rawAddr, " ", "", -1) == "<>" {
|
||||
if strings.ReplaceAll(rawAddr, " ", "") == "<>" {
|
||||
addr = "<>"
|
||||
} else {
|
||||
e, err := mail.ParseAddress(rawAddr)
|
||||
@@ -668,11 +669,11 @@ func (c *Conn) DATA(params string) (code int, msg string) {
|
||||
// Read the data. Enforce CRLF correctness, and maximum size.
|
||||
c.data, err = readUntilDot(c.reader, c.maxDataSize)
|
||||
if err != nil {
|
||||
if err == errMessageTooLarge {
|
||||
if errors.Is(err, errMessageTooLarge) {
|
||||
// Message is too big; excess data has already been discarded.
|
||||
return 552, "5.3.4 Message too big"
|
||||
}
|
||||
if err == errInvalidLineEnding {
|
||||
if errors.Is(err, errInvalidLineEnding) {
|
||||
// We can't properly recover from this, so we have to drop the
|
||||
// connection.
|
||||
c.writeResponse(521, "5.5.2 Error reading DATA: invalid line ending")
|
||||
@@ -734,7 +735,7 @@ func (c *Conn) DATA(params string) (code int, msg string) {
|
||||
"In return to thy service, I grant thee the gift of Immortality!",
|
||||
"You ascend to the status of Demigod(dess)...",
|
||||
}
|
||||
return 250, "2.0.0 " + msgs[rand.Int()%len(msgs)]
|
||||
return 250, "2.0.0 " + msgs[rand.IntN(len(msgs))]
|
||||
}
|
||||
|
||||
func (c *Conn) addReceivedHeader() {
|
||||
@@ -884,7 +885,7 @@ func sanitizeEHLODomain(s string) string {
|
||||
c >= '0' && c <= '9',
|
||||
c == '-', c == '.',
|
||||
c == '[', c == ']', c == ':':
|
||||
n.WriteString(string(c))
|
||||
n.WriteRune(c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -895,7 +896,7 @@ func sanitizeEHLODomain(s string) string {
|
||||
// indicating if it's permanent, and the error itself.
|
||||
func (c *Conn) runPostDataHook(data []byte) ([]byte, bool, error) {
|
||||
// TODO: check if the file is executable.
|
||||
if _, err := os.Stat(c.postDataHook); os.IsNotExist(err) {
|
||||
if _, err := os.Stat(c.postDataHook); errors.Is(err, fs.ErrNotExist) {
|
||||
hookResults.Add("post-data:skip", 1)
|
||||
return nil, false, nil
|
||||
}
|
||||
@@ -1152,8 +1153,8 @@ func (c *Conn) AUTH(params string) (code int, msg string) {
|
||||
// If the response is not there, we reply with 334, and expect the
|
||||
// response back from the client in the next message.
|
||||
|
||||
sp := strings.SplitN(params, " ", 2)
|
||||
if len(sp) < 1 || sp[0] != "PLAIN" {
|
||||
mech, response, hasResponse := strings.Cut(params, " ")
|
||||
if mech != "PLAIN" {
|
||||
// As we only offer plain, this should not really happen.
|
||||
return 534, "5.7.9 Asmodeus demands 534 zorkmids for safe passage"
|
||||
}
|
||||
@@ -1162,10 +1163,7 @@ func (c *Conn) AUTH(params string) (code int, msg string) {
|
||||
// find their way to the users in some circumstances.
|
||||
|
||||
// Get the response, either from the message or interactively.
|
||||
response := ""
|
||||
if len(sp) == 2 {
|
||||
response = sp[1]
|
||||
} else {
|
||||
if !hasResponse {
|
||||
// Reply 334 and expect the user to provide it.
|
||||
// In this case, the text IS relevant, as it is taken as the
|
||||
// server-side SASL challenge (empty for PLAIN).
|
||||
@@ -1232,13 +1230,8 @@ func (c *Conn) readCommand() (cmd, params string, err error) {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
sp := strings.SplitN(msg, " ", 2)
|
||||
cmd = strings.ToUpper(sp[0])
|
||||
if len(sp) > 1 {
|
||||
params = sp[1]
|
||||
}
|
||||
|
||||
return cmd, params, err
|
||||
cmd, params, _ = strings.Cut(msg, " ")
|
||||
return strings.ToUpper(cmd), params, err
|
||||
}
|
||||
|
||||
func (c *Conn) readLine() (line string, err error) {
|
||||
|
||||
@@ -38,7 +38,7 @@ func readUntilDot(r *bufio.Reader, max int64) ([]byte, error) {
|
||||
loop:
|
||||
for {
|
||||
b, err := r.ReadByte()
|
||||
if err == io.EOF {
|
||||
if errors.Is(err, io.EOF) {
|
||||
return buf, io.ErrUnexpectedEOF
|
||||
} else if err != nil {
|
||||
return buf, err
|
||||
|
||||
@@ -340,9 +340,7 @@ func (s *Server) ListenAndServe() {
|
||||
|
||||
// Never return. If the serve goroutines have problems, they will abort
|
||||
// execution.
|
||||
for {
|
||||
time.Sleep(24 * time.Hour)
|
||||
}
|
||||
select {}
|
||||
}
|
||||
|
||||
func (s *Server) serve(l net.Listener, mode SocketMode) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net"
|
||||
"net/smtp"
|
||||
"net/textproto"
|
||||
@@ -486,7 +487,7 @@ func TestStartTLSOnTLS(t *testing.T) {
|
||||
func TestAddDKIMSigner(t *testing.T) {
|
||||
s := NewServer()
|
||||
err := s.AddDKIMSigner("example.com", "selector", "keyfile-does-not-exist")
|
||||
if !os.IsNotExist(err) {
|
||||
if !errors.Is(err, fs.ErrNotExist) {
|
||||
t.Errorf("AddDKIMSigner: expected not exist, got %v", err)
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -86,13 +86,13 @@ func parsePolicy(raw []byte) (*Policy, error) {
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(raw))
|
||||
for scanner.Scan() {
|
||||
sp := strings.SplitN(scanner.Text(), ":", 2)
|
||||
if len(sp) != 2 {
|
||||
key, value, ok := strings.Cut(scanner.Text(), ":")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
key := strings.TrimSpace(sp[0])
|
||||
value := strings.TrimSpace(sp[1])
|
||||
key = strings.TrimSpace(key)
|
||||
value = strings.TrimSpace(value)
|
||||
|
||||
// Only care for the keys we recognize.
|
||||
switch key {
|
||||
@@ -293,9 +293,9 @@ func matchDomain(domain, pattern string) bool {
|
||||
// For wildcards, skip the first part of the domain and match the rest.
|
||||
// Note that if the pattern is malformed this might fail, but we are ok
|
||||
// with that.
|
||||
if strings.HasPrefix(pattern, "*.") {
|
||||
parts := strings.SplitN(domain, ".", 2)
|
||||
if len(parts) > 1 && parts[1] == pattern[2:] {
|
||||
if suffix, ok := strings.CutPrefix(pattern, "*."); ok {
|
||||
_, rest, found := strings.Cut(domain, ".")
|
||||
if found && rest == suffix {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package testlib
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -22,7 +24,7 @@ func TestBasic(t *testing.T) {
|
||||
}
|
||||
|
||||
RemoveIfOk(t, dir)
|
||||
if _, err := os.Stat(dir); !os.IsNotExist(err) {
|
||||
if _, err := os.Stat(dir); !errors.Is(err, fs.ErrNotExist) {
|
||||
t.Fatalf("%s existed, should have been deleted: %v", dir, err)
|
||||
}
|
||||
}
|
||||
@@ -45,7 +47,7 @@ func TestLeaveDirOnError(t *testing.T) {
|
||||
myt.Errorf("something bad happened")
|
||||
|
||||
RemoveIfOk(myt, dir)
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
if _, err := os.Stat(dir); errors.Is(err, fs.ErrNotExist) {
|
||||
t.Fatalf("%s was removed, should have been kept", dir)
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"io/fs"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/crypto/scrypt"
|
||||
@@ -73,7 +73,7 @@ func Load(fname string) (*DB, error) {
|
||||
db.db = &ProtoDB{Users: map[string]*Password{}}
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
// If the file does not exist now, it is not an error, as it might
|
||||
// exist later and we want to be able to read it.
|
||||
err = nil
|
||||
|
||||
Reference in New Issue
Block a user