package main
import (
"fmt"
"net/http"
"time"
)
func mainPage(w http.ResponseWriter, r *http.Request) {
session, err := r.Cookie("session_id")
// учебный пример! это не проверка авторизации!
loggedIn := (err != http.ErrNoCookie)
if loggedIn {
fmt.Fprintln(w, `logout`)
fmt.Fprintln(w, "Welcome, "+session.Value)
} else {
fmt.Fprintln(w, `login`)
fmt.Fprintln(w, "You need to login")
}
}
func loginPage(w http.ResponseWriter, r *http.Request) {
expiration := time.Now().Add(10 * time.Hour)
cookie := http.Cookie{
Name: "session_id",
Value: "rvasily",
Expires: expiration,
}
http.SetCookie(w, &cookie)
http.Redirect(w, r, "/", http.StatusFound)
}
func logoutPage(w http.ResponseWriter, r *http.Request) {
session, err := r.Cookie("session_id")
if err == http.ErrNoCookie {
http.Redirect(w, r, "/", http.StatusFound)
return
}
session.Expires = time.Now().AddDate(0, 0, -1)
http.SetCookie(w, session)
http.Redirect(w, r, "/", http.StatusFound)
}
// -----------
func adminIndex(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `site index`)
fmt.Fprintln(w, "Admin main page")
}
func panicPage(w http.ResponseWriter, r *http.Request) {
panic("this must me recovered")
}
// -----------
func pageWithAllChecks(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
fmt.Println("recovered", err)
http.Error(w, "Internal server error", 500)
}
}()
defer func(start time.Time) {
fmt.Printf("[%s] %s, %s %s\n",
r.Method, r.RemoteAddr, r.URL.Path, time.Since(start))
}(time.Now())
_, err := r.Cookie("session_id")
// учебный пример! это не проверка авторизации!
if err != nil {
fmt.Println("no auth at", r.URL.Path)
http.Redirect(w, r, "/", http.StatusFound)
return
}
// your logic
}
// -----------
func adminAuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("adminAuthMiddleware", r.URL.Path)
_, err := r.Cookie("session_id")
// учебный пример! это не проверка авторизации!
if err != nil {
fmt.Println("no auth at", r.URL.Path)
http.Redirect(w, r, "/", http.StatusFound)
return
}
next.ServeHTTP(w, r)
})
}
func accessLogMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("accessLogMiddleware", r.URL.Path)
start := time.Now()
next.ServeHTTP(w, r)
fmt.Printf("[%s] %s, %s %s\n",
r.Method, r.RemoteAddr, r.URL.Path, time.Since(start))
})
}
func panicMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("panicMiddleware", r.URL.Path)
defer func() {
if err := recover(); err != nil {
fmt.Println("recovered", err)
http.Error(w, "Internal server error", 500)
}
}()
next.ServeHTTP(w, r)
})
}
// -----------
func main() {
adminMux := http.NewServeMux()
adminMux.HandleFunc("/admin/", adminIndex)
adminMux.HandleFunc("/admin/panic", panicPage)
// set middleware
adminHandler := adminAuthMiddleware(adminMux)
siteMux := http.NewServeMux()
siteMux.Handle("/admin/", adminHandler)
siteMux.HandleFunc("/login", loginPage)
siteMux.HandleFunc("/logout", logoutPage)
siteMux.HandleFunc("/", mainPage)
// set middleware
siteHandler := accessLogMiddleware(siteMux)
siteHandler = panicMiddleware(siteHandler)
fmt.Println("starting server at :8080")
http.ListenAndServe(":8080", siteHandler)
}