• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 The gRPC Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package http2interop
16
17import (
18	"fmt"
19	"time"
20)
21
22// Section 6.5 says the minimum SETTINGS_MAX_FRAME_SIZE is 16,384
23func testSmallMaxFrameSize(ctx *HTTP2InteropCtx) error {
24	conn, err := connect(ctx)
25	if err != nil {
26		return err
27	}
28	defer conn.Close()
29	conn.SetDeadline(time.Now().Add(defaultTimeout))
30
31	sf := &SettingsFrame{
32		Params: []SettingsParameter{{
33			Identifier: SettingsMaxFrameSize,
34			Value:      1<<14 - 1, // 1 less than the smallest maximum
35		}},
36	}
37
38	if err := http2Connect(conn, sf); err != nil {
39		return err
40	}
41
42	if _, err := expectGoAwaySoon(conn); err != nil {
43		return err
44	}
45
46	return nil
47}
48
49// Section 6.5.3 says all settings frames must be acked.
50func testAllSettingsFramesAcked(ctx *HTTP2InteropCtx) error {
51	conn, err := connect(ctx)
52	if err != nil {
53		return err
54	}
55	defer conn.Close()
56	conn.SetDeadline(time.Now().Add(defaultTimeout))
57
58	sf := &SettingsFrame{}
59	if err := http2Connect(conn, sf); err != nil {
60		return err
61	}
62
63	// The spec says "The values in the SETTINGS frame MUST be processed in the order they
64	// appear. [...] Once all values have been processed, the recipient MUST immediately
65	// emit a SETTINGS frame with the ACK flag set."  From my understanding, processing all
66	// of no values warrants an ack per frame.
67	for i := 0; i < 10; i++ {
68		if err := streamFrame(conn, sf); err != nil {
69			return err
70		}
71	}
72
73	var settingsFramesReceived = 0
74	// The server by default sends a settings frame as part of the handshake, and another
75	// after the receipt of the initial settings frame as part of our connection preface.
76	// This means we expected 1 + 1 + 10 = 12 settings frames in return, with all but the
77	// first having the ack bit.
78	for settingsFramesReceived < 12 {
79		f, err := parseFrame(conn)
80		if err != nil {
81			return err
82		}
83
84		// Other frames come down the wire too, including window update.  Just ignore those.
85		if f, ok := f.(*SettingsFrame); ok {
86			settingsFramesReceived += 1
87			if settingsFramesReceived == 1 {
88				if f.Header.Flags&SETTINGS_FLAG_ACK > 0 {
89					return fmt.Errorf("settings frame should not have used ack: %v", f)
90				}
91				continue
92			}
93
94			if f.Header.Flags&SETTINGS_FLAG_ACK == 0 {
95				return fmt.Errorf("settings frame should have used ack: %v", f)
96			}
97			if len(f.Params) != 0 {
98				return fmt.Errorf("settings ack cannot have params: %v", f)
99			}
100		}
101	}
102
103	return nil
104}
105