mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
Close internal Pipes in websocketconn.Conn Close.
Unless something externally called Write after Close, the writeLoop(ws, pr2) goroutine would run forever, because nothing would ever close pw2/pr2. https://bugs.torproject.org/33367#comment:4
This commit is contained in:
parent
1220853a67
commit
380b133155
2 changed files with 30 additions and 0 deletions
|
@ -24,6 +24,8 @@ func (conn *Conn) Write(b []byte) (n int, err error) {
|
|||
}
|
||||
|
||||
func (conn *Conn) Close() error {
|
||||
conn.Reader.(*io.PipeReader).Close()
|
||||
conn.Writer.(*io.PipeWriter).Close()
|
||||
// Ignore any error in trying to write a Close frame.
|
||||
_ = conn.Conn.WriteControl(websocket.CloseMessage, []byte{}, time.Now().Add(time.Second))
|
||||
return conn.Conn.Close()
|
||||
|
|
|
@ -233,3 +233,31 @@ func TestConcurrentWrite(t *testing.T) {
|
|||
t.Fatalf("Write: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Read and Write methods return errors after Close.
|
||||
func TestClose(t *testing.T) {
|
||||
s, c, err := connPair()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
err = s.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var buf [10]byte
|
||||
n, err := s.Read(buf[:])
|
||||
if n != 0 || err == nil {
|
||||
t.Fatalf("Read after Close returned (%v, %v), expected (%v, non-nil)", n, err, 0)
|
||||
}
|
||||
|
||||
_, err = s.Write([]byte{1, 2, 3})
|
||||
// Here we break the abstraction a little and look for a specific error,
|
||||
// io.ErrClosedPipe. This is because we know the Conn uses an io.Pipe
|
||||
// internally.
|
||||
if err != io.ErrClosedPipe {
|
||||
t.Fatalf("Write after Close returned %v, expected %v", err, io.ErrClosedPipe)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue