bootstrap.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package bootstrap
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "time"
  8. "github.com/vladimirok5959/golang-ctrlc/ctrlc"
  9. )
  10. type customHandler func(h http.Handler) http.Handler
  11. type callbackBeforeAfter func(ctx context.Context, w http.ResponseWriter, r *http.Request, o interface{})
  12. type callbackServer func(s *http.Server)
  13. type Opts struct {
  14. Handle customHandler
  15. Host string
  16. Timeout time.Duration
  17. Path string
  18. Before callbackBeforeAfter
  19. After callbackBeforeAfter
  20. Cbserv callbackServer
  21. Object interface{}
  22. }
  23. type bootstrap struct {
  24. ctx context.Context
  25. opts *Opts
  26. }
  27. func new(ctx context.Context, opts *Opts) *bootstrap {
  28. return &bootstrap{ctx: ctx, opts: opts}
  29. }
  30. func (this *bootstrap) handler(w http.ResponseWriter, r *http.Request) {
  31. if this.opts.Before != nil {
  32. this.opts.Before(this.ctx, w, r, this.opts.Object)
  33. }
  34. if r.URL.Path == "/"+this.opts.Path+"/bootstrap.css" {
  35. w.Header().Set("Cache-Control", "public, max-age=31536000")
  36. w.Header().Set("Content-Type", "text/css")
  37. w.Write(resource_bootstrap_css)
  38. return
  39. } else if r.URL.Path == "/"+this.opts.Path+"/bootstrap.js" {
  40. w.Header().Set("Cache-Control", "public, max-age=31536000")
  41. w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
  42. w.Write(resource_bootstrap_js)
  43. return
  44. } else if r.URL.Path == "/"+this.opts.Path+"/jquery.js" {
  45. w.Header().Set("Cache-Control", "public, max-age=31536000")
  46. w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
  47. w.Write(resource_jquery_js)
  48. return
  49. } else if r.URL.Path == "/"+this.opts.Path+"/popper.js" {
  50. w.Header().Set("Cache-Control", "public, max-age=31536000")
  51. w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
  52. w.Write(resource_popper_js)
  53. return
  54. }
  55. if this.opts.After != nil {
  56. this.opts.After(this.ctx, w, r, this.opts.Object)
  57. }
  58. }
  59. func Start(opts *Opts) {
  60. if opts == nil {
  61. fmt.Println("Start: options is not defined")
  62. os.Exit(1)
  63. }
  64. ctrlc.App(
  65. opts.Timeout,
  66. func(ctx context.Context, shutdown context.CancelFunc) *[]ctrlc.Iface {
  67. mux := http.NewServeMux()
  68. mux.HandleFunc("/", new(ctx, opts).handler)
  69. var srv *http.Server
  70. if opts.Handle == nil {
  71. srv = &http.Server{
  72. Addr: opts.Host,
  73. Handler: mux,
  74. }
  75. } else {
  76. srv = &http.Server{
  77. Addr: opts.Host,
  78. Handler: opts.Handle(mux),
  79. }
  80. }
  81. if opts.Cbserv != nil {
  82. opts.Cbserv(srv)
  83. }
  84. go func() {
  85. fmt.Printf("Starting server at http://%s/\n", opts.Host)
  86. if err := srv.ListenAndServe(); err != nil {
  87. if err != http.ErrServerClosed {
  88. fmt.Printf("Web server startup error: %s\n", err.Error())
  89. shutdown()
  90. return
  91. }
  92. }
  93. }()
  94. return &[]ctrlc.Iface{srv}
  95. },
  96. )
  97. }