Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
at HEAD 56 lines 1.4 kB view raw
1package hostutil 2 3import ( 4 "fmt" 5 "net/url" 6 "strings" 7 8 "github.com/bluesky-social/indigo/atproto/syntax" 9) 10 11func ParseHostname(raw string) (hostname string, noSSL bool, err error) { 12 // handle case of bare hostname 13 if !strings.Contains(raw, "://") { 14 if strings.HasPrefix(raw, "localhost:") { 15 raw = "http://" + raw 16 } else { 17 raw = "https://" + raw 18 } 19 } 20 21 u, err := url.Parse(raw) 22 if err != nil { 23 return "", false, fmt.Errorf("not a valid host URL: %w", err) 24 } 25 26 switch u.Scheme { 27 case "https", "wss": 28 noSSL = false 29 case "http", "ws": 30 noSSL = true 31 default: 32 return "", false, fmt.Errorf("unsupported URL scheme: %s", u.Scheme) 33 } 34 35 // 'localhost' (exact string) is allowed *with* a required port number; SSL is optional 36 if u.Hostname() == "localhost" { 37 if u.Port() == "" || !strings.HasPrefix(u.Host, "localhost:") { 38 return "", false, fmt.Errorf("port number is required for localhost") 39 } 40 return u.Host, noSSL, nil 41 } 42 43 // port numbers not allowed otherwise 44 if u.Port() != "" { 45 return "", false, fmt.Errorf("port number not allowed for non-local names") 46 } 47 48 // check it is a real hostname (eg, not IP address or single-word alias) 49 h, err := syntax.ParseHandle(u.Host) 50 if err != nil { 51 return "", false, fmt.Errorf("not a public hostname") 52 } 53 54 // lower-case in response 55 return h.Normalize().String(), noSSL, nil 56}