package main import ( "html/template" "log" "net/http" "net/http/httptest" "strings" ) type TemplateHandler struct { handler http.Handler } func (t *TemplateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // We use our custom handler to prettify directories. Files are served via default. if strings.HasSuffix(r.URL.Path, "/") { r.Header.Del("If-Modified-Since") rec := httptest.NewRecorder() defer rec.Body.Reset() // passing the recorder instead of the real ResponseWriter t.handler.ServeHTTP(rec, r) // we copy the original headers first for k, v := range rec.Header() { w.Header()[k] = v } // BUG: Sometimes we get a 0 byte response if rec.Body.Len() == 0 { log.Println("Error: Empty body. Requested:", r.URL.Path) } // we serve a file instead of a html page if !strings.Contains(w.Header().Get("Content-Type"), "text/html") { w.Write(rec.Body.Bytes()) return } data := rec.Body.String() // we serve the directoy page if strings.HasPrefix(data, "
") {
execTemplate(w, r, data)
} else {
w.Write(rec.Body.Bytes())
}
return
} else {
t.handler.ServeHTTP(w, r)
}
}
func execTemplate(w http.ResponseWriter, r *http.Request, data string) {
data = strings.Replace(data, "", "", 1)
data = strings.Replace(data, "
", "", 1)
data = strings.Replace(data, "", "
", -1)
data = ".. (up a dir)
" + data
tmpl := template.New("page")
tmpl, err := tmpl.Parse(renderTemplate())
if err != nil {
log.Println(err.Error())
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
err = tmpl.Execute(w, struct {
Data template.HTML
URL string
}{Data: template.HTML(data), URL: r.URL.Path})
if err != nil {
log.Println(err)
}
}
func NewTemplateHandler(handler http.Handler, allowedHost string) *TemplateHandler {
return &TemplateHandler{handler: handler}
}
func renderTemplate() string {
html := `
{{.URL}}
`
return html
}