-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
net/http: A race condition in the http.response.write
#53912
Comments
http.response.write
http.response.write
http.response.write
please show code that can reproduce the issue |
http.response.write
http.response.write
A demo version: package main
import (
"io"
"net/http"
"sync"
)
type Handler struct {
buf []byte
}
// just for demo
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
var wg sync.WaitGroup
wg.Add(1) // avoid early exits
go func() {
defer wg.Done()
if hijack, ok := w.(http.Hijacker); ok {
conn, _, err := hijack.Hijack()
if err != nil {
return
}
conn.Close()
}
}()
w.Write(h.buf) // should return OK or ErrHijack, not panic
wg.Wait()
}
func main() {
go http.ListenAndServe("127.0.0.1:8080", &Handler{
buf: make([]byte, 4096),
})
var wg sync.WaitGroup
wg.Add(8)
for i := 0; i < 8; i++ {
go func() {
defer wg.Done()
for {
res, err := http.Get("http://127.0.0.1:8080/")
if err != nil {
continue
}
io.Copy(io.Discard, res.Body)
res.Body.Close()
}
}()
}
wg.Wait()
} go run hijack.go panic: or: go run hijack.go goroutine 23757 [running]: |
A race condition in the
func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error)
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
calling the
Hijack()
from a goroutine while the http request is being processed.What did you expect to see?
Any
Write
operation on the http.ResponseWriter should return OK orErrHijacked
.Return OK: before the
Hijack()
is called.Return ErrHijacked: after the
Hijack()
is called.What did you see instead?
A panic happened.
In the statement
if w.conn.hijacked()
,write
will return ErrHijacked ifconn.hijacked()
is true and theconn.hijacked()
is protected byconn
's Mutex. But the following operations are not protected byconn
's Mutex.If the request was hijacked after
if w.conn.hijacked()
, Thebufio.Writer
inresponse
may be modified concurrently.The text was updated successfully, but these errors were encountered: