You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.0 KiB

  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build autocert
  5. // This file adds automatic TLS certificate support (using
  6. // golang.org/x/crypto/acme/autocert), conditional on the use of the
  7. // autocert build tag. It sets the serveAutoCertHook func variable
  8. // non-nil. It is used by main.go.
  9. //
  10. // TODO: make this the default? We're in the Go 1.8 freeze now, so
  11. // this is too invasive to be default, but we want it for
  12. // https://beta.golang.org/
  13. package main
  14. import (
  15. "crypto/tls"
  16. "flag"
  17. "net"
  18. "net/http"
  19. "time"
  20. "golang.org/x/crypto/acme/autocert"
  21. "golang.org/x/net/http2"
  22. )
  23. var (
  24. autoCertDirFlag = flag.String("autocert_cache_dir", "/var/cache/autocert", "Directory to cache TLS certs")
  25. autoCertHostFlag = flag.String("autocert_hostname", "", "optional hostname to require in autocert SNI requests")
  26. )
  27. func init() {
  28. serveAutoCertHook = serveAutoCert
  29. }
  30. func serveAutoCert(h http.Handler) error {
  31. m := autocert.Manager{
  32. Cache: autocert.DirCache(*autoCertDirFlag),
  33. Prompt: autocert.AcceptTOS,
  34. }
  35. if *autoCertHostFlag != "" {
  36. m.HostPolicy = autocert.HostWhitelist(*autoCertHostFlag)
  37. }
  38. srv := &http.Server{
  39. Handler: h,
  40. TLSConfig: &tls.Config{
  41. GetCertificate: m.GetCertificate,
  42. },
  43. IdleTimeout: 60 * time.Second,
  44. }
  45. http2.ConfigureServer(srv, &http2.Server{})
  46. ln, err := net.Listen("tcp", ":443")
  47. if err != nil {
  48. return err
  49. }
  50. return srv.Serve(tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, srv.TLSConfig))
  51. }
  52. // tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
  53. // connections. It's used by ListenAndServe and ListenAndServeTLS so
  54. // dead TCP connections (e.g. closing laptop mid-download) eventually
  55. // go away.
  56. type tcpKeepAliveListener struct {
  57. *net.TCPListener
  58. }
  59. func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
  60. tc, err := ln.AcceptTCP()
  61. if err != nil {
  62. return
  63. }
  64. tc.SetKeepAlive(true)
  65. tc.SetKeepAlivePeriod(3 * time.Minute)
  66. return tc, nil
  67. }