Return the next frame from the socket.
(buf, continuation=False)
| 215 | |
| 216 | |
| 217 | def parse_frame(buf, continuation=False): |
| 218 | """Return the next frame from the socket.""" |
| 219 | # read header |
| 220 | data = yield from buf.read(2) |
| 221 | first_byte, second_byte = data |
| 222 | |
| 223 | fin = (first_byte >> 7) & 1 |
| 224 | rsv1 = (first_byte >> 6) & 1 |
| 225 | rsv2 = (first_byte >> 5) & 1 |
| 226 | rsv3 = (first_byte >> 4) & 1 |
| 227 | opcode = first_byte & 0xf |
| 228 | |
| 229 | # frame-fin = %x0 ; more frames of this message follow |
| 230 | # / %x1 ; final frame of this message |
| 231 | # frame-rsv1 = %x0 ; 1 bit, MUST be 0 unless negotiated otherwise |
| 232 | # frame-rsv2 = %x0 ; 1 bit, MUST be 0 unless negotiated otherwise |
| 233 | # frame-rsv3 = %x0 ; 1 bit, MUST be 0 unless negotiated otherwise |
| 234 | if rsv1 or rsv2 or rsv3: |
| 235 | raise WebSocketError( |
| 236 | CLOSE_PROTOCOL_ERROR, |
| 237 | 'Received frame with non-zero reserved bits') |
| 238 | |
| 239 | if opcode > 0x7 and fin == 0: |
| 240 | raise WebSocketError( |
| 241 | CLOSE_PROTOCOL_ERROR, |
| 242 | 'Received fragmented control frame') |
| 243 | |
| 244 | if fin == 0 and opcode == OPCODE_CONTINUATION and not continuation: |
| 245 | raise WebSocketError( |
| 246 | CLOSE_PROTOCOL_ERROR, |
| 247 | 'Received new fragment frame with non-zero ' |
| 248 | 'opcode {!r}'.format(opcode)) |
| 249 | |
| 250 | has_mask = (second_byte >> 7) & 1 |
| 251 | length = (second_byte) & 0x7f |
| 252 | |
| 253 | # Control frames MUST have a payload length of 125 bytes or less |
| 254 | if opcode > 0x7 and length > 125: |
| 255 | raise WebSocketError( |
| 256 | CLOSE_PROTOCOL_ERROR, |
| 257 | "Control frame payload cannot be larger than 125 bytes") |
| 258 | |
| 259 | # read payload |
| 260 | if length == 126: |
| 261 | data = yield from buf.read(2) |
| 262 | length = UNPACK_LEN2(data)[0] |
| 263 | elif length > 126: |
| 264 | data = yield from buf.read(8) |
| 265 | length = UNPACK_LEN3(data)[0] |
| 266 | |
| 267 | if has_mask: |
| 268 | mask = yield from buf.read(4) |
| 269 | |
| 270 | if length: |
| 271 | payload = yield from buf.read(length) |
| 272 | else: |
| 273 | payload = bytearray() |
| 274 |
no test coverage detected