maragudk / maragudk/gomponents
Investigate setting Content-Type in http.Adapt
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 1.9k
- Forks
- 59
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 17
Description
`http.Adapt` doesn't set a `Content-Type` header, so `net/http` sniffs one from the first bytes of the response. Documents and fragments starting with a few tags come out as `text/html`, but fragments starting with most other tags come out as `text/plain`.
```go
h := ghttp.Adapt(func(http.ResponseWriter, *http.Request) (g.Node, error) {
return html.Tr(html.Td(g.Text("hat"))), nil
})
srv := httptest.NewServer(h)
res, _ := http.Get(srv.URL)
fmt.Println(res.Header.Get("Content-Type")) // text/plain; charset=utf-8
```
Observed on main (df71cfa), rendering each node through `Adapt`:
| Node | Real server (`httptest.NewServer`) | `httptest.NewRecorder` |
|---|---|---|
| `HTML5(...)` document | `text/html; charset=utf-8` | `text/html; charset=utf-8` |
| `
| `
` fragment | `text/html; charset=utf-8` | `text/plain; charset=utf-8` |
| ``, `
Two things are going on:
- The real server buffers up to 2 KB before writing headers, then sniffs with `http.DetectContentType`. That only recognises a handful of tags (`` in one call, which is why documents come out right.
This matters for fragment responses. htmx swaps a `text/plain` response anyway, but Datastar picks what to do with a response from its `Content-Type`, so a `text/plain` fragment isn't patched.
Options to consider:
1. Have `Adapt` set `Content-Type: text/html; charset=utf-8` when the handler hasn't set one, before any `WriteHeader` call.
2. Leave `Adapt` as is and document that fragment handlers should set the header.
Option 1 looks like the smaller surprise. It does change behaviour for a handler that returns `Raw` plain text and relies on sniffing to get `text/plain`, so it's worth checking whether that happens in practice.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the http.Adapt entry point and reproduce the Content-Type difference with httptest.NewServer and httptest.NewRecorder using the element and document examples. Check how handlers returning Raw plain text currently behave, then add focused coverage for fragment responses and any intended plain-text exception. Done means the chosen behavior is consistent for real servers and recorders and the tests document it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100