| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- package record
-
- import (
- "bytes"
- "encoding/base64"
- "encoding/binary"
- "fmt"
- "io"
- )
-
- type Record struct {
- Type Type
- Version Version
- Payload bytes.Buffer
- }
-
- func (r *Record) String() string {
- return fmt.Sprintf("<tlsRecord(type=%v, version=%v, payload=%s)>",
- r.Type,
- r.Version,
- base64.StdEncoding.EncodeToString(r.Payload.Bytes()))
- }
-
- func (r *Record) Reset() {
- r.Payload.Reset()
- }
-
- func (r *Record) Read(reader io.Reader) error {
- r.Reset()
-
- buf := [2]byte{}
-
- if _, err := io.ReadFull(reader, buf[:1]); err != nil {
- return fmt.Errorf("cannot read type: %w", err)
- }
-
- r.Type = Type(buf[0])
- if err := r.Type.Valid(); err != nil {
- return fmt.Errorf("invalid type: %w", err)
- }
-
- if _, err := io.ReadFull(reader, buf[:]); err != nil {
- return fmt.Errorf("cannot read version: %w", err)
- }
-
- r.Version = Version(binary.BigEndian.Uint16(buf[:]))
- if err := r.Version.Valid(); err != nil {
- return fmt.Errorf("invalid version: %w", err)
- }
-
- if _, err := io.ReadFull(reader, buf[:]); err != nil {
- return fmt.Errorf("cannot read payload length: %w", err)
- }
-
- length := int64(binary.BigEndian.Uint16(buf[:]))
- if _, err := io.CopyN(&r.Payload, reader, length); err != nil {
- return fmt.Errorf("cannot read payload: %w", err)
- }
-
- return nil
- }
-
- func (r *Record) Dump(writer io.Writer) error {
- buf := [2]byte{byte(r.Type), 0}
- if _, err := writer.Write(buf[:1]); err != nil {
- return fmt.Errorf("cannot dump record type: %w", err)
- }
-
- binary.BigEndian.PutUint16(buf[:], uint16(r.Version))
-
- if _, err := writer.Write(buf[:]); err != nil {
- return fmt.Errorf("cannot dump version: %w", err)
- }
-
- binary.BigEndian.PutUint16(buf[:], uint16(r.Payload.Len()))
-
- if _, err := writer.Write(buf[:]); err != nil {
- return fmt.Errorf("cannot dump payload length: %w", err)
- }
-
- if _, err := writer.Write(r.Payload.Bytes()); err != nil {
- return fmt.Errorf("cannot dump record: %w", err)
- }
-
- return nil
- }
|