(ctx context.Context)
| 181 | } |
| 182 | |
| 183 | func (c *Conn) readLoop(ctx context.Context) (header, error) { |
| 184 | for { |
| 185 | h, err := c.readFrameHeader(ctx) |
| 186 | if err != nil { |
| 187 | return header{}, err |
| 188 | } |
| 189 | |
| 190 | if h.rsv1 && c.readRSV1Illegal(h) || h.rsv2 || h.rsv3 { |
| 191 | err := fmt.Errorf("received header with unexpected rsv bits set: %v:%v:%v", h.rsv1, h.rsv2, h.rsv3) |
| 192 | c.writeError(StatusProtocolError, err) |
| 193 | return header{}, err |
| 194 | } |
| 195 | |
| 196 | if !c.client && !h.masked { |
| 197 | return header{}, errors.New("received unmasked frame from client") |
| 198 | } |
| 199 | |
| 200 | switch h.opcode { |
| 201 | case opClose, opPing, opPong: |
| 202 | err = c.handleControl(ctx, h) |
| 203 | if err != nil { |
| 204 | // Pass through CloseErrors when receiving a close frame. |
| 205 | if h.opcode == opClose && CloseStatus(err) != -1 { |
| 206 | return header{}, err |
| 207 | } |
| 208 | return header{}, fmt.Errorf("failed to handle control frame %v: %w", h.opcode, err) |
| 209 | } |
| 210 | case opContinuation, opText, opBinary: |
| 211 | return h, nil |
| 212 | default: |
| 213 | err := fmt.Errorf("received unknown opcode %v", h.opcode) |
| 214 | c.writeError(StatusProtocolError, err) |
| 215 | return header{}, err |
| 216 | } |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | // prepareRead sets the read timeout and checks whether the connection is closed. |
| 221 | func (c *Conn) prepareRead(ctx context.Context) (bool, error) { |
no test coverage detected