package main import ( "log" "net/http" "strings" ) type imagesHandler struct { name string auth func(*http.Request) bool hndlr http.Handler getter func(fname string) (*Picture, error) } func ImagesHandler(name string, auth func(*http.Request) bool, hndlr http.Handler, getter func(fname string) (*Picture, error)) imagesHandler { return imagesHandler{name, auth, hndlr, getter} } func (i imagesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { log.Printf("Handling %s %s request from %s: %s [%s]\n", r.Method, i.name, r.RemoteAddr, r.URL.Path, r.UserAgent()) // Don't handle subdirectories if strings.Contains(r.URL.Path[1:], "/") { http.Error(w, "Image not found.", http.StatusBadRequest) return } // Refuse most methods if r.Method != "GET" && r.Method != "HEAD" { http.Error(w, "Method not allowed.", http.StatusMethodNotAllowed) return } // Refuse content if r.ContentLength != 0 { http.Error(w, "This request doesn't accept content.", http.StatusRequestEntityTooLarge) return } // Check rights if !i.auth(r) { w.Header().Set("WWW-Authenticate", "Basic realm=\"YouP0m\"") http.Error(w, "You are not allowed to perform this request.", http.StatusUnauthorized) return } // Search the picture if pict, err := i.getter(r.URL.Path[1:]); err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } else { r.URL.Path = "/" + pict.path i.hndlr.ServeHTTP(w, r) } }