Skip to content

Commit 46f4112

Browse files
alixandernhooyr
authored andcommitted
fix closenow race
1 parent 8d2374e commit 46f4112

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

accept_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ package websocket
66
import (
77
"bufio"
88
"errors"
9+
"io"
910
"net"
1011
"net/http"
1112
"net/http/httptest"
1213
"strings"
14+
"sync"
1315
"testing"
1416

1517
"nhooyr.io/websocket/internal/test/assert"
@@ -142,6 +144,43 @@ func TestAccept(t *testing.T) {
142144
_, err := Accept(w, r, nil)
143145
assert.Contains(t, err, `failed to hijack connection`)
144146
})
147+
t.Run("closeRace", func(t *testing.T) {
148+
t.Parallel()
149+
150+
server, _ := net.Pipe()
151+
152+
pr, pw := io.Pipe()
153+
rw := bufio.NewReadWriter(bufio.NewReader(pr), bufio.NewWriter(pw))
154+
newResponseWriter := func() http.ResponseWriter {
155+
return mockHijacker{
156+
ResponseWriter: httptest.NewRecorder(),
157+
hijack: func() (net.Conn, *bufio.ReadWriter, error) {
158+
return server, rw, nil
159+
},
160+
}
161+
}
162+
w := newResponseWriter()
163+
164+
r := httptest.NewRequest("GET", "/", nil)
165+
r.Header.Set("Connection", "Upgrade")
166+
r.Header.Set("Upgrade", "websocket")
167+
r.Header.Set("Sec-WebSocket-Version", "13")
168+
r.Header.Set("Sec-WebSocket-Key", xrand.Base64(16))
169+
170+
c, err := Accept(w, r, nil)
171+
wg := &sync.WaitGroup{}
172+
wg.Add(2)
173+
go func() {
174+
c.Close(StatusInternalError, "the sky is falling")
175+
wg.Done()
176+
}()
177+
go func() {
178+
c.CloseNow()
179+
wg.Done()
180+
}()
181+
wg.Wait()
182+
assert.Success(t, err)
183+
})
145184
}
146185

147186
func Test_verifyClientHandshake(t *testing.T) {

close.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ func (c *Conn) CloseNow() (err error) {
113113
}
114114

115115
c.close(nil)
116+
c.closeMu.Lock()
117+
defer c.closeMu.Unlock()
116118
return c.closeErr
117119
}
118120

0 commit comments

Comments
 (0)