Support separate bind address and server name#49
Conversation
Add --server-name flag to 'sth start' that controls the externally visible address while --host controls the actual bind address. Usage: sth start --host 0.0.0.0 --port 3939 --server-name 192.168.2.14 Closes #48
- Validate --server-name rejects spaces, slashes, colons, and protocol prefixes - Origins() now includes 127.0.0.1 as fallback when serverName is set - Add tests for domain serverName, empty string fallback, and validation
Replace denylist-based serverName validation with positive allowlist using net.ParseIP for IPs and hostname regex for domain names. Add boundary test cases for special characters, leading/trailing dots, and valid hostname patterns. Add HTTP-only scheme comment on Origin().
- Only accept IPv4 in isValidServerName to avoid generating invalid URLs (IPv6 addresses need bracket wrapping in URLs which is not supported) - Move ip := address.IP after serverName check in Origin() for clarity - Add IPv6 test cases to invalid serverName list
|
此变更集功能完整、测试覆盖充分,代码风格与现有代码一致。以下为新引入的更具体的发现: 可合并 本次 PR 新增 阻塞项:无建议项
|
|
发现遗漏 分析总结将 Issue #48 作为 spec 对比 PR 代码,发现以下遗漏: MEDIUM
LOW
|
- Reject consecutive dots in server names (e.g. a..b) in isValidServerName - Use serverName in session creation response URLs via serverBaseURL() - Add --bind as alias for --host per issue spec - Add test for serverName used in session URLs - Add a..b and host..domain.com to invalid test cases
|
发现遗漏 分析总结将 Issue #48 作为 spec,对比 PR 实现代码,发现以下遗漏: MEDIUM
LOW
|
|
可合并 总结PR 功能完整、测试覆盖充分,新增 阻塞项:无建议项
|
…-Proto, document --bind - serverBaseURL now uses actual listener port instead of configured port - serverBaseURL respects X-Forwarded-Proto header and TLS for scheme - Add comment explaining why '..' check is needed despite regex - Rename host variable to bindAddr in cli.go for clarity - Document --bind flag in usage string
|
可合并 本次 PR 新增 阻塞项:无 建议项:
|
…, improve regex - serverBaseURL omits port 80 (http) and 443 (https) in generated URLs - Extract determineScheme() for consistent scheme detection across baseURL and serverBaseURL - Improve hostnamePattern regex to natively reject consecutive dots - Warn when both --host and --bind are specified - Add unit tests for serverBaseURL port handling, fallback, and X-Forwarded-Proto
|
可合并 总览PR 新增 关键设计评价
阻塞项:无建议项
|
|
无遗漏 分析总结将 Issue #48 作为 spec 对比 PR 实现,所有需求均已覆盖: Spec 要求 vs 实现对照
此前 review 中发现的问题均已修复
PR 功能完整,spec 中所有需求均已实现,无遗漏。 |
…st, safe type assertion
|
无遗漏 将 Issue #48 作为 spec 对比 PR 实现,所有需求均已覆盖:
此前 review 中指出的 |
|
可合并 总结PR 新增 阻塞项:无建议项
|









Problem
--hostcontrols both the bind address and the externally-visible server name. When deploying on an internal machine that listens on0.0.0.0, generated links and CORS origins expose0.0.0.0or127.0.0.1instead of the actual LAN IP (e.g.192.168.2.14).Approach
Add a
--server-nameCLI flag that decouples the public hostname/IP from the bind address.internal/cli/cli.go: parse--server-namefrom flags, forward it toserver.New.internal/server/server.go:New()now accepts aserverNameparameter.isValidServerName()validates the value — accepts IPv4 addresses and hostnames matching^[a-zA-Z0-9]([a-zA-Z0-9.\-]*[a-zA-Z0-9])?$; rejects IPv6, URLs, and names with special characters.Origin()returnshttp://<serverName>:<port>when set, otherwise falls back to the listener address.Origins()returns a single-element slice with the server-name origin instead of expanding all interfaces.--server-name.Usage:
sth start --host 0.0.0.0 --port 3939 --server-name 192.168.2.14Tests
New tests in
internal/server/server_test.go:TestServerNameOverridesOrigin— verifiesOrigin()andOrigins()return the custom address.TestServerNameDomain— verifies hostname values likemyhost.localwork.TestServerNameEmptyFallsBack— verifies emptyserverNamepreserves existing behaviour.TestServerNameValidation— rejects 21 invalid inputs (spaces, slashes, IPv6, URLs, leading/trailing dots/hyphens, etc.).TestServerNameValidationAcceptsValid— accepts 10 valid inputs (IPv4, FQDN, short names, edge-case IPs).All existing tests updated to pass the new
serverNameparameter toNew().Closes #48