write.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package ws
  2. import (
  3. "encoding/binary"
  4. "io"
  5. )
  6. // Header size length bounds in bytes.
  7. const (
  8. MaxHeaderSize = 14
  9. MinHeaderSize = 2
  10. )
  11. const (
  12. bit0 = 0x80
  13. bit1 = 0x40
  14. bit2 = 0x20
  15. bit3 = 0x10
  16. bit4 = 0x08
  17. bit5 = 0x04
  18. bit6 = 0x02
  19. bit7 = 0x01
  20. len7 = int64(125)
  21. len16 = int64(^(uint16(0)))
  22. len64 = int64(^(uint64(0)) >> 1)
  23. )
  24. // HeaderSize returns number of bytes that are needed to encode given header.
  25. // It returns -1 if header is malformed.
  26. func HeaderSize(h Header) (n int) {
  27. switch {
  28. case h.Length < 126:
  29. n = 2
  30. case h.Length <= len16:
  31. n = 4
  32. case h.Length <= len64:
  33. n = 10
  34. default:
  35. return -1
  36. }
  37. if h.Masked {
  38. n += len(h.Mask)
  39. }
  40. return n
  41. }
  42. // WriteHeader writes header binary representation into w.
  43. func WriteHeader(w io.Writer, h Header) error {
  44. // Make slice of bytes with capacity 14 that could hold any header.
  45. bts := make([]byte, MaxHeaderSize)
  46. if h.Fin {
  47. bts[0] |= bit0
  48. }
  49. bts[0] |= h.Rsv << 4
  50. bts[0] |= byte(h.OpCode)
  51. var n int
  52. switch {
  53. case h.Length <= len7:
  54. bts[1] = byte(h.Length)
  55. n = 2
  56. case h.Length <= len16:
  57. bts[1] = 126
  58. binary.BigEndian.PutUint16(bts[2:4], uint16(h.Length))
  59. n = 4
  60. case h.Length <= len64:
  61. bts[1] = 127
  62. binary.BigEndian.PutUint64(bts[2:10], uint64(h.Length))
  63. n = 10
  64. default:
  65. return ErrHeaderLengthUnexpected
  66. }
  67. if h.Masked {
  68. bts[1] |= bit0
  69. n += copy(bts[n:], h.Mask[:])
  70. }
  71. _, err := w.Write(bts[:n])
  72. return err
  73. }
  74. // WriteFrame writes frame binary representation into w.
  75. func WriteFrame(w io.Writer, f Frame) error {
  76. err := WriteHeader(w, f.Header)
  77. if err != nil {
  78. return err
  79. }
  80. _, err = w.Write(f.Payload)
  81. return err
  82. }
  83. // MustWriteFrame is like WriteFrame but panics if frame can not be read.
  84. func MustWriteFrame(w io.Writer, f Frame) {
  85. if err := WriteFrame(w, f); err != nil {
  86. panic(err)
  87. }
  88. }