mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-25 13:29:27 +01:00
implement candidate compromise proposal for websockets
1. Text and binary frames are accepted 2. Text frames are sent by default 3. Binary frames are sent to clients who negotiate `binary.ircv3.net` 4. Non-UTF8 data is not accepted (enabling websockets still enables UTFONLY)
This commit is contained in:
parent
640572e151
commit
d547d05205
@ -691,7 +691,7 @@ func (client *Client) run(session *Session) {
|
|||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
var quitMessage string
|
var quitMessage string
|
||||||
switch err {
|
switch err {
|
||||||
case ircreader.ErrReadQ, errWSBinaryMessage:
|
case ircreader.ErrReadQ:
|
||||||
quitMessage = err.Error()
|
quitMessage = err.Error()
|
||||||
default:
|
default:
|
||||||
quitMessage = "connection closed"
|
quitMessage = "connection closed"
|
||||||
|
@ -5,7 +5,6 @@ package irc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
|
||||||
"net"
|
"net"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
@ -22,8 +21,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
crlf = []byte{'\r', '\n'}
|
crlf = []byte{'\r', '\n'}
|
||||||
errWSBinaryMessage = errors.New("WebSocket binary messages are unsupported")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IRCConn abstracts away the distinction between a regular
|
// IRCConn abstracts away the distinction between a regular
|
||||||
@ -90,11 +88,13 @@ func (cc *IRCStreamConn) Close() (err error) {
|
|||||||
|
|
||||||
// IRCWSConn is an IRCConn over a websocket.
|
// IRCWSConn is an IRCConn over a websocket.
|
||||||
type IRCWSConn struct {
|
type IRCWSConn struct {
|
||||||
conn *websocket.Conn
|
conn *websocket.Conn
|
||||||
|
binary bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIRCWSConn(conn *websocket.Conn) IRCWSConn {
|
func NewIRCWSConn(conn *websocket.Conn) IRCWSConn {
|
||||||
return IRCWSConn{conn: conn}
|
binary := conn.Subprotocol() == "binary.ircv3.net"
|
||||||
|
return IRCWSConn{conn: conn, binary: binary}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wc IRCWSConn) UnderlyingConn() *utils.WrappedConn {
|
func (wc IRCWSConn) UnderlyingConn() *utils.WrappedConn {
|
||||||
@ -106,7 +106,11 @@ func (wc IRCWSConn) UnderlyingConn() *utils.WrappedConn {
|
|||||||
func (wc IRCWSConn) WriteLine(buf []byte) (err error) {
|
func (wc IRCWSConn) WriteLine(buf []byte) (err error) {
|
||||||
buf = bytes.TrimSuffix(buf, crlf)
|
buf = bytes.TrimSuffix(buf, crlf)
|
||||||
// #1483: if we have websockets at all, then we're enforcing utf8
|
// #1483: if we have websockets at all, then we're enforcing utf8
|
||||||
return wc.conn.WriteMessage(websocket.TextMessage, buf)
|
messageType := websocket.TextMessage
|
||||||
|
if wc.binary {
|
||||||
|
messageType = websocket.BinaryMessage
|
||||||
|
}
|
||||||
|
return wc.conn.WriteMessage(messageType, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wc IRCWSConn) WriteLines(buffers [][]byte) (err error) {
|
func (wc IRCWSConn) WriteLines(buffers [][]byte) (err error) {
|
||||||
@ -122,11 +126,12 @@ func (wc IRCWSConn) WriteLines(buffers [][]byte) (err error) {
|
|||||||
func (wc IRCWSConn) ReadLine() (line []byte, err error) {
|
func (wc IRCWSConn) ReadLine() (line []byte, err error) {
|
||||||
messageType, line, err := wc.conn.ReadMessage()
|
messageType, line, err := wc.conn.ReadMessage()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if messageType == websocket.TextMessage {
|
if messageType == websocket.BinaryMessage && globalUtf8EnforcementSetting {
|
||||||
return line, nil
|
if !utf8.Valid(line) {
|
||||||
} else {
|
return line, errInvalidUtf8
|
||||||
return nil, errWSBinaryMessage
|
}
|
||||||
}
|
}
|
||||||
|
return line, nil
|
||||||
} else if err == websocket.ErrReadLimit {
|
} else if err == websocket.ErrReadLimit {
|
||||||
return line, ircreader.ErrReadQ
|
return line, ircreader.ErrReadQ
|
||||||
} else {
|
} else {
|
||||||
|
@ -166,7 +166,7 @@ func (wl *WSListener) handle(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
Subprotocols: []string{"text.ircv3.net"},
|
Subprotocols: []string{"text.ircv3.net", "binary.ircv3.net"},
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := wsUpgrader.Upgrade(w, r, nil)
|
conn, err := wsUpgrader.Upgrade(w, r, nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user