goaway.go 1.49 KB
Newer Older
Jeromy's avatar
Jeromy committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package frame

import "io"

const (
	goAwayBodySize  = 8
	goAwayFrameSize = headerSize + goAwayBodySize
)

// Instruct the remote side not to initiate new streams
type RGoAway struct {
	Header
	body  [goAwayBodySize]byte
	debug []byte
}

func (f *RGoAway) LastStreamId() StreamId {
	return StreamId(order.Uint32(f.body[0:]) & streamMask)
}

func (f *RGoAway) ErrorCode() ErrorCode {
	return ErrorCode(order.Uint32(f.body[4:]))
}

func (f *RGoAway) Debug() []byte {
	return f.debug
}

func (f *RGoAway) readFrom(d deserializer) (err error) {
	if _, err = io.ReadFull(d, f.body[:]); err != nil {
		return
	}

	f.debug = make([]byte, f.Length()-goAwayBodySize)
	if _, err = io.ReadFull(d, f.debug); err != nil {
		return
	}

	return
}

type WGoAway struct {
	Header
	data  [goAwayFrameSize]byte
	debug []byte
}

func (f *WGoAway) writeTo(s serializer) (err error) {
	if _, err = s.Write(f.data[:]); err != nil {
		return
	}

	if _, err = s.Write(f.debug); err != nil {
		return
	}

	return
}

func (f *WGoAway) Set(lastStreamId StreamId, errorCode ErrorCode, debug []byte) (err error) {
	if f.Header.SetAll(TypeGoAway, len(debug)+goAwayFrameSize, 0, 0); err != nil {
		return
	}

	if lastStreamId > streamMask {
		err = protoError("Related stream id %d is out of range", lastStreamId)
		return
	}

	order.PutUint32(f.data[headerSize:], uint32(lastStreamId))
	order.PutUint32(f.data[headerSize+4:], uint32(errorCode))
	return
}

func NewWGoAway() (f *WGoAway) {
	f = new(WGoAway)
	f.Header = Header(f.data[:headerSize])
	return
}