mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 13:49:58 +00:00
TUN-8685: Bump coredns dependency
Closes TUN-8685
This commit is contained in:
4
vendor/github.com/gobwas/ws/wsutil/cipher.go
generated
vendored
4
vendor/github.com/gobwas/ws/wsutil/cipher.go
generated
vendored
@@ -34,7 +34,7 @@ func (c *CipherReader) Read(p []byte) (n int, err error) {
|
||||
n, err = c.r.Read(p)
|
||||
ws.Cipher(p[:n], c.mask, c.pos)
|
||||
c.pos += n
|
||||
return
|
||||
return n, err
|
||||
}
|
||||
|
||||
// CipherWriter implements io.Writer that applies xor-cipher to the bytes
|
||||
@@ -68,5 +68,5 @@ func (c *CipherWriter) Write(p []byte) (n int, err error) {
|
||||
n, err = c.w.Write(cp)
|
||||
c.pos += n
|
||||
|
||||
return
|
||||
return n, err
|
||||
}
|
||||
|
1
vendor/github.com/gobwas/ws/wsutil/dialer.go
generated
vendored
1
vendor/github.com/gobwas/ws/wsutil/dialer.go
generated
vendored
@@ -113,6 +113,7 @@ type rwConn struct {
|
||||
func (rwc rwConn) Read(p []byte) (int, error) {
|
||||
return rwc.r.Read(p)
|
||||
}
|
||||
|
||||
func (rwc rwConn) Write(p []byte) (int, error) {
|
||||
return rwc.w.Write(p)
|
||||
}
|
||||
|
31
vendor/github.com/gobwas/ws/wsutil/extenstion.go
generated
vendored
Normal file
31
vendor/github.com/gobwas/ws/wsutil/extenstion.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
package wsutil
|
||||
|
||||
import "github.com/gobwas/ws"
|
||||
|
||||
// RecvExtension is an interface for clearing fragment header RSV bits.
|
||||
type RecvExtension interface {
|
||||
UnsetBits(ws.Header) (ws.Header, error)
|
||||
}
|
||||
|
||||
// RecvExtensionFunc is an adapter to allow the use of ordinary functions as
|
||||
// RecvExtension.
|
||||
type RecvExtensionFunc func(ws.Header) (ws.Header, error)
|
||||
|
||||
// BitsRecv implements RecvExtension.
|
||||
func (fn RecvExtensionFunc) UnsetBits(h ws.Header) (ws.Header, error) {
|
||||
return fn(h)
|
||||
}
|
||||
|
||||
// SendExtension is an interface for setting fragment header RSV bits.
|
||||
type SendExtension interface {
|
||||
SetBits(ws.Header) (ws.Header, error)
|
||||
}
|
||||
|
||||
// SendExtensionFunc is an adapter to allow the use of ordinary functions as
|
||||
// SendExtension.
|
||||
type SendExtensionFunc func(ws.Header) (ws.Header, error)
|
||||
|
||||
// BitsSend implements SendExtension.
|
||||
func (fn SendExtensionFunc) SetBits(h ws.Header) (ws.Header, error) {
|
||||
return fn(h)
|
||||
}
|
2
vendor/github.com/gobwas/ws/wsutil/handler.go
generated
vendored
2
vendor/github.com/gobwas/ws/wsutil/handler.go
generated
vendored
@@ -199,7 +199,7 @@ func (c ControlHandler) HandleClose(h ws.Header) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = w.Flush(); err != nil {
|
||||
if err := w.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
return ClosedError{
|
||||
|
8
vendor/github.com/gobwas/ws/wsutil/helper.go
generated
vendored
8
vendor/github.com/gobwas/ws/wsutil/helper.go
generated
vendored
@@ -64,14 +64,14 @@ func ReadMessage(r io.Reader, s ws.State, m []Message) ([]Message, error) {
|
||||
|
||||
// ReadClientMessage reads next message from r, considering that caller
|
||||
// represents server side.
|
||||
// It is a shortcut for ReadMessage(r, ws.StateServerSide, m)
|
||||
// It is a shortcut for ReadMessage(r, ws.StateServerSide, m).
|
||||
func ReadClientMessage(r io.Reader, m []Message) ([]Message, error) {
|
||||
return ReadMessage(r, ws.StateServerSide, m)
|
||||
}
|
||||
|
||||
// ReadServerMessage reads next message from r, considering that caller
|
||||
// represents client side.
|
||||
// It is a shortcut for ReadMessage(r, ws.StateClientSide, m)
|
||||
// It is a shortcut for ReadMessage(r, ws.StateClientSide, m).
|
||||
func ReadServerMessage(r io.Reader, m []Message) ([]Message, error) {
|
||||
return ReadMessage(r, ws.StateClientSide, m)
|
||||
}
|
||||
@@ -113,7 +113,7 @@ func ReadClientText(rw io.ReadWriter) ([]byte, error) {
|
||||
// It discards received text messages.
|
||||
//
|
||||
// Note this may handle and write control frames into the writer part of a given
|
||||
// io.ReadWriter.
|
||||
// io.ReadWriter.
|
||||
func ReadClientBinary(rw io.ReadWriter) ([]byte, error) {
|
||||
p, _, err := readData(rw, ws.StateServerSide, ws.OpBinary)
|
||||
return p, err
|
||||
@@ -133,7 +133,7 @@ func ReadServerData(rw io.ReadWriter) ([]byte, ws.OpCode, error) {
|
||||
// It discards received binary messages.
|
||||
//
|
||||
// Note this may handle and write control frames into the writer part of a given
|
||||
// io.ReadWriter.
|
||||
// io.ReadWriter.
|
||||
func ReadServerText(rw io.ReadWriter) ([]byte, error) {
|
||||
p, _, err := readData(rw, ws.StateClientSide, ws.OpText)
|
||||
return p, err
|
||||
|
46
vendor/github.com/gobwas/ws/wsutil/reader.go
generated
vendored
46
vendor/github.com/gobwas/ws/wsutil/reader.go
generated
vendored
@@ -12,6 +12,10 @@ import (
|
||||
// preceding NextFrame() call.
|
||||
var ErrNoFrameAdvance = errors.New("no frame advance")
|
||||
|
||||
// ErrFrameTooLarge indicates that a message of length higher than
|
||||
// MaxFrameSize was being read.
|
||||
var ErrFrameTooLarge = errors.New("frame too large")
|
||||
|
||||
// FrameHandlerFunc handles parsed frame header and its body represented by
|
||||
// io.Reader.
|
||||
//
|
||||
@@ -37,7 +41,17 @@ type Reader struct {
|
||||
// bytes are not valid UTF-8 sequence, ErrInvalidUTF8 returned.
|
||||
CheckUTF8 bool
|
||||
|
||||
// TODO(gobwas): add max frame size limit here.
|
||||
// Extensions is a list of negotiated extensions for reader Source.
|
||||
// It is used to meet the specs and clear appropriate bits in fragment
|
||||
// header RSV segment.
|
||||
Extensions []RecvExtension
|
||||
|
||||
// MaxFrameSize controls the maximum frame size in bytes
|
||||
// that can be read. A message exceeding that size will return
|
||||
// a ErrFrameTooLarge to the application.
|
||||
//
|
||||
// Not setting this field means there is no limit.
|
||||
MaxFrameSize int64
|
||||
|
||||
OnContinuation FrameHandlerFunc
|
||||
OnIntermediate FrameHandlerFunc
|
||||
@@ -97,12 +111,13 @@ func (r *Reader) Read(p []byte) (n int, err error) {
|
||||
|
||||
n, err = r.frame.Read(p)
|
||||
if err != nil && err != io.EOF {
|
||||
return
|
||||
return n, err
|
||||
}
|
||||
if err == nil && r.raw.N != 0 {
|
||||
return
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// EOF condition (either err is io.EOF or r.raw.N is zero).
|
||||
switch {
|
||||
case r.raw.N != 0:
|
||||
err = io.ErrUnexpectedEOF
|
||||
@@ -112,6 +127,8 @@ func (r *Reader) Read(p []byte) (n int, err error) {
|
||||
r.resetFragment()
|
||||
|
||||
case r.CheckUTF8 && !r.utf8.Valid():
|
||||
// NOTE: check utf8 only when full message received, since partial
|
||||
// reads may be invalid.
|
||||
n = r.utf8.Accepted()
|
||||
err = ErrInvalidUTF8
|
||||
|
||||
@@ -120,7 +137,7 @@ func (r *Reader) Read(p []byte) (n int, err error) {
|
||||
err = io.EOF
|
||||
}
|
||||
|
||||
return
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Discard discards current message unread bytes.
|
||||
@@ -166,14 +183,29 @@ func (r *Reader) NextFrame() (hdr ws.Header, err error) {
|
||||
return hdr, err
|
||||
}
|
||||
|
||||
if n := r.MaxFrameSize; n > 0 && hdr.Length > n {
|
||||
return hdr, ErrFrameTooLarge
|
||||
}
|
||||
|
||||
// Save raw reader to use it on discarding frame without ciphering and
|
||||
// other streaming checks.
|
||||
r.raw = io.LimitedReader{r.Source, hdr.Length}
|
||||
r.raw = io.LimitedReader{
|
||||
R: r.Source,
|
||||
N: hdr.Length,
|
||||
}
|
||||
|
||||
frame := io.Reader(&r.raw)
|
||||
if hdr.Masked {
|
||||
frame = NewCipherReader(frame, hdr.Mask)
|
||||
}
|
||||
|
||||
for _, x := range r.Extensions {
|
||||
hdr, err = x.UnsetBits(hdr)
|
||||
if err != nil {
|
||||
return hdr, err
|
||||
}
|
||||
}
|
||||
|
||||
if r.fragmented() {
|
||||
if hdr.OpCode.IsControl() {
|
||||
if cb := r.OnIntermediate; cb != nil {
|
||||
@@ -183,7 +215,7 @@ func (r *Reader) NextFrame() (hdr ws.Header, err error) {
|
||||
// Ensure that src is empty.
|
||||
_, err = io.Copy(ioutil.Discard, &r.raw)
|
||||
}
|
||||
return
|
||||
return hdr, err
|
||||
}
|
||||
} else {
|
||||
r.opCode = hdr.OpCode
|
||||
@@ -208,7 +240,7 @@ func (r *Reader) NextFrame() (hdr ws.Header, err error) {
|
||||
r.State = r.State.Set(ws.StateFragmented)
|
||||
}
|
||||
|
||||
return
|
||||
return hdr, err
|
||||
}
|
||||
|
||||
func (r *Reader) fragmented() bool {
|
||||
|
2
vendor/github.com/gobwas/ws/wsutil/utf8.go
generated
vendored
2
vendor/github.com/gobwas/ws/wsutil/utf8.go
generated
vendored
@@ -65,7 +65,7 @@ func (u *UTF8Reader) Read(p []byte) (n int, err error) {
|
||||
u.state, u.codep = s, c
|
||||
u.accepted = accepted
|
||||
|
||||
return
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Valid checks current reader state. It returns true if all read bytes are
|
||||
|
319
vendor/github.com/gobwas/ws/wsutil/writer.go
generated
vendored
319
vendor/github.com/gobwas/ws/wsutil/writer.go
generated
vendored
@@ -84,38 +84,6 @@ func (c *ControlWriter) Flush() error {
|
||||
return c.w.Flush()
|
||||
}
|
||||
|
||||
// Writer contains logic of buffering output data into a WebSocket fragments.
|
||||
// It is much the same as bufio.Writer, except the thing that it works with
|
||||
// WebSocket frames, not the raw data.
|
||||
//
|
||||
// Writer writes frames with specified OpCode.
|
||||
// It uses ws.State to decide whether the output frames must be masked.
|
||||
//
|
||||
// Note that it does not check control frame size or other RFC rules.
|
||||
// That is, it must be used with special care to write control frames without
|
||||
// violation of RFC. You could use ControlWriter that wraps Writer and contains
|
||||
// some guards for writing control frames.
|
||||
//
|
||||
// If an error occurs writing to a Writer, no more data will be accepted and
|
||||
// all subsequent writes will return the error.
|
||||
// After all data has been written, the client should call the Flush() method
|
||||
// to guarantee all data has been forwarded to the underlying io.Writer.
|
||||
type Writer struct {
|
||||
dest io.Writer
|
||||
|
||||
n int // Buffered bytes counter.
|
||||
raw []byte // Raw representation of buffer, including reserved header bytes.
|
||||
buf []byte // Writeable part of buffer, without reserved header bytes.
|
||||
|
||||
op ws.OpCode
|
||||
state ws.State
|
||||
|
||||
dirty bool
|
||||
fragmented bool
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
var writers = pool.New(128, 65536)
|
||||
|
||||
// GetWriter tries to reuse Writer getting it from the pool.
|
||||
@@ -145,6 +113,58 @@ func PutWriter(w *Writer) {
|
||||
writers.Put(w, w.Size())
|
||||
}
|
||||
|
||||
// Writer contains logic of buffering output data into a WebSocket fragments.
|
||||
// It is much the same as bufio.Writer, except the thing that it works with
|
||||
// WebSocket frames, not the raw data.
|
||||
//
|
||||
// Writer writes frames with specified OpCode.
|
||||
// It uses ws.State to decide whether the output frames must be masked.
|
||||
//
|
||||
// Note that it does not check control frame size or other RFC rules.
|
||||
// That is, it must be used with special care to write control frames without
|
||||
// violation of RFC. You could use ControlWriter that wraps Writer and contains
|
||||
// some guards for writing control frames.
|
||||
//
|
||||
// If an error occurs writing to a Writer, no more data will be accepted and
|
||||
// all subsequent writes will return the error.
|
||||
//
|
||||
// After all data has been written, the client should call the Flush() method
|
||||
// to guarantee all data has been forwarded to the underlying io.Writer.
|
||||
type Writer struct {
|
||||
// dest specifies a destination of buffer flushes.
|
||||
dest io.Writer
|
||||
|
||||
// op specifies the WebSocket operation code used in flushed frames.
|
||||
op ws.OpCode
|
||||
|
||||
// state specifies the state of the Writer.
|
||||
state ws.State
|
||||
|
||||
// extensions is a list of negotiated extensions for writer Dest.
|
||||
// It is used to meet the specs and set appropriate bits in fragment
|
||||
// header RSV segment.
|
||||
extensions []SendExtension
|
||||
|
||||
// noFlush reports whether buffer must grow instead of being flushed.
|
||||
noFlush bool
|
||||
|
||||
// Raw representation of the buffer, including reserved header bytes.
|
||||
raw []byte
|
||||
|
||||
// Writeable part of buffer, without reserved header bytes.
|
||||
// Resetting this to nil will not result in reallocation if raw is not nil.
|
||||
// And vice versa: if buf is not nil, then Writer is assumed as ready and
|
||||
// initialized.
|
||||
buf []byte
|
||||
|
||||
// Buffered bytes counter.
|
||||
n int
|
||||
|
||||
dirty bool
|
||||
fseq int
|
||||
err error
|
||||
}
|
||||
|
||||
// NewWriter returns a new Writer whose buffer has the DefaultWriteBuffer size.
|
||||
func NewWriter(dest io.Writer, state ws.State, op ws.OpCode) *Writer {
|
||||
return NewWriterBufferSize(dest, state, op, 0)
|
||||
@@ -186,57 +206,63 @@ func NewWriterBufferSize(dest io.Writer, state ws.State, op ws.OpCode, n int) *W
|
||||
//
|
||||
// It panics if len(buf) is too small to fit header and payload data.
|
||||
func NewWriterBuffer(dest io.Writer, state ws.State, op ws.OpCode, buf []byte) *Writer {
|
||||
offset := reserve(state, len(buf))
|
||||
if len(buf) <= offset {
|
||||
panic("buffer too small")
|
||||
}
|
||||
|
||||
return &Writer{
|
||||
w := &Writer{
|
||||
dest: dest,
|
||||
raw: buf,
|
||||
buf: buf[offset:],
|
||||
state: state,
|
||||
op: op,
|
||||
raw: buf,
|
||||
}
|
||||
w.initBuf()
|
||||
return w
|
||||
}
|
||||
|
||||
func reserve(state ws.State, n int) (offset int) {
|
||||
var mask int
|
||||
if state.ClientSide() {
|
||||
mask = 4
|
||||
}
|
||||
|
||||
switch {
|
||||
case n <= int(len7)+mask+2:
|
||||
return mask + 2
|
||||
case n <= int(len16)+mask+4:
|
||||
return mask + 4
|
||||
default:
|
||||
return mask + 10
|
||||
func (w *Writer) initBuf() {
|
||||
offset := reserve(w.state, len(w.raw))
|
||||
if len(w.raw) <= offset {
|
||||
panic("wsutil: writer buffer is too small")
|
||||
}
|
||||
w.buf = w.raw[offset:]
|
||||
}
|
||||
|
||||
// headerSize returns number of bytes needed to encode header of a frame with
|
||||
// given state and length.
|
||||
func headerSize(s ws.State, n int) int {
|
||||
return ws.HeaderSize(ws.Header{
|
||||
Length: int64(n),
|
||||
Masked: s.ClientSide(),
|
||||
})
|
||||
}
|
||||
|
||||
// Reset discards any buffered data, clears error, and resets w to have given
|
||||
// state and write frames with given OpCode to dest.
|
||||
// Reset resets Writer as it was created by New() methods.
|
||||
// Note that Reset does reset extensions and other options was set after
|
||||
// Writer initialization.
|
||||
func (w *Writer) Reset(dest io.Writer, state ws.State, op ws.OpCode) {
|
||||
w.n = 0
|
||||
w.dirty = false
|
||||
w.fragmented = false
|
||||
w.dest = dest
|
||||
w.state = state
|
||||
w.op = op
|
||||
|
||||
w.initBuf()
|
||||
|
||||
w.n = 0
|
||||
w.dirty = false
|
||||
w.fseq = 0
|
||||
w.extensions = w.extensions[:0]
|
||||
w.noFlush = false
|
||||
}
|
||||
|
||||
// Size returns the size of the underlying buffer in bytes.
|
||||
// ResetOp is an quick version of Reset().
|
||||
// ResetOp does reset unwritten fragments and does not reset results of
|
||||
// SetExtensions() or DisableFlush() methods.
|
||||
func (w *Writer) ResetOp(op ws.OpCode) {
|
||||
w.op = op
|
||||
w.n = 0
|
||||
w.dirty = false
|
||||
w.fseq = 0
|
||||
}
|
||||
|
||||
// SetExtensions adds xs as extensions to be used during writes.
|
||||
func (w *Writer) SetExtensions(xs ...SendExtension) {
|
||||
w.extensions = xs
|
||||
}
|
||||
|
||||
// DisableFlush denies Writer to write fragments.
|
||||
func (w *Writer) DisableFlush() {
|
||||
w.noFlush = true
|
||||
}
|
||||
|
||||
// Size returns the size of the underlying buffer in bytes (not including
|
||||
// WebSocket header bytes).
|
||||
func (w *Writer) Size() int {
|
||||
return len(w.buf)
|
||||
}
|
||||
@@ -263,6 +289,10 @@ func (w *Writer) Write(p []byte) (n int, err error) {
|
||||
|
||||
var nn int
|
||||
for len(p) > w.Available() && w.err == nil {
|
||||
if w.noFlush {
|
||||
w.Grow(len(p))
|
||||
continue
|
||||
}
|
||||
if w.Buffered() == 0 {
|
||||
// Large write, empty buffer. Write directly from p to avoid copy.
|
||||
// Trade off here is that we make additional Write() to underlying
|
||||
@@ -295,6 +325,55 @@ func (w *Writer) Write(p []byte) (n int, err error) {
|
||||
return n, w.err
|
||||
}
|
||||
|
||||
func ceilPowerOfTwo(n int) int {
|
||||
n |= n >> 1
|
||||
n |= n >> 2
|
||||
n |= n >> 4
|
||||
n |= n >> 8
|
||||
n |= n >> 16
|
||||
n |= n >> 32
|
||||
n++
|
||||
return n
|
||||
}
|
||||
|
||||
// Grow grows Writer's internal buffer capacity to guarantee space for another
|
||||
// n bytes of _payload_ -- that is, frame header is not included in n.
|
||||
func (w *Writer) Grow(n int) {
|
||||
// NOTE: we must respect the possibility of header reserved bytes grow.
|
||||
var (
|
||||
size = len(w.raw)
|
||||
prevOffset = len(w.raw) - len(w.buf)
|
||||
nextOffset = len(w.raw) - len(w.buf)
|
||||
buffered = w.Buffered()
|
||||
)
|
||||
for cap := size - nextOffset - buffered; cap < n; {
|
||||
// This loop runs twice only at split cases, when reservation of raw
|
||||
// buffer space for the header shrinks capacity of new buffer such that
|
||||
// it still less than n.
|
||||
//
|
||||
// Loop is safe here because:
|
||||
// - (offset + buffered + n) is greater than size, otherwise (cap < n)
|
||||
// would be false:
|
||||
// size = offset + buffered + freeSpace (cap)
|
||||
// size' = offset + buffered + wantSpace (n)
|
||||
// Since (cap < n) is true in the loop condition, size' is guaranteed
|
||||
// to be greater => no infinite loop.
|
||||
size = ceilPowerOfTwo(nextOffset + buffered + n)
|
||||
nextOffset = reserve(w.state, size)
|
||||
cap = size - nextOffset - buffered
|
||||
}
|
||||
if size < len(w.raw) {
|
||||
panic("wsutil: buffer grow leads to its reduce")
|
||||
}
|
||||
if size == len(w.raw) {
|
||||
return
|
||||
}
|
||||
p := make([]byte, size)
|
||||
copy(p[nextOffset-prevOffset:], w.raw[:prevOffset+buffered])
|
||||
w.raw = p
|
||||
w.buf = w.raw[nextOffset:]
|
||||
}
|
||||
|
||||
// WriteThrough writes data bypassing the buffer.
|
||||
// Note that Writer's buffer must be empty before calling WriteThrough().
|
||||
func (w *Writer) WriteThrough(p []byte) (n int, err error) {
|
||||
@@ -305,13 +384,37 @@ func (w *Writer) WriteThrough(p []byte) (n int, err error) {
|
||||
return 0, ErrNotEmpty
|
||||
}
|
||||
|
||||
w.err = writeFrame(w.dest, w.state, w.opCode(), false, p)
|
||||
var frame ws.Frame
|
||||
frame.Header = ws.Header{
|
||||
OpCode: w.opCode(),
|
||||
Fin: false,
|
||||
Length: int64(len(p)),
|
||||
}
|
||||
for _, x := range w.extensions {
|
||||
frame.Header, err = x.SetBits(frame.Header)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
if w.state.ClientSide() {
|
||||
// Should copy bytes to prevent corruption of caller data.
|
||||
payload := pbytes.GetLen(len(p))
|
||||
defer pbytes.Put(payload)
|
||||
copy(payload, p)
|
||||
|
||||
frame.Payload = payload
|
||||
frame = ws.MaskFrameInPlace(frame)
|
||||
} else {
|
||||
frame.Payload = p
|
||||
}
|
||||
|
||||
w.err = ws.WriteFrame(w.dest, frame)
|
||||
if w.err == nil {
|
||||
n = len(p)
|
||||
}
|
||||
|
||||
w.dirty = true
|
||||
w.fragmented = true
|
||||
w.fseq++
|
||||
|
||||
return n, w.err
|
||||
}
|
||||
@@ -321,7 +424,11 @@ func (w *Writer) ReadFrom(src io.Reader) (n int64, err error) {
|
||||
var nn int
|
||||
for err == nil {
|
||||
if w.Available() == 0 {
|
||||
err = w.FlushFragment()
|
||||
if w.noFlush {
|
||||
w.Grow(w.Buffered()) // Twice bigger.
|
||||
} else {
|
||||
err = w.FlushFragment()
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -367,7 +474,7 @@ func (w *Writer) Flush() error {
|
||||
w.err = w.flushFragment(true)
|
||||
w.n = 0
|
||||
w.dirty = false
|
||||
w.fragmented = false
|
||||
w.fseq = 0
|
||||
|
||||
return w.err
|
||||
}
|
||||
@@ -381,35 +488,49 @@ func (w *Writer) FlushFragment() error {
|
||||
|
||||
w.err = w.flushFragment(false)
|
||||
w.n = 0
|
||||
w.fragmented = true
|
||||
w.fseq++
|
||||
|
||||
return w.err
|
||||
}
|
||||
|
||||
func (w *Writer) flushFragment(fin bool) error {
|
||||
frame := ws.NewFrame(w.opCode(), fin, w.buf[:w.n])
|
||||
func (w *Writer) flushFragment(fin bool) (err error) {
|
||||
var (
|
||||
payload = w.buf[:w.n]
|
||||
header = ws.Header{
|
||||
OpCode: w.opCode(),
|
||||
Fin: fin,
|
||||
Length: int64(len(payload)),
|
||||
}
|
||||
)
|
||||
for _, ext := range w.extensions {
|
||||
header, err = ext.SetBits(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if w.state.ClientSide() {
|
||||
frame = ws.MaskFrameInPlace(frame)
|
||||
header.Masked = true
|
||||
header.Mask = ws.NewMask()
|
||||
ws.Cipher(payload, header.Mask, 0)
|
||||
}
|
||||
|
||||
// Write header to the header segment of the raw buffer.
|
||||
head := len(w.raw) - len(w.buf)
|
||||
offset := head - ws.HeaderSize(frame.Header)
|
||||
var (
|
||||
offset = len(w.raw) - len(w.buf)
|
||||
skip = offset - ws.HeaderSize(header)
|
||||
)
|
||||
buf := bytesWriter{
|
||||
buf: w.raw[offset:head],
|
||||
buf: w.raw[skip:offset],
|
||||
}
|
||||
if err := ws.WriteHeader(&buf, frame.Header); err != nil {
|
||||
if err := ws.WriteHeader(&buf, header); err != nil {
|
||||
// Must never be reached.
|
||||
panic("dump header error: " + err.Error())
|
||||
}
|
||||
|
||||
_, err := w.dest.Write(w.raw[offset : head+w.n])
|
||||
|
||||
_, err = w.dest.Write(w.raw[skip : offset+w.n])
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *Writer) opCode() ws.OpCode {
|
||||
if w.fragmented {
|
||||
if w.fseq > 0 {
|
||||
return ws.OpContinuation
|
||||
}
|
||||
return w.op
|
||||
@@ -448,3 +569,31 @@ func writeFrame(w io.Writer, s ws.State, op ws.OpCode, fin bool, p []byte) error
|
||||
|
||||
return ws.WriteFrame(w, frame)
|
||||
}
|
||||
|
||||
// reserve calculates number of bytes need to be reserved for frame header.
|
||||
//
|
||||
// Note that instead of ws.HeaderSize() it does calculation based on the buffer
|
||||
// size, not the payload size.
|
||||
func reserve(state ws.State, n int) (offset int) {
|
||||
var mask int
|
||||
if state.ClientSide() {
|
||||
mask = 4
|
||||
}
|
||||
switch {
|
||||
case n <= int(len7)+mask+2:
|
||||
return mask + 2
|
||||
case n <= int(len16)+mask+4:
|
||||
return mask + 4
|
||||
default:
|
||||
return mask + 10
|
||||
}
|
||||
}
|
||||
|
||||
// headerSize returns number of bytes needed to encode header of a frame with
|
||||
// given state and length.
|
||||
func headerSize(s ws.State, n int) int {
|
||||
return ws.HeaderSize(ws.Header{
|
||||
Length: int64(n),
|
||||
Masked: s.ClientSide(),
|
||||
})
|
||||
}
|
||||
|
70
vendor/github.com/gobwas/ws/wsutil/wsutil.go
generated
vendored
70
vendor/github.com/gobwas/ws/wsutil/wsutil.go
generated
vendored
@@ -3,54 +3,54 @@ Package wsutil provides utilities for working with WebSocket protocol.
|
||||
|
||||
Overview:
|
||||
|
||||
// Read masked text message from peer and check utf8 encoding.
|
||||
header, err := ws.ReadHeader(conn)
|
||||
if err != nil {
|
||||
// handle err
|
||||
}
|
||||
// Read masked text message from peer and check utf8 encoding.
|
||||
header, err := ws.ReadHeader(conn)
|
||||
if err != nil {
|
||||
// handle err
|
||||
}
|
||||
|
||||
// Prepare to read payload.
|
||||
r := io.LimitReader(conn, header.Length)
|
||||
r = wsutil.NewCipherReader(r, header.Mask)
|
||||
r = wsutil.NewUTF8Reader(r)
|
||||
// Prepare to read payload.
|
||||
r := io.LimitReader(conn, header.Length)
|
||||
r = wsutil.NewCipherReader(r, header.Mask)
|
||||
r = wsutil.NewUTF8Reader(r)
|
||||
|
||||
payload, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
// handle err
|
||||
}
|
||||
payload, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
// handle err
|
||||
}
|
||||
|
||||
You could get the same behavior using just `wsutil.Reader`:
|
||||
|
||||
r := wsutil.Reader{
|
||||
Source: conn,
|
||||
CheckUTF8: true,
|
||||
}
|
||||
r := wsutil.Reader{
|
||||
Source: conn,
|
||||
CheckUTF8: true,
|
||||
}
|
||||
|
||||
payload, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
// handle err
|
||||
}
|
||||
payload, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
// handle err
|
||||
}
|
||||
|
||||
Or even simplest:
|
||||
|
||||
payload, err := wsutil.ReadClientText(conn)
|
||||
if err != nil {
|
||||
// handle err
|
||||
}
|
||||
payload, err := wsutil.ReadClientText(conn)
|
||||
if err != nil {
|
||||
// handle err
|
||||
}
|
||||
|
||||
Package is also exports tools for buffered writing:
|
||||
|
||||
// Create buffered writer, that will buffer output bytes and send them as
|
||||
// 128-length fragments (with exception on large writes, see the doc).
|
||||
writer := wsutil.NewWriterSize(conn, ws.StateServerSide, ws.OpText, 128)
|
||||
// Create buffered writer, that will buffer output bytes and send them as
|
||||
// 128-length fragments (with exception on large writes, see the doc).
|
||||
writer := wsutil.NewWriterSize(conn, ws.StateServerSide, ws.OpText, 128)
|
||||
|
||||
_, err := io.CopyN(writer, rand.Reader, 100)
|
||||
if err == nil {
|
||||
err = writer.Flush()
|
||||
}
|
||||
if err != nil {
|
||||
// handle error
|
||||
}
|
||||
_, err := io.CopyN(writer, rand.Reader, 100)
|
||||
if err == nil {
|
||||
err = writer.Flush()
|
||||
}
|
||||
if err != nil {
|
||||
// handle error
|
||||
}
|
||||
|
||||
For more utils and helpers see the documentation.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user