From ee39de1cee15d71f0581fe761eab4787e734554c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 20:57:05 +0000 Subject: [PATCH 1/6] Initial plan From 92514805d0e6e81bf9cac09461e0b85e4abab10e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:12:24 +0000 Subject: [PATCH 2/6] Add step.http_proxy pipeline step for transparent reverse proxy Co-authored-by: intel352 <77607+intel352@users.noreply.github.com> --- cmd/wfctl/type_registry.go | 5 + module/pipeline_step_http_proxy.go | 226 +++++++++++ module/pipeline_step_http_proxy_test.go | 488 ++++++++++++++++++++++++ plugins/pipelinesteps/plugin.go | 2 + plugins/pipelinesteps/plugin_test.go | 1 + schema/module_schema.go | 15 + schema/schema.go | 1 + 7 files changed, 738 insertions(+) create mode 100644 module/pipeline_step_http_proxy.go create mode 100644 module/pipeline_step_http_proxy_test.go diff --git a/cmd/wfctl/type_registry.go b/cmd/wfctl/type_registry.go index 31ae0e99..6d2101e7 100644 --- a/cmd/wfctl/type_registry.go +++ b/cmd/wfctl/type_registry.go @@ -571,6 +571,11 @@ func KnownStepTypes() map[string]StepTypeInfo { Plugin: "pipelinesteps", ConfigKeys: []string{"url", "method", "headers", "body", "timeout", "auth"}, }, + "step.http_proxy": { + Type: "step.http_proxy", + Plugin: "pipelinesteps", + ConfigKeys: []string{"backend_url_key", "resource_key", "forward_headers", "timeout"}, + }, "step.request_parse": { Type: "step.request_parse", Plugin: "pipelinesteps", diff --git a/module/pipeline_step_http_proxy.go b/module/pipeline_step_http_proxy.go new file mode 100644 index 00000000..02de4f29 --- /dev/null +++ b/module/pipeline_step_http_proxy.go @@ -0,0 +1,226 @@ +package module + +import ( + "context" + "fmt" + "io" + "net/http" + "strings" + "time" + + "github.com/CrisisTextLine/modular" +) + +// HTTPProxyStep forwards the original HTTP request to a dynamically resolved +// backend URL and writes the backend response directly to the client. +// It is designed for API gateway / reverse-proxy use cases where the backend +// URL is determined by earlier pipeline steps (e.g. a database lookup). +type HTTPProxyStep struct { + name string + backendURLKey string + resourceKey string + forwardHeaders []string + timeout time.Duration + httpClient *http.Client +} + +// NewHTTPProxyStepFactory returns a StepFactory that creates HTTPProxyStep instances. +func NewHTTPProxyStepFactory() StepFactory { + return func(name string, config map[string]any, _ modular.Application) (PipelineStep, error) { + step := &HTTPProxyStep{ + name: name, + backendURLKey: "backend_url", + resourceKey: "path_params.resource", + timeout: 30 * time.Second, + httpClient: http.DefaultClient, + } + + if key, ok := config["backend_url_key"].(string); ok && key != "" { + step.backendURLKey = key + } + + if key, ok := config["resource_key"].(string); ok && key != "" { + step.resourceKey = key + } + + if headers, ok := config["forward_headers"]; ok { + switch v := headers.(type) { + case []string: + step.forwardHeaders = v + case []any: + for _, h := range v { + if s, ok := h.(string); ok { + step.forwardHeaders = append(step.forwardHeaders, s) + } + } + } + } + + if timeout, ok := config["timeout"].(string); ok && timeout != "" { + if d, err := time.ParseDuration(timeout); err == nil { + step.timeout = d + } + } + + return step, nil + } +} + +// Name returns the step name. +func (s *HTTPProxyStep) Name() string { return s.name } + +// Execute forwards the original HTTP request to the resolved backend URL and +// writes the backend response directly to the response writer. +func (s *HTTPProxyStep) Execute(ctx context.Context, pc *PipelineContext) (*StepResult, error) { + // Resolve backend URL from pipeline context + backendURL := s.resolveStringValue(s.backendURLKey, pc) + if backendURL == "" { + return nil, fmt.Errorf("http_proxy step %q: backend URL not found at key %q in pipeline context", s.name, s.backendURLKey) + } + + // Resolve optional resource path suffix + resource := s.resolveStringValue(s.resourceKey, pc) + + // Build the target URL + targetURL := strings.TrimRight(backendURL, "/") + if resource != "" { + targetURL += "/" + strings.TrimLeft(resource, "/") + } + + // Get the original HTTP request from metadata + origReq, _ := pc.Metadata["_http_request"].(*http.Request) + + // Append original query string + if origReq != nil && origReq.URL.RawQuery != "" { + targetURL += "?" + origReq.URL.RawQuery + } + + // Determine the HTTP method + method := http.MethodGet + if origReq != nil { + method = origReq.Method + } + + // Build the request body + var bodyReader io.Reader + if origReq != nil && origReq.Body != nil { + bodyReader = origReq.Body + } + + ctx, cancel := context.WithTimeout(ctx, s.timeout) + defer cancel() + + proxyReq, err := http.NewRequestWithContext(ctx, method, targetURL, bodyReader) //nolint:gosec // G107: URL is dynamically resolved from pipeline context + if err != nil { + return nil, fmt.Errorf("http_proxy step %q: failed to create proxy request: %w", s.name, err) + } + + // Forward Content-Length from the original request + if origReq != nil && origReq.ContentLength > 0 { + proxyReq.ContentLength = origReq.ContentLength + } + + // Forward configured headers from the original request + if origReq != nil && len(s.forwardHeaders) > 0 { + for _, h := range s.forwardHeaders { + if vals := origReq.Header.Values(h); len(vals) > 0 { + for _, v := range vals { + proxyReq.Header.Add(h, v) + } + } + } + } + + // Execute the proxy request + resp, err := s.httpClient.Do(proxyReq) + if err != nil { + return nil, fmt.Errorf("http_proxy step %q: proxy request failed: %w", s.name, err) + } + defer resp.Body.Close() + + // Read the backend response body + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("http_proxy step %q: failed to read proxy response: %w", s.name, err) + } + + // Try to write directly to the response writer if available + w, hasWriter := pc.Metadata["_http_response_writer"].(http.ResponseWriter) + if hasWriter { + // Copy backend response headers + for k, vals := range resp.Header { + for _, v := range vals { + w.Header().Add(k, v) + } + } + + // Write status code + w.WriteHeader(resp.StatusCode) + + // Write body + if len(respBody) > 0 { + if _, writeErr := w.Write(respBody); writeErr != nil { + return nil, fmt.Errorf("http_proxy step %q: failed to write response: %w", s.name, writeErr) + } + } + + // Mark response as handled + pc.Metadata["_response_handled"] = true + + return &StepResult{ + Output: map[string]any{ + "status_code": resp.StatusCode, + "proxied_to": targetURL, + }, + Stop: true, + }, nil + } + + // No response writer available — return the proxied response as output + respHeaders := make(map[string]any, len(resp.Header)) + for k, v := range resp.Header { + if len(v) == 1 { + respHeaders[k] = v[0] + } else { + vals := make([]any, len(v)) + for i, hv := range v { + vals[i] = hv + } + respHeaders[k] = vals + } + } + + return &StepResult{ + Output: map[string]any{ + "status_code": resp.StatusCode, + "headers": respHeaders, + "body": string(respBody), + "proxied_to": targetURL, + }, + Stop: true, + }, nil +} + +// resolveStringValue resolves a dot-path key from the pipeline context. +// It supports nested paths like "path_params.resource" by traversing +// pc.Current as a nested map. +func (s *HTTPProxyStep) resolveStringValue(key string, pc *PipelineContext) string { + parts := strings.Split(key, ".") + var current any = pc.Current + + for _, part := range parts { + m, ok := current.(map[string]any) + if !ok { + return "" + } + current, ok = m[part] + if !ok { + return "" + } + } + + if str, ok := current.(string); ok { + return str + } + return "" +} diff --git a/module/pipeline_step_http_proxy_test.go b/module/pipeline_step_http_proxy_test.go new file mode 100644 index 00000000..c8935670 --- /dev/null +++ b/module/pipeline_step_http_proxy_test.go @@ -0,0 +1,488 @@ +package module + +import ( + "bytes" + "context" + "io" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestHTTPProxyStep_BasicProxy(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Header().Set("X-Backend", "test") + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(`{"proxied":true}`)) + })) + defer backend.Close() + + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-test", map[string]any{}, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + step.(*HTTPProxyStep).httpClient = backend.Client() + + origReq := httptest.NewRequest("GET", "/original", nil) + recorder := httptest.NewRecorder() + + pc := NewPipelineContext(map[string]any{ + "backend_url": backend.URL, + }, map[string]any{ + "_http_request": origReq, + "_http_response_writer": recorder, + }) + + result, err := step.Execute(context.Background(), pc) + if err != nil { + t.Fatalf("execute error: %v", err) + } + + if !result.Stop { + t.Error("expected Stop=true") + } + + if result.Output["status_code"] != http.StatusOK { + t.Errorf("expected status_code 200, got %v", result.Output["status_code"]) + } + + resp := recorder.Result() + if resp.StatusCode != http.StatusOK { + t.Errorf("expected response status 200, got %d", resp.StatusCode) + } + + body, _ := io.ReadAll(resp.Body) + if string(body) != `{"proxied":true}` { + t.Errorf("expected proxied body, got %q", string(body)) + } + + if resp.Header.Get("Content-Type") != "application/json" { + t.Errorf("expected Content-Type application/json, got %q", resp.Header.Get("Content-Type")) + } + + if resp.Header.Get("X-Backend") != "test" { + t.Errorf("expected X-Backend header, got %q", resp.Header.Get("X-Backend")) + } + + if pc.Metadata["_response_handled"] != true { + t.Error("expected _response_handled=true") + } +} + +func TestHTTPProxyStep_WithResourcePath(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(r.URL.Path)) + })) + defer backend.Close() + + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-resource", map[string]any{ + "resource_key": "path_params.resource", + }, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + step.(*HTTPProxyStep).httpClient = backend.Client() + + origReq := httptest.NewRequest("GET", "/original", nil) + recorder := httptest.NewRecorder() + + pc := NewPipelineContext(map[string]any{ + "backend_url": backend.URL, + "path_params": map[string]any{ + "resource": "api/v1/users", + }, + }, map[string]any{ + "_http_request": origReq, + "_http_response_writer": recorder, + }) + + result, err := step.Execute(context.Background(), pc) + if err != nil { + t.Fatalf("execute error: %v", err) + } + + if !result.Stop { + t.Error("expected Stop=true") + } + + body, _ := io.ReadAll(recorder.Result().Body) + if string(body) != "/api/v1/users" { + t.Errorf("expected path /api/v1/users, got %q", string(body)) + } +} + +func TestHTTPProxyStep_ForwardHeaders(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(r.Header.Get("Authorization") + "|" + r.Header.Get("X-Request-Id"))) + })) + defer backend.Close() + + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-headers", map[string]any{ + "forward_headers": []any{"Authorization", "X-Request-Id"}, + }, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + step.(*HTTPProxyStep).httpClient = backend.Client() + + origReq := httptest.NewRequest("GET", "/original", nil) + origReq.Header.Set("Authorization", "Bearer token123") + origReq.Header.Set("X-Request-Id", "req-456") + origReq.Header.Set("X-Not-Forwarded", "should-not-appear") + recorder := httptest.NewRecorder() + + pc := NewPipelineContext(map[string]any{ + "backend_url": backend.URL, + }, map[string]any{ + "_http_request": origReq, + "_http_response_writer": recorder, + }) + + _, err = step.Execute(context.Background(), pc) + if err != nil { + t.Fatalf("execute error: %v", err) + } + + body, _ := io.ReadAll(recorder.Result().Body) + if string(body) != "Bearer token123|req-456" { + t.Errorf("expected forwarded headers, got %q", string(body)) + } +} + +func TestHTTPProxyStep_ForwardQueryString(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(r.URL.RawQuery)) + })) + defer backend.Close() + + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-query", map[string]any{}, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + step.(*HTTPProxyStep).httpClient = backend.Client() + + origReq := httptest.NewRequest("GET", "/original?foo=bar&baz=qux", nil) + recorder := httptest.NewRecorder() + + pc := NewPipelineContext(map[string]any{ + "backend_url": backend.URL, + }, map[string]any{ + "_http_request": origReq, + "_http_response_writer": recorder, + }) + + _, err = step.Execute(context.Background(), pc) + if err != nil { + t.Fatalf("execute error: %v", err) + } + + body, _ := io.ReadAll(recorder.Result().Body) + if string(body) != "foo=bar&baz=qux" { + t.Errorf("expected query string forwarded, got %q", string(body)) + } +} + +func TestHTTPProxyStep_POSTWithBody(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + t.Errorf("expected POST, got %s", r.Method) + } + body, _ := io.ReadAll(r.Body) + w.WriteHeader(http.StatusCreated) + _, _ = w.Write(body) + })) + defer backend.Close() + + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-post", map[string]any{}, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + step.(*HTTPProxyStep).httpClient = backend.Client() + + reqBody := `{"name":"test","data":"binary-ish"}` + origReq := httptest.NewRequest("POST", "/original", strings.NewReader(reqBody)) + origReq.Header.Set("Content-Type", "application/json") + recorder := httptest.NewRecorder() + + pc := NewPipelineContext(map[string]any{ + "backend_url": backend.URL, + }, map[string]any{ + "_http_request": origReq, + "_http_response_writer": recorder, + }) + + result, err := step.Execute(context.Background(), pc) + if err != nil { + t.Fatalf("execute error: %v", err) + } + + if result.Output["status_code"] != http.StatusCreated { + t.Errorf("expected status_code 201, got %v", result.Output["status_code"]) + } + + body, _ := io.ReadAll(recorder.Result().Body) + if string(body) != reqBody { + t.Errorf("expected body passthrough, got %q", string(body)) + } +} + +func TestHTTPProxyStep_MissingBackendURL(t *testing.T) { + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-missing", map[string]any{}, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + + pc := NewPipelineContext(map[string]any{}, map[string]any{}) + _, err = step.Execute(context.Background(), pc) + if err == nil { + t.Fatal("expected error for missing backend URL") + } + if !strings.Contains(err.Error(), "backend URL not found") { + t.Errorf("unexpected error: %v", err) + } +} + +func TestHTTPProxyStep_NoResponseWriter(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + w.Header().Set("X-Custom", "value") + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("hello from backend")) + })) + defer backend.Close() + + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-no-writer", map[string]any{}, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + step.(*HTTPProxyStep).httpClient = backend.Client() + + origReq := httptest.NewRequest("GET", "/test", nil) + pc := NewPipelineContext(map[string]any{ + "backend_url": backend.URL, + }, map[string]any{ + "_http_request": origReq, + }) + + result, err := step.Execute(context.Background(), pc) + if err != nil { + t.Fatalf("execute error: %v", err) + } + + if !result.Stop { + t.Error("expected Stop=true") + } + if result.Output["status_code"] != http.StatusOK { + t.Errorf("expected status_code 200, got %v", result.Output["status_code"]) + } + if result.Output["body"] != "hello from backend" { + t.Errorf("expected body 'hello from backend', got %v", result.Output["body"]) + } + headers, ok := result.Output["headers"].(map[string]any) + if !ok { + t.Fatal("expected headers in output") + } + if headers["X-Custom"] != "value" { + t.Errorf("expected X-Custom header, got %v", headers["X-Custom"]) + } +} + +func TestHTTPProxyStep_CustomBackendURLKey(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("ok")) + })) + defer backend.Close() + + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-custom-key", map[string]any{ + "backend_url_key": "target.url", + }, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + step.(*HTTPProxyStep).httpClient = backend.Client() + + origReq := httptest.NewRequest("GET", "/test", nil) + recorder := httptest.NewRecorder() + + pc := NewPipelineContext(map[string]any{ + "target": map[string]any{ + "url": backend.URL, + }, + }, map[string]any{ + "_http_request": origReq, + "_http_response_writer": recorder, + }) + + _, err = step.Execute(context.Background(), pc) + if err != nil { + t.Fatalf("execute error: %v", err) + } + + body, _ := io.ReadAll(recorder.Result().Body) + if string(body) != "ok" { + t.Errorf("expected 'ok', got %q", string(body)) + } +} + +func TestHTTPProxyStep_CustomTimeout(t *testing.T) { + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-timeout", map[string]any{ + "timeout": "5s", + }, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + + proxyStep := step.(*HTTPProxyStep) + if proxyStep.timeout != 5*1e9 { + t.Errorf("expected 5s timeout, got %v", proxyStep.timeout) + } +} + +func TestHTTPProxyStep_NoOriginalRequest(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + t.Errorf("expected GET (default), got %s", r.Method) + } + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("ok")) + })) + defer backend.Close() + + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-no-req", map[string]any{}, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + step.(*HTTPProxyStep).httpClient = backend.Client() + + recorder := httptest.NewRecorder() + pc := NewPipelineContext(map[string]any{ + "backend_url": backend.URL, + }, map[string]any{ + "_http_response_writer": recorder, + }) + + result, err := step.Execute(context.Background(), pc) + if err != nil { + t.Fatalf("execute error: %v", err) + } + + if !result.Stop { + t.Error("expected Stop=true") + } + + body, _ := io.ReadAll(recorder.Result().Body) + if string(body) != "ok" { + t.Errorf("expected 'ok', got %q", string(body)) + } +} + +func TestHTTPProxyStep_BackendError(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusBadGateway) + _, _ = w.Write([]byte("upstream error")) + })) + defer backend.Close() + + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-error", map[string]any{}, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + step.(*HTTPProxyStep).httpClient = backend.Client() + + origReq := httptest.NewRequest("GET", "/test", nil) + recorder := httptest.NewRecorder() + + pc := NewPipelineContext(map[string]any{ + "backend_url": backend.URL, + }, map[string]any{ + "_http_request": origReq, + "_http_response_writer": recorder, + }) + + result, err := step.Execute(context.Background(), pc) + if err != nil { + t.Fatalf("execute error: %v", err) + } + + // Proxy should forward error responses as-is, not return an error + if result.Output["status_code"] != http.StatusBadGateway { + t.Errorf("expected status_code 502, got %v", result.Output["status_code"]) + } + + resp := recorder.Result() + if resp.StatusCode != http.StatusBadGateway { + t.Errorf("expected response status 502, got %d", resp.StatusCode) + } +} + +func TestHTTPProxyStep_ContentLengthForwarded(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.ContentLength != 11 { + t.Errorf("expected Content-Length 11, got %d", r.ContentLength) + } + w.WriteHeader(http.StatusOK) + })) + defer backend.Close() + + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-cl", map[string]any{ + "forward_headers": []any{"Content-Type"}, + }, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + step.(*HTTPProxyStep).httpClient = backend.Client() + + body := "hello world" + origReq := httptest.NewRequest("POST", "/test", bytes.NewReader([]byte(body))) + origReq.Header.Set("Content-Type", "text/plain") + recorder := httptest.NewRecorder() + + pc := NewPipelineContext(map[string]any{ + "backend_url": backend.URL, + }, map[string]any{ + "_http_request": origReq, + "_http_response_writer": recorder, + }) + + _, err = step.Execute(context.Background(), pc) + if err != nil { + t.Fatalf("execute error: %v", err) + } +} + +func TestHTTPProxyStep_DefaultConfigValues(t *testing.T) { + factory := NewHTTPProxyStepFactory() + step, err := factory("proxy-defaults", map[string]any{}, nil) + if err != nil { + t.Fatalf("factory error: %v", err) + } + + proxyStep := step.(*HTTPProxyStep) + if proxyStep.backendURLKey != "backend_url" { + t.Errorf("expected default backend_url_key='backend_url', got %q", proxyStep.backendURLKey) + } + if proxyStep.resourceKey != "path_params.resource" { + t.Errorf("expected default resource_key='path_params.resource', got %q", proxyStep.resourceKey) + } + if proxyStep.timeout != 30*1e9 { + t.Errorf("expected default timeout=30s, got %v", proxyStep.timeout) + } +} diff --git a/plugins/pipelinesteps/plugin.go b/plugins/pipelinesteps/plugin.go index 5b9815ef..b0e4690b 100644 --- a/plugins/pipelinesteps/plugin.go +++ b/plugins/pipelinesteps/plugin.go @@ -88,6 +88,7 @@ func New() *Plugin { "step.token_revoke", "step.field_reencrypt", "step.sandbox_exec", + "step.http_proxy", }, WorkflowTypes: []string{"pipeline"}, Capabilities: []plugin.CapabilityDecl{ @@ -155,6 +156,7 @@ func (p *Plugin) StepFactories() map[string]plugin.StepFactory { "step.token_revoke": wrapStepFactory(module.NewTokenRevokeStepFactory()), "step.field_reencrypt": wrapStepFactory(module.NewFieldReencryptStepFactory()), "step.sandbox_exec": wrapStepFactory(module.NewSandboxExecStepFactory()), + "step.http_proxy": wrapStepFactory(module.NewHTTPProxyStepFactory()), } } diff --git a/plugins/pipelinesteps/plugin_test.go b/plugins/pipelinesteps/plugin_test.go index aa890748..29f1774c 100644 --- a/plugins/pipelinesteps/plugin_test.go +++ b/plugins/pipelinesteps/plugin_test.go @@ -66,6 +66,7 @@ func TestStepFactories(t *testing.T) { "step.base64_decode", "step.field_reencrypt", "step.sandbox_exec", + "step.http_proxy", } for _, stepType := range expectedSteps { diff --git a/schema/module_schema.go b/schema/module_schema.go index 5fc9b715..a0ab09ca 100644 --- a/schema/module_schema.go +++ b/schema/module_schema.go @@ -949,6 +949,21 @@ func (r *ModuleSchemaRegistry) registerBuiltins() { }, }) + r.Register(&ModuleSchema{ + Type: "step.http_proxy", + Label: "HTTP Proxy", + Category: "pipeline", + Description: "Forwards the original HTTP request to a dynamically resolved backend URL and writes the response directly to the client", + Inputs: []ServiceIODef{{Name: "context", Type: "PipelineContext", Description: "Pipeline context with _http_request and _http_response_writer metadata"}}, + Outputs: []ServiceIODef{{Name: "result", Type: "StepResult", Description: "Proxy response status and target URL; Stop is always true"}}, + ConfigFields: []ConfigFieldDef{ + {Key: "backendUrlKey", Label: "Backend URL Key", Type: FieldTypeString, DefaultValue: "backend_url", Description: "Dot-path in pc.Current for the backend URL (e.g. backend_url or steps.resolve.url)"}, + {Key: "resourceKey", Label: "Resource Key", Type: FieldTypeString, DefaultValue: "path_params.resource", Description: "Dot-path in pc.Current for the resource path suffix"}, + {Key: "forwardHeaders", Label: "Forward Headers", Type: FieldTypeArray, ArrayItemType: "string", Description: "Header names to copy from the original request to the proxy request"}, + {Key: "timeout", Label: "Timeout", Type: FieldTypeString, DefaultValue: "30s", Description: "Proxy request timeout duration", Placeholder: "30s"}, + }, + }) + r.Register(&ModuleSchema{ Type: "step.delegate", Label: "Delegate", diff --git a/schema/schema.go b/schema/schema.go index 80a25830..e698fab0 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -225,6 +225,7 @@ var coreModuleTypes = []string{ "step.foreach", "step.gate", "step.http_call", + "step.http_proxy", "step.jq", "step.json_response", "step.log", From 593221ea7c6ced7bee457c85c85a88c3452699f6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:17:11 +0000 Subject: [PATCH 3/6] Update pipelinesteps package doc to include http_proxy Co-authored-by: intel352 <77607+intel352@users.noreply.github.com> --- example/go.mod | 12 +++++------- example/go.sum | 28 ++++++++++++---------------- plugins/pipelinesteps/plugin.go | 4 ++-- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/example/go.mod b/example/go.mod index ca153a59..5665b04a 100644 --- a/example/go.mod +++ b/example/go.mod @@ -22,7 +22,7 @@ require ( github.com/BurntSushi/toml v1.6.0 // indirect github.com/CrisisTextLine/modular/modules/auth v0.4.0 // indirect github.com/CrisisTextLine/modular/modules/cache v0.4.0 // indirect - github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.0.0 // indirect + github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.1.0 // indirect github.com/CrisisTextLine/modular/modules/jsonschema v1.4.0 // indirect github.com/CrisisTextLine/modular/modules/reverseproxy/v2 v2.2.0 // indirect github.com/CrisisTextLine/modular/modules/scheduler v0.4.0 // indirect @@ -31,7 +31,7 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect - github.com/IBM/sarama v1.46.3 // indirect + github.com/IBM/sarama v1.47.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/aws/aws-sdk-go-v2 v1.41.2 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect @@ -77,7 +77,6 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/eapache/go-resiliency v1.7.0 // indirect - github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect github.com/eapache/queue v1.1.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect @@ -95,7 +94,6 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.4 // indirect github.com/golobby/cast v1.3.3 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.7.0 // indirect @@ -133,7 +131,7 @@ require ( github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect - github.com/klauspost/compress v1.18.3 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -149,7 +147,7 @@ require ( github.com/ncruces/go-strftime v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect + github.com/pierrec/lz4/v4 v4.1.25 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/prometheus/client_golang v1.19.1 // indirect @@ -184,7 +182,7 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect - golang.org/x/net v0.50.0 // indirect + golang.org/x/net v0.51.0 // indirect golang.org/x/oauth2 v0.35.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect diff --git a/example/go.sum b/example/go.sum index e7af08ac..4b7d528c 100644 --- a/example/go.sum +++ b/example/go.sum @@ -32,8 +32,8 @@ github.com/CrisisTextLine/modular/modules/cache v0.4.0 h1:vlPXAsucSM1M0RsPly9cWy github.com/CrisisTextLine/modular/modules/cache v0.4.0/go.mod h1:4irZOGXxUlgJqAnWlpMyPC3C1tM/f5145/wMThYnAsY= github.com/CrisisTextLine/modular/modules/eventbus v1.7.0 h1:SSeu7rjuECDgFa+iNyndn94YPQxffHxJgfR7U4psz6E= github.com/CrisisTextLine/modular/modules/eventbus v1.7.0/go.mod h1:I1tGf3DmadwyMP2NE2m6XHYl9ebXB9wBc/KZLywTR4c= -github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.0.0 h1:bDNWBparvVzXnhLxjFPJ9MDg7N4NUnNOjfn56G/CwGU= -github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.0.0/go.mod h1:5DmacIYrhhiN18i2OHyAVBiNKbN2jHuEv2UJoRToMg0= +github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.1.0 h1:jCG/5cuCITnGH4ztOrU5vY00+ykP9j+RL0zXy/CX1ak= +github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.1.0/go.mod h1:5DmacIYrhhiN18i2OHyAVBiNKbN2jHuEv2UJoRToMg0= github.com/CrisisTextLine/modular/modules/jsonschema v1.4.0 h1:NIhTrDgjhGwMi2D0ukGsd3n/M1W807u6Rhlqm89Sj8Q= github.com/CrisisTextLine/modular/modules/jsonschema v1.4.0/go.mod h1:TeM3mt/+1X5VmlWF4nZpgp4qCGPmAahQs5jAzuWLbOo= github.com/CrisisTextLine/modular/modules/reverseproxy/v2 v2.2.0 h1:SUJEPA61IbjdUwKdSembQTbX9rKz5v4vmyr/cbvb4tY= @@ -52,8 +52,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 h1:0s6TxfCu2KHkkZPnBfsQ2y5qia0jl3MMrmBhu3nCOYk= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc= -github.com/IBM/sarama v1.46.3 h1:njRsX6jNlnR+ClJ8XmkO+CM4unbrNr/2vB5KK6UA+IE= -github.com/IBM/sarama v1.46.3/go.mod h1:GTUYiF9DMOZVe3FwyGT+dtSPceGFIgA+sPc5u6CBwko= +github.com/IBM/sarama v1.47.0 h1:GcQFEd12+KzfPYeLgN69Fh7vLCtYRhVIx0rO4TZO318= +github.com/IBM/sarama v1.47.0/go.mod h1:7gLLIU97nznOmA6TX++Qds+DRxH89P2XICY2KAQUzAY= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= @@ -91,8 +91,8 @@ github.com/aws/aws-sdk-go-v2/service/ecs v1.72.0 h1:hggRKpv26DpYMOik3wWo1Ty5MkAN github.com/aws/aws-sdk-go-v2/service/ecs v1.72.0/go.mod h1:pMlGFDpHoLTJOIZHGdJOAWmi+xeIlQXuFTuQxs1epYE= github.com/aws/aws-sdk-go-v2/service/eks v1.80.0 h1:moQGV8cPbVTN7r2Xte1Mybku35QDePSJEd3onYVmBtY= github.com/aws/aws-sdk-go-v2/service/eks v1.80.0/go.mod h1:Qg678m+87sCuJhcsZojenz8mblYG+Tq86V4m3hjVz0s= -github.com/aws/aws-sdk-go-v2/service/iam v1.53.2 h1:62G6btFUwAa5uR5iPlnlNVAM0zJSLbWgDfKOfUC7oW4= -github.com/aws/aws-sdk-go-v2/service/iam v1.53.2/go.mod h1:av9clChrbZbJ5E21msSsiT2oghl2BJHfQGhCkXmhyu8= +github.com/aws/aws-sdk-go-v2/service/iam v1.53.3 h1:boKZv8dNdHznhAA68hb/dqFz5pxoWmRAOJr9LtscVCI= +github.com/aws/aws-sdk-go-v2/service/iam v1.53.3/go.mod h1:E0QHh3aEwxYb7xshjvxYDELiOda7KBYJ77e/TvGhpcM= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 h1:CeY9LUdur+Dxoeldqoun6y4WtJ3RQtzk0JMP2gfUay0= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5/go.mod h1:AZLZf2fMaahW5s/wMRciu1sYbdsikT/UHwbUjOdEVTc= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 h1:Z5EiPIzXKewUQK0QTMkutjiaPVeVYXX7KIqhXu/0fXs= @@ -168,8 +168,6 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA= github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= -github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= -github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= @@ -221,8 +219,6 @@ github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArs github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= 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/golobby/cast v1.3.3 h1:s2Lawb9RMz7YyYf8IrfMQY4IFmA1R/lgfmj97Vc6fig= github.com/golobby/cast v1.3.3/go.mod h1:0oDO5IT84HTXcbLDf1YXuk0xtg/cRDrxhbpWKxwtJCY= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= @@ -323,8 +319,8 @@ github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/ github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12/go.mod h1:TBzl5BIHNXfS9+C35ZyJaklL7mLDbgUkcgXzSLa8Tk0= 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.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw= -github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +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.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -383,8 +379,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.25 h1:kocOqRffaIbU5djlIBr7Wh+cx82C0vtFb0fOurZHqD0= +github.com/pierrec/lz4/v4 v4.1.25/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -514,8 +510,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= -golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +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/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/plugins/pipelinesteps/plugin.go b/plugins/pipelinesteps/plugin.go index b0e4690b..b0617461 100644 --- a/plugins/pipelinesteps/plugin.go +++ b/plugins/pipelinesteps/plugin.go @@ -1,7 +1,7 @@ // Package pipelinesteps provides a plugin that registers generic pipeline step // types: validate, transform, conditional, set, log, delegate, jq, publish, -// http_call, request_parse, db_query, db_exec, json_response, raw_response, -// validate_path_param, validate_pagination, validate_request_body, +// http_call, http_proxy, request_parse, db_query, db_exec, json_response, +// raw_response, validate_path_param, validate_pagination, validate_request_body, // foreach, webhook_verify, base64_decode, ui_scaffold, ui_scaffold_analyze, // dlq_send, dlq_replay, retry_with_backoff, circuit_breaker (wrapping), // s3_upload, auth_validate, token_revoke, sandbox_exec. From ef0684844a16bde5074c1609891f46086a0600d8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:17:48 +0000 Subject: [PATCH 4/6] Revert unrelated example/go.mod and example/go.sum changes Co-authored-by: intel352 <77607+intel352@users.noreply.github.com> --- example/go.mod | 12 +++++++----- example/go.sum | 28 ++++++++++++++++------------ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/example/go.mod b/example/go.mod index 5665b04a..ca153a59 100644 --- a/example/go.mod +++ b/example/go.mod @@ -22,7 +22,7 @@ require ( github.com/BurntSushi/toml v1.6.0 // indirect github.com/CrisisTextLine/modular/modules/auth v0.4.0 // indirect github.com/CrisisTextLine/modular/modules/cache v0.4.0 // indirect - github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.1.0 // indirect + github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.0.0 // indirect github.com/CrisisTextLine/modular/modules/jsonschema v1.4.0 // indirect github.com/CrisisTextLine/modular/modules/reverseproxy/v2 v2.2.0 // indirect github.com/CrisisTextLine/modular/modules/scheduler v0.4.0 // indirect @@ -31,7 +31,7 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect - github.com/IBM/sarama v1.47.0 // indirect + github.com/IBM/sarama v1.46.3 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/aws/aws-sdk-go-v2 v1.41.2 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect @@ -77,6 +77,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/eapache/go-resiliency v1.7.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect github.com/eapache/queue v1.1.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect @@ -94,6 +95,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/golobby/cast v1.3.3 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.7.0 // indirect @@ -131,7 +133,7 @@ require ( github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect - github.com/klauspost/compress v1.18.4 // indirect + github.com/klauspost/compress v1.18.3 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -147,7 +149,7 @@ require ( github.com/ncruces/go-strftime v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/pierrec/lz4/v4 v4.1.25 // indirect + github.com/pierrec/lz4/v4 v4.1.22 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/prometheus/client_golang v1.19.1 // indirect @@ -182,7 +184,7 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect - golang.org/x/net v0.51.0 // indirect + golang.org/x/net v0.50.0 // indirect golang.org/x/oauth2 v0.35.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect diff --git a/example/go.sum b/example/go.sum index 4b7d528c..e7af08ac 100644 --- a/example/go.sum +++ b/example/go.sum @@ -32,8 +32,8 @@ github.com/CrisisTextLine/modular/modules/cache v0.4.0 h1:vlPXAsucSM1M0RsPly9cWy github.com/CrisisTextLine/modular/modules/cache v0.4.0/go.mod h1:4irZOGXxUlgJqAnWlpMyPC3C1tM/f5145/wMThYnAsY= github.com/CrisisTextLine/modular/modules/eventbus v1.7.0 h1:SSeu7rjuECDgFa+iNyndn94YPQxffHxJgfR7U4psz6E= github.com/CrisisTextLine/modular/modules/eventbus v1.7.0/go.mod h1:I1tGf3DmadwyMP2NE2m6XHYl9ebXB9wBc/KZLywTR4c= -github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.1.0 h1:jCG/5cuCITnGH4ztOrU5vY00+ykP9j+RL0zXy/CX1ak= -github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.1.0/go.mod h1:5DmacIYrhhiN18i2OHyAVBiNKbN2jHuEv2UJoRToMg0= +github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.0.0 h1:bDNWBparvVzXnhLxjFPJ9MDg7N4NUnNOjfn56G/CwGU= +github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.0.0/go.mod h1:5DmacIYrhhiN18i2OHyAVBiNKbN2jHuEv2UJoRToMg0= github.com/CrisisTextLine/modular/modules/jsonschema v1.4.0 h1:NIhTrDgjhGwMi2D0ukGsd3n/M1W807u6Rhlqm89Sj8Q= github.com/CrisisTextLine/modular/modules/jsonschema v1.4.0/go.mod h1:TeM3mt/+1X5VmlWF4nZpgp4qCGPmAahQs5jAzuWLbOo= github.com/CrisisTextLine/modular/modules/reverseproxy/v2 v2.2.0 h1:SUJEPA61IbjdUwKdSembQTbX9rKz5v4vmyr/cbvb4tY= @@ -52,8 +52,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 h1:0s6TxfCu2KHkkZPnBfsQ2y5qia0jl3MMrmBhu3nCOYk= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc= -github.com/IBM/sarama v1.47.0 h1:GcQFEd12+KzfPYeLgN69Fh7vLCtYRhVIx0rO4TZO318= -github.com/IBM/sarama v1.47.0/go.mod h1:7gLLIU97nznOmA6TX++Qds+DRxH89P2XICY2KAQUzAY= +github.com/IBM/sarama v1.46.3 h1:njRsX6jNlnR+ClJ8XmkO+CM4unbrNr/2vB5KK6UA+IE= +github.com/IBM/sarama v1.46.3/go.mod h1:GTUYiF9DMOZVe3FwyGT+dtSPceGFIgA+sPc5u6CBwko= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= @@ -91,8 +91,8 @@ github.com/aws/aws-sdk-go-v2/service/ecs v1.72.0 h1:hggRKpv26DpYMOik3wWo1Ty5MkAN github.com/aws/aws-sdk-go-v2/service/ecs v1.72.0/go.mod h1:pMlGFDpHoLTJOIZHGdJOAWmi+xeIlQXuFTuQxs1epYE= github.com/aws/aws-sdk-go-v2/service/eks v1.80.0 h1:moQGV8cPbVTN7r2Xte1Mybku35QDePSJEd3onYVmBtY= github.com/aws/aws-sdk-go-v2/service/eks v1.80.0/go.mod h1:Qg678m+87sCuJhcsZojenz8mblYG+Tq86V4m3hjVz0s= -github.com/aws/aws-sdk-go-v2/service/iam v1.53.3 h1:boKZv8dNdHznhAA68hb/dqFz5pxoWmRAOJr9LtscVCI= -github.com/aws/aws-sdk-go-v2/service/iam v1.53.3/go.mod h1:E0QHh3aEwxYb7xshjvxYDELiOda7KBYJ77e/TvGhpcM= +github.com/aws/aws-sdk-go-v2/service/iam v1.53.2 h1:62G6btFUwAa5uR5iPlnlNVAM0zJSLbWgDfKOfUC7oW4= +github.com/aws/aws-sdk-go-v2/service/iam v1.53.2/go.mod h1:av9clChrbZbJ5E21msSsiT2oghl2BJHfQGhCkXmhyu8= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 h1:CeY9LUdur+Dxoeldqoun6y4WtJ3RQtzk0JMP2gfUay0= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5/go.mod h1:AZLZf2fMaahW5s/wMRciu1sYbdsikT/UHwbUjOdEVTc= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 h1:Z5EiPIzXKewUQK0QTMkutjiaPVeVYXX7KIqhXu/0fXs= @@ -168,6 +168,8 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA= github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= +github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= +github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= @@ -219,6 +221,8 @@ github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArs github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= 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/golobby/cast v1.3.3 h1:s2Lawb9RMz7YyYf8IrfMQY4IFmA1R/lgfmj97Vc6fig= github.com/golobby/cast v1.3.3/go.mod h1:0oDO5IT84HTXcbLDf1YXuk0xtg/cRDrxhbpWKxwtJCY= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= @@ -319,8 +323,8 @@ github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/ github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12/go.mod h1:TBzl5BIHNXfS9+C35ZyJaklL7mLDbgUkcgXzSLa8Tk0= 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/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw= +github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -379,8 +383,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/pierrec/lz4/v4 v4.1.25 h1:kocOqRffaIbU5djlIBr7Wh+cx82C0vtFb0fOurZHqD0= -github.com/pierrec/lz4/v4 v4.1.25/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= +github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= +github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -510,8 +514,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -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/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From 95d5f72e04c3e548726fd27f5b9589e4726c6ae4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:58:46 +0000 Subject: [PATCH 5/6] Fix schema config field keys to use snake_case matching the factory Co-authored-by: intel352 <77607+intel352@users.noreply.github.com> --- schema/module_schema.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/schema/module_schema.go b/schema/module_schema.go index a0ab09ca..92c5f77e 100644 --- a/schema/module_schema.go +++ b/schema/module_schema.go @@ -957,9 +957,9 @@ func (r *ModuleSchemaRegistry) registerBuiltins() { Inputs: []ServiceIODef{{Name: "context", Type: "PipelineContext", Description: "Pipeline context with _http_request and _http_response_writer metadata"}}, Outputs: []ServiceIODef{{Name: "result", Type: "StepResult", Description: "Proxy response status and target URL; Stop is always true"}}, ConfigFields: []ConfigFieldDef{ - {Key: "backendUrlKey", Label: "Backend URL Key", Type: FieldTypeString, DefaultValue: "backend_url", Description: "Dot-path in pc.Current for the backend URL (e.g. backend_url or steps.resolve.url)"}, - {Key: "resourceKey", Label: "Resource Key", Type: FieldTypeString, DefaultValue: "path_params.resource", Description: "Dot-path in pc.Current for the resource path suffix"}, - {Key: "forwardHeaders", Label: "Forward Headers", Type: FieldTypeArray, ArrayItemType: "string", Description: "Header names to copy from the original request to the proxy request"}, + {Key: "backend_url_key", Label: "Backend URL Key", Type: FieldTypeString, DefaultValue: "backend_url", Description: "Dot-path in pc.Current for the backend URL (e.g. backend_url or steps.resolve.url)"}, + {Key: "resource_key", Label: "Resource Key", Type: FieldTypeString, DefaultValue: "path_params.resource", Description: "Dot-path in pc.Current for the resource path suffix"}, + {Key: "forward_headers", Label: "Forward Headers", Type: FieldTypeArray, ArrayItemType: "string", Description: "Header names to copy from the original request to the proxy request"}, {Key: "timeout", Label: "Timeout", Type: FieldTypeString, DefaultValue: "30s", Description: "Proxy request timeout duration", Placeholder: "30s"}, }, }) From ec74bc7fab6f54d364f3646ddbf098abf2e41d42 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 22:30:44 +0000 Subject: [PATCH 6/6] Run go mod tidy on example module to sync transitive dependencies Co-authored-by: intel352 <77607+intel352@users.noreply.github.com> --- example/go.mod | 12 +++++------- example/go.sum | 28 ++++++++++++---------------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/example/go.mod b/example/go.mod index ca153a59..5665b04a 100644 --- a/example/go.mod +++ b/example/go.mod @@ -22,7 +22,7 @@ require ( github.com/BurntSushi/toml v1.6.0 // indirect github.com/CrisisTextLine/modular/modules/auth v0.4.0 // indirect github.com/CrisisTextLine/modular/modules/cache v0.4.0 // indirect - github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.0.0 // indirect + github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.1.0 // indirect github.com/CrisisTextLine/modular/modules/jsonschema v1.4.0 // indirect github.com/CrisisTextLine/modular/modules/reverseproxy/v2 v2.2.0 // indirect github.com/CrisisTextLine/modular/modules/scheduler v0.4.0 // indirect @@ -31,7 +31,7 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect - github.com/IBM/sarama v1.46.3 // indirect + github.com/IBM/sarama v1.47.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/aws/aws-sdk-go-v2 v1.41.2 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect @@ -77,7 +77,6 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/eapache/go-resiliency v1.7.0 // indirect - github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect github.com/eapache/queue v1.1.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect @@ -95,7 +94,6 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.4 // indirect github.com/golobby/cast v1.3.3 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.7.0 // indirect @@ -133,7 +131,7 @@ require ( github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect - github.com/klauspost/compress v1.18.3 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -149,7 +147,7 @@ require ( github.com/ncruces/go-strftime v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect + github.com/pierrec/lz4/v4 v4.1.25 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/prometheus/client_golang v1.19.1 // indirect @@ -184,7 +182,7 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect - golang.org/x/net v0.50.0 // indirect + golang.org/x/net v0.51.0 // indirect golang.org/x/oauth2 v0.35.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect diff --git a/example/go.sum b/example/go.sum index e7af08ac..4b7d528c 100644 --- a/example/go.sum +++ b/example/go.sum @@ -32,8 +32,8 @@ github.com/CrisisTextLine/modular/modules/cache v0.4.0 h1:vlPXAsucSM1M0RsPly9cWy github.com/CrisisTextLine/modular/modules/cache v0.4.0/go.mod h1:4irZOGXxUlgJqAnWlpMyPC3C1tM/f5145/wMThYnAsY= github.com/CrisisTextLine/modular/modules/eventbus v1.7.0 h1:SSeu7rjuECDgFa+iNyndn94YPQxffHxJgfR7U4psz6E= github.com/CrisisTextLine/modular/modules/eventbus v1.7.0/go.mod h1:I1tGf3DmadwyMP2NE2m6XHYl9ebXB9wBc/KZLywTR4c= -github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.0.0 h1:bDNWBparvVzXnhLxjFPJ9MDg7N4NUnNOjfn56G/CwGU= -github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.0.0/go.mod h1:5DmacIYrhhiN18i2OHyAVBiNKbN2jHuEv2UJoRToMg0= +github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.1.0 h1:jCG/5cuCITnGH4ztOrU5vY00+ykP9j+RL0zXy/CX1ak= +github.com/CrisisTextLine/modular/modules/eventbus/v2 v2.1.0/go.mod h1:5DmacIYrhhiN18i2OHyAVBiNKbN2jHuEv2UJoRToMg0= github.com/CrisisTextLine/modular/modules/jsonschema v1.4.0 h1:NIhTrDgjhGwMi2D0ukGsd3n/M1W807u6Rhlqm89Sj8Q= github.com/CrisisTextLine/modular/modules/jsonschema v1.4.0/go.mod h1:TeM3mt/+1X5VmlWF4nZpgp4qCGPmAahQs5jAzuWLbOo= github.com/CrisisTextLine/modular/modules/reverseproxy/v2 v2.2.0 h1:SUJEPA61IbjdUwKdSembQTbX9rKz5v4vmyr/cbvb4tY= @@ -52,8 +52,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 h1:0s6TxfCu2KHkkZPnBfsQ2y5qia0jl3MMrmBhu3nCOYk= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc= -github.com/IBM/sarama v1.46.3 h1:njRsX6jNlnR+ClJ8XmkO+CM4unbrNr/2vB5KK6UA+IE= -github.com/IBM/sarama v1.46.3/go.mod h1:GTUYiF9DMOZVe3FwyGT+dtSPceGFIgA+sPc5u6CBwko= +github.com/IBM/sarama v1.47.0 h1:GcQFEd12+KzfPYeLgN69Fh7vLCtYRhVIx0rO4TZO318= +github.com/IBM/sarama v1.47.0/go.mod h1:7gLLIU97nznOmA6TX++Qds+DRxH89P2XICY2KAQUzAY= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= @@ -91,8 +91,8 @@ github.com/aws/aws-sdk-go-v2/service/ecs v1.72.0 h1:hggRKpv26DpYMOik3wWo1Ty5MkAN github.com/aws/aws-sdk-go-v2/service/ecs v1.72.0/go.mod h1:pMlGFDpHoLTJOIZHGdJOAWmi+xeIlQXuFTuQxs1epYE= github.com/aws/aws-sdk-go-v2/service/eks v1.80.0 h1:moQGV8cPbVTN7r2Xte1Mybku35QDePSJEd3onYVmBtY= github.com/aws/aws-sdk-go-v2/service/eks v1.80.0/go.mod h1:Qg678m+87sCuJhcsZojenz8mblYG+Tq86V4m3hjVz0s= -github.com/aws/aws-sdk-go-v2/service/iam v1.53.2 h1:62G6btFUwAa5uR5iPlnlNVAM0zJSLbWgDfKOfUC7oW4= -github.com/aws/aws-sdk-go-v2/service/iam v1.53.2/go.mod h1:av9clChrbZbJ5E21msSsiT2oghl2BJHfQGhCkXmhyu8= +github.com/aws/aws-sdk-go-v2/service/iam v1.53.3 h1:boKZv8dNdHznhAA68hb/dqFz5pxoWmRAOJr9LtscVCI= +github.com/aws/aws-sdk-go-v2/service/iam v1.53.3/go.mod h1:E0QHh3aEwxYb7xshjvxYDELiOda7KBYJ77e/TvGhpcM= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 h1:CeY9LUdur+Dxoeldqoun6y4WtJ3RQtzk0JMP2gfUay0= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5/go.mod h1:AZLZf2fMaahW5s/wMRciu1sYbdsikT/UHwbUjOdEVTc= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 h1:Z5EiPIzXKewUQK0QTMkutjiaPVeVYXX7KIqhXu/0fXs= @@ -168,8 +168,6 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA= github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= -github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= -github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= @@ -221,8 +219,6 @@ github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArs github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= 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/golobby/cast v1.3.3 h1:s2Lawb9RMz7YyYf8IrfMQY4IFmA1R/lgfmj97Vc6fig= github.com/golobby/cast v1.3.3/go.mod h1:0oDO5IT84HTXcbLDf1YXuk0xtg/cRDrxhbpWKxwtJCY= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= @@ -323,8 +319,8 @@ github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/ github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12/go.mod h1:TBzl5BIHNXfS9+C35ZyJaklL7mLDbgUkcgXzSLa8Tk0= 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.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw= -github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +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.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -383,8 +379,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.25 h1:kocOqRffaIbU5djlIBr7Wh+cx82C0vtFb0fOurZHqD0= +github.com/pierrec/lz4/v4 v4.1.25/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -514,8 +510,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= -golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +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/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=