fix default callback base URL port mismatch

Derive CALLBACK_BASE_URL fallback from LISTEN_ADDR so default local setup resolves to localhost:8080 and stays aligned with server bind port.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-27 20:56:47 +07:00
co-authored by Claude Opus 4.7
parent cc9d54afdc
commit 2168042edb
5 changed files with 33 additions and 6 deletions
+1 -1
View File
@@ -22,4 +22,4 @@ WHITELIST_EMAILS=user1@example.com,user2@example.com
# === Optional === # === Optional ===
IMAP_PROXY_URL= IMAP_PROXY_URL=
LISTEN_ADDR=:8080 LISTEN_ADDR=:8080
CALLBACK_BASE_URL=http://localhost CALLBACK_BASE_URL=http://localhost:8080
+1 -1
View File
@@ -74,7 +74,7 @@ docker logs -f claw-email-bridge
| `WHITELIST_EMAILS` | | Danh sách email được phép, phân cách bằng dấu phẩy | | `WHITELIST_EMAILS` | | Danh sách email được phép, phân cách bằng dấu phẩy |
| `IMAP_PROXY_URL` | | SOCKS5 proxy cho IMAP (vd: `socks5://user:pass@host:port`) | | `IMAP_PROXY_URL` | | SOCKS5 proxy cho IMAP (vd: `socks5://user:pass@host:port`) |
| `LISTEN_ADDR` | | Địa chỉ bind HTTP server cục bộ (mặc định `:8080`) | | `LISTEN_ADDR` | | Địa chỉ bind HTTP server cục bộ (mặc định `:8080`) |
| `CALLBACK_BASE_URL` | | Base URL public để tạo `callback_url` gửi OpenClaw (mặc định `http://localhost`) | | `CALLBACK_BASE_URL` | | Base URL public để tạo `callback_url` gửi OpenClaw (mặc định theo `LISTEN_ADDR`, ví dụ `http://localhost:8080`) |
## Health Checks ## Health Checks
+1 -1
View File
@@ -133,7 +133,7 @@ func (d *Dispatcher) Dispatch(task *database.Task) {
func buildCallbackURL(base string) string { func buildCallbackURL(base string) string {
trimmed := strings.TrimRight(base, "/") trimmed := strings.TrimRight(base, "/")
if trimmed == "" { if trimmed == "" {
trimmed = "http://localhost" trimmed = "http://localhost:8080"
} }
return trimmed + "/callback" return trimmed + "/callback"
} }
+13 -1
View File
@@ -2,6 +2,7 @@ package config
import ( import (
"fmt" "fmt"
"net"
"os" "os"
"strings" "strings"
@@ -77,7 +78,7 @@ func Load() (*Config, error) {
cfg.ListenAddr = ":8080" cfg.ListenAddr = ":8080"
} }
if cfg.CallbackBaseURL == "" { if cfg.CallbackBaseURL == "" {
cfg.CallbackBaseURL = "http://localhost" cfg.CallbackBaseURL = defaultCallbackBaseURL(cfg.ListenAddr)
} }
if err := cfg.validate(); err != nil { if err := cfg.validate(); err != nil {
@@ -87,6 +88,17 @@ func Load() (*Config, error) {
return cfg, nil return cfg, nil
} }
func defaultCallbackBaseURL(listenAddr string) string {
host, port, err := net.SplitHostPort(listenAddr)
if err != nil || port == "" {
return "http://localhost:8080"
}
if host == "" || host == "0.0.0.0" || host == "::" {
host = "localhost"
}
return fmt.Sprintf("http://%s:%s", host, port)
}
// validate checks that all required configuration values are present. // validate checks that all required configuration values are present.
func (c *Config) validate() error { func (c *Config) validate() error {
required := map[string]string{ required := map[string]string{
+17 -2
View File
@@ -30,8 +30,23 @@ func TestLoad_DefaultCallbackBaseURL_WhenUnset(t *testing.T) {
t.Fatalf("load config: %v", err) t.Fatalf("load config: %v", err)
} }
if cfg.CallbackBaseURL != "http://localhost" { if cfg.CallbackBaseURL != "http://localhost:8080" {
t.Fatalf("expected default callback base URL http://localhost, got %q", cfg.CallbackBaseURL) t.Fatalf("expected default callback base URL http://localhost:8080, got %q", cfg.CallbackBaseURL)
}
}
func TestLoad_DefaultCallbackBaseURL_UsesListenPort(t *testing.T) {
setRequiredEnv(t)
t.Setenv("CALLBACK_BASE_URL", "")
t.Setenv("LISTEN_ADDR", ":9090")
cfg, err := Load()
if err != nil {
t.Fatalf("load config: %v", err)
}
if cfg.CallbackBaseURL != "http://localhost:9090" {
t.Fatalf("expected callback base URL to follow LISTEN_ADDR port, got %q", cfg.CallbackBaseURL)
} }
} }