readFrameHeader reads a header from the reader. See https://tools.ietf.org/html/rfc6455#section-5.2.
(r *bufio.Reader, readBuf []byte)
| 50 | // readFrameHeader reads a header from the reader. |
| 51 | // See https://tools.ietf.org/html/rfc6455#section-5.2. |
| 52 | func readFrameHeader(r *bufio.Reader, readBuf []byte) (h header, err error) { |
| 53 | defer errd.Wrap(&err, "failed to read frame header") |
| 54 | |
| 55 | b, err := r.ReadByte() |
| 56 | if err != nil { |
| 57 | return header{}, err |
| 58 | } |
| 59 | |
| 60 | h.fin = b&(1<<7) != 0 |
| 61 | h.rsv1 = b&(1<<6) != 0 |
| 62 | h.rsv2 = b&(1<<5) != 0 |
| 63 | h.rsv3 = b&(1<<4) != 0 |
| 64 | |
| 65 | h.opcode = opcode(b & 0xf) |
| 66 | |
| 67 | b, err = r.ReadByte() |
| 68 | if err != nil { |
| 69 | return header{}, err |
| 70 | } |
| 71 | |
| 72 | h.masked = b&(1<<7) != 0 |
| 73 | |
| 74 | payloadLength := b &^ (1 << 7) |
| 75 | switch { |
| 76 | case payloadLength < 126: |
| 77 | h.payloadLength = int64(payloadLength) |
| 78 | case payloadLength == 126: |
| 79 | _, err = io.ReadFull(r, readBuf[:2]) |
| 80 | h.payloadLength = int64(binary.BigEndian.Uint16(readBuf)) |
| 81 | case payloadLength == 127: |
| 82 | _, err = io.ReadFull(r, readBuf) |
| 83 | h.payloadLength = int64(binary.BigEndian.Uint64(readBuf)) |
| 84 | } |
| 85 | if err != nil { |
| 86 | return header{}, err |
| 87 | } |
| 88 | |
| 89 | if h.payloadLength < 0 { |
| 90 | return header{}, fmt.Errorf("received negative payload length: %v", h.payloadLength) |
| 91 | } |
| 92 | |
| 93 | if h.masked { |
| 94 | _, err = io.ReadFull(r, readBuf[:4]) |
| 95 | if err != nil { |
| 96 | return header{}, err |
| 97 | } |
| 98 | h.maskKey = binary.LittleEndian.Uint32(readBuf) |
| 99 | } |
| 100 | |
| 101 | return h, nil |
| 102 | } |
| 103 | |
| 104 | // maxControlPayload is the maximum length of a control frame payload. |
| 105 | // See https://tools.ietf.org/html/rfc6455#section-5.5. |
searching dependent graphs…