Source File
helper.go
Belonging Package
github.com/gobwas/ws/wsutil
package wsutilimport ()// Message represents a message from peer, that could be presented in one or// more frames. That is, it contains payload of all message fragments and// operation code of initial frame for this message.type Message struct {OpCode ws.OpCodePayload []byte}// ReadMessage is a helper function that reads next message from r. It appends// received message(s) to the third argument and returns the result of it and// an error if some failure happened. That is, it probably could receive more// than one message when peer sending fragmented message in multiple frames and// want to send some control frame between fragments. Then returned slice will// contain those control frames at first, and then result of gluing fragments.//// TODO(gobwas): add DefaultReader with buffer size options.func ( io.Reader, ws.State, []Message) ([]Message, error) {:= Reader{Source: ,State: ,CheckUTF8: true,OnIntermediate: func( ws.Header, io.Reader) error {, := ioutil.ReadAll()if != nil {return}= append(, Message{.OpCode, })return nil},}, := .NextFrame()if != nil {return ,}var []byteif .Fin {// No more frames will be read. Use fixed sized buffer to read payload.= make([]byte, .Length)// It is not possible to receive io.EOF here because Reader does not// return EOF if frame payload was successfully fetched.// Thus we consistent here with io.Reader behavior._, = io.ReadFull(&, )} else {// Frame is fragmented, thus use ioutil.ReadAll behavior.var bytes.Buffer_, = .ReadFrom(&)= .Bytes()}if != nil {return ,}return append(, Message{.OpCode, }), nil}// ReadClientMessage reads next message from r, considering that caller// represents server side.// It is a shortcut for ReadMessage(r, ws.StateServerSide, m).func ( io.Reader, []Message) ([]Message, error) {return ReadMessage(, ws.StateServerSide, )}// ReadServerMessage reads next message from r, considering that caller// represents client side.// It is a shortcut for ReadMessage(r, ws.StateClientSide, m).func ( io.Reader, []Message) ([]Message, error) {return ReadMessage(, ws.StateClientSide, )}// ReadData is a helper function that reads next data (non-control) message// from rw.// It takes care on handling all control frames. It will write response on// control frames to the write part of rw. It blocks until some data frame// will be received.//// Note this may handle and write control frames into the writer part of a// given io.ReadWriter.func ( io.ReadWriter, ws.State) ([]byte, ws.OpCode, error) {return readData(, , ws.OpText|ws.OpBinary)}// ReadClientData reads next data message from rw, considering that caller// represents server side. It is a shortcut for ReadData(rw, ws.StateServerSide).//// Note this may handle and write control frames into the writer part of a// given io.ReadWriter.func ( io.ReadWriter) ([]byte, ws.OpCode, error) {return ReadData(, ws.StateServerSide)}// ReadClientText reads next text message from rw, considering that caller// represents server side. It is a shortcut for ReadData(rw, ws.StateServerSide).// It discards received binary messages.//// Note this may handle and write control frames into the writer part of a// given io.ReadWriter.func ( io.ReadWriter) ([]byte, error) {, , := readData(, ws.StateServerSide, ws.OpText)return ,}// ReadClientBinary reads next binary message from rw, considering that caller// represents server side. It is a shortcut for ReadData(rw, ws.StateServerSide).// It discards received text messages.//// Note this may handle and write control frames into the writer part of a given// io.ReadWriter.func ( io.ReadWriter) ([]byte, error) {, , := readData(, ws.StateServerSide, ws.OpBinary)return ,}// ReadServerData reads next data message from rw, considering that caller// represents client side. It is a shortcut for ReadData(rw, ws.StateClientSide).//// Note this may handle and write control frames into the writer part of a// given io.ReadWriter.func ( io.ReadWriter) ([]byte, ws.OpCode, error) {return ReadData(, ws.StateClientSide)}// ReadServerText reads next text message from rw, considering that caller// represents client side. It is a shortcut for ReadData(rw, ws.StateClientSide).// It discards received binary messages.//// Note this may handle and write control frames into the writer part of a given// io.ReadWriter.func ( io.ReadWriter) ([]byte, error) {, , := readData(, ws.StateClientSide, ws.OpText)return ,}// ReadServerBinary reads next binary message from rw, considering that caller// represents client side. It is a shortcut for ReadData(rw, ws.StateClientSide).// It discards received text messages.//// Note this may handle and write control frames into the writer part of a// given io.ReadWriter.func ( io.ReadWriter) ([]byte, error) {, , := readData(, ws.StateClientSide, ws.OpBinary)return ,}// WriteMessage is a helper function that writes message to the w. It// constructs single frame with given operation code and payload.// It uses given state to prepare side-dependent things, like cipher// payload bytes from client to server. It will not mutate p bytes if// cipher must be made.//// If you want to write message in fragmented frames, use Writer instead.func ( io.Writer, ws.State, ws.OpCode, []byte) error {return writeFrame(, , , true, )}// WriteServerMessage writes message to w, considering that caller// represents server side.func ( io.Writer, ws.OpCode, []byte) error {return WriteMessage(, ws.StateServerSide, , )}// WriteServerText is the same as WriteServerMessage with// ws.OpText.func ( io.Writer, []byte) error {return WriteServerMessage(, ws.OpText, )}// WriteServerBinary is the same as WriteServerMessage with// ws.OpBinary.func ( io.Writer, []byte) error {return WriteServerMessage(, ws.OpBinary, )}// WriteClientMessage writes message to w, considering that caller// represents client side.func ( io.Writer, ws.OpCode, []byte) error {return WriteMessage(, ws.StateClientSide, , )}// WriteClientText is the same as WriteClientMessage with// ws.OpText.func ( io.Writer, []byte) error {return WriteClientMessage(, ws.OpText, )}// WriteClientBinary is the same as WriteClientMessage with// ws.OpBinary.func ( io.Writer, []byte) error {return WriteClientMessage(, ws.OpBinary, )}// HandleClientControlMessage handles control frame from conn and writes// response when needed.//// It considers that caller represents server side.func ( io.Writer, Message) error {return HandleControlMessage(, ws.StateServerSide, )}// HandleServerControlMessage handles control frame from conn and writes// response when needed.//// It considers that caller represents client side.func ( io.Writer, Message) error {return HandleControlMessage(, ws.StateClientSide, )}// HandleControlMessage handles message which was read by ReadMessage()// functions.//// That is, it is expected, that payload is already unmasked and frame header// were checked by ws.CheckHeader() call.func ( io.Writer, ws.State, Message) error {return (ControlHandler{DisableSrcCiphering: true,Src: bytes.NewReader(.Payload),Dst: ,State: ,}).Handle(ws.Header{Length: int64(len(.Payload)),OpCode: .OpCode,Fin: true,Masked: .ServerSide(),})}// ControlFrameHandler returns FrameHandlerFunc for handling control frames.// For more info see ControlHandler docs.func ( io.Writer, ws.State) FrameHandlerFunc {return func( ws.Header, io.Reader) error {return (ControlHandler{DisableSrcCiphering: true,Src: ,Dst: ,State: ,}).Handle()}}func readData( io.ReadWriter, ws.State, ws.OpCode) ([]byte, ws.OpCode, error) {:= ControlFrameHandler(, ):= Reader{Source: ,State: ,CheckUTF8: true,SkipHeaderCheck: false,OnIntermediate: ,}for {, := .NextFrame()if != nil {return nil, 0,}if .OpCode.IsControl() {if := (, &); != nil {return nil, 0,}continue}if .OpCode& == 0 {if := .Discard(); != nil {return nil, 0,}continue}, := ioutil.ReadAll(&)return , .OpCode,}}
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |