MCPcopy Index your code
hub / github.com/subtrace/subtrace / readFrame

Method readFrame

cmd/run/socket/proxy.go:692–778  ·  view source on GitHub ↗
(isClient bool)

Source from the content-addressed store, hash-verified

690}
691
692func (w *websocket) readFrame(isClient bool) (*websocketFrame, error) {
693 header := make([]byte, 2)
694 if _, err := w.readFull(isClient, header); err != nil {
695 return nil, fmt.Errorf("read header: %w", err)
696 }
697
698 fin := header[0]&0x80 != 0
699
700 rsv := header[0] & 0x70
701 rsv1 := rsv&0x40 != 0
702 rsv2 := rsv&0x20 != 0
703 rsv3 := rsv&0x10 != 0
704
705 if rsv2 || rsv3 {
706 return nil, fmt.Errorf("unsupported extension: RSV1=%t, RSV2=%t, RSV3=%t", rsv1, rsv2, rsv3)
707 }
708
709 opcode := header[0] & 0x0F
710
711 masked := header[1]&0x80 != 0
712 if isClient && !masked {
713 return nil, fmt.Errorf("client sent unmasked frame")
714 }
715
716 switch opcode {
717 case wsOpcodeContinuation, wsOpcodeText, wsOpcodeBinary, wsOpcodePing, wsOpcodePong, wsOpcodeClose:
718 default:
719 return nil, fmt.Errorf("invalid opcode: %x", opcode)
720 }
721
722 payloadLen := uint64(header[1] & 0x7F)
723 if payloadLen == 126 {
724 ext := make([]byte, 2)
725 if _, err := w.readFull(isClient, ext); err != nil {
726 return nil, fmt.Errorf("read extended length (len=126): %w", err)
727 }
728 payloadLen = uint64(binary.BigEndian.Uint16(ext))
729 } else if payloadLen == 127 {
730 ext := make([]byte, 8)
731 if _, err := w.readFull(isClient, ext); err != nil {
732 return nil, fmt.Errorf("read extended length (len=127): %w", err)
733 }
734 payloadLen = binary.BigEndian.Uint64(ext)
735 }
736
737 mask := make([]byte, 4)
738 if masked {
739 if _, err := w.readFull(isClient, mask); err != nil {
740 return nil, fmt.Errorf("read mask: %w", err)
741 }
742 }
743
744 // Check beforehand so we don't allocate arbitrarily large amounts of memory
745 // for the payload. All the other reads use fixed size buffers, so they're fine.
746 remaining := w.n.Load()
747 if remaining < payloadLen {
748 return nil, fmt.Errorf("%w: limit=%d, have=%d, want=%d, msgsRead=%d", errWebsocketPayloadLimitExceeded, tracer.PayloadLimitBytes, remaining, payloadLen, len(w.getMessages()))
749 }

Callers 1

proxyMethod · 0.95

Calls 3

readFullMethod · 0.95
getMessagesMethod · 0.95
LoadMethod · 0.80

Tested by

no test coverage detected