server.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package main
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "errors"
  6. "io/ioutil"
  7. "net/http"
  8. "net/url"
  9. )
  10. import (
  11. "github.com/fatih/color"
  12. log "github.com/sirupsen/logrus"
  13. "github.com/vulcand/oxy/forward"
  14. "github.com/vulcand/oxy/roundrobin"
  15. "golang.org/x/crypto/acme/autocert"
  16. )
  17. // Initialize the autocert manager and configure it,
  18. // also create an instance of the http.Server and link the autocert manager to it.
  19. func InitServer() error {
  20. m := autocert.Manager{
  21. Cache: autocert.DirCache(*STORAGE),
  22. Prompt: autocert.AcceptTOS,
  23. HostPolicy: func(ctx context.Context, host string) error {
  24. if _, ok := HOSTS[host]; ok {
  25. return nil
  26. }
  27. return errors.New("Unkown host(" + host + ")")
  28. },
  29. }
  30. _ = m
  31. s := &http.Server{
  32. Addr: *HTTPS_ADDR,
  33. TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
  34. Handler: ServeHTTP(),
  35. }
  36. log.SetOutput(ioutil.Discard)
  37. return s.ListenAndServeTLS("", "")
  38. }
  39. // The main server handler
  40. func ServeHTTP() http.Handler {
  41. return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
  42. if upstreams, ok := HOSTS[req.Host]; ok {
  43. forwarder, _ := forward.New(forward.PassHostHeader(true))
  44. loadbalancer, _ := roundrobin.New(forwarder)
  45. for _, upstream := range upstreams {
  46. if url, err := url.Parse(upstream); err == nil {
  47. loadbalancer.UpsertServer(url)
  48. } else {
  49. colorize(color.FgRed, "⇛", err.Error())
  50. }
  51. }
  52. res.Header().Set("X-HTTPSIFY-Version", VERSION)
  53. loadbalancer.ServeHTTP(res, req)
  54. return
  55. }
  56. http.Error(res, "The request service couldn't be found here", http.StatusNotImplemented)
  57. })
  58. }