blob: 9e5d03ff6457bdb683fa2498009ac8fbec882097 [file] [log] [blame]
William Kurkianea869482019-04-09 15:16:11 -04001// 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
15package types
16
17import (
18 "errors"
19 "fmt"
20 "net"
21 "net/url"
22 "sort"
23 "strings"
24)
25
26type URLs []url.URL
27
28func 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
56func MustNewURLs(strs []string) URLs {
57 urls, err := NewURLs(strs)
58 if err != nil {
59 panic(err)
60 }
61 return urls
62}
63
64func (us URLs) String() string {
65 return strings.Join(us.StringSlice(), ",")
66}
67
68func (us *URLs) Sort() {
69 sort.Sort(us)
70}
71func (us URLs) Len() int { return len(us) }
72func (us URLs) Less(i, j int) bool { return us[i].String() < us[j].String() }
73func (us URLs) Swap(i, j int) { us[i], us[j] = us[j], us[i] }
74
75func (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}