diff --git a/acme/acme.go b/acme/acme.go index b03d51e..4014024 100644 --- a/acme/acme.go +++ b/acme/acme.go @@ -71,8 +71,8 @@ func IssueCertificates(cacheDir, email, challengeType string, domains []string, cfg.Issuers = append(cfg.Issuers, myAcme) - for i := range domains { - err := cfg.ObtainCertAsync(context.Background(), domains[i]) + for _, domain := range domains { + err := cfg.ObtainCertAsync(context.Background(), domain) if err != nil { return nil, err } diff --git a/config/uploads.go b/config/uploads.go index 4ddca6d..8054814 100644 --- a/config/uploads.go +++ b/config/uploads.go @@ -30,12 +30,12 @@ func (cfg *Uploads) InitDefaults() error { cfg.Forbidden = make(map[string]struct{}) cfg.Allowed = make(map[string]struct{}) - for i := range cfg.Forbid { - cfg.Forbidden[cfg.Forbid[i]] = struct{}{} + for _, ext := range cfg.Forbid { + cfg.Forbidden[ext] = struct{}{} } - for i := range cfg.Allow { - cfg.Allowed[cfg.Allow[i]] = struct{}{} + for _, ext := range cfg.Allow { + cfg.Allowed[ext] = struct{}{} } for k := range cfg.Forbidden { diff --git a/go.work.sum b/go.work.sum index b3e8bcb..70f15a5 100644 --- a/go.work.sum +++ b/go.work.sum @@ -2087,6 +2087,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= @@ -2566,6 +2568,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -2682,6 +2685,8 @@ go.temporal.io/api v1.28.0/go.mod h1:sAtVCXkwNaCtHVMP6B/FlK8PcEnaDjJ+KHCwS/ufscI go.temporal.io/api v1.30.0 h1:6U/6lgpXf4UCywYxL3YfssqeI7IQnt9yNzwlfozUi2o= go.temporal.io/api v1.30.0/go.mod h1:PIZ+UyGTMh3HJFauMysfanNBAh3f0jRf1xydrhTEcSQ= go.temporal.io/api v1.57.0/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM= +go.temporal.io/api v1.62.2 h1:jFhIzlqNyJsJZTiCRQmTIMv6OTQ5BZ57z8gbgLGMaoo= +go.temporal.io/api v1.62.2/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM= go.temporal.io/sdk v1.26.0-rc.2 h1:0NX4wR2qwD6xCv+JNhZdViamsITMYWzZkUqBJEIVHBw= go.temporal.io/sdk v1.26.0-rc.2/go.mod h1:HDr8fIWJ/HF8dJwTPgOayI8PYB5WoVIxUMjzE78M2ng= go.temporal.io/sdk/contrib/opentelemetry v0.4.0 h1:Ddx+39cESh4CNFI6cy8TI1OBJC8MUQUDzt6TpIJJjPQ= @@ -2871,6 +2876,7 @@ golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= @@ -3231,6 +3237,7 @@ google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4/go. google.golang.org/genproto/googleapis/api v0.0.0-20251103181224-f26f9409b101/go.mod h1:E17fc4PDhkr22dE3RgnH2hEubUaky6ZwW4VhANxyspg= google.golang.org/genproto/googleapis/api v0.0.0-20251124214823-79d6a2a48846/go.mod h1:Fk4kyraUvqD7i5H6S43sj2W98fbZa75lpZz/eUyhfO0= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d h1:EocjzKLywydp5uZ5tJ79iP6Q0UjDnyiHkGRWxuPBP8s= google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:48U2I+QQUYhsFrg2SY6r+nJzeOtjey7j//WBESw+qyQ= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc h1:g3hIDl0jRNd9PPTs2uBzYuaD5mQuwOkZY0vSc0LR32o= google.golang.org/genproto/googleapis/bytestream v0.0.0-20240125205218-1f4bbc51befe h1:weYsP+dNijSQVoLAb5bpUos3ciBpNU/NEVlHFKrk8pg= @@ -3257,6 +3264,7 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d h1:t/LOSXPJ9R0B6fnZNyALBRfZBH0Uy0gT+uR+SJ6syqQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= @@ -3285,6 +3293,8 @@ google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/handler/handler_test.go b/handler/handler_test.go index 341221d..f7a6e40 100644 --- a/handler/handler_test.go +++ b/handler/handler_test.go @@ -59,7 +59,7 @@ func TestServeHTTP_InvalidMultipart_Returns400(t *testing.T) { h := newTestHandler(t, defaultCfg(), nil) // Boundary declared in header but body has no valid multipart parts → EOF. - req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader("")) + req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/", strings.NewReader("")) req.Header.Set("Content-Type", "multipart/form-data; boundary=1111") rr := httptest.NewRecorder() @@ -73,7 +73,7 @@ func TestServeHTTP_InvalidMultipart_Returns400(t *testing.T) { func TestServeHTTP_StreamBody_MaxBytesExceeded_Returns413(t *testing.T) { h := newTestHandler(t, defaultCfg(), nil) - req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader("this body is too long")) + req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/", strings.NewReader("this body is too long")) req.Header.Set("Content-Type", "application/json") rr := httptest.NewRecorder() @@ -92,7 +92,7 @@ func TestServeHTTP_TruncatedMultipart_Returns400(t *testing.T) { // Multipart body with an open part but no closing boundary → ErrUnexpectedEOF. body := "--1111\r\nContent-Disposition: form-data; name=\"f\"\r\n\r\nval" - req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(body)) + req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/", strings.NewReader(body)) req.Header.Set("Content-Type", "multipart/form-data; boundary=1111") rr := httptest.NewRecorder() @@ -150,7 +150,7 @@ func TestHandleError_DebugMode_WritesEscapedError(t *testing.T) { } func TestURI_PlainHTTP(t *testing.T) { - r := httptest.NewRequest(http.MethodGet, "/path?q=1", nil) + r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/path?q=1", nil) r.Host = "example.com" got := URI(r) @@ -161,7 +161,7 @@ func TestURI_PlainHTTP(t *testing.T) { } func TestURI_TLSRequest_HTTPSScheme(t *testing.T) { - r := httptest.NewRequest(http.MethodGet, "/path?q=1", nil) + r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/path?q=1", nil) r.Host = "example.com" r.TLS = &tls.ConnectionState{} @@ -173,7 +173,7 @@ func TestURI_TLSRequest_HTTPSScheme(t *testing.T) { } func TestURI_StripsCRLFInjection(t *testing.T) { - r := httptest.NewRequest(http.MethodGet, "/path", nil) + r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/path", nil) r.Host = "example.com" // Inject CRLF into the raw query — a classic HTTP response-splitting vector. r.URL.RawQuery = "param=value\r\nX-Injected: true" @@ -206,7 +206,7 @@ func TestServeHTTP_PoolExecError_Returns500(t *testing.T) { mp := &mockPool{execErr: fmt.Errorf("worker died")} h := newTestHandler(t, defaultCfg(), mp) - req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(`{"key":"val"}`)) + req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/", strings.NewReader(`{"key":"val"}`)) req.Header.Set("Content-Type", "application/json") rr := httptest.NewRecorder() @@ -217,11 +217,128 @@ func TestServeHTTP_PoolExecError_Returns500(t *testing.T) { } } +// ── Group B′: FetchIP edge cases ───────────────────────────────────────────── + +func TestFetchIP_EdgeCases(t *testing.T) { + tests := []struct { + name string + input string + want string + }{ + {"empty string", "", ""}, + {"ipv4 no port", "10.0.0.1", "10.0.0.1"}, + {"ipv6 bracketed with port", "[::1]:8080", "::1"}, + {"ipv6 full address bare", "2001:db8::1", "2001:db8::1"}, + {"garbage with colons", "not:a:valid:thing", ""}, + {"port only", ":8080", ""}, + {"ipv4 with empty port", "127.0.0.1:", "127.0.0.1"}, + {"ipv6 full with port", "[2001:db8::1]:443", "2001:db8::1"}, + } + + log := zap.NewNop() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := FetchIP(tt.input, log) + if got != tt.want { + t.Errorf("FetchIP(%q) = %q, want %q", tt.input, got, tt.want) + } + }) + } +} + +// ── Group B″: URI edge cases ───────────────────────────────────────────────── + +func TestURI_EdgeCases(t *testing.T) { + tests := []struct { + name string + setup func() *http.Request + want string + }{ + { + name: "empty host", + setup: func() *http.Request { + r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/", nil) + r.Host = "" + return r + }, + want: "http:///", + }, + { + name: "host with port", + setup: func() *http.Request { + r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/p", nil) + r.Host = "example.com:8080" + return r + }, + want: "http://example.com:8080/p", + }, + { + name: "url already has host set", + setup: func() *http.Request { + r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/x", nil) + r.URL.Host = "other.com" + return r + }, + want: "//other.com/x", + }, + { + name: "root path only", + setup: func() *http.Request { + r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/", nil) + r.Host = "example.com" + return r + }, + want: "http://example.com/", + }, + { + name: "query but no path", + setup: func() *http.Request { + r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/", nil) + r.Host = "example.com" + r.URL.Path = "" + r.URL.RawQuery = "a=1" + return r + }, + want: "http://example.com?a=1", + }, + { + name: "encoded CRLF in path preserved", + setup: func() *http.Request { + r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/foo%0D%0Abar", nil) + r.Host = "example.com" + return r + }, + want: "http://example.com/foo%0D%0Abar", + }, + { + name: "tab in query not stripped", + setup: func() *http.Request { + r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/", nil) + r.Host = "example.com" + r.URL.RawQuery = "x=1\tX-Bad: true" + return r + }, + want: "http://example.com/?x=1\tX-Bad: true", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := URI(tt.setup()) + if got != tt.want { + t.Errorf("URI() = %q, want %q", got, tt.want) + } + }) + } +} + +// ── Group C: mockPool tests ─────────────────────────────────────────────────── + func TestServeHTTP_NoFreeWorkers_SetsHeader(t *testing.T) { mp := &mockPool{execErr: errors.E(errors.NoFreeWorkers)} h := newTestHandler(t, defaultCfg(), mp) - req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(`{"key":"val"}`)) + req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/", strings.NewReader(`{"key":"val"}`)) req.Header.Set("Content-Type", "application/json") rr := httptest.NewRecorder() diff --git a/handler/response.go b/handler/response.go index c16a6ed..411469a 100644 --- a/handler/response.go +++ b/handler/response.go @@ -53,8 +53,8 @@ func (h *Handler) handlePROTOresponse(pld *payload.Payload, w http.ResponseWrite push := rsp.GetHeaders()[HTTP2Push].GetValues() if pusher, ok := w.(http.Pusher); ok { - for i := range push { - err = pusher.Push(string(rsp.GetHeaders()[HTTP2Push].GetValues()[i]), nil) + for _, pushVal := range push { + err = pusher.Push(string(pushVal), nil) if err != nil { return err } diff --git a/handler/uploads.go b/handler/uploads.go index 1257ca4..0adf8ff 100644 --- a/handler/uploads.go +++ b/handler/uploads.go @@ -60,7 +60,7 @@ func (u *Uploads) Open(log *zap.Logger, dir string, forbid, allow map[string]str func (u *Uploads) Clear(log *zap.Logger) { for _, f := range u.list { if f.TempFilename != "" && exists(f.TempFilename) { - err := os.Remove(f.TempFilename) //nolint:gosec + err := os.Remove(f.TempFilename) if err != nil && log != nil { log.Error("error removing the file", zap.Error(err)) } @@ -164,7 +164,7 @@ func (f *FileUpload) Open(dir string, forbid, allow map[string]struct{}) error { // exists if file exists. func exists(path string) bool { - if _, err := os.Stat(path); os.IsNotExist(err) { //nolint:gosec + if _, err := os.Stat(path); os.IsNotExist(err) { return false } return true diff --git a/init.go b/init.go index 93d5697..3bb15f0 100644 --- a/init.go +++ b/init.go @@ -57,8 +57,8 @@ func nilOr(cfg *config.Config) *acme.Config { func (p *Plugin) applyBundledMiddleware() { // apply max_req_size and logger middleware - for i := range p.servers { - switch srv := p.servers[i].Server().(type) { + for _, s := range p.servers { + switch srv := s.Server().(type) { case *http.Server: srv.Handler = bundledMw.MaxRequestSize(srv.Handler, p.cfg.MaxRequestSize*MB) srv.Handler = bundledMw.NewLogMiddleware(srv.Handler, p.cfg.AccessLogs, p.log) @@ -66,7 +66,7 @@ func (p *Plugin) applyBundledMiddleware() { srv.Handler = bundledMw.MaxRequestSize(srv.Handler, p.cfg.MaxRequestSize*MB) srv.Handler = bundledMw.NewLogMiddleware(srv.Handler, p.cfg.AccessLogs, p.log) default: - p.log.DPanic("unknown server type", zap.Any("server", p.servers[i].Server())) + p.log.DPanic("unknown server type", zap.Any("server", s.Server())) } } } diff --git a/metrics.go b/metrics.go index 5866737..51ce153 100644 --- a/metrics.go +++ b/metrics.go @@ -68,14 +68,14 @@ func (s *StatsExporter) Collect(ch chan<- prometheus.Metric) { var invalid float64 // collect the memory - for i := range workerStates { - cum += float64(workerStates[i].MemoryUsage) + for _, ws := range workerStates { + cum += float64(ws.MemoryUsage) - ch <- prometheus.MustNewConstMetric(s.StateDesc, prometheus.GaugeValue, 0, workerStates[i].StatusStr, strconv.Itoa(int(workerStates[i].Pid))) - ch <- prometheus.MustNewConstMetric(s.WorkerMemoryDesc, prometheus.GaugeValue, float64(workerStates[i].MemoryUsage), strconv.Itoa(int(workerStates[i].Pid))) + ch <- prometheus.MustNewConstMetric(s.StateDesc, prometheus.GaugeValue, 0, ws.StatusStr, strconv.Itoa(int(ws.Pid))) + ch <- prometheus.MustNewConstMetric(s.WorkerMemoryDesc, prometheus.GaugeValue, float64(ws.MemoryUsage), strconv.Itoa(int(ws.Pid))) // sync with sdk/worker/state.go - switch workerStates[i].Status { + switch ws.Status { case fsm.StateReady: ready++ case fsm.StateWorking: diff --git a/middleware/redirect.go b/middleware/redirect.go index a7eea19..d17bc80 100644 --- a/middleware/redirect.go +++ b/middleware/redirect.go @@ -1,9 +1,10 @@ package middleware import ( - "fmt" + "net" "net/http" "net/url" + "strconv" "strings" ) @@ -26,11 +27,17 @@ func Redirect(_ http.Handler, port int) http.Handler { // TLSAddr replaces listen or host port with port configured by SSLConfig config. func TLSAddr(host string, forcePort bool, sslPort int) string { - // remove current forcePort first - host = strings.Split(host, ":")[0] + if u, err := url.Parse("//" + host); err == nil { + host = u.Hostname() + } if forcePort || sslPort != 443 { - host = fmt.Sprintf("%s:%v", host, sslPort) + return net.JoinHostPort(host, strconv.Itoa(sslPort)) + } + + // url.URL.Host requires bracketed IPv6 literals even without a port. + if strings.Contains(host, ":") { + return "[" + host + "]" } return host diff --git a/middleware/redirect_test.go b/middleware/redirect_test.go new file mode 100644 index 0000000..d6fb489 --- /dev/null +++ b/middleware/redirect_test.go @@ -0,0 +1,141 @@ +package middleware + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTLSAddr(t *testing.T) { + tests := []struct { + name string + host string + forcePort bool + sslPort int + want string + }{ + // IPv4 with port — standard cases + {"ipv4 with port, default ssl port", "example.com:8080", false, 443, "example.com"}, + {"ipv4 with port, force port", "example.com:8080", true, 443, "example.com:443"}, + {"ipv4 with port, non-default ssl port", "example.com:8080", false, 8443, "example.com:8443"}, + + // IPv4 without port + {"ipv4 no port, default ssl port", "example.com", false, 443, "example.com"}, + {"ipv4 no port, force port", "example.com", true, 443, "example.com:443"}, + + // IPv6 with port — core fix + {"ipv6 with port, default ssl port", "[::1]:8080", false, 443, "[::1]"}, + {"ipv6 with port, force port", "[::1]:8080", true, 443, "[::1]:443"}, + {"ipv6 with port, non-default ssl port", "[::1]:8080", false, 8443, "[::1]:8443"}, + + // IPv6 without port (bare bracketed form from r.Host) + {"ipv6 no port, default ssl port", "[::1]", false, 443, "[::1]"}, + {"ipv6 no port, force port", "[::1]", true, 443, "[::1]:443"}, + + // Edge cases — degenerate inputs + {"empty host", "", false, 443, ""}, + {"empty host forced port", "", true, 443, ":443"}, + {"host with trailing colon", "example.com:", false, 443, "example.com"}, + {"ip literal with zone", "[fe80::1%25eth0]:80", false, 443, "[fe80::1%eth0]"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := TLSAddr(tt.host, tt.forcePort, tt.sslPort) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestRedirect(t *testing.T) { + tests := []struct { + name string + method string + host string + path string + query string + sslPort int + wantLoc string + wantCode int + }{ + { + name: "basic http to https", + method: http.MethodGet, + host: "example.com", + path: "/page", + sslPort: 443, + wantLoc: "https://example.com/page", + wantCode: http.StatusPermanentRedirect, + }, + { + name: "preserves query string", + method: http.MethodGet, + host: "example.com", + path: "/search", + query: "q=hello&lang=en", + sslPort: 443, + wantLoc: "https://example.com/search?q=hello&lang=en", + wantCode: http.StatusPermanentRedirect, + }, + { + name: "non-default ssl port", + method: http.MethodGet, + host: "example.com", + path: "/", + sslPort: 8443, + wantLoc: "https://example.com:8443/", + wantCode: http.StatusPermanentRedirect, + }, + { + name: "POST gets 308 not 301", + method: http.MethodPost, + host: "example.com", + path: "/api", + sslPort: 443, + wantLoc: "https://example.com/api", + wantCode: http.StatusPermanentRedirect, + }, + { + name: "IPv6 host", + method: http.MethodGet, + host: "[::1]:8080", + path: "/", + sslPort: 443, + wantLoc: "https://[::1]/", + wantCode: http.StatusPermanentRedirect, + }, + { + name: "empty path", + method: http.MethodGet, + host: "example.com", + path: "", + sslPort: 443, + wantLoc: "https://example.com", + wantCode: http.StatusPermanentRedirect, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req := httptest.NewRequestWithContext(t.Context(), tt.method, "/", nil) + req.Host = tt.host + req.URL.Path = tt.path + req.URL.RawQuery = tt.query + + called := false + inner := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) { + called = true + }) + + rr := httptest.NewRecorder() + Redirect(inner, tt.sslPort).ServeHTTP(rr, req) + + assert.Equal(t, tt.wantCode, rr.Code) + assert.Equal(t, tt.wantLoc, rr.Header().Get("Location")) + assert.NotEmpty(t, rr.Header().Get("Strict-Transport-Security"), "STS header must be set") + assert.False(t, called, "inner handler should not be called") + }) + } +} diff --git a/plugin.go b/plugin.go index dc75d44..1158070 100644 --- a/plugin.go +++ b/plugin.go @@ -171,9 +171,9 @@ func (p *Plugin) Stop(ctx context.Context) error { doneCh := make(chan struct{}, 1) go func() { - for i := range p.servers { - if p.servers[i] != nil { - p.servers[i].Stop() + for _, srv := range p.servers { + if srv != nil { + srv.Stop() } } diff --git a/servers/fcgi/fcgi.go b/servers/fcgi/fcgi.go index af3996a..51674c9 100644 --- a/servers/fcgi/fcgi.go +++ b/servers/fcgi/fcgi.go @@ -65,11 +65,11 @@ func (s *Server) Stop() { } func applyMiddleware(server *http.Server, middleware map[string]api.Middleware, order []string, log *zap.Logger) { - for i := range order { - if mdwr, ok := middleware[order[i]]; ok { + for _, name := range order { + if mdwr, ok := middleware[name]; ok { server.Handler = mdwr.Middleware(server.Handler) } else { - log.Warn("requested middleware does not exist", zap.String("requested", order[i])) + log.Warn("requested middleware does not exist", zap.String("requested", name)) } } } diff --git a/servers/http11/http.go b/servers/http11/http.go index b0cdda1..277270e 100644 --- a/servers/http11/http.go +++ b/servers/http11/http.go @@ -110,11 +110,11 @@ func (s *Server) Stop() { } func applyMiddleware(server *http.Server, middleware map[string]api.Middleware, order []string, log *zap.Logger) { - for i := range order { - if mdwr, ok := middleware[order[i]]; ok { + for _, name := range order { + if mdwr, ok := middleware[name]; ok { server.Handler = mdwr.Middleware(server.Handler) } else { - log.Warn("requested middleware does not exist", zap.String("requested", order[i])) + log.Warn("requested middleware does not exist", zap.String("requested", name)) } } } diff --git a/servers/http3/http3.go b/servers/http3/http3.go index f49920f..b7c272c 100644 --- a/servers/http3/http3.go +++ b/servers/http3/http3.go @@ -85,11 +85,11 @@ func (s *Server) Stop() { } func applyMiddleware(server *http3.Server, middleware map[string]api.Middleware, order []string, log *zap.Logger) { - for i := range order { - if mdwr, ok := middleware[order[i]]; ok { + for _, name := range order { + if mdwr, ok := middleware[name]; ok { server.Handler = mdwr.Middleware(server.Handler) } else { - log.Warn("requested middleware does not exist", zap.String("requested", order[i])) + log.Warn("requested middleware does not exist", zap.String("requested", name)) } } } diff --git a/servers/https/config.go b/servers/https/config.go index adcd2ad..65ced3a 100644 --- a/servers/https/config.go +++ b/servers/https/config.go @@ -1,9 +1,9 @@ package https import ( + "net" "os" "strconv" - "strings" "github.com/roadrunner-server/errors" "github.com/roadrunner-server/http/v5/acme" @@ -97,26 +97,20 @@ func (s *SSL) EnableACME() bool { func (s *SSL) Valid() error { const op = errors.Op("ssl_valid") - parts := strings.Split(s.Address, ":") - switch len(parts) { - // :443 form - // 127.0.0.1:443 form - // use 0.0.0.0 as host and 443 as port - case 2: - if parts[0] == "" { - s.host = "127.0.0.1" - } else { - s.host = parts[0] - } - - port, err := strconv.Atoi(parts[1]) - if err != nil { - return errors.E(op, err) - } - s.Port = port - default: - return errors.E(op, errors.Errorf("unknown format, accepted format is [: or :], provided: %s", s.Address)) + host, portStr, err := net.SplitHostPort(s.Address) + if err != nil { + return errors.E(op, err) + } + if host == "" { + s.host = "127.0.0.1" + } else { + s.host = host + } + port, err := strconv.ParseUint(portStr, 10, 16) + if err != nil { + return errors.E(op, err) } + s.Port = int(port) // the user use they own certificates if s.Acme == nil { diff --git a/servers/https/config_test.go b/servers/https/config_test.go index 8b8c17f..50bc72e 100644 --- a/servers/https/config_test.go +++ b/servers/https/config_test.go @@ -114,3 +114,47 @@ func TestSSL_Valid7(t *testing.T) { err := conf.Valid() assert.Error(t, err) } + +// Ensures ParseUint enforces 0–65535 (Atoi would have accepted 99999 silently). +func TestSSL_ValidPortOutOfRange(t *testing.T) { + conf := &SSL{Address: ":99999"} + assert.Error(t, conf.Valid()) +} + +// Ensures net.SplitHostPort correctly parses a bracketed IPv6 address. +// Valid() should reach the cert-check step, not fail at the parse step. +func TestSSL_ValidIPv6ParseOK(t *testing.T) { + conf := &SSL{ + Address: "[::1]:443", + Key: "nonexistent.key", + Cert: "nonexistent.crt", + } + err := conf.Valid() + // Must fail at cert-not-found, so host and Port were parsed correctly. + assert.Error(t, err) + assert.Equal(t, "::1", conf.host) + assert.Equal(t, 443, conf.Port) +} + +func TestTlsAddr(t *testing.T) { + tests := []struct { + name string + host string + forcePort bool + sslPort int + want string + }{ + {"ipv4 force port", "0.0.0.0:80", true, 443, "0.0.0.0:443"}, + {"ipv6 with port force port", "[::1]:80", true, 443, "[::1]:443"}, + {"ipv6 with port non-default ssl", "[::1]:80", false, 8443, "[::1]:8443"}, + {"ipv6 no port force port", "[::1]", true, 443, "[::1]:443"}, + {"ipv6 with port default ssl", "[::1]:443", false, 443, "[::1]"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tlsAddr(tt.host, tt.forcePort, tt.sslPort) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/servers/https/https.go b/servers/https/https.go index 89a50c3..301f4be 100644 --- a/servers/https/https.go +++ b/servers/https/https.go @@ -4,10 +4,12 @@ import ( "crypto/tls" "crypto/x509" stderr "errors" - "fmt" "log" + "net" "net/http" + "net/url" "os" + "strconv" "strings" "time" @@ -185,22 +187,28 @@ func initTLS(handler http.Handler, errLog *log.Logger, addr string, port int) *h // tlsAddr replaces listen or host port with port configured by SSLConfig config. func tlsAddr(host string, forcePort bool, sslPort int) string { - // remove current forcePort first - host = strings.Split(host, ":")[0] + if u, err := url.Parse("//" + host); err == nil { + host = u.Hostname() + } if forcePort || sslPort != 443 { - host = fmt.Sprintf("%s:%v", host, sslPort) + return net.JoinHostPort(host, strconv.Itoa(sslPort)) + } + + // url.URL.Host requires bracketed IPv6 literals even without a port. + if strings.Contains(host, ":") { + return "[" + host + "]" } return host } func applyMiddleware(server *http.Server, middleware map[string]api.Middleware, order []string, log *zap.Logger) { - for i := range order { - if mdwr, ok := middleware[order[i]]; ok { + for _, name := range order { + if mdwr, ok := middleware[name]; ok { server.Handler = mdwr.Middleware(server.Handler) } else { - log.Warn("requested middleware does not exist", zap.String("requested", order[i])) + log.Warn("requested middleware does not exist", zap.String("requested", name)) } } } diff --git a/status.go b/status.go index da0802f..b2a9d0f 100644 --- a/status.go +++ b/status.go @@ -14,8 +14,8 @@ func (p *Plugin) Status() (*status.Status, error) { workers := p.pool.Workers() - for i := range workers { - if workers[i].State().IsActive() { + for _, w := range workers { + if w.State().IsActive() { return &status.Status{ Code: http.StatusOK, }, nil @@ -34,10 +34,10 @@ func (p *Plugin) Ready() (*status.Status, error) { workers := p.pool.Workers() - for i := range workers { + for _, w := range workers { // If state of the worker is ready (at least 1) // we assume, that plugin's worker pool is ready - if workers[i].State().Compare(fsm.StateReady) { + if w.State().Compare(fsm.StateReady) { return &status.Status{ Code: http.StatusOK, }, nil diff --git a/tests/go.mod b/tests/go.mod index 0072d58..3c52f65 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -17,7 +17,6 @@ require ( github.com/roadrunner-server/informer/v5 v5.1.9 github.com/roadrunner-server/logger/v5 v5.1.9 github.com/roadrunner-server/memory/v5 v5.2.9 - github.com/roadrunner-server/otel/v5 v5.4.0 // indirect github.com/roadrunner-server/pool v1.1.3 github.com/roadrunner-server/resetter/v5 v5.1.9 github.com/roadrunner-server/rpc/v5 v5.1.9 @@ -38,11 +37,9 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/caddyserver/certmagic v0.25.2 // indirect github.com/caddyserver/zerossl v0.1.5 // indirect - github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect @@ -51,11 +48,7 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gofiber/fiber/v2 v2.52.12 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/mock v1.7.0-rc.1 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/joho/godotenv v1.5.1 // indirect github.com/klauspost/compress v1.18.4 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect @@ -67,8 +60,6 @@ require ( github.com/mholt/acmez/v3 v3.1.6 // indirect github.com/miekg/dns v1.1.72 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/nexus-rpc/sdk-go v0.6.0 // indirect - github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect @@ -83,7 +74,6 @@ require ( github.com/roadrunner-server/errors v1.4.1 // indirect github.com/roadrunner-server/events v1.0.1 // indirect github.com/roadrunner-server/tcplisten v1.5.2 // indirect - github.com/robfig/cron v1.2.0 // indirect github.com/rs/cors v1.11.1 // indirect github.com/sagikazarmark/locafero v0.12.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect @@ -91,7 +81,6 @@ require ( github.com/spf13/cast v1.10.0 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/spf13/viper v1.21.0 // indirect - github.com/stretchr/objx v0.5.3 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tklauser/go-sysconf v0.3.16 // indirect github.com/tklauser/numcpus v0.11.0 // indirect @@ -104,19 +93,10 @@ require ( go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.66.0 go.opentelemetry.io/contrib/propagators/jaeger v1.41.0 // indirect - go.opentelemetry.io/otel v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.41.0 // indirect + go.opentelemetry.io/otel v1.41.0 go.opentelemetry.io/otel/metric v1.41.0 // indirect go.opentelemetry.io/otel/sdk v1.41.0 go.opentelemetry.io/otel/trace v1.41.0 // indirect - go.opentelemetry.io/proto/otlp v1.9.0 // indirect - go.temporal.io/api v1.62.2 // indirect - go.temporal.io/sdk v1.40.0 // indirect - go.temporal.io/sdk/contrib/opentelemetry v0.7.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect @@ -126,12 +106,8 @@ require ( golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect - golang.org/x/time v0.14.0 // indirect golang.org/x/tools v0.42.0 // indirect golang.org/x/tools/godoc v0.1.0-deprecated // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect - google.golang.org/grpc v1.79.1 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/tests/go.sum b/tests/go.sum index c9ce424..40b5573 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -7,16 +7,12 @@ github.com/caddyserver/certmagic v0.25.2 h1:D7xcS7ggX/WEY54x0czj7ioTkmDWKIgxtIi2 github.com/caddyserver/certmagic v0.25.2/go.mod h1:llW/CvsNmza8S6hmsuggsZeiX+uS27dkqY27wDIuBWg= github.com/caddyserver/zerossl v0.1.5 h1:dkvOjBAEEtY6LIGAHei7sw2UgqSD6TrWweXpV7lvEvE= github.com/caddyserver/zerossl v0.1.5/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= -github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= -github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw= -github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -41,27 +37,15 @@ github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gofiber/fiber/v2 v2.52.12 h1:0LdToKclcPOj8PktUdIKo9BUohjjwfnQl42Dhw8/WUw= github.com/gofiber/fiber/v2 v2.52.12/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U= -github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3/go.mod h1:NbCUVmiS4foBGBHOYlCT25+YmGpJ32dZPi75pGEUpj4= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= @@ -88,10 +72,6 @@ github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/nexus-rpc/sdk-go v0.6.0 h1:QRgnP2zTbxEbiyWG/aXH8uSC5LV/Mg1fqb19jb4DBlo= -github.com/nexus-rpc/sdk-go v0.6.0/go.mod h1:FHdPfVQwRuJFZFTF0Y2GOAxCrbIBNrcPna9slkGKPYk= -github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= -github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= @@ -138,8 +118,6 @@ github.com/roadrunner-server/logger/v5 v5.1.9 h1:3Kn+NYXF7Ww5LvkwMZwkv1q99t5qusI github.com/roadrunner-server/logger/v5 v5.1.9/go.mod h1:hwct/TWTmxYsVzowLx4g9HkY5z2/gpYOC+UN8btsrAA= github.com/roadrunner-server/memory/v5 v5.2.9 h1:niLep2dyUaYhrn+I12kTXjGUTUSbVJa+jyvNJrbt/hw= github.com/roadrunner-server/memory/v5 v5.2.9/go.mod h1:UcE3Sf0TYRmAG1HukXmzsztGD0nBi6RRhG75K11Fqpk= -github.com/roadrunner-server/otel/v5 v5.4.0 h1:5X+yF/4jiH7Pmq0ctsy7MmnSMsNxgZthZXul1ysT5vQ= -github.com/roadrunner-server/otel/v5 v5.4.0/go.mod h1:1sK/RbNlH/JY4e+M6TSJzzAfDDBbSX7FAS3RxUVVQII= github.com/roadrunner-server/pool v1.1.3 h1:KMsiL6yuYBWGk73bdO0akwP+fJ63bxDF972JukCGsxI= github.com/roadrunner-server/pool v1.1.3/go.mod h1:8ceC7NvZKJRciv+KJmcyk5CeDugoel6GD+crm5kBFW0= github.com/roadrunner-server/resetter/v5 v5.1.9 h1:rH1nxkgvItbMEp1/JFZqcijOkkav4zo0E4wcVXBcXa8= @@ -154,8 +132,6 @@ github.com/roadrunner-server/static/v5 v5.2.0 h1:xpZgIlvKWdWUJ37BtbNLtL/kN1rNFME github.com/roadrunner-server/static/v5 v5.2.0/go.mod h1:jp3eATJDSLmidXI25YDievkKp5XZ35qK6g4vHwpS0Ug= github.com/roadrunner-server/tcplisten v1.5.2 h1:nn8yXYrhRDkfQ9AAu4V075uT4fZRmOnpxkawgE+bWPA= github.com/roadrunner-server/tcplisten v1.5.2/go.mod h1:DufGBz7Dlx2KrNe/4RukEvGMTqZKB0Uve1GztwcyyR8= -github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= -github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= @@ -175,8 +151,6 @@ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= -github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= -github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= @@ -197,9 +171,7 @@ github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZ github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yookoala/gofast v0.8.0 h1:UmGTeBj2EF5gvS58ByE9HFdQ9MeYSUIwf7JN9aFno3Y= github.com/yookoala/gofast v0.8.0/go.mod h1:OJU201Q6HCaE1cASckaTbMm3KB6e0cZxK0mgqfwOKvQ= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= @@ -216,16 +188,6 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.41.0 h1:uw+ghxLS0Wb98XfAhgJVQv go.opentelemetry.io/contrib/propagators/jaeger v1.41.0/go.mod h1:Og4snN98wfeGoKm516W5+v0orAqwRRB5TAOJetk/HdM= go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 h1:mq/Qcf28TWz719lE3/hMB4KkyDuLJIvgJnFGcd0kEUI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0/go.mod h1:yk5LXEYhsL2htyDNJbEq7fWzNEigeEdV5xBF/Y+kAv0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0/go.mod h1:Izur+Wt8gClgMJqO/cZ8wdeeMryJ/xxiOVgFSSfpDTY= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.41.0 h1:61oRQmYGMW7pXmFjPg1Muy84ndqMxQ6SH2L8fBG8fSY= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.41.0/go.mod h1:c0z2ubK4RQL+kSDuuFu9WnuXimObon3IiKjJf4NACvU= -go.opentelemetry.io/otel/exporters/zipkin v1.41.0 h1:Jqg1mB+SKysx0NcRalLkDwzxVMIzkCm5qYiJq9uOtp0= -go.opentelemetry.io/otel/exporters/zipkin v1.41.0/go.mod h1:QfWtG1A/i1AIu33iL23EdTyPLzhylCF3ulSA8QxNK5U= go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= go.opentelemetry.io/otel/sdk v1.41.0 h1:YPIEXKmiAwkGl3Gu1huk1aYWwtpRLeskpV+wPisxBp8= @@ -233,14 +195,6 @@ go.opentelemetry.io/otel/sdk v1.41.0/go.mod h1:ahFdU0G5y8IxglBf0QBJXgSe7agzjE4Gi go.opentelemetry.io/otel/sdk/metric v1.41.0 h1:siZQIYBAUd1rlIWQT2uCxWJxcCO7q3TriaMlf08rXw8= go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= -go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= -go.temporal.io/api v1.62.2 h1:jFhIzlqNyJsJZTiCRQmTIMv6OTQ5BZ57z8gbgLGMaoo= -go.temporal.io/api v1.62.2/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM= -go.temporal.io/sdk v1.40.0 h1:n9JN3ezVpWBxLzz5xViCo0sKxp7kVVhr1Su0bcMRNNs= -go.temporal.io/sdk v1.40.0/go.mod h1:tauxVfN174F0bdEs27+i0h8UPD7xBb6Py2SPHo7f1C0= -go.temporal.io/sdk/contrib/opentelemetry v0.7.0 h1:GSna1HP+1ibNXZ9xlVdQU2zFVqdt5VcdF0dzpeaYccQ= -go.temporal.io/sdk/contrib/opentelemetry v0.7.0/go.mod h1:oQJC6UIl3FbSYh4f2MlUAIYSE6FPw02X1Tw8/bOvfxg= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= @@ -260,73 +214,42 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= -golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200908211811-12e1bf57a112/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk= golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/genproto v0.0.0-20260226221140-a57be14db171 h1:RxhCsti413yL0IjU9dVvuTbCISo8gs3RW1jPMStck+4= google.golang.org/genproto v0.0.0-20260226221140-a57be14db171/go.mod h1:uhvzakVEqAuXU3TC2JCsxIRe5f77l+JySE3EqPoMyqM= -google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= -google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= -google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/tests/handler_test.go b/tests/handler_test.go index 380c68d..58ad122 100644 --- a/tests/handler_test.go +++ b/tests/handler_test.go @@ -29,7 +29,7 @@ import ( ) func TestHandler_Echo(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "echo", "pipes") }, @@ -81,11 +81,11 @@ func TestHandler_Echo(t *testing.T) { }() assert.Equal(t, 201, r.StatusCode) assert.Equal(t, "WORLD", body) - p.Destroy(context.Background()) + p.Destroy(t.Context()) } func TestHandler_Headers(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "header", "pipes") }, @@ -160,7 +160,7 @@ func TestHandler_Headers(t *testing.T) { } func TestHandler_Empty_User_Agent(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "user-agent", "pipes") }, @@ -234,7 +234,7 @@ func TestHandler_Empty_User_Agent(t *testing.T) { } func TestHandler_User_Agent(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "user-agent", "pipes") }, @@ -308,7 +308,7 @@ func TestHandler_User_Agent(t *testing.T) { } func TestHandler_Cookies(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "cookie", "pipes") }, @@ -384,7 +384,7 @@ func TestHandler_Cookies(t *testing.T) { } func TestHandler_JsonPayload_POST(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "payload", "pipes") }, @@ -458,7 +458,7 @@ func TestHandler_JsonPayload_POST(t *testing.T) { } func TestHandler_JsonPayload_PUT(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "payload", "pipes") }, @@ -528,7 +528,7 @@ func TestHandler_JsonPayload_PUT(t *testing.T) { } func TestHandler_JsonPayload_PATCH(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "payload", "pipes") }, @@ -598,7 +598,7 @@ func TestHandler_JsonPayload_PATCH(t *testing.T) { } func TestHandler_UrlEncoded_POST_DELETE(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/psr-worker-echo.php") }, @@ -690,7 +690,7 @@ func TestHandler_UrlEncoded_POST_DELETE(t *testing.T) { } func TestHandler_FormData_POST(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "data", "pipes") }, @@ -783,7 +783,7 @@ func TestHandler_FormData_POST(t *testing.T) { } func TestHandler_FormData_POST_Overwrite(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "data", "pipes") }, @@ -880,7 +880,7 @@ func TestHandler_FormData_POST_Overwrite(t *testing.T) { } func TestHandler_FormData_POST_Form_UrlEncoded_Charset(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "data", "pipes") }, @@ -973,7 +973,7 @@ func TestHandler_FormData_POST_Form_UrlEncoded_Charset(t *testing.T) { } func TestHandler_FormData_PUT(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "data", "pipes") }, @@ -1067,7 +1067,7 @@ func TestHandler_FormData_PUT(t *testing.T) { } func TestHandler_FormData_PATCH(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "data", "pipes") }, @@ -1160,7 +1160,7 @@ func TestHandler_FormData_PATCH(t *testing.T) { } func TestHandler_Multipart_POST(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "data", "pipes") }, @@ -1295,7 +1295,7 @@ func TestHandler_Multipart_POST(t *testing.T) { } func TestHandler_Multipart_PUT(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "data", "pipes") }, @@ -1430,7 +1430,7 @@ func TestHandler_Multipart_PUT(t *testing.T) { } func TestHandler_Multipart_PATCH(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "data", "pipes") }, @@ -1568,7 +1568,7 @@ func TestHandler_Multipart_PATCH(t *testing.T) { } func TestHandler_Error(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "error", "pipes") }, @@ -1624,7 +1624,7 @@ func TestHandler_Error(t *testing.T) { } func TestHandler_Error2(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "error2", "pipes") }, @@ -1680,7 +1680,7 @@ func TestHandler_Error2(t *testing.T) { } func TestHandler_ResponseDuration(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "echo", "pipes") }, @@ -1738,7 +1738,7 @@ func TestHandler_ResponseDuration(t *testing.T) { } func TestHandler_ResponseDurationDelayed(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "echoDelay", "pipes") }, @@ -1779,7 +1779,7 @@ func TestHandler_ResponseDurationDelayed(t *testing.T) { } func TestHandler_ErrorDuration(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "error", "pipes") }, @@ -1836,7 +1836,7 @@ func TestHandler_ErrorDuration(t *testing.T) { } func TestHandler_IP(t *testing.T) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(t.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "ip", "pipes") }, @@ -1893,7 +1893,7 @@ func TestHandler_IP(t *testing.T) { } func BenchmarkHandler_Listen_Echo(b *testing.B) { - p, err := staticPool.NewPool(context.Background(), + p, err := staticPool.NewPool(b.Context(), func(cmd []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "echo", "pipes") }, @@ -1944,11 +1944,11 @@ func BenchmarkHandler_Listen_Echo(b *testing.B) { b.ReportAllocs() bb := "WORLD" - req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://127.0.0.1:8188/?hello=world", nil) + req, err := http.NewRequestWithContext(b.Context(), http.MethodGet, "http://127.0.0.1:8188/?hello=world", nil) require.NoError(b, err) client := &http.Client{} - for n := 0; n < b.N; n++ { + for b.Loop() { r, err := client.Do(req) require.NoError(b, err) // Response might be nil here diff --git a/tests/http_plugin2_test.go b/tests/http_plugin2_test.go index 1748b0f..3c94889 100644 --- a/tests/http_plugin2_test.go +++ b/tests/http_plugin2_test.go @@ -2,7 +2,6 @@ package tests import ( "bytes" - "context" "crypto/tls" "io" "log/slog" @@ -115,7 +114,7 @@ func echoHTTPPost(t *testing.T) { rdr := bytes.NewReader(bd) client := &http.Client{} - req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, "http://127.0.0.1:10084/", rdr) + req, err := http.NewRequestWithContext(t.Context(), http.MethodPost, "http://127.0.0.1:10084/", rdr) assert.NoError(t, err) resp, err := client.Do(req) @@ -131,7 +130,7 @@ func echoHTTPPost(t *testing.T) { for range 20 { rdr = bytes.NewReader(bd) - req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, "http://127.0.0.1:10084/", rdr) + req, err := http.NewRequestWithContext(t.Context(), http.MethodPost, "http://127.0.0.1:10084/", rdr) assert.NoError(t, err) req.Header.Add("Content-Type", "application/json") @@ -493,7 +492,7 @@ func TestHTTPExecTTL(t *testing.T) { time.Sleep(time.Second) - req, err2 := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://127.0.0.1:18988", nil) + req, err2 := http.NewRequestWithContext(t.Context(), http.MethodGet, "http://127.0.0.1:18988", nil) require.NoError(t, err2) r, err2 := http.DefaultClient.Do(req) diff --git a/tests/http_plugin3_test.go b/tests/http_plugin3_test.go index 110b087..3d404ac 100644 --- a/tests/http_plugin3_test.go +++ b/tests/http_plugin3_test.go @@ -3,7 +3,6 @@ package tests import ( "bufio" "bytes" - "context" "crypto/rand" "crypto/tls" "fmt" @@ -1120,7 +1119,7 @@ func TestHTTPBigURLEncoded(t *testing.T) { form.Add("foo", string(buf)) - req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, "http://127.0.0.1:55777", strings.NewReader(form.Encode())) + req, err := http.NewRequestWithContext(t.Context(), http.MethodPost, "http://127.0.0.1:55777", strings.NewReader(form.Encode())) require.NoError(t, err) client := &http.Client{} @@ -1208,7 +1207,7 @@ func TestHTTPBigURLEncoded2(t *testing.T) { // after encode will be ~28mb form.Add("foo", string(buf)) - req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, "http://127.0.0.1:55778", strings.NewReader(form.Encode())) + req, err := http.NewRequestWithContext(t.Context(), http.MethodPost, "http://127.0.0.1:55778", strings.NewReader(form.Encode())) require.NoError(t, err) client := &http.Client{} @@ -1295,7 +1294,7 @@ func TestHTTPBigURLEncoded3(t *testing.T) { form.Add("foo", string(buf)) - req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, "http://127.0.0.1:55779", strings.NewReader(form.Encode())) + req, err := http.NewRequestWithContext(t.Context(), http.MethodPost, "http://127.0.0.1:55779", strings.NewReader(form.Encode())) require.NoError(t, err) client := &http.Client{} diff --git a/tests/http_plugin_test.go b/tests/http_plugin_test.go index 20006d0..b7b6b50 100644 --- a/tests/http_plugin_test.go +++ b/tests/http_plugin_test.go @@ -549,7 +549,7 @@ func fcgiEcho(t *testing.T) { ) w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://site.local/?hello=world", nil) + req := httptest.NewRequestWithContext(t.Context(), "GET", "http://site.local/?hello=world", nil) fcgiHandler.ServeHTTP(w, req) body, err := io.ReadAll(w.Result().Body) //nolint:bodyclose @@ -642,7 +642,7 @@ func sslRedirect(t *testing.T) { }, } - req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://127.0.0.1:8087?hello=world", nil) + req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, "http://127.0.0.1:8087?hello=world", nil) assert.NoError(t, err) r, err := client.Do(req) @@ -740,7 +740,7 @@ func sslPush(t *testing.T) { }, } - req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "https://127.0.0.1:8894?hello=world", nil) + req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, "https://127.0.0.1:8894?hello=world", nil) assert.NoError(t, err) r, err := client.Do(req) @@ -838,7 +838,7 @@ func fcgiEcho1(t *testing.T) { ) w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://site.local/hello-world", nil) + req := httptest.NewRequestWithContext(t.Context(), "GET", "http://site.local/hello-world", nil) fcgiHandler.ServeHTTP(w, req) _, err := io.ReadAll(w.Result().Body) //nolint:bodyclose @@ -924,7 +924,7 @@ func fcgiEchoUnix(t *testing.T) { ) w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://site.local/hello-world", nil) + req := httptest.NewRequestWithContext(t.Context(), "GET", "http://site.local/hello-world", nil) fcgiHandler.ServeHTTP(w, req) _, err := io.ReadAll(w.Result().Body) //nolint:bodyclose @@ -1005,7 +1005,7 @@ func fcgiReqURI(t *testing.T) { ) w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://site.local/hello-world", nil) + req := httptest.NewRequestWithContext(t.Context(), "GET", "http://site.local/hello-world", nil) fcgiHandler.ServeHTTP(w, req) body, err := io.ReadAll(w.Result().Body) //nolint:bodyclose @@ -1171,7 +1171,7 @@ func TestH2CUpgrade(t *testing.T) { time.Sleep(time.Second * 1) client := &http.Client{} - req, err := http.NewRequestWithContext(context.Background(), "PRI", "http://127.0.0.1:8083", nil) + req, err := http.NewRequestWithContext(t.Context(), "PRI", "http://127.0.0.1:8083", nil) assert.NoError(t, err) req.Header.Add("Upgrade", "h2c") @@ -1187,7 +1187,7 @@ func TestH2CUpgrade(t *testing.T) { assert.Equal(t, http.StatusSwitchingProtocols, r.StatusCode) - req, err = http.NewRequestWithContext(context.Background(), http.MethodGet, "http://127.0.0.1:8083?hello=world", nil) + req, err = http.NewRequestWithContext(t.Context(), http.MethodGet, "http://127.0.0.1:8083?hello=world", nil) assert.NoError(t, err) resp, err := client.Do(req) diff --git a/tests/uploads_test.go b/tests/uploads_test.go index 58b8c48..e7df135 100644 --- a/tests/uploads_test.go +++ b/tests/uploads_test.go @@ -29,7 +29,7 @@ import ( const testFile = "uploads_test.go" func TestHandler_Upload_File(t *testing.T) { - pl, err := staticPool.NewPool(context.Background(), + pl, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "upload", "pipes") }, @@ -67,7 +67,7 @@ func TestHandler_Upload_File(t *testing.T) { go func() { errL := hs.ListenAndServe() - if errL != nil && !errors.Is(http.ErrServerClosed, errL) { + if errL != nil && !errors.Is(errL, http.ErrServerClosed) { t.Errorf("error listening the interface: error %v", errL) } }() @@ -122,7 +122,7 @@ func TestHandler_Upload_File(t *testing.T) { } func TestHandler_Upload_NestedFile(t *testing.T) { - pl, err := staticPool.NewPool(context.Background(), + pl, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "upload", "pipes") }, @@ -161,7 +161,7 @@ func TestHandler_Upload_NestedFile(t *testing.T) { go func() { errL := hs.ListenAndServe() - if errL != nil && !errors.Is(http.ErrServerClosed, errL) { + if errL != nil && !errors.Is(errL, http.ErrServerClosed) { t.Errorf("error listening the interface: error %v", errL) } }() @@ -216,7 +216,7 @@ func TestHandler_Upload_NestedFile(t *testing.T) { } func TestHandler_Upload_File_NoTmpDir(t *testing.T) { - pl, err := staticPool.NewPool(context.Background(), + pl, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "upload", "pipes") }, @@ -254,7 +254,7 @@ func TestHandler_Upload_File_NoTmpDir(t *testing.T) { go func() { err = hs.ListenAndServe() - if err != nil && !errors.Is(http.ErrServerClosed, err) { + if err != nil && !errors.Is(err, http.ErrServerClosed) { t.Errorf("error listening the interface: error %v", err) } }() @@ -309,7 +309,7 @@ func TestHandler_Upload_File_NoTmpDir(t *testing.T) { } func TestHandler_Upload_File_Forbids(t *testing.T) { - pl, err := staticPool.NewPool(context.Background(), + pl, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "upload", "pipes") }, @@ -347,7 +347,7 @@ func TestHandler_Upload_File_Forbids(t *testing.T) { go func() { err = hs.ListenAndServe() - if err != nil && !errors.Is(http.ErrServerClosed, err) { + if err != nil && !errors.Is(err, http.ErrServerClosed) { t.Errorf("error listening the interface: error %v", err) } }() @@ -402,7 +402,7 @@ func TestHandler_Upload_File_Forbids(t *testing.T) { } func TestHandler_Upload_File_NotAllowed(t *testing.T) { - pl, err := staticPool.NewPool(context.Background(), + pl, err := staticPool.NewPool(t.Context(), func(_ []string) *exec.Cmd { return exec.Command("php", "php_test_files/http/client.php", "upload", "pipes") }, @@ -440,7 +440,7 @@ func TestHandler_Upload_File_NotAllowed(t *testing.T) { go func() { err = hs.ListenAndServe() - if err != nil && !errors.Is(http.ErrServerClosed, err) { + if err != nil && !errors.Is(err, http.ErrServerClosed) { t.Errorf("error listening the interface: error %v", err) } }()