Carl Mastrangelo | 368a304 | 2015-12-01 16:19:23 -0800 | [diff] [blame] | 1 | package http2interop |
| 2 | |
| 3 | import ( |
Carl Mastrangelo | 756beae | 2015-12-11 16:43:28 -0800 | [diff] [blame] | 4 | "fmt" |
Carl Mastrangelo | 368a304 | 2015-12-01 16:19:23 -0800 | [diff] [blame] | 5 | "time" |
| 6 | ) |
| 7 | |
| 8 | // Section 6.5 says the minimum SETTINGS_MAX_FRAME_SIZE is 16,384 |
| 9 | func testSmallMaxFrameSize(ctx *HTTP2InteropCtx) error { |
| 10 | conn, err := connect(ctx) |
| 11 | if err != nil { |
| 12 | return err |
| 13 | } |
| 14 | defer conn.Close() |
Carl Mastrangelo | 368a304 | 2015-12-01 16:19:23 -0800 | [diff] [blame] | 15 | conn.SetDeadline(time.Now().Add(defaultTimeout)) |
| 16 | |
| 17 | sf := &SettingsFrame{ |
| 18 | Params: []SettingsParameter{{ |
| 19 | Identifier: SettingsMaxFrameSize, |
| 20 | Value: 1<<14 - 1, // 1 less than the smallest maximum |
| 21 | }}, |
| 22 | } |
| 23 | |
| 24 | if err := http2Connect(conn, sf); err != nil { |
| 25 | return err |
| 26 | } |
| 27 | |
| 28 | if _, err := expectGoAwaySoon(conn); err != nil { |
| 29 | return err |
| 30 | } |
| 31 | |
| 32 | return nil |
| 33 | } |
Carl Mastrangelo | 756beae | 2015-12-11 16:43:28 -0800 | [diff] [blame] | 34 | |
| 35 | // Section 6.5.3 says all settings frames must be acked. |
| 36 | func testAllSettingsFramesAcked(ctx *HTTP2InteropCtx) error { |
| 37 | conn, err := connect(ctx) |
| 38 | if err != nil { |
| 39 | return err |
| 40 | } |
| 41 | defer conn.Close() |
| 42 | conn.SetDeadline(time.Now().Add(defaultTimeout)) |
| 43 | |
| 44 | sf := &SettingsFrame{} |
| 45 | if err := http2Connect(conn, sf); err != nil { |
| 46 | return err |
| 47 | } |
| 48 | |
| 49 | // The spec says "The values in the SETTINGS frame MUST be processed in the order they |
| 50 | // appear. [...] Once all values have been processed, the recipient MUST immediately |
| 51 | // emit a SETTINGS frame with the ACK flag set." From my understanding, processing all |
| 52 | // of no values warrants an ack per frame. |
| 53 | for i := 0; i < 10; i++ { |
| 54 | if err := streamFrame(conn, sf); err != nil { |
| 55 | return err |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | var settingsFramesReceived = 0 |
| 60 | // The server by default sends a settings frame as part of the handshake, and another |
| 61 | // after the receipt of the initial settings frame as part of our conneection preface. |
| 62 | // This means we expected 1 + 1 + 10 = 12 settings frames in return, with all but the |
| 63 | // first having the ack bit. |
| 64 | for settingsFramesReceived < 12 { |
| 65 | f, err := parseFrame(conn) |
| 66 | if err != nil { |
| 67 | return err |
| 68 | } |
| 69 | |
| 70 | // Other frames come down the wire too, including window update. Just ignore those. |
| 71 | if f, ok := f.(*SettingsFrame); ok { |
| 72 | settingsFramesReceived += 1 |
| 73 | if settingsFramesReceived == 1 { |
| 74 | if f.Header.Flags&SETTINGS_FLAG_ACK > 0 { |
| 75 | return fmt.Errorf("settings frame should not have used ack: %v") |
| 76 | } |
| 77 | continue |
| 78 | } |
| 79 | |
| 80 | if f.Header.Flags&SETTINGS_FLAG_ACK == 0 { |
| 81 | return fmt.Errorf("settings frame should have used ack: %v", f) |
| 82 | } |
| 83 | if len(f.Params) != 0 { |
| 84 | return fmt.Errorf("settings ack cannot have params: %v", f) |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | return nil |
| 90 | } |