| package http2interop |
| |
| import ( |
| "fmt" |
| "time" |
| ) |
| |
| // Section 6.5 says the minimum SETTINGS_MAX_FRAME_SIZE is 16,384 |
| func testSmallMaxFrameSize(ctx *HTTP2InteropCtx) error { |
| conn, err := connect(ctx) |
| if err != nil { |
| return err |
| } |
| defer conn.Close() |
| conn.SetDeadline(time.Now().Add(defaultTimeout)) |
| |
| sf := &SettingsFrame{ |
| Params: []SettingsParameter{{ |
| Identifier: SettingsMaxFrameSize, |
| Value: 1<<14 - 1, // 1 less than the smallest maximum |
| }}, |
| } |
| |
| if err := http2Connect(conn, sf); err != nil { |
| return err |
| } |
| |
| if _, err := expectGoAwaySoon(conn); err != nil { |
| return err |
| } |
| |
| return nil |
| } |
| |
| // Section 6.5.3 says all settings frames must be acked. |
| func testAllSettingsFramesAcked(ctx *HTTP2InteropCtx) error { |
| conn, err := connect(ctx) |
| if err != nil { |
| return err |
| } |
| defer conn.Close() |
| conn.SetDeadline(time.Now().Add(defaultTimeout)) |
| |
| sf := &SettingsFrame{} |
| if err := http2Connect(conn, sf); err != nil { |
| return err |
| } |
| |
| // The spec says "The values in the SETTINGS frame MUST be processed in the order they |
| // appear. [...] Once all values have been processed, the recipient MUST immediately |
| // emit a SETTINGS frame with the ACK flag set." From my understanding, processing all |
| // of no values warrants an ack per frame. |
| for i := 0; i < 10; i++ { |
| if err := streamFrame(conn, sf); err != nil { |
| return err |
| } |
| } |
| |
| var settingsFramesReceived = 0 |
| // The server by default sends a settings frame as part of the handshake, and another |
| // after the receipt of the initial settings frame as part of our conneection preface. |
| // This means we expected 1 + 1 + 10 = 12 settings frames in return, with all but the |
| // first having the ack bit. |
| for settingsFramesReceived < 12 { |
| f, err := parseFrame(conn) |
| if err != nil { |
| return err |
| } |
| |
| // Other frames come down the wire too, including window update. Just ignore those. |
| if f, ok := f.(*SettingsFrame); ok { |
| settingsFramesReceived += 1 |
| if settingsFramesReceived == 1 { |
| if f.Header.Flags&SETTINGS_FLAG_ACK > 0 { |
| return fmt.Errorf("settings frame should not have used ack: %v") |
| } |
| continue |
| } |
| |
| if f.Header.Flags&SETTINGS_FLAG_ACK == 0 { |
| return fmt.Errorf("settings frame should have used ack: %v", f) |
| } |
| if len(f.Params) != 0 { |
| return fmt.Errorf("settings ack cannot have params: %v", f) |
| } |
| } |
| } |
| |
| return nil |
| } |