go 16 lines · 1 tab

Content sniffing for uploads (don't trust the header)

Leah Thompson Jan 2026
1 tab
package api

import (
  "io"
  "net/http"
)

func DetectType(f io.Reader) (string, []byte, error) {
  buf := make([]byte, 512)
  n, err := io.ReadFull(f, buf)
  if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
    return "", nil, err
  }
  buf = buf[:n]
  return http.DetectContentType(buf), buf, nil
}
1 file · go Explain with highlit

Clients can lie about Content-Type, so for uploads I prefer sniffing the first bytes with http.DetectContentType. The safe flow is: open the multipart file, read a small prefix, detect type, then rewind (or re-open) before writing to disk or object storage. This keeps you from accepting “image/png” that is actually an executable, and it reduces surprises in downstream processing. I also enforce a maximum size at the HTTP layer with MaxBytesReader and validate file extensions only as a secondary signal. In production, I keep an allowlist of MIME types per upload endpoint (avatars vs PDFs vs videos) and I log rejections with request IDs. This snippet demonstrates the minimal sniffing step that makes upload validation meaningfully safer.


Related snips

Share this code

Here's the card — post it anywhere.

Content sniffing for uploads (don't trust the header) — share card
Link copied