9
9
"bytes"
10
10
"context"
11
11
"crypto/rand"
12
- "crypto/tls"
13
12
"embed"
14
13
"encoding/base64"
15
14
"encoding/json"
@@ -159,6 +158,7 @@ func Run() error {
159
158
return errors .New ("--hostname, if specified, cannot be empty" )
160
159
}
161
160
161
+ // create tsNet server and wait for it to be ready & connected.
162
162
srv := & tsnet.Server {
163
163
ControlURL : * controlURL ,
164
164
Hostname : * hostname ,
@@ -171,77 +171,65 @@ func Run() error {
171
171
return err
172
172
}
173
173
174
- // create tsNet server and wait for it to be ready & connected.
175
174
localClient , _ = srv .LocalClient ()
175
+ out:
176
+ for {
177
+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
178
+ defer cancel ()
179
+ status , err := srv .Up (ctx )
180
+ if err == nil && status != nil {
181
+ break out
182
+ }
183
+ }
184
+
176
185
ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
177
186
defer cancel ()
178
- _ , err = srv . Up (ctx )
187
+ status , err := localClient . Status (ctx )
179
188
if err != nil {
180
189
return err
181
190
}
191
+ enableTLS := status .Self .HasCap (tailcfg .CapabilityHTTPS )
192
+ dnsName := status .Self .DNSName
182
193
183
- enableTLS := len (srv .CertDomains ()) > 0
194
+ var httpHandler http.Handler
195
+ var httpsHandler http.Handler
184
196
if enableTLS {
185
- // warm the certificate cache for all cert domains to prevent users waiting
186
- // on ACME challenges in-line on their first request.
187
- for _ , d := range srv .CertDomains () {
188
- log .Printf ("Provisioning TLS certificate for %s ..." , d )
189
- ctx , cancel := context .WithTimeout (context .Background (), time .Minute )
190
- defer cancel ()
191
-
192
- _ , _ , err := localClient .CertPair (ctx , d )
193
- if err != nil {
194
- return err
195
- }
196
- }
197
+ redirectFqdn := strings .TrimSuffix (dnsName , "." )
198
+ httpHandler = redirectHandler (redirectFqdn )
199
+ httpsHandler = HSTS (serveHandler ())
200
+ } else {
201
+ httpHandler = serveHandler ()
202
+ httpsHandler = nil
203
+ }
197
204
198
- redirectFqdn := srv .CertDomains ()[0 ]
199
- // HTTP listener that redirects to our HTTPS listener.
200
- log .Println ("Listening on :80" )
201
- httpListener , err := srv .Listen ("tcp" , ":80" )
205
+ if httpsHandler != nil {
206
+ log .Println ("Listening on :443" )
207
+ httpsListener , err := srv .ListenTLS ("tcp" , ":443" )
202
208
if err != nil {
203
209
return err
204
210
}
205
211
go func () error {
206
- log .Printf ("Serving http ://%s/ ..." , * hostname )
207
- if err := http .Serve (httpListener , redirectHandler ( redirectFqdn ) ); err != nil {
212
+ log .Printf ("Serving https ://%s/ ..." , strings . TrimSuffix ( dnsName , "." ) )
213
+ if err := http .Serve (httpsListener , httpsHandler ); err != nil {
208
214
return err
209
215
}
210
216
return nil
211
217
}()
218
+ }
212
219
213
- log .Println ("Listening on :443" )
214
- httpsListener , err := srv .Listen ("tcp" , ":443" )
215
- if err != nil {
216
- return err
217
- }
218
- s := http.Server {
219
- Addr : ":443" ,
220
- Handler : HSTS (serveHandler ()),
221
- TLSConfig : & tls.Config {
222
- GetCertificate : localClient .GetCertificate ,
223
- },
224
- }
225
-
226
- log .Printf ("Serving https://%s/\n " , redirectFqdn )
227
- if err := s .ServeTLS (httpsListener , "" , "" ); err != nil {
228
- return err
229
- }
230
- return nil
231
- } else {
232
- // no TLS, just serve on :80
233
- log .Println ("Listening on :80" )
234
- httpListener , err := srv .Listen ("tcp" , ":80" )
235
- if err != nil {
236
- return err
237
- }
238
- log .Printf ("Serving http://%s/ ..." , * hostname )
239
- if err := http .Serve (httpListener , serveHandler ()); err != nil {
240
- return err
241
- }
242
- return nil
220
+ // HTTP handler that either serves primary handler or redirects to HTTPS
221
+ // depending on availability of TLS.
222
+ log .Println ("Listening on :80" )
223
+ httpListener , err := srv .Listen ("tcp" , ":80" )
224
+ if err != nil {
225
+ return err
226
+ }
227
+ log .Printf ("Serving http://%s/ ..." , * hostname )
228
+ if err := http .Serve (httpListener , httpHandler ); err != nil {
229
+ return err
243
230
}
244
231
232
+ return nil
245
233
}
246
234
247
235
var (
@@ -351,9 +339,7 @@ func deleteLinkStats(link *Link) {
351
339
// requests. It redirects all requests to the HTTPs version of the same URL.
352
340
func redirectHandler (hostname string ) http.Handler {
353
341
return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
354
- path := r .URL .Path
355
- newUrl := fmt .Sprintf ("https://%s%s" , hostname , path )
356
- http .Redirect (w , r , newUrl , http .StatusMovedPermanently )
342
+ http .Redirect (w , r , (& url.URL {Scheme : "https" , Host : hostname , Path : r .URL .Path }).String (), http .StatusMovedPermanently )
357
343
})
358
344
}
359
345
0 commit comments