@@ -2,8 +2,8 @@ package runner
22
33import (
44 "context"
5- "crypto/tls"
65 "fmt"
6+ "log"
77 "net"
88 "net/http"
99 "os"
@@ -13,6 +13,7 @@ import (
1313 "time"
1414
1515 "github.com/gotify/server/v2/config"
16+ "golang.org/x/crypto/acme"
1617 "golang.org/x/crypto/acme/autocert"
1718)
1819
@@ -31,6 +32,8 @@ func Run(router http.Handler, conf *config.Configuration) error {
3132 if conf .Server .SSL .Enabled {
3233 if conf .Server .SSL .LetsEncrypt .Enabled {
3334 applyLetsEncrypt (s , conf )
35+ } else if conf .Server .SSL .CertFile != "" && conf .Server .SSL .CertKey != "" {
36+ log .Fatalf ("CertFile and CertKey must be set to use HTTPS when LetsEncrypt is disabled, please set GOTIFY_SERVER_SSL_CERTFILE and GOTIFY_SERVER_SSL_CERTKEY" )
3437 }
3538
3639 httpsListener , err := startListening ("TLS connection" , conf .Server .SSL .ListenAddr , conf .Server .SSL .Port , conf .Server .KeepAlivePeriodSeconds )
@@ -94,12 +97,43 @@ func getNetworkAndAddr(listenAddr string, port int) (string, string) {
9497 return "tcp" , fmt .Sprintf ("%s:%d" , listenAddr , port )
9598}
9699
100+ type LoggingRoundTripper struct {
101+ RoundTripper http.RoundTripper
102+ }
103+
104+ func (l * LoggingRoundTripper ) RoundTrip (r * http.Request ) (resp * http.Response , err error ) {
105+ log .Printf ("Let's Encrypt Client Request: %s %s\n " , r .Method , r .URL .String ())
106+ resp , err = l .RoundTripper .RoundTrip (r )
107+ if resp .StatusCode == 429 {
108+ log .Printf ("Let's Encrypt Client Rate Limited: Retry-After %s on %s %s\n " , resp .Header .Get ("Retry-After" ), r .Method , r .URL .String ())
109+ } else if resp .StatusCode >= 400 {
110+ log .Printf ("Let's Encrypt Client Request Failed: Unexpected status code %d on %s %s\n " , resp .StatusCode , r .Method , r .URL .String ())
111+ } else if err != nil {
112+ log .Printf ("Let's Encrypt Client Request Failed: %s on %s %s\n " , err .Error (), r .Method , r .URL .String ())
113+ }
114+ return
115+ }
116+
97117func applyLetsEncrypt (s * http.Server , conf * config.Configuration ) {
118+ httpClient := http .DefaultClient
119+ httpClient .Transport = & LoggingRoundTripper {RoundTripper : http .DefaultTransport }
120+ httpClient .Timeout = 60 * time .Second
121+
122+ acmeClient := & acme.Client {
123+ HTTPClient : httpClient ,
124+ DirectoryURL : conf .Server .SSL .LetsEncrypt .DirectoryURL ,
125+ }
98126 certManager := autocert.Manager {
99- Prompt : func (tosURL string ) bool { return conf .Server .SSL .LetsEncrypt .AcceptTOS },
127+ Client : acmeClient ,
128+ Prompt : func (tosURL string ) bool {
129+ if ! conf .Server .SSL .LetsEncrypt .AcceptTOS {
130+ log .Fatalf ("Let's Encrypt TOS must be accepted to use Let's Encrypt, please acknowledge TOS at %s and set GOTIFY_SERVER_SSL_LETSENCRYPT_ACCEPTTOS=true" , tosURL )
131+ }
132+ return true
133+ },
100134 HostPolicy : autocert .HostWhitelist (conf .Server .SSL .LetsEncrypt .Hosts ... ),
101135 Cache : autocert .DirCache (conf .Server .SSL .LetsEncrypt .Cache ),
102136 }
103137 s .Handler = certManager .HTTPHandler (s .Handler )
104- s .TLSConfig = & tls. Config { GetCertificate : certManager .GetCertificate }
138+ s .TLSConfig = certManager .TLSConfig ()
105139}
0 commit comments