fix(websocket): http: superfluous response.WriteHeader on websocket initiation failure

This commit is contained in:
yusing 2025-05-31 22:29:02 +08:00
parent 54bf84dcba
commit ecfd018b0b
3 changed files with 20 additions and 4 deletions

View file

@ -19,7 +19,6 @@ func RenewCert(w http.ResponseWriter, r *http.Request) {
conn, err := gpwebsocket.Initiate(w, r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer conn.Close()

View file

@ -73,7 +73,6 @@ func (m *memLogger) Write(p []byte) (n int, err error) {
func (m *memLogger) ServeHTTP(w http.ResponseWriter, r *http.Request) {
conn, err := gpwebsocket.Initiate(w, r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

View file

@ -31,8 +31,15 @@ func SetWebsocketAllowedDomains(h http.Header, domains []string) {
const writeTimeout = time.Second * 10
// Initiate upgrades the HTTP connection to a WebSocket connection.
// It returns a WebSocket connection and an error if the upgrade fails.
// It logs and responds with an error if the upgrade fails.
//
// No further http.Error should be called after this function.
func Initiate(w http.ResponseWriter, r *http.Request) (*websocket.Conn, error) {
upgrader := websocket.Upgrader{}
upgrader := websocket.Upgrader{
Error: errHandler,
}
allowedDomains := WebsocketAllowedDomains(r.Header)
if len(allowedDomains) == 0 {
@ -71,7 +78,6 @@ func Initiate(w http.ResponseWriter, r *http.Request) (*websocket.Conn, error) {
func Periodic(w http.ResponseWriter, r *http.Request, interval time.Duration, do func(conn *websocket.Conn) error) {
conn, err := Initiate(w, r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer conn.Close()
@ -103,3 +109,15 @@ func WriteText(conn *websocket.Conn, msg string) error {
_ = conn.SetWriteDeadline(time.Now().Add(writeTimeout))
return conn.WriteMessage(websocket.TextMessage, []byte(msg))
}
func errHandler(w http.ResponseWriter, r *http.Request, status int, reason error) {
log.Error().
Str("remote", r.RemoteAddr).
Str("host", r.Host).
Str("url", r.URL.String()).
Int("status", status).
AnErr("reason", reason).
Msg("websocket error")
w.Header().Set("Sec-Websocket-Version", "13")
http.Error(w, http.StatusText(status), status)
}