go.etcd.io/etcd@v3.3.27+incompatible/pkg/types/urls.go (about) 1 // Copyright 2015 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package types 16 17 import ( 18 "errors" 19 "fmt" 20 "net" 21 "net/url" 22 "sort" 23 "strings" 24 ) 25 26 type URLs []url.URL 27 28 func NewURLs(strs []string) (URLs, error) { 29 all := make([]url.URL, len(strs)) 30 if len(all) == 0 { 31 return nil, errors.New("no valid URLs given") 32 } 33 for i, in := range strs { 34 in = strings.TrimSpace(in) 35 u, err := url.Parse(in) 36 if err != nil { 37 return nil, err 38 } 39 if u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "unix" && u.Scheme != "unixs" { 40 return nil, fmt.Errorf("URL scheme must be http, https, unix, or unixs: %s", in) 41 } 42 if _, _, err := net.SplitHostPort(u.Host); err != nil { 43 return nil, fmt.Errorf(`URL address does not have the form "host:port": %s`, in) 44 } 45 if u.Path != "" { 46 return nil, fmt.Errorf("URL must not contain a path: %s", in) 47 } 48 all[i] = *u 49 } 50 us := URLs(all) 51 us.Sort() 52 53 return us, nil 54 } 55 56 func MustNewURLs(strs []string) URLs { 57 urls, err := NewURLs(strs) 58 if err != nil { 59 panic(err) 60 } 61 return urls 62 } 63 64 func (us URLs) String() string { 65 return strings.Join(us.StringSlice(), ",") 66 } 67 68 func (us *URLs) Sort() { 69 sort.Sort(us) 70 } 71 func (us URLs) Len() int { return len(us) } 72 func (us URLs) Less(i, j int) bool { return us[i].String() < us[j].String() } 73 func (us URLs) Swap(i, j int) { us[i], us[j] = us[j], us[i] } 74 75 func (us URLs) StringSlice() []string { 76 out := make([]string, len(us)) 77 for i := range us { 78 out[i] = us[i].String() 79 } 80 81 return out 82 }