util.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package main
  2. import (
  3. "fmt"
  4. "net"
  5. "strings"
  6. "time"
  7. )
  8. // util.go —— 无状态的纯工具函数(便于单元测试与复用)。
  9. // isPortOpen 检测端口是否有监听者。
  10. func isPortOpen(host string, port int) bool {
  11. if host == "" {
  12. host = "127.0.0.1"
  13. }
  14. conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", host, port), 1200*time.Millisecond)
  15. if err != nil {
  16. return false
  17. }
  18. _ = conn.Close()
  19. return true
  20. }
  21. // extractHTTPURL 从一行输出里取出 http(s) URL(去除尾随分隔符)。
  22. func extractHTTPURL(line string) string {
  23. idx := strings.Index(line, "http")
  24. if idx < 0 {
  25. return ""
  26. }
  27. url := strings.TrimSpace(line[idx:])
  28. if i := strings.IndexAny(url, " "); i > 0 {
  29. url = url[:i]
  30. }
  31. if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
  32. return url
  33. }
  34. return ""
  35. }
  36. // humanDuration 简短的时长展示。
  37. func humanDuration(d time.Duration) string {
  38. if d <= 0 {
  39. return "0 秒"
  40. }
  41. sec := int(d.Seconds())
  42. switch {
  43. case sec < 60:
  44. return fmt.Sprintf("%d 秒", sec)
  45. case sec < 3600:
  46. return fmt.Sprintf("%d 分钟", sec/60)
  47. default:
  48. return fmt.Sprintf("%d 小时 %d 分", sec/3600, (sec%3600)/60)
  49. }
  50. }
  51. // shortURL 菜单标题只显示 origin,避免 token 撑爆标题。
  52. func shortURL(u string) string {
  53. if i := strings.Index(u, "?"); i > 0 {
  54. return u[:i]
  55. }
  56. return u
  57. }