main.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package main
  2. import (
  3. "context"
  4. "errors"
  5. "flag"
  6. "fmt"
  7. "log"
  8. "net/http"
  9. "os"
  10. "os/signal"
  11. "strconv"
  12. "strings"
  13. "time"
  14. "golang-fave/constants"
  15. "golang-fave/engine/actions"
  16. "golang-fave/engine/wrapper"
  17. )
  18. var ParamHost string
  19. var ParamPort int
  20. var ParamWwwDir string
  21. var VhostHomeDir string
  22. func init() {
  23. flag.StringVar(&ParamHost, "host", "0.0.0.0", "server host")
  24. flag.IntVar(&ParamPort, "port", 8080, "server port")
  25. flag.StringVar(&ParamWwwDir, "dir", "", "virtual hosts directory")
  26. flag.Parse()
  27. }
  28. func main() {
  29. if _, err := os.Stat(ParamWwwDir); os.IsNotExist(err) {
  30. fmt.Println("Virtual hosts directory is not exists")
  31. fmt.Println("Example: ./fave -host 127.0.0.1 -port 80 -dir ./hosts")
  32. return
  33. }
  34. if ParamWwwDir[len(ParamWwwDir)-1] != '/' {
  35. ParamWwwDir = ParamWwwDir + "/"
  36. }
  37. // Handle
  38. mux := http.NewServeMux()
  39. mux.HandleFunc("/", handler)
  40. srv := &http.Server{
  41. Addr: fmt.Sprintf("%s:%d", ParamHost, ParamPort),
  42. Handler: mux,
  43. }
  44. stop := make(chan os.Signal)
  45. signal.Notify(stop, os.Interrupt)
  46. go func() {
  47. log.Printf("Starting server at %s:%d", ParamHost, ParamPort)
  48. if err := srv.ListenAndServe(); err != nil {
  49. if err != http.ErrServerClosed {
  50. log.Fatal(err)
  51. }
  52. }
  53. }()
  54. // Wait for signal
  55. <-stop
  56. log.Printf("Shutting down server...\n")
  57. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  58. defer cancel()
  59. if err := srv.Shutdown(ctx); err != nil {
  60. log.Fatal(err)
  61. } else {
  62. log.Printf("Server is off!")
  63. }
  64. }
  65. func vhExists(vhosthome string) bool {
  66. if st, err := os.Stat(vhosthome); !os.IsNotExist(err) {
  67. if err == nil {
  68. fmode := st.Mode()
  69. if fmode.IsDir() {
  70. return true
  71. }
  72. }
  73. }
  74. return false
  75. }
  76. func handler(w http.ResponseWriter, r *http.Request) {
  77. // Build vhost home dir
  78. host := r.Host
  79. port := strconv.Itoa(ParamPort)
  80. index := strings.Index(host, ":")
  81. if index > -1 {
  82. port = host[index+1:]
  83. host = host[0:index]
  84. }
  85. // Cut "www" if exists
  86. if strings.HasPrefix(host, "www.") {
  87. host = host[4:]
  88. }
  89. VhostHomeDir = ParamWwwDir + host
  90. // Check if virtual host exists
  91. if !vhExists(VhostHomeDir) {
  92. host = "localhost"
  93. VhostHomeDir = ParamWwwDir + host
  94. }
  95. // Set protocol
  96. r.URL.Scheme = "http"
  97. // Set server name
  98. w.Header().Set("Server", "fave.pro/"+constants.ServerVersion)
  99. wrap := wrapper.New(&w, r, host, port, ParamWwwDir, VhostHomeDir)
  100. // Check if localhost exists
  101. if !vhExists(VhostHomeDir) && !strings.HasPrefix(r.URL.Path, "/assets/") {
  102. wrap.PrintEnginePageError(errors.New("Folder " + VhostHomeDir + " is not found"))
  103. return
  104. }
  105. // Create and start engine
  106. wrap.Run(func(wrapper *wrapper.Wrapper) bool {
  107. // Actions
  108. action := actions.New(wrapper)
  109. if action.Run() {
  110. wrapper.Session.Save()
  111. return true
  112. }
  113. // Pages
  114. return handlerPage(wrapper)
  115. })
  116. }