Go version
go version go1.24.5 linux/amd64
Output of go env
in your module/workspace:
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE='on'
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHEPROG=''
GODEBUG=''
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2965077955=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOOS='linux'
GOPROXY='https://proxy.golang.org,direct'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOVCS=''
GOVERSION='go1.24.5'
GOWORK=''
PKG_CONFIG='pkg-config'
What did you do?
I tested Go's HTTP request parsing if it correctly implements RFC 9110 Section 5.2 Field Lines and Field Value.
The following is the test code. The same code is available on Go Playground. https://go.dev/play/p/_yte4oVPoKr
package main
import (
"bufio"
"bytes"
"fmt"
"net/http"
)
func main() {
// NOTE: Use CRLF (\r\n) line endings per HTTP/1.1.
raw := "" +
"POST /api/v1/widgets?limit=10 HTTP/1.1\r\n" +
"Host: example.com\r\n" +
"User-Agent: demo-client/1.0\r\n" +
"X-Foo: foo, bar\r\n" +
"X-foo: zot\r\n" +
"Content-Type: application/json\r\n" +
"Content-Length: 18\r\n" +
"\r\n" +
`{"name":"gizmo"}`
br := bufio.NewReader(bytes.NewBufferString(raw))
req, err := http.ReadRequest(br)
if err != nil {
panic(err)
}
defer req.Body.Close()
fmt.Printf("X-Foo: %#v", req.Header.Values("x-foo"))
}
What did you see happen?
The program printed:
X-Foo: []string{"foo, bar", "zot"}
What did you expect to see?
It should return
X-Foo: []string{"foo", "bar", "zot"}
or alternatively,
X-Foo: []string{"foo, bar, zot"}
This is the behavior of the Fetch API of JavaScript.
Comment From: ymmt2005
Closing this because RFC 9110 says that the concatenation is optional in section 5.3.
A recipient MAY combine multiple field lines within a field section that have the same field name into one field line, without changing the semantics of the message, by appending each subsequent field line value to the initial field line value in order, separated by a comma (",") and optional whitespace (OWS, defined in Section 5.6.3). For consistency, use comma SP.