package rpm import "codit/internal/util" import "net/http" type HTTPServer struct { handler http.Handler auth AuthFunc logger *util.Logger } type AuthFunc func(username, password string) (bool, error) func NewHTTPServer(baseDir string, auth AuthFunc, logger *util.Logger) *HTTPServer { var server HTTPServer server = HTTPServer{ handler: http.FileServer(http.Dir(baseDir)), auth: auth, logger: logger, } return &server } func (s *HTTPServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { var ok bool var username string var password string var allowed bool var err error var userLabel string var recorder *statusRecorder userLabel = "-" recorder = &statusRecorder{ResponseWriter: w, status: http.StatusOK} if s.auth != nil { username, password, ok = r.BasicAuth() if !ok { recorder.Header().Set("WWW-Authenticate", `Basic realm="rpm"`) recorder.WriteHeader(http.StatusUnauthorized) s.logger.Write("rpm", util.LOG_INFO, "method=%s path=%s remote=%s user=%s status=%d", r.Method, r.URL.Path, r.RemoteAddr, userLabel, recorder.status) return } allowed, err = s.auth(username, password) if err != nil || !allowed { recorder.Header().Set("WWW-Authenticate", `Basic realm="rpm"`) recorder.WriteHeader(http.StatusUnauthorized) userLabel = username s.logger.Write("rpm", util.LOG_INFO, "method=%s path=%s remote=%s user=%s status=%d", r.Method, r.URL.Path, r.RemoteAddr, userLabel, recorder.status) return } userLabel = username } s.handler.ServeHTTP(recorder, r) s.logger.Write("rpm", util.LOG_INFO, "method=%s path=%s remote=%s user=%s status=%d", r.Method, r.URL.Path, r.RemoteAddr, userLabel, recorder.status) } type statusRecorder struct { http.ResponseWriter status int } func (r *statusRecorder) WriteHeader(code int) { r.status = code r.ResponseWriter.WriteHeader(code) }