ParseEndpoint parses an endpoint string into a structured format with separate scheme, host, port, and path portions, as well as the original input string.
(str string)
| 88 | // ParseEndpoint parses an endpoint string into a structured format with separate |
| 89 | // scheme, host, port, and path portions, as well as the original input string. |
| 90 | func ParseEndpoint(str string) (Endpoint, error) { |
| 91 | input := str |
| 92 | |
| 93 | u, err := url.Parse(str) |
| 94 | if err != nil { |
| 95 | return Endpoint{}, err |
| 96 | } |
| 97 | |
| 98 | switch u.Scheme { |
| 99 | case "tcp", "tls": |
| 100 | // ALL GREEN |
| 101 | |
| 102 | // scheme:OPAQUE URL syntax |
| 103 | if u.Host == "" && u.Opaque != "" { |
| 104 | u.Host = u.Opaque |
| 105 | } |
| 106 | case "unix": |
| 107 | // scheme:OPAQUE URL syntax |
| 108 | if u.Path == "" && u.Opaque != "" { |
| 109 | u.Path = u.Opaque |
| 110 | } |
| 111 | |
| 112 | var actualPath string |
| 113 | if u.Host != "" { |
| 114 | actualPath += u.Host |
| 115 | } |
| 116 | if u.Path != "" { |
| 117 | actualPath += u.Path |
| 118 | } |
| 119 | |
| 120 | if !filepath.IsAbs(actualPath) { |
| 121 | actualPath = filepath.Join(RuntimeDirectory, actualPath) |
| 122 | } |
| 123 | |
| 124 | return Endpoint{Original: input, Scheme: u.Scheme, Path: actualPath}, err |
| 125 | default: |
| 126 | return Endpoint{}, fmt.Errorf("unsupported scheme: %s (%+v)", input, u) |
| 127 | } |
| 128 | |
| 129 | // separate host and port |
| 130 | host, port, err := net.SplitHostPort(u.Host) |
| 131 | if err != nil { |
| 132 | host, port, err = net.SplitHostPort(u.Host + ":") |
| 133 | if err != nil { |
| 134 | host = u.Host |
| 135 | } |
| 136 | } |
| 137 | if port == "" { |
| 138 | return Endpoint{}, fmt.Errorf("port is required") |
| 139 | } |
| 140 | |
| 141 | return Endpoint{Original: input, Scheme: u.Scheme, Host: host, Port: port, Path: u.Path}, err |
| 142 | } |
no outgoing calls