integration: Add HTTP Upgrade test
This commit is contained in:
parent
9803f92e9c
commit
87cadca3d8
|
@ -558,6 +558,39 @@ func TestH2H1RequestTrailer(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestH2H1Upgrade tests HTTP Upgrade to HTTP/2
|
||||||
|
func TestH2H1Upgrade(t *testing.T) {
|
||||||
|
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http1(requestParam{
|
||||||
|
name: "TestH2H1Upgrade",
|
||||||
|
header: []hpack.HeaderField{
|
||||||
|
pair("Connection", "Upgrade, HTTP2-Settings"),
|
||||||
|
pair("Upgrade", "h2c-14"),
|
||||||
|
pair("HTTP2-Settings", "AAMAAABkAAQAAP__"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http1() = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := res.status, 101; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = st.http2(requestParam{
|
||||||
|
httpUpgrade: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestH2H1GracefulShutdown tests graceful shutdown.
|
// TestH2H1GracefulShutdown tests graceful shutdown.
|
||||||
func TestH2H1GracefulShutdown(t *testing.T) {
|
func TestH2H1GracefulShutdown(t *testing.T) {
|
||||||
st := newServerTester(nil, t, noopHandler)
|
st := newServerTester(nil, t, noopHandler)
|
||||||
|
|
|
@ -247,15 +247,16 @@ func (st *serverTester) readSpdyFrame() (spdy.Frame, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type requestParam struct {
|
type requestParam struct {
|
||||||
name string // name for this request to identify the request in log easily
|
name string // name for this request to identify the request in log easily
|
||||||
streamID uint32 // stream ID, automatically assigned if 0
|
streamID uint32 // stream ID, automatically assigned if 0
|
||||||
method string // method, defaults to GET
|
method string // method, defaults to GET
|
||||||
scheme string // scheme, defaults to http
|
scheme string // scheme, defaults to http
|
||||||
authority string // authority, defaults to backend server address
|
authority string // authority, defaults to backend server address
|
||||||
path string // path, defaults to /
|
path string // path, defaults to /
|
||||||
header []hpack.HeaderField // additional request header fields
|
header []hpack.HeaderField // additional request header fields
|
||||||
body []byte // request body
|
body []byte // request body
|
||||||
trailer []hpack.HeaderField // trailer part
|
trailer []hpack.HeaderField // trailer part
|
||||||
|
httpUpgrade bool // true if upgraded to HTTP/2 through HTTP Upgrade
|
||||||
}
|
}
|
||||||
|
|
||||||
// wrapper for request body to set trailer part
|
// wrapper for request body to set trailer part
|
||||||
|
@ -478,69 +479,70 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
|
||||||
streams := make(map[uint32]*serverResponse)
|
streams := make(map[uint32]*serverResponse)
|
||||||
streams[id] = res
|
streams[id] = res
|
||||||
|
|
||||||
method := "GET"
|
if !rp.httpUpgrade {
|
||||||
if rp.method != "" {
|
method := "GET"
|
||||||
method = rp.method
|
if rp.method != "" {
|
||||||
}
|
method = rp.method
|
||||||
_ = st.enc.WriteField(pair(":method", method))
|
|
||||||
|
|
||||||
scheme := "http"
|
|
||||||
if rp.scheme != "" {
|
|
||||||
scheme = rp.scheme
|
|
||||||
}
|
|
||||||
_ = st.enc.WriteField(pair(":scheme", scheme))
|
|
||||||
|
|
||||||
authority := st.authority
|
|
||||||
if rp.authority != "" {
|
|
||||||
authority = rp.authority
|
|
||||||
}
|
|
||||||
_ = st.enc.WriteField(pair(":authority", authority))
|
|
||||||
|
|
||||||
path := "/"
|
|
||||||
if rp.path != "" {
|
|
||||||
path = rp.path
|
|
||||||
}
|
|
||||||
_ = st.enc.WriteField(pair(":path", path))
|
|
||||||
|
|
||||||
_ = st.enc.WriteField(pair("test-case", rp.name))
|
|
||||||
|
|
||||||
for _, h := range rp.header {
|
|
||||||
_ = st.enc.WriteField(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
|
|
||||||
StreamID: id,
|
|
||||||
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0,
|
|
||||||
EndHeaders: true,
|
|
||||||
BlockFragment: st.headerBlkBuf.Bytes(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(rp.body) != 0 {
|
|
||||||
// TODO we assume rp.body fits in 1 frame
|
|
||||||
if err := st.fr.WriteData(id, len(rp.trailer) == 0, rp.body); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
}
|
_ = st.enc.WriteField(pair(":method", method))
|
||||||
|
|
||||||
if len(rp.trailer) != 0 {
|
scheme := "http"
|
||||||
st.headerBlkBuf.Reset()
|
if rp.scheme != "" {
|
||||||
for _, h := range rp.trailer {
|
scheme = rp.scheme
|
||||||
|
}
|
||||||
|
_ = st.enc.WriteField(pair(":scheme", scheme))
|
||||||
|
|
||||||
|
authority := st.authority
|
||||||
|
if rp.authority != "" {
|
||||||
|
authority = rp.authority
|
||||||
|
}
|
||||||
|
_ = st.enc.WriteField(pair(":authority", authority))
|
||||||
|
|
||||||
|
path := "/"
|
||||||
|
if rp.path != "" {
|
||||||
|
path = rp.path
|
||||||
|
}
|
||||||
|
_ = st.enc.WriteField(pair(":path", path))
|
||||||
|
|
||||||
|
_ = st.enc.WriteField(pair("test-case", rp.name))
|
||||||
|
|
||||||
|
for _, h := range rp.header {
|
||||||
_ = st.enc.WriteField(h)
|
_ = st.enc.WriteField(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
|
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
|
||||||
StreamID: id,
|
StreamID: id,
|
||||||
EndStream: true,
|
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0,
|
||||||
EndHeaders: true,
|
EndHeaders: true,
|
||||||
BlockFragment: st.headerBlkBuf.Bytes(),
|
BlockFragment: st.headerBlkBuf.Bytes(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if len(rp.body) != 0 {
|
||||||
|
// TODO we assume rp.body fits in 1 frame
|
||||||
|
if err := st.fr.WriteData(id, len(rp.trailer) == 0, rp.body); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(rp.trailer) != 0 {
|
||||||
|
st.headerBlkBuf.Reset()
|
||||||
|
for _, h := range rp.trailer {
|
||||||
|
_ = st.enc.WriteField(h)
|
||||||
|
}
|
||||||
|
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
|
||||||
|
StreamID: id,
|
||||||
|
EndStream: true,
|
||||||
|
EndHeaders: true,
|
||||||
|
BlockFragment: st.headerBlkBuf.Bytes(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
loop:
|
loop:
|
||||||
for {
|
for {
|
||||||
fr, err := st.readFrame()
|
fr, err := st.readFrame()
|
||||||
|
|
Loading…
Reference in New Issue