123456789101112131415161718192021222324252627282930313233343536373839404142 |
- package util
- import (
- "net/http"
- "strings"
- )
- // ContentTypeWriter is an implementation of http.ResponseWriter that will detect the content type and set the
- // Content-Type and (optionally) Content-Disposition headers accordingly.
- //
- // It will always set a Content-Type based on http.DetectContentType, but will never send the "text/html"
- // content type.
- type ContentTypeWriter struct {
- w http.ResponseWriter
- filename string
- sniffed bool
- }
- // NewContentTypeWriter creates a new ContentTypeWriter
- func NewContentTypeWriter(w http.ResponseWriter, filename string) *ContentTypeWriter {
- return &ContentTypeWriter{w, filename, false}
- }
- func (w *ContentTypeWriter) Write(p []byte) (n int, err error) {
- if w.sniffed {
- return w.w.Write(p)
- }
- // Detect and set Content-Type header
- // Fix content types that we don't want to inline-render in the browser. In particular,
- // we don't want to render HTML in the browser for security reasons.
- contentType, _ := DetectContentType(p, w.filename)
- if strings.HasPrefix(contentType, "text/html") {
- contentType = strings.ReplaceAll(contentType, "text/html", "text/plain")
- } else if contentType == "application/octet-stream" {
- contentType = "" // Reset to let downstream http.ResponseWriter take care of it
- }
- if contentType != "" {
- w.w.Header().Set("Content-Type", contentType)
- }
- w.sniffed = true
- return w.w.Write(p)
- }
|