webserv.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package webserv
  2. import (
  3. "errors"
  4. "fmt"
  5. "net/http"
  6. "sync"
  7. )
  8. /*
  9. Static Web Server package
  10. This module host a static web server
  11. */
  12. type WebServerOptions struct {
  13. Port string //Port for listening
  14. EnableDirectoryListing bool //Enable listing of directory
  15. WebRoot string //Folder for stroing the static web folders
  16. }
  17. type WebServer struct {
  18. mux *http.ServeMux
  19. server *http.Server
  20. option *WebServerOptions
  21. isRunning bool
  22. mu sync.Mutex
  23. }
  24. // NewWebServer creates a new WebServer instance.
  25. func NewWebServer(options *WebServerOptions) *WebServer {
  26. return &WebServer{
  27. mux: http.NewServeMux(),
  28. option: options,
  29. isRunning: false,
  30. mu: sync.Mutex{},
  31. }
  32. }
  33. // ChangePort changes the server's port.
  34. func (ws *WebServer) ChangePort(port string) error {
  35. ws.mu.Lock()
  36. defer ws.mu.Unlock()
  37. if ws.isRunning {
  38. if err := ws.Stop(); err != nil {
  39. return err
  40. }
  41. }
  42. ws.option.Port = port
  43. ws.server.Addr = ":" + port
  44. return nil
  45. }
  46. // Start starts the web server.
  47. func (ws *WebServer) Start() error {
  48. ws.mu.Lock()
  49. defer ws.mu.Unlock()
  50. //Check if server already running
  51. if ws.isRunning {
  52. return fmt.Errorf("web server is already running")
  53. }
  54. //Check if the port is usable
  55. if IsPortInUse(ws.option.Port) {
  56. return errors.New("Port already in use or access denied by host OS")
  57. }
  58. //Dispose the old mux and create a new one
  59. ws.mux = http.NewServeMux()
  60. //Create a static web server
  61. fs := http.FileServer(http.Dir(ws.option.WebRoot))
  62. ws.mux.Handle("/", ws.fsMiddleware(fs))
  63. ws.server = &http.Server{
  64. Addr: ":" + ws.option.Port,
  65. Handler: ws.mux,
  66. }
  67. go func() {
  68. if err := ws.server.ListenAndServe(); err != nil {
  69. if err != http.ErrServerClosed {
  70. fmt.Printf("Web server error: %v\n", err)
  71. }
  72. }
  73. }()
  74. ws.isRunning = true
  75. return nil
  76. }
  77. // Stop stops the web server.
  78. func (ws *WebServer) Stop() error {
  79. ws.mu.Lock()
  80. defer ws.mu.Unlock()
  81. if !ws.isRunning {
  82. return fmt.Errorf("web server is not running")
  83. }
  84. if err := ws.server.Close(); err != nil {
  85. return err
  86. }
  87. ws.isRunning = false
  88. return nil
  89. }
  90. // UpdateDirectoryListing enables or disables directory listing.
  91. func (ws *WebServer) UpdateDirectoryListing(enable bool) {
  92. ws.mu.Lock()
  93. defer ws.mu.Unlock()
  94. ws.option.EnableDirectoryListing = enable
  95. }
  96. // Close stops the web server without returning an error.
  97. func (ws *WebServer) Close() {
  98. ws.Stop()
  99. }