This repository has been archived by the owner on Jun 5, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
uri.go
72 lines (66 loc) · 1.46 KB
/
uri.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package turn
import (
"errors"
"fmt"
"net/url"
"strconv"
)
// Scheme definitions from RFC 7065 Section 3.2.
const (
Scheme = "turn"
SchemeSecure = "turns"
)
// Transport definitions as in RFC 7065.
const (
TransportTCP = "tcp"
TransportUDP = "udp"
)
// URI as defined in RFC 7065.
type URI struct {
Scheme string
Host string
Port int
Transport string
}
func (u URI) String() string {
transportSuffix := ""
if len(u.Transport) > 0 {
transportSuffix = "?transport=" + u.Transport
}
if u.Port != 0 {
return fmt.Sprintf("%s:%s:%d%s",
u.Scheme, u.Host, u.Port, transportSuffix,
)
}
return u.Scheme + ":" + u.Host + transportSuffix
}
// ParseURI parses URI from string.
func ParseURI(rawURI string) (URI, error) {
// Carefully reusing URI parser from net/url.
u, urlParseErr := url.Parse(rawURI)
if urlParseErr != nil {
return URI{}, urlParseErr
}
if u.Scheme != Scheme && u.Scheme != SchemeSecure {
return URI{}, fmt.Errorf("unknown uri scheme %q", u.Scheme)
}
if u.Opaque == "" {
return URI{}, errors.New("invalid uri format: expected opaque")
}
// Using URL methods to split host.
u.Host = u.Opaque
host, rawPort := u.Hostname(), u.Port()
uri := URI{
Scheme: u.Scheme,
Host: host,
Transport: u.Query().Get("transport"),
}
if len(rawPort) > 0 {
port, portErr := strconv.Atoi(rawPort)
if portErr == nil {
// URL parser already verifies that port is integer.
uri.Port = port
}
}
return uri, nil
}