Skip to content

some code path didn't check closed state #216

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

Closed
zhangyoufu opened this issue Mar 15, 2020 · 1 comment
Closed

some code path didn't check closed state #216

zhangyoufu opened this issue Mar 15, 2020 · 1 comment

Comments

@zhangyoufu
Copy link

zhangyoufu commented Mar 15, 2020

Everywhere we got an error when read from / write into underlying transport (incl. flush write buffer), we should check if we have closed the connection, and wrap a CloseError.

How to reproduce

package main

import (
	"context"
	"log"
	"net/http"
	"net/http/httptest"
	"strings"
	"time"

	"nhooyr.io/websocket"
)

func handleHTTP(w http.ResponseWriter, r *http.Request) {
	ws, err := websocket.Accept(w, r, nil)
	if err == nil {
		go handleWS(ws)
	}
}

func handleWS(conn *websocket.Conn) {
	defer conn.Close(websocket.StatusInternalError, "oops")
	ctx := context.Background()
	for {
		_, _, err := conn.Read(ctx)
		if err != nil {
			return
		}
	}
}

func main() {
	ctx := context.Background()

	server := httptest.NewServer(http.HandlerFunc(handleHTTP))
	defer server.Close()

	url := strings.Replace(server.URL, "http", "ws", 1)
	client, _, _ := websocket.Dial(ctx, url, nil)

	// write something in background
	joinCh := make(chan struct{})
	go func() {
		defer close(joinCh)
		for {
			err := client.Write(ctx, websocket.MessageText, []byte("test"))
			if err != nil {
				log.Print("client write error: ", err)
				log.Print("client close status code: ", websocket.CloseStatus(err))
				return
			}
		}
	}()

	// close after some time
	time.Sleep(time.Millisecond)
	_ = client.Close(websocket.StatusNormalClosure, "bye")

	<- joinCh
}

Expected output

2020/03/15 21:20:23 client write error: failed to write msg: failed to close writer: failed to write fin frame: failed to write frame: WebSocket closed: sent close frame: status = StatusNormalClosure and reason = "bye"
2020/03/15 21:20:23 client close status code: StatusNormalClosure

Unexpected output

2020/03/15 21:20:21 client write error: failed to write msg: failed to close writer: failed to write fin frame: failed to write frame: failed to flush: write tcp 127.0.0.1:59943->127.0.0.1:59942: use of closed network connection
2020/03/15 21:20:21 client close status code: StatusCode(-1)
@nhooyr
Copy link
Contributor

nhooyr commented Mar 17, 2020

Thanks for reporting. Will close with #215.

@nhooyr nhooyr closed this as completed Mar 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants