bootstrap.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package bootstrap
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "os/signal"
  8. "syscall"
  9. "time"
  10. )
  11. type customHandler func(h http.Handler) http.Handler
  12. type callbackBeforeAfter func(w http.ResponseWriter, r *http.Request, o interface{})
  13. type callbackServer func(s *http.Server)
  14. type bootstrap struct {
  15. path string
  16. before callbackBeforeAfter
  17. after callbackBeforeAfter
  18. object interface{}
  19. }
  20. func new(path string, before callbackBeforeAfter, after callbackBeforeAfter, object interface{}) *bootstrap {
  21. return &bootstrap{path, before, after, object}
  22. }
  23. func (this *bootstrap) handler(w http.ResponseWriter, r *http.Request) {
  24. if this.before != nil {
  25. this.before(w, r, this.object)
  26. }
  27. if r.URL.Path == "/"+this.path+"/bootstrap.css" {
  28. w.Header().Set("Cache-Control", "public, max-age=31536000")
  29. w.Header().Set("Content-Type", "text/css")
  30. w.Write(resource_bootstrap_css)
  31. return
  32. } else if r.URL.Path == "/"+this.path+"/bootstrap.js" {
  33. w.Header().Set("Cache-Control", "public, max-age=31536000")
  34. w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
  35. w.Write(resource_bootstrap_js)
  36. return
  37. } else if r.URL.Path == "/"+this.path+"/jquery.js" {
  38. w.Header().Set("Cache-Control", "public, max-age=31536000")
  39. w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
  40. w.Write(resource_jquery_js)
  41. return
  42. } else if r.URL.Path == "/"+this.path+"/popper.js" {
  43. w.Header().Set("Cache-Control", "public, max-age=31536000")
  44. w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
  45. w.Write(resource_popper_js)
  46. return
  47. }
  48. if this.after != nil {
  49. this.after(w, r, this.object)
  50. }
  51. }
  52. func Start(h customHandler, host string, timeout time.Duration, path string, before callbackBeforeAfter, after callbackBeforeAfter, cbserv callbackServer, object interface{}) {
  53. mux := http.NewServeMux()
  54. mux.HandleFunc("/", new(path, before, after, object).handler)
  55. var srv *http.Server
  56. if h == nil {
  57. srv = &http.Server{
  58. Addr: host,
  59. Handler: mux,
  60. }
  61. } else {
  62. srv = &http.Server{
  63. Addr: host,
  64. Handler: h(mux),
  65. }
  66. }
  67. if cbserv != nil {
  68. cbserv(srv)
  69. }
  70. stop := make(chan os.Signal)
  71. signal.Notify(stop, syscall.SIGTERM)
  72. signal.Notify(stop, syscall.SIGINT)
  73. go func() {
  74. fmt.Printf("Starting server at http://%s/\n", host)
  75. if err := srv.ListenAndServe(); err != nil {
  76. if err != http.ErrServerClosed {
  77. fmt.Println(err)
  78. stop <- os.Interrupt
  79. os.Exit(1)
  80. }
  81. }
  82. }()
  83. switch val := <-stop; val {
  84. case syscall.SIGTERM:
  85. fmt.Println("Shutting down server (terminate)...")
  86. case syscall.SIGINT:
  87. fmt.Println("Shutting down server (interrupt)...")
  88. default:
  89. fmt.Println("Shutting down server...")
  90. }
  91. ctx, cancel := context.WithTimeout(context.Background(), timeout*time.Second)
  92. defer cancel()
  93. if err := srv.Shutdown(ctx); err != nil {
  94. fmt.Println(err)
  95. os.Exit(1)
  96. }
  97. }