added full URL for listening server
This commit is contained in:
@ -5,7 +5,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"supervisor/internal/config"
|
||||
@ -56,7 +58,7 @@ func New(cfg config.Config) (*App, error) {
|
||||
func (a *App) Run(ctx context.Context) error {
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
a.logger.Printf("HTTP server listening on %s", a.cfg.Addr)
|
||||
a.logServerURLs()
|
||||
errCh <- a.httpServer.ListenAndServe()
|
||||
}()
|
||||
|
||||
@ -73,3 +75,134 @@ func (a *App) Run(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) logServerURLs() {
|
||||
urls, err := serverURLs(a.cfg.Addr)
|
||||
if err != nil {
|
||||
a.logger.Printf("warning: determine local server URLs: %v", err)
|
||||
}
|
||||
if len(urls) == 0 {
|
||||
a.logger.Printf("HTTP server listening on %s", a.cfg.Addr)
|
||||
return
|
||||
}
|
||||
|
||||
a.logger.Print("HTTP server available at:")
|
||||
for _, url := range urls {
|
||||
a.logger.Printf(" %s", url)
|
||||
}
|
||||
}
|
||||
|
||||
func serverURLs(addr string) ([]string, error) {
|
||||
return serverURLsWithLocalIPv4Addrs(addr, discoverLocalIPv4Addrs)
|
||||
}
|
||||
|
||||
func serverURLsWithLocalIPv4Addrs(addr string, localIPv4Addrs func() ([]string, error)) ([]string, error) {
|
||||
host, port, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
urls := make([]string, 0, 4)
|
||||
seen := make(map[string]struct{})
|
||||
addURL := func(host string) {
|
||||
if host == "" {
|
||||
return
|
||||
}
|
||||
url := "http://" + net.JoinHostPort(host, port)
|
||||
if _, ok := seen[url]; ok {
|
||||
return
|
||||
}
|
||||
seen[url] = struct{}{}
|
||||
urls = append(urls, url)
|
||||
}
|
||||
|
||||
if isWildcardHost(host) {
|
||||
addURL("localhost")
|
||||
addURL("127.0.0.1")
|
||||
|
||||
addrs, err := localIPv4Addrs()
|
||||
for _, addr := range addrs {
|
||||
ip := net.ParseIP(addr)
|
||||
if !isUsableLocalIPv4(ip) {
|
||||
continue
|
||||
}
|
||||
addURL(ip.String())
|
||||
}
|
||||
return urls, err
|
||||
}
|
||||
|
||||
ip := net.ParseIP(host)
|
||||
if ip == nil {
|
||||
addURL(host)
|
||||
return urls, nil
|
||||
}
|
||||
if ip4 := ip.To4(); ip4 != nil && !ip4.IsUnspecified() {
|
||||
addURL(ip4.String())
|
||||
}
|
||||
return urls, nil
|
||||
}
|
||||
|
||||
func isWildcardHost(host string) bool {
|
||||
return host == "" || host == "0.0.0.0" || host == "::"
|
||||
}
|
||||
|
||||
func discoverLocalIPv4Addrs() ([]string, error) {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addrs := make([]string, 0)
|
||||
seen := make(map[string]struct{})
|
||||
for _, iface := range interfaces {
|
||||
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
ifaceAddrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return addrs, err
|
||||
}
|
||||
for _, ifaceAddr := range ifaceAddrs {
|
||||
ip := ipFromAddr(ifaceAddr)
|
||||
if !isUsableLocalIPv4(ip) {
|
||||
continue
|
||||
}
|
||||
|
||||
addr := ip.To4().String()
|
||||
if _, ok := seen[addr]; ok {
|
||||
continue
|
||||
}
|
||||
seen[addr] = struct{}{}
|
||||
addrs = append(addrs, addr)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(addrs)
|
||||
return addrs, nil
|
||||
}
|
||||
|
||||
func ipFromAddr(addr net.Addr) net.IP {
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
return v.IP
|
||||
case *net.IPAddr:
|
||||
return v.IP
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func isUsableLocalIPv4(ip net.IP) bool {
|
||||
if ip == nil {
|
||||
return false
|
||||
}
|
||||
ip4 := ip.To4()
|
||||
if ip4 == nil {
|
||||
return false
|
||||
}
|
||||
return !ip4.IsUnspecified() &&
|
||||
!ip4.IsLoopback() &&
|
||||
!ip4.IsMulticast() &&
|
||||
!ip4.IsLinkLocalUnicast()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user