-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlistener.go
82 lines (76 loc) · 2.25 KB
/
listener.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
73
74
75
76
77
78
79
80
81
82
package webserv
import (
"crypto/tls"
"fmt"
"net"
"os"
)
const (
FullchainPem = "fullchain.pem"
PrivkeyPem = "privkey.pem"
)
// Listener creates a net.Listener given an optional preferred address or port
// and an optional directory containing certificate files.
//
// If certDir is not empty, it calls LoadCert to load fullchain.pem and privkey.pem.
//
// The listener will default to all addresses and standard port
// depending on privileges and if a certificate was loaded or not.
//
// These defaults can be overridden with the listenAddr argument.
//
// Returns the net.Listener and listenURL if there was no error.
// If certificates were successfully loaded, absCertDir will be the absolute path to that directory.
func Listener(listenAddr, certDir, fullchainPem, privkeyPem, overrideUrl string) (l net.Listener, listenUrl, absCertDir string, err error) {
var cert *tls.Certificate
if cert, absCertDir, err = LoadCert(certDir, fullchainPem, privkeyPem); err == nil {
var schemesuffix string
if cert != nil {
schemesuffix = "s"
l, err = tls.Listen("tcp", defaultAddress(listenAddr, ":443", ":8443"),
&tls.Config{
Certificates: []tls.Certificate{*cert},
MinVersion: tls.VersionTLS13,
},
)
} else {
l, err = net.Listen("tcp", defaultAddress(listenAddr, ":80", ":8080"))
}
if l != nil {
if listenUrl = overrideUrl; listenUrl == "" {
listenUrl = fmt.Sprintf("http%s://%s", schemesuffix, listenUrlString(l, cert))
}
}
}
return
}
func defaultAddress(address, defaultpriv, defaultother string) string {
if address == "" {
address = defaultpriv
if os.Geteuid() > 0 {
address = defaultother
}
}
return address
}
func localhostOrDNSName(cert *tls.Certificate) string {
if cert != nil && cert.Leaf != nil && len(cert.Leaf.DNSNames) > 0 {
name := cert.Leaf.DNSNames[0]
if host, _, err := net.SplitHostPort(name); err == nil {
name = host
}
return name
}
return "localhost"
}
func listenUrlString(l net.Listener, cert *tls.Certificate) (addr string) {
addr = l.Addr().String()
if host, port, err := net.SplitHostPort(addr); err == nil {
if ip := net.ParseIP(host); ip != nil {
if ip.IsUnspecified() || ip.IsLoopback() {
addr = net.JoinHostPort(localhostOrDNSName(cert), port)
}
}
}
return
}