@@ -47,22 +47,39 @@ func ListenAndServe(handler http.Handler, opt *Options) error {
47
47
if err != nil {
48
48
return fmt .Errorf (`net.Listen("tcp", %q): %v` , opt .Addr , err )
49
49
}
50
+ defer ln .Close ()
51
+
52
+ if opt .AutocertCacheBucket == "" {
53
+ err := http .Serve (ln , handler )
54
+ ln .Close ()
55
+ return fmt .Errorf ("http.Serve = %v" , err )
56
+ }
50
57
58
+ // handler is served primarily via HTTPS, so just redirect HTTP to HTTPS.
59
+ redirect := & http.Server {
60
+ Addr : ln .Addr ().String (),
61
+ Handler : http .HandlerFunc (redirectToHTTPS ),
62
+ }
51
63
errc := make (chan error )
52
64
go func () {
53
- var h http.Handler
54
- if opt .AutocertCacheBucket != "" {
55
- // handler is served primarily via HTTPS, so just redirect HTTP to HTTPS.
56
- h = http .HandlerFunc (redirectToHTTPS )
57
- } else {
58
- h = handler
59
- }
60
- errc <- fmt .Errorf ("http.Serve = %v" , http .Serve (ln , h ))
65
+ err := redirect .Serve (ln )
66
+ errc <- fmt .Errorf ("http.Serve = %v" , err )
61
67
}()
62
- if opt .AutocertCacheBucket != "" {
63
- go func () { errc <- serveAutocertTLS (handler , opt .AutocertCacheBucket ) }()
64
- }
65
- return <- errc
68
+
69
+ ctx , cancel := context .WithCancel (context .TODO ())
70
+ go func () {
71
+ errc <- serveAutocertTLS (ctx , handler , opt .AutocertCacheBucket )
72
+ }()
73
+
74
+ // Wait for the first error.
75
+ err = <- errc
76
+
77
+ // Stop the other handler (whichever it may be) and wait for it to return.
78
+ redirect .Close ()
79
+ cancel ()
80
+ <- errc
81
+
82
+ return err
66
83
}
67
84
68
85
// redirectToHTTPS will redirect to the https version of the URL requested. If
@@ -80,13 +97,30 @@ func redirectToHTTPS(w http.ResponseWriter, r *http.Request) {
80
97
// for its autocert cache. It will only serve on domains of the form *.golang.org.
81
98
//
82
99
// serveAutocertTLS always returns a non-nil error.
83
- func serveAutocertTLS (h http.Handler , bucket string ) error {
100
+ func serveAutocertTLS (ctx context. Context , h http.Handler , bucket string ) error {
84
101
ln , err := net .Listen ("tcp" , ":443" )
85
102
if err != nil {
86
103
return err
87
104
}
88
105
defer ln .Close ()
89
- sc , err := storage .NewClient (context .Background ())
106
+
107
+ ctx , cancel := context .WithCancel (ctx )
108
+ server := & http.Server {
109
+ Addr : ln .Addr ().String (),
110
+ Handler : h ,
111
+ }
112
+ done := make (chan struct {})
113
+ go func () {
114
+ <- ctx .Done ()
115
+ server .Close ()
116
+ close (done )
117
+ }()
118
+ defer func () {
119
+ cancel ()
120
+ <- done
121
+ }()
122
+
123
+ sc , err := storage .NewClient (ctx )
90
124
if err != nil {
91
125
return fmt .Errorf ("storage.NewClient: %v" , err )
92
126
}
@@ -107,10 +141,6 @@ func serveAutocertTLS(h http.Handler, bucket string) error {
107
141
NextProtos : []string {"h2" , "http/1.1" },
108
142
}
109
143
tlsLn := tls .NewListener (tcpKeepAliveListener {ln .(* net.TCPListener )}, config )
110
- server := & http.Server {
111
- Addr : ln .Addr ().String (),
112
- Handler : h ,
113
- }
114
144
if err := http2 .ConfigureServer (server , nil ); err != nil {
115
145
return fmt .Errorf ("http2.ConfigureServer: %v" , err )
116
146
}
0 commit comments