func (l *FilesystemLoader) processEvents() { for { select { case event, ok := <-l.watcher.Events: if !ok { log.Printf("watching filesystem templates stopped") return } var path, name = event.Name, l.templateNames[event.Name] var templateChan = l.templateChans[path] if event.Op == fsnotify.Write || event.Op == fsnotify.Chmod { if template, err := l.LoadHtmlTemplate(name); err != nil { log.Warnf("error while reloading template %s from %s: %s", name, path, err) } else { log.Printf("reloading template %s from %s", name, path) templateChan <- template } } case err, ok := <-l.watcher.Errors: if !ok { log.Printf("watching filesystem templates stopped") return } log.Printf("error while watching filesystem templates: %s", err) } } }
func (e *TemplateDeliverer) ServeHTTP(writer http.ResponseWriter, request *http.Request) { if request.Method != "GET" { log.Printf("%s %s: wrong method for template handling", request.Method, request.URL) failer.ServeMethodNotAllowed(writer, request) return } readCloser, err := e.loader.LoadResource(request.URL.Path) if err != nil { log.Printf("%s %s: error while opening template resource: %s", request.Method, request.URL, err) failer.ServeNotFound(writer, request) return } defer readCloser.Close() writer.Header().Set("Content-Type", e.detectMimeType(request)) _, err = io.Copy(writer, readCloser) if err != nil { log.Printf("%s %s: error while writing template resource to output: %s", request.Method, request.URL, err) failer.ServeInternalServerError(writer, request) return } }
func (a *HttpBasicAuthenticator) LoginHandler() http.Handler { return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { if a.loginRequiresHeader != "" && request.Header.Get(a.loginRequiresHeader) == "" { log.Printf("%s %s: deny login because of missing connection header '%s'", request.Method, request.URL, a.loginRequiresHeader) failer.ServeBadRequest(writer, request) return } var user = a.userAttemptingAuth(request) if user != "" { a.authenticate(writer, request) // NOTE: Delay request even if authentication was successful, so that the // attacker needs our response time.Sleep(a.bruteBlocker.Delay(user, request.RemoteAddr, a.requestAuth.IsAuthenticated(request))) if a.requestAuth.IsAuthenticated(request) && a.requestAuth.UserID(request) == user { log.Printf("%s %s: authenticated as %s", request.Method, request.URL, a.requestAuth.UserID(request)) a.sessionAuth.SetUserID(writer, request, a.requestAuth.UserID(request)) router.RedirectToViewMode(writer, request) return } } a.basicAuth.RequireAuth(writer, request) }) }
func (e *Editor) serveWriter(writer http.ResponseWriter, request *http.Request) { if !e.store.HasWriteAccessForRequest(request) { log.Printf("%s %s: no write permissions", request.Method, request.URL) failer.ServeUnauthorized(writer, request) return } var content = request.FormValue("content") if content == "" { log.Printf("%s %s: no valid content in request", request.Method, request.URL) failer.ServeBadRequest(writer, request) return } e.store.WriteString(request, content) if err := e.store.Err(); err != nil { log.Printf("%s %s: %s", request.Method, request.URL, err) failer.ServeInternalServerError(writer, request) return } log.Printf("%s %s: wrote %d bytes", request.Method, request.URL, len(content)) if request.FormValue("saveAndReturn") != "" { router.RedirectToViewMode(writer, request) return } router.RedirectToEditMode(writer, request) }
func htpasswdFilePath(contentRoot gopath.GoPath) gopath.GoPath { htpasswdFile := contentRoot.JoinPath(".htpasswd") if !htpasswdFile.IsExists() { log.Printf("no .htpasswd found") } else { log.Printf("using authentication data from .htpasswd") } return htpasswdFile }
func (s *CookieAuthenticator) session(request *http.Request) *sessions.Session { session, err := s.cookieStore.Get(request, authenticationStoreSessionName) if err != nil { log.Printf("%s %s: failed to decode existing cookie session", request.Method, request.URL) } return session }
func (s *CookieAuthenticator) removeCookie(writer http.ResponseWriter, request *http.Request) { var session = s.session(request) session.Options.MaxAge = -1 if err := s.cookieStore.Save(request, writer, session); err != nil { log.Printf("%s %s: failed to clear cookie", request.Method, request.URL) } }
func (e *Editor) serveDeleter(writer http.ResponseWriter, request *http.Request) { if !e.store.HasDeleteAccessForRequest(request) { log.Printf("%s %s: no delete permissions", request.Method, request.URL) failer.ServeUnauthorized(writer, request) return } e.store.Delete(request) if err := e.store.Err(); err != nil { log.Printf("%s %s: %s", request.Method, request.URL, err) failer.ServeInternalServerError(writer, request) return } log.Printf("%s %s: deleted", request.Method, request.URL) fmt.Fprintf(writer, "Successfully deleted") }
func RequestLogger(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var start = time.Now() var stats = &responseWriterWithStats{wrapped: w} next.ServeHTTP(stats, r) log.Printf("[%s] %d %s %s [%d bytes in %s]", clientIP(r), stats.status, r.Method, r.URL, stats.bytesWritten, time.Since(start)) }) }
func (s *CookieAuthenticator) SetUserID(writer http.ResponseWriter, request *http.Request, userId string) { if userId == "" { s.removeCookie(writer, request) } else { var session = s.session(request) session.Values[userIDKey] = userId if err := s.cookieStore.Save(request, writer, session); err != nil { log.Printf("%s %s: failed to store userid in cookie", request.Method, request.URL) } } }
func (f rawFormatter) serveFromReader(reader io.Reader, writer http.ResponseWriter, request *http.Request) { writer.Header().Set("Content-Type", f.mimeType) // TODO: Use http.ServeContent instead _, err := io.Copy(writer, reader) if err != nil { log.Printf("%s %s: %s", request.Method, request.URL, err) failer.ServeInternalServerError(writer, request) return } }
func (s *CookieAuthenticator) UserID(request *http.Request) string { var session = s.session(request) var userId = session.Values[userIDKey] if userId != nil { if strVal, ok := userId.(string); ok { return strVal } else { log.Printf("%s %s: failed to read userId from value %s", request.Method, request.URL, userId) } } return "" }
func templatePath(contentRoot gopath.GoPath, cfg config.Config) (result gopath.GoPath) { // configuration result = gopath.FromPath(cfg.TemplatePath) if !result.IsEmpty() { if !result.IsDirectory() { log.Fatalf("configured template path is no directory: %s", result.Path()) } log.Printf("using templates from %s (by configuration)", result.Path()) return result } // convention result = contentRoot.JoinPath(defaultTemplateDirectoryName) if result.IsDirectory() { log.Printf("using templates from %s (by convention)", result.Path()) return result } // default log.Printf("using default templates") return gopath.Empty() }
func main() { log.Printf("--- gone startup ---") cfg := config.FromCommandline() switch cfg.Command { case config.CommandExportTemplates: exportTemplates(cfg) case config.CommandListen: listen(cfg) case config.CommandHelp: config.PrintUsage() } }
func (v *Viewer) ServeHTTP(writer http.ResponseWriter, request *http.Request) { if !v.store.HasReadAccessForRequest(request) { log.Printf("%s %s: no read permissions", request.Method, request.URL) failer.ServeUnauthorized(writer, request) return } if request.Method != "GET" { v.serveNonGET(writer, request) return } v.serveGET(writer, request) }
func (r Router) ServeHTTP(writer http.ResponseWriter, request *http.Request) { var err = request.ParseForm() if err != nil { log.Printf("%s %s: %s", request.Method, request.URL, err) failer.ServeBadRequest(writer, request) } else if Is(ModeTemplate, request) { r.templateDeliverer.ServeHTTP(writer, request) } else if Is(ModeLogin, request) { r.authenticator.ServeHTTP(writer, request) } else if Is(ModeEdit, request) || Is(ModeCreate, request) || Is(ModeDelete, request) { r.editor.ServeHTTP(writer, request) } else { r.viewer.ServeHTTP(writer, request) } }
func (e *Editor) serveEditUI(writer http.ResponseWriter, request *http.Request) { if !e.store.HasWriteAccessForRequest(request) { log.Printf("%s %s: no write permissions", request.Method, request.URL) failer.ServeUnauthorized(writer, request) return } if !router.Is(router.ModeCreate, request) && !e.store.HasReadAccessForRequest(request) { log.Printf("%s %s: no read permissions", request.Method, request.URL) failer.ServeUnauthorized(writer, request) return } mimeType := e.store.MimeTypeForRequest(request) if err := e.assertEditableTextFile(request, mimeType); err != nil { log.Printf("%s %s: no editable text file: %s", request.Method, request.URL, err) failer.ServeUnsupportedMediaType(writer, request) return } var content = e.store.ReadString(request) if err := e.store.Err(); err != nil { if !store.IsPathNotFoundError(err) { log.Printf("%s %s: %s", request.Method, request.URL, err) failer.ServeInternalServerError(writer, request) return } else if router.Is(router.ModeEdit, request) { log.Printf("%s %s: file to be edited does not exist: %s", request.Method, request.URL, err) failer.ServeNotFound(writer, request) return } } else if router.Is(router.ModeCreate, request) { log.Printf("%s %s: file to be created already exists: %s", request.Method, request.URL, err) failer.ServeConflict(writer, request) return } err := e.renderer.Render(writer, request.URL, content, mimeType, router.Is(router.ModeEdit, request)) if err != nil { log.Printf("%s %s: %s", request.Method, request.URL, err) failer.ServeInternalServerError(writer, request) return } log.Printf("%s %s: served from template", request.Method, request.URL) }
func (l *FilesystemLoader) WatchHtmlTemplate(name string) <-chan *template.Template { var path = l.templatePath(name).Path() l.templateNames[path] = name templateChan, ok := l.templateChans[path] if !ok { templateChan = make(chan *template.Template) l.templateChans[path] = templateChan } if err := l.watcher.Add(path); err != nil { log.Printf("couldn't watch filesystem template %s: %s", path, err) return make(chan *template.Template) } return templateChan }
func (e *Editor) ServeHTTP(writer http.ResponseWriter, request *http.Request) { if e.isServeWriter(request) { e.serveWriter(writer, request) return } if e.isServeDeleter(request) { e.serveDeleter(writer, request) return } if e.isServeCreateUI(request) || e.isServeEditUI(request) { e.serveEditUI(writer, request) return } log.Printf("%s %s: method not allowed", request.Method, request.URL) failer.ServeMethodNotAllowed(writer, request) }
func createHttpAuthenticator( auth authenticator.Authenticator, contentRoot gopath.GoPath, cfg config.Config, ) authenticator.HttpAuthenticator { var bruteBlocker = bruteblocker.New( cfg.BruteforceMaxDelay, cfg.BruteforceDelayStep, cfg.BruteforceDelayStep/5, cfg.BruteforceDelayStep/20, cfg.BruteforceDropDelayAfter, ) if cfg.RequireSSLHeader != "" { log.Printf("Requiring SSL header %s on login (by configuration)", cfg.RequireSSLHeader) } return authenticator.NewHttpBasicAuthenticator( auth, htpasswdFilePath(contentRoot), cfg.RequireSSLHeader, bruteBlocker, ) }
func registerExtension(ext string, mimeType string) { if err := mime.AddExtensionType("."+ext, mimeType); err != nil { log.Printf("error adding %s as extension for Mime type %s: %s", ext, mimeType, err) } }
func (v *Viewer) log(request *http.Request, err error) { log.Printf("%s %s: %s", request.Method, request.URL, err) }