package main import ( "fmt" "html/template" "log" "net/http" "os" "path/filepath" "github.com/joho/godotenv" ) func main() { // Load the .env file err := godotenv.Load() if err != nil { // Try to load the .env.example file fmt.Println("Error loading .env file, trying .env.example") err = godotenv.Load(".env.example") if err != nil { log.Fatal("Error loading .env.example file") } } http.HandleFunc("/", mainHandler) http.HandleFunc("/assets/", assetHandler) fmt.Println("Starting server on :3000 ...") log.Fatal(http.ListenAndServe(":3000", nil)) } func mainHandler(w http.ResponseWriter, r *http.Request) { // Sanitize the path to prevent directory traversal attacks relPath := r.URL.Path if relPath == "/" { relPath = "/index" } // Check method switch r.Method { case http.MethodGet: getHandler(relPath, w, r) case http.MethodPost: postHandler(relPath, w, r) default: errorPage(405, w, r) } } func getHandler(relPath string, w http.ResponseWriter, r *http.Request) { tmplPath := filepath.Join("templates", filepath.Clean(relPath)+".html") // Get message from Env message := os.Getenv("MESSAGE") // Parse the template tmpl, err := template.ParseFiles(tmplPath) if err != nil { errorPage(404, w, r) return } // Create a map to hold the data requestData := map[string]interface{}{"envMessage": message} // Execute the template err = tmpl.Execute(w, requestData) if err != nil { http.Error(w, "Error rendering template", http.StatusInternalServerError) } } func postHandler(relPath string, w http.ResponseWriter, r *http.Request) { switch relPath { case "/index": indexPostHandler(w, r) default: errorPage(405, w, r) } } func indexPostHandler(w http.ResponseWriter, r *http.Request) { // Parse the form data err := r.ParseForm() if err != nil { errorPage(500, w, r) return } // Get the form data message := r.FormValue("message") // Print the message to the console log.Printf("Message: %s", message) // Create a map to hold the data requestData := map[string]interface{}{ "message": message, } // Return a page with message tmpl, err := template.ParseFiles("templates/index.html") if err != nil { errorPage(500, w, r) return } err = tmpl.Execute(w, requestData) } func errorPage(errorCode int, w http.ResponseWriter, r *http.Request) { w.WriteHeader(errorCode) tmpl, err := template.ParseFiles("templates/error.html") if err != nil { log.Printf("Error loading error page template: %v", err) http.Error(w, "Error loading error page", http.StatusInternalServerError) return } errorMsgs := map[int]string{ 404: "Page not found for " + r.URL.Path, 405: "Method not allowed", 500: "Internal server error", } // Check if errorcode isn't in the map if _, ok := errorMsgs[errorCode]; !ok { errorCode = 500 } // Correcting the initialization of the errorData map errorData := map[string]interface{}{ "short": errorCode, "long": errorMsgs[errorCode], } err = tmpl.Execute(w, errorData) if err != nil { log.Printf("Error executing error page template: %v", err) http.Error(w, "Error rendering error page", http.StatusInternalServerError) } } func assetHandler(w http.ResponseWriter, r *http.Request) { // Serve static files from templates/assets http.ServeFile(w, r, filepath.Join("templates", filepath.Clean(r.URL.Path))) }