commit
d801a23f91
|
@ -30,9 +30,10 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/bradfitz/gomemcache/memcache"
|
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/bradfitz/gomemcache/memcache"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeKey(len int) []byte {
|
func makeKey(len int) []byte {
|
||||||
|
@ -89,9 +90,7 @@ func main() {
|
||||||
Expiration: int32((*interval) + 300),
|
Expiration: int32((*interval) + 300),
|
||||||
})
|
})
|
||||||
|
|
||||||
select {
|
<-time.After(time.Duration(*interval) * time.Second)
|
||||||
case <-time.After(time.Duration(*interval) * time.Second):
|
|
||||||
}
|
|
||||||
|
|
||||||
// rotate keys. the last key is now encryption key.
|
// rotate keys. the last key is now encryption key.
|
||||||
// generate new key and append it to the last, so that
|
// generate new key and append it to the last, so that
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
|
|
||||||
// TestH1H1PlainGET tests whether simple HTTP/1 GET request works.
|
// TestH1H1PlainGET tests whether simple HTTP/1 GET request works.
|
||||||
func TestH1H1PlainGET(t *testing.T) {
|
func TestH1H1PlainGET(t *testing.T) {
|
||||||
st := newServerTester(nil, t, noopHandler)
|
st := newServerTester(t, options{})
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -37,7 +37,7 @@ func TestH1H1PlainGET(t *testing.T) {
|
||||||
// TestH1H1PlainGETClose tests whether simple HTTP/1 GET request with
|
// TestH1H1PlainGETClose tests whether simple HTTP/1 GET request with
|
||||||
// Connection: close request header field works.
|
// Connection: close request header field works.
|
||||||
func TestH1H1PlainGETClose(t *testing.T) {
|
func TestH1H1PlainGETClose(t *testing.T) {
|
||||||
st := newServerTester(nil, t, noopHandler)
|
st := newServerTester(t, options{})
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -59,9 +59,12 @@ func TestH1H1PlainGETClose(t *testing.T) {
|
||||||
// TestH1H1InvalidMethod tests that server rejects invalid method with
|
// TestH1H1InvalidMethod tests that server rejects invalid method with
|
||||||
// 501 status code
|
// 501 status code
|
||||||
func TestH1H1InvalidMethod(t *testing.T) {
|
func TestH1H1InvalidMethod(t *testing.T) {
|
||||||
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Errorf("server should not forward this request")
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
t.Errorf("server should not forward this request")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -80,9 +83,12 @@ func TestH1H1InvalidMethod(t *testing.T) {
|
||||||
// TestH1H1MultipleRequestCL tests that server rejects request which
|
// TestH1H1MultipleRequestCL tests that server rejects request which
|
||||||
// contains multiple Content-Length header fields.
|
// contains multiple Content-Length header fields.
|
||||||
func TestH1H1MultipleRequestCL(t *testing.T) {
|
func TestH1H1MultipleRequestCL(t *testing.T) {
|
||||||
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Errorf("server should not forward bad request")
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
t.Errorf("server should not forward bad request")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, fmt.Sprintf(`GET / HTTP/1.1
|
if _, err := io.WriteString(st.conn, fmt.Sprintf(`GET / HTTP/1.1
|
||||||
|
@ -109,7 +115,7 @@ Content-Length: 0
|
||||||
// // TestH1H1ConnectFailure tests that server handles the situation that
|
// // TestH1H1ConnectFailure tests that server handles the situation that
|
||||||
// // connection attempt to HTTP/1 backend failed.
|
// // connection attempt to HTTP/1 backend failed.
|
||||||
// func TestH1H1ConnectFailure(t *testing.T) {
|
// func TestH1H1ConnectFailure(t *testing.T) {
|
||||||
// st := newServerTester(nil, t, noopHandler)
|
// st := newServerTester(t, options{})
|
||||||
// defer st.Close()
|
// defer st.Close()
|
||||||
|
|
||||||
// // shutdown backend server to simulate backend connect failure
|
// // shutdown backend server to simulate backend connect failure
|
||||||
|
@ -130,7 +136,10 @@ Content-Length: 0
|
||||||
// TestH1H1AffinityCookie tests that affinity cookie is sent back in
|
// TestH1H1AffinityCookie tests that affinity cookie is sent back in
|
||||||
// cleartext http.
|
// cleartext http.
|
||||||
func TestH1H1AffinityCookie(t *testing.T) {
|
func TestH1H1AffinityCookie(t *testing.T) {
|
||||||
st := newServerTester([]string{"--affinity-cookie"}, t, noopHandler)
|
opts := options{
|
||||||
|
args: []string{"--affinity-cookie"},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -154,7 +163,11 @@ func TestH1H1AffinityCookie(t *testing.T) {
|
||||||
// TestH1H1AffinityCookieTLS tests that affinity cookie is sent back
|
// TestH1H1AffinityCookieTLS tests that affinity cookie is sent back
|
||||||
// in https.
|
// in https.
|
||||||
func TestH1H1AffinityCookieTLS(t *testing.T) {
|
func TestH1H1AffinityCookieTLS(t *testing.T) {
|
||||||
st := newServerTesterTLS([]string{"--alpn-h1", "--affinity-cookie"}, t, noopHandler)
|
opts := options{
|
||||||
|
args: []string{"--alpn-h1", "--affinity-cookie"},
|
||||||
|
tls: true,
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -177,7 +190,7 @@ func TestH1H1AffinityCookieTLS(t *testing.T) {
|
||||||
|
|
||||||
// TestH1H1GracefulShutdown tests graceful shutdown.
|
// TestH1H1GracefulShutdown tests graceful shutdown.
|
||||||
func TestH1H1GracefulShutdown(t *testing.T) {
|
func TestH1H1GracefulShutdown(t *testing.T) {
|
||||||
st := newServerTester(nil, t, noopHandler)
|
st := newServerTester(t, options{})
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -218,9 +231,13 @@ func TestH1H1GracefulShutdown(t *testing.T) {
|
||||||
|
|
||||||
// TestH1H1HostRewrite tests that server rewrites Host header field
|
// TestH1H1HostRewrite tests that server rewrites Host header field
|
||||||
func TestH1H1HostRewrite(t *testing.T) {
|
func TestH1H1HostRewrite(t *testing.T) {
|
||||||
st := newServerTester([]string{"--host-rewrite"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
w.Header().Add("request-host", r.Host)
|
args: []string{"--host-rewrite"},
|
||||||
})
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Add("request-host", r.Host)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -240,9 +257,12 @@ func TestH1H1HostRewrite(t *testing.T) {
|
||||||
// TestH1H1BadHost tests that server rejects request including bad
|
// TestH1H1BadHost tests that server rejects request including bad
|
||||||
// characters in host header field.
|
// characters in host header field.
|
||||||
func TestH1H1BadHost(t *testing.T) {
|
func TestH1H1BadHost(t *testing.T) {
|
||||||
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Errorf("server should not forward this request")
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
t.Errorf("server should not forward this request")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, "GET / HTTP/1.1\r\nTest-Case: TestH1H1HBadHost\r\nHost: foo\"bar\r\n\r\n"); err != nil {
|
if _, err := io.WriteString(st.conn, "GET / HTTP/1.1\r\nTest-Case: TestH1H1HBadHost\r\nHost: foo\"bar\r\n\r\n"); err != nil {
|
||||||
|
@ -260,9 +280,12 @@ func TestH1H1BadHost(t *testing.T) {
|
||||||
// TestH1H1BadAuthority tests that server rejects request including
|
// TestH1H1BadAuthority tests that server rejects request including
|
||||||
// bad characters in authority component of requset URI.
|
// bad characters in authority component of requset URI.
|
||||||
func TestH1H1BadAuthority(t *testing.T) {
|
func TestH1H1BadAuthority(t *testing.T) {
|
||||||
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Errorf("server should not forward this request")
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
t.Errorf("server should not forward this request")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, "GET http://foo\"bar/ HTTP/1.1\r\nTest-Case: TestH1H1HBadAuthority\r\nHost: foobar\r\n\r\n"); err != nil {
|
if _, err := io.WriteString(st.conn, "GET http://foo\"bar/ HTTP/1.1\r\nTest-Case: TestH1H1HBadAuthority\r\nHost: foobar\r\n\r\n"); err != nil {
|
||||||
|
@ -280,9 +303,12 @@ func TestH1H1BadAuthority(t *testing.T) {
|
||||||
// TestH1H1BadScheme tests that server rejects request including
|
// TestH1H1BadScheme tests that server rejects request including
|
||||||
// bad characters in scheme component of requset URI.
|
// bad characters in scheme component of requset URI.
|
||||||
func TestH1H1BadScheme(t *testing.T) {
|
func TestH1H1BadScheme(t *testing.T) {
|
||||||
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Errorf("server should not forward this request")
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
t.Errorf("server should not forward this request")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, "GET http*://example.com/ HTTP/1.1\r\nTest-Case: TestH1H1HBadScheme\r\nHost: example.com\r\n\r\n"); err != nil {
|
if _, err := io.WriteString(st.conn, "GET http*://example.com/ HTTP/1.1\r\nTest-Case: TestH1H1HBadScheme\r\nHost: example.com\r\n\r\n"); err != nil {
|
||||||
|
@ -300,9 +326,12 @@ func TestH1H1BadScheme(t *testing.T) {
|
||||||
// TestH1H1HTTP10 tests that server can accept HTTP/1.0 request
|
// TestH1H1HTTP10 tests that server can accept HTTP/1.0 request
|
||||||
// without Host header field
|
// without Host header field
|
||||||
func TestH1H1HTTP10(t *testing.T) {
|
func TestH1H1HTTP10(t *testing.T) {
|
||||||
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
w.Header().Add("request-host", r.Host)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
w.Header().Add("request-host", r.Host)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H1HTTP10\r\n\r\n"); err != nil {
|
if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H1HTTP10\r\n\r\n"); err != nil {
|
||||||
|
@ -326,9 +355,12 @@ func TestH1H1HTTP10(t *testing.T) {
|
||||||
// field using actual backend server even if --no-http-rewrite is
|
// field using actual backend server even if --no-http-rewrite is
|
||||||
// used.
|
// used.
|
||||||
func TestH1H1HTTP10NoHostRewrite(t *testing.T) {
|
func TestH1H1HTTP10NoHostRewrite(t *testing.T) {
|
||||||
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
w.Header().Add("request-host", r.Host)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
w.Header().Add("request-host", r.Host)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H1HTTP10NoHostRewrite\r\n\r\n"); err != nil {
|
if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H1HTTP10NoHostRewrite\r\n\r\n"); err != nil {
|
||||||
|
@ -351,21 +383,24 @@ func TestH1H1HTTP10NoHostRewrite(t *testing.T) {
|
||||||
// TestH1H1RequestTrailer tests request trailer part is forwarded to
|
// TestH1H1RequestTrailer tests request trailer part is forwarded to
|
||||||
// backend.
|
// backend.
|
||||||
func TestH1H1RequestTrailer(t *testing.T) {
|
func TestH1H1RequestTrailer(t *testing.T) {
|
||||||
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
buf := make([]byte, 4096)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
for {
|
buf := make([]byte, 4096)
|
||||||
_, err := r.Body.Read(buf)
|
for {
|
||||||
if err == io.EOF {
|
_, err := r.Body.Read(buf)
|
||||||
break
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("r.Body.Read() = %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if got, want := r.Trailer.Get("foo"), "bar"; got != want {
|
||||||
t.Fatalf("r.Body.Read() = %v", err)
|
t.Errorf("r.Trailer.Get(foo): %v; want %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
if got, want := r.Trailer.Get("foo"), "bar"; got != want {
|
}
|
||||||
t.Errorf("r.Trailer.Get(foo): %v; want %v", got, want)
|
st := newServerTester(t, opts)
|
||||||
}
|
|
||||||
})
|
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -389,9 +424,13 @@ func TestH1H1HeaderFieldBufferPath(t *testing.T) {
|
||||||
// The value 100 is chosen so that sum of header fields bytes
|
// The value 100 is chosen so that sum of header fields bytes
|
||||||
// does not exceed it. We use > 100 bytes URI to exceed this
|
// does not exceed it. We use > 100 bytes URI to exceed this
|
||||||
// limit.
|
// limit.
|
||||||
st := newServerTester([]string{"--request-header-field-buffer=100"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatal("execution path should not be here")
|
args: []string{"--request-header-field-buffer=100"},
|
||||||
})
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatal("execution path should not be here")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -409,9 +448,13 @@ func TestH1H1HeaderFieldBufferPath(t *testing.T) {
|
||||||
// TestH1H1HeaderFieldBuffer tests that request with header fields
|
// TestH1H1HeaderFieldBuffer tests that request with header fields
|
||||||
// larger than configured buffer size is rejected.
|
// larger than configured buffer size is rejected.
|
||||||
func TestH1H1HeaderFieldBuffer(t *testing.T) {
|
func TestH1H1HeaderFieldBuffer(t *testing.T) {
|
||||||
st := newServerTester([]string{"--request-header-field-buffer=10"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatal("execution path should not be here")
|
args: []string{"--request-header-field-buffer=10"},
|
||||||
})
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatal("execution path should not be here")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -428,9 +471,13 @@ func TestH1H1HeaderFieldBuffer(t *testing.T) {
|
||||||
// TestH1H1HeaderFields tests that request with header fields more
|
// TestH1H1HeaderFields tests that request with header fields more
|
||||||
// than configured number is rejected.
|
// than configured number is rejected.
|
||||||
func TestH1H1HeaderFields(t *testing.T) {
|
func TestH1H1HeaderFields(t *testing.T) {
|
||||||
st := newServerTester([]string{"--max-request-header-fields=1"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatal("execution path should not be here")
|
args: []string{"--max-request-header-fields=1"},
|
||||||
})
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatal("execution path should not be here")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -451,9 +498,12 @@ func TestH1H1HeaderFields(t *testing.T) {
|
||||||
|
|
||||||
// TestH1H1Websocket tests that HTTP Upgrade to WebSocket works.
|
// TestH1H1Websocket tests that HTTP Upgrade to WebSocket works.
|
||||||
func TestH1H1Websocket(t *testing.T) {
|
func TestH1H1Websocket(t *testing.T) {
|
||||||
st := newServerTesterHandler(nil, t, websocket.Handler(func(ws *websocket.Conn) {
|
opts := options{
|
||||||
io.Copy(ws, ws)
|
handler: websocket.Handler(func(ws *websocket.Conn) {
|
||||||
}))
|
io.Copy(ws, ws)
|
||||||
|
}).ServeHTTP,
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
content := []byte("hello world")
|
content := []byte("hello world")
|
||||||
|
@ -472,11 +522,15 @@ func TestH1H1Websocket(t *testing.T) {
|
||||||
// TestH1H1ReqPhaseSetHeader tests mruby request phase hook
|
// TestH1H1ReqPhaseSetHeader tests mruby request phase hook
|
||||||
// modifies request header fields.
|
// modifies request header fields.
|
||||||
func TestH1H1ReqPhaseSetHeader(t *testing.T) {
|
func TestH1H1ReqPhaseSetHeader(t *testing.T) {
|
||||||
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-set-header.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
if got, want := r.Header.Get("User-Agent"), "mruby"; got != want {
|
args: []string{"--mruby-file=" + testDir + "/req-set-header.rb"},
|
||||||
t.Errorf("User-Agent = %v; want %v", got, want)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
if got, want := r.Header.Get("User-Agent"), "mruby"; got != want {
|
||||||
})
|
t.Errorf("User-Agent = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -494,9 +548,13 @@ func TestH1H1ReqPhaseSetHeader(t *testing.T) {
|
||||||
// TestH1H1ReqPhaseReturn tests mruby request phase hook returns
|
// TestH1H1ReqPhaseReturn tests mruby request phase hook returns
|
||||||
// custom response.
|
// custom response.
|
||||||
func TestH1H1ReqPhaseReturn(t *testing.T) {
|
func TestH1H1ReqPhaseReturn(t *testing.T) {
|
||||||
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatalf("request should not be forwarded")
|
args: []string{"--mruby-file=" + testDir + "/req-return.rb"},
|
||||||
})
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -530,7 +588,10 @@ func TestH1H1ReqPhaseReturn(t *testing.T) {
|
||||||
// TestH1H1RespPhaseSetHeader tests mruby response phase hook modifies
|
// TestH1H1RespPhaseSetHeader tests mruby response phase hook modifies
|
||||||
// response header fields.
|
// response header fields.
|
||||||
func TestH1H1RespPhaseSetHeader(t *testing.T) {
|
func TestH1H1RespPhaseSetHeader(t *testing.T) {
|
||||||
st := newServerTester([]string{"--mruby-file=" + testDir + "/resp-set-header.rb"}, t, noopHandler)
|
opts := options{
|
||||||
|
args: []string{"--mruby-file=" + testDir + "/resp-set-header.rb"},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -552,7 +613,10 @@ func TestH1H1RespPhaseSetHeader(t *testing.T) {
|
||||||
// TestH1H1RespPhaseReturn tests mruby response phase hook returns
|
// TestH1H1RespPhaseReturn tests mruby response phase hook returns
|
||||||
// custom response.
|
// custom response.
|
||||||
func TestH1H1RespPhaseReturn(t *testing.T) {
|
func TestH1H1RespPhaseReturn(t *testing.T) {
|
||||||
st := newServerTester([]string{"--mruby-file=" + testDir + "/resp-return.rb"}, t, noopHandler)
|
opts := options{
|
||||||
|
args: []string{"--mruby-file=" + testDir + "/resp-return.rb"},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -586,7 +650,10 @@ func TestH1H1RespPhaseReturn(t *testing.T) {
|
||||||
// TestH1H1HTTPSRedirect tests that the request to the backend which
|
// TestH1H1HTTPSRedirect tests that the request to the backend which
|
||||||
// requires TLS is redirected to https URI.
|
// requires TLS is redirected to https URI.
|
||||||
func TestH1H1HTTPSRedirect(t *testing.T) {
|
func TestH1H1HTTPSRedirect(t *testing.T) {
|
||||||
st := newServerTester([]string{"--redirect-if-not-tls"}, t, noopHandler)
|
opts := options{
|
||||||
|
args: []string{"--redirect-if-not-tls"},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -607,7 +674,13 @@ func TestH1H1HTTPSRedirect(t *testing.T) {
|
||||||
// TestH1H1HTTPSRedirectPort tests that the request to the backend
|
// TestH1H1HTTPSRedirectPort tests that the request to the backend
|
||||||
// which requires TLS is redirected to https URI with given port.
|
// which requires TLS is redirected to https URI with given port.
|
||||||
func TestH1H1HTTPSRedirectPort(t *testing.T) {
|
func TestH1H1HTTPSRedirectPort(t *testing.T) {
|
||||||
st := newServerTester([]string{"--redirect-if-not-tls", "--redirect-https-port=8443"}, t, noopHandler)
|
opts := options{
|
||||||
|
args: []string{
|
||||||
|
"--redirect-if-not-tls",
|
||||||
|
"--redirect-https-port=8443",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -629,7 +702,7 @@ func TestH1H1HTTPSRedirectPort(t *testing.T) {
|
||||||
// TestH1H1POSTRequests tests that server can handle 2 requests with
|
// TestH1H1POSTRequests tests that server can handle 2 requests with
|
||||||
// request body.
|
// request body.
|
||||||
func TestH1H1POSTRequests(t *testing.T) {
|
func TestH1H1POSTRequests(t *testing.T) {
|
||||||
st := newServerTester(nil, t, noopHandler)
|
st := newServerTester(t, options{})
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -658,7 +731,10 @@ func TestH1H1POSTRequests(t *testing.T) {
|
||||||
// // TestH1H2ConnectFailure tests that server handles the situation that
|
// // TestH1H2ConnectFailure tests that server handles the situation that
|
||||||
// // connection attempt to HTTP/2 backend failed.
|
// // connection attempt to HTTP/2 backend failed.
|
||||||
// func TestH1H2ConnectFailure(t *testing.T) {
|
// func TestH1H2ConnectFailure(t *testing.T) {
|
||||||
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
// opts := options{
|
||||||
|
// args: []string{"--http2-bridge"},
|
||||||
|
// }
|
||||||
|
// st := newServerTester(t, opts)
|
||||||
// defer st.Close()
|
// defer st.Close()
|
||||||
|
|
||||||
// // simulate backend connect attempt failure
|
// // simulate backend connect attempt failure
|
||||||
|
@ -679,9 +755,13 @@ func TestH1H1POSTRequests(t *testing.T) {
|
||||||
// TestH1H2NoHost tests that server rejects request without Host
|
// TestH1H2NoHost tests that server rejects request without Host
|
||||||
// header field for HTTP/2 backend.
|
// header field for HTTP/2 backend.
|
||||||
func TestH1H2NoHost(t *testing.T) {
|
func TestH1H2NoHost(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Errorf("server should not forward bad request")
|
args: []string{"--http2-bridge"},
|
||||||
})
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Errorf("server should not forward bad request")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
// without Host header field, we expect 400 response
|
// without Host header field, we expect 400 response
|
||||||
|
@ -703,9 +783,13 @@ func TestH1H2NoHost(t *testing.T) {
|
||||||
// TestH1H2HTTP10 tests that server can accept HTTP/1.0 request
|
// TestH1H2HTTP10 tests that server can accept HTTP/1.0 request
|
||||||
// without Host header field
|
// without Host header field
|
||||||
func TestH1H2HTTP10(t *testing.T) {
|
func TestH1H2HTTP10(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
w.Header().Add("request-host", r.Host)
|
args: []string{"--http2-bridge"},
|
||||||
})
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Add("request-host", r.Host)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H2HTTP10\r\n\r\n"); err != nil {
|
if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H2HTTP10\r\n\r\n"); err != nil {
|
||||||
|
@ -729,9 +813,13 @@ func TestH1H2HTTP10(t *testing.T) {
|
||||||
// field using actual backend server even if --no-http-rewrite is
|
// field using actual backend server even if --no-http-rewrite is
|
||||||
// used.
|
// used.
|
||||||
func TestH1H2HTTP10NoHostRewrite(t *testing.T) {
|
func TestH1H2HTTP10NoHostRewrite(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
w.Header().Add("request-host", r.Host)
|
args: []string{"--http2-bridge"},
|
||||||
})
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Add("request-host", r.Host)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H2HTTP10NoHostRewrite\r\n\r\n"); err != nil {
|
if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H2HTTP10NoHostRewrite\r\n\r\n"); err != nil {
|
||||||
|
@ -756,11 +844,15 @@ func TestH1H2HTTP10NoHostRewrite(t *testing.T) {
|
||||||
// concatenates crumbled Cookies automatically, so this test is not
|
// concatenates crumbled Cookies automatically, so this test is not
|
||||||
// much effective now.
|
// much effective now.
|
||||||
func TestH1H2CrumbleCookie(t *testing.T) {
|
func TestH1H2CrumbleCookie(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
if got, want := r.Header.Get("Cookie"), "alpha; bravo; charlie"; got != want {
|
args: []string{"--http2-bridge"},
|
||||||
t.Errorf("Cookie: %v; want %v", got, want)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
if got, want := r.Header.Get("Cookie"), "alpha; bravo; charlie"; got != want {
|
||||||
})
|
t.Errorf("Cookie: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -780,11 +872,15 @@ func TestH1H2CrumbleCookie(t *testing.T) {
|
||||||
// TestH1H2GenerateVia tests that server generates Via header field to and
|
// TestH1H2GenerateVia tests that server generates Via header field to and
|
||||||
// from backend server.
|
// from backend server.
|
||||||
func TestH1H2GenerateVia(t *testing.T) {
|
func TestH1H2GenerateVia(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
if got, want := r.Header.Get("Via"), "1.1 nghttpx"; got != want {
|
args: []string{"--http2-bridge"},
|
||||||
t.Errorf("Via: %v; want %v", got, want)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
if got, want := r.Header.Get("Via"), "1.1 nghttpx"; got != want {
|
||||||
})
|
t.Errorf("Via: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -801,12 +897,16 @@ func TestH1H2GenerateVia(t *testing.T) {
|
||||||
// TestH1H2AppendVia tests that server adds value to existing Via
|
// TestH1H2AppendVia tests that server adds value to existing Via
|
||||||
// header field to and from backend server.
|
// header field to and from backend server.
|
||||||
func TestH1H2AppendVia(t *testing.T) {
|
func TestH1H2AppendVia(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
if got, want := r.Header.Get("Via"), "foo, 1.1 nghttpx"; got != want {
|
args: []string{"--http2-bridge"},
|
||||||
t.Errorf("Via: %v; want %v", got, want)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
if got, want := r.Header.Get("Via"), "foo, 1.1 nghttpx"; got != want {
|
||||||
w.Header().Add("Via", "bar")
|
t.Errorf("Via: %v; want %v", got, want)
|
||||||
})
|
}
|
||||||
|
w.Header().Add("Via", "bar")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -826,12 +926,16 @@ func TestH1H2AppendVia(t *testing.T) {
|
||||||
// TestH1H2NoVia tests that server does not add value to existing Via
|
// TestH1H2NoVia tests that server does not add value to existing Via
|
||||||
// header field to and from backend server.
|
// header field to and from backend server.
|
||||||
func TestH1H2NoVia(t *testing.T) {
|
func TestH1H2NoVia(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge", "--no-via"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
if got, want := r.Header.Get("Via"), "foo"; got != want {
|
args: []string{"--http2-bridge", "--no-via"},
|
||||||
t.Errorf("Via: %v; want %v", got, want)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
if got, want := r.Header.Get("Via"), "foo"; got != want {
|
||||||
w.Header().Add("Via", "bar")
|
t.Errorf("Via: %v; want %v", got, want)
|
||||||
})
|
}
|
||||||
|
w.Header().Add("Via", "bar")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -851,9 +955,16 @@ func TestH1H2NoVia(t *testing.T) {
|
||||||
// TestH1H2ReqPhaseReturn tests mruby request phase hook returns
|
// TestH1H2ReqPhaseReturn tests mruby request phase hook returns
|
||||||
// custom response.
|
// custom response.
|
||||||
func TestH1H2ReqPhaseReturn(t *testing.T) {
|
func TestH1H2ReqPhaseReturn(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge", "--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatalf("request should not be forwarded")
|
args: []string{
|
||||||
})
|
"--http2-bridge",
|
||||||
|
"--mruby-file=" + testDir + "/req-return.rb",
|
||||||
|
},
|
||||||
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -887,7 +998,13 @@ func TestH1H2ReqPhaseReturn(t *testing.T) {
|
||||||
// TestH1H2RespPhaseReturn tests mruby response phase hook returns
|
// TestH1H2RespPhaseReturn tests mruby response phase hook returns
|
||||||
// custom response.
|
// custom response.
|
||||||
func TestH1H2RespPhaseReturn(t *testing.T) {
|
func TestH1H2RespPhaseReturn(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge", "--mruby-file=" + testDir + "/resp-return.rb"}, t, noopHandler)
|
opts := options{
|
||||||
|
args: []string{
|
||||||
|
"--http2-bridge",
|
||||||
|
"--mruby-file=" + testDir + "/resp-return.rb",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -921,11 +1038,15 @@ func TestH1H2RespPhaseReturn(t *testing.T) {
|
||||||
// TestH1H2TE tests that "te: trailers" header is forwarded to HTTP/2
|
// TestH1H2TE tests that "te: trailers" header is forwarded to HTTP/2
|
||||||
// backend server by stripping other encodings.
|
// backend server by stripping other encodings.
|
||||||
func TestH1H2TE(t *testing.T) {
|
func TestH1H2TE(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
if got, want := r.Header.Get("te"), "trailers"; got != want {
|
args: []string{"--http2-bridge"},
|
||||||
t.Errorf("te: %v; want %v", got, want)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
if got, want := r.Header.Get("te"), "trailers"; got != want {
|
||||||
})
|
t.Errorf("te: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -945,9 +1066,14 @@ func TestH1H2TE(t *testing.T) {
|
||||||
// TestH1APIBackendconfig exercise backendconfig API endpoint routine
|
// TestH1APIBackendconfig exercise backendconfig API endpoint routine
|
||||||
// for successful case.
|
// for successful case.
|
||||||
func TestH1APIBackendconfig(t *testing.T) {
|
func TestH1APIBackendconfig(t *testing.T) {
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatalf("request should not be forwarded")
|
args: []string{"-f127.0.0.1,3010;api;no-tls"},
|
||||||
}, 3010)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
},
|
||||||
|
connectPort: 3010,
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -982,9 +1108,14 @@ backend=127.0.0.1,3011
|
||||||
// TestH1APIBackendconfigQuery exercise backendconfig API endpoint
|
// TestH1APIBackendconfigQuery exercise backendconfig API endpoint
|
||||||
// routine with query.
|
// routine with query.
|
||||||
func TestH1APIBackendconfigQuery(t *testing.T) {
|
func TestH1APIBackendconfigQuery(t *testing.T) {
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatalf("request should not be forwarded")
|
args: []string{"-f127.0.0.1,3010;api;no-tls"},
|
||||||
}, 3010)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
},
|
||||||
|
connectPort: 3010,
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -1019,9 +1150,14 @@ backend=127.0.0.1,3011
|
||||||
// TestH1APIBackendconfigBadMethod exercise backendconfig API endpoint
|
// TestH1APIBackendconfigBadMethod exercise backendconfig API endpoint
|
||||||
// routine with bad method.
|
// routine with bad method.
|
||||||
func TestH1APIBackendconfigBadMethod(t *testing.T) {
|
func TestH1APIBackendconfigBadMethod(t *testing.T) {
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatalf("request should not be forwarded")
|
args: []string{"-f127.0.0.1,3010;api;no-tls"},
|
||||||
}, 3010)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
},
|
||||||
|
connectPort: 3010,
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -1055,9 +1191,14 @@ backend=127.0.0.1,3011
|
||||||
|
|
||||||
// TestH1APIConfigrevision tests configrevision API.
|
// TestH1APIConfigrevision tests configrevision API.
|
||||||
func TestH1APIConfigrevision(t *testing.T) {
|
func TestH1APIConfigrevision(t *testing.T) {
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatalf("request should not be forwarded")
|
args: []string{"-f127.0.0.1,3010;api;no-tls"},
|
||||||
}, 3010)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
},
|
||||||
|
connectPort: 3010,
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -1093,9 +1234,14 @@ func TestH1APIConfigrevision(t *testing.T) {
|
||||||
// TestH1APINotFound exercise backendconfig API endpoint routine when
|
// TestH1APINotFound exercise backendconfig API endpoint routine when
|
||||||
// API endpoint is not found.
|
// API endpoint is not found.
|
||||||
func TestH1APINotFound(t *testing.T) {
|
func TestH1APINotFound(t *testing.T) {
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatalf("request should not be forwarded")
|
args: []string{"-f127.0.0.1,3010;api;no-tls"},
|
||||||
}, 3010)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
},
|
||||||
|
connectPort: 3010,
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -1129,9 +1275,14 @@ backend=127.0.0.1,3011
|
||||||
|
|
||||||
// TestH1Healthmon tests health monitor endpoint.
|
// TestH1Healthmon tests health monitor endpoint.
|
||||||
func TestH1Healthmon(t *testing.T) {
|
func TestH1Healthmon(t *testing.T) {
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3011;healthmon;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatalf("request should not be forwarded")
|
args: []string{"-f127.0.0.1,3011;healthmon;no-tls"},
|
||||||
}, 3011)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
},
|
||||||
|
connectPort: 3011,
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
|
@ -1149,9 +1300,13 @@ func TestH1Healthmon(t *testing.T) {
|
||||||
// TestH1ResponseBeforeRequestEnd tests the situation where response
|
// TestH1ResponseBeforeRequestEnd tests the situation where response
|
||||||
// ends before request body finishes.
|
// ends before request body finishes.
|
||||||
func TestH1ResponseBeforeRequestEnd(t *testing.T) {
|
func TestH1ResponseBeforeRequestEnd(t *testing.T) {
|
||||||
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
t.Fatal("request should not be forwarded")
|
args: []string{"--mruby-file=" + testDir + "/req-return.rb"},
|
||||||
})
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatal("request should not be forwarded")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, fmt.Sprintf(`POST / HTTP/1.1
|
if _, err := io.WriteString(st.conn, fmt.Sprintf(`POST / HTTP/1.1
|
||||||
|
@ -1176,21 +1331,24 @@ Content-Length: 1000000
|
||||||
// TestH1H1ChunkedEndsPrematurely tests that an HTTP/1.1 request fails
|
// TestH1H1ChunkedEndsPrematurely tests that an HTTP/1.1 request fails
|
||||||
// if the backend chunked encoded response ends prematurely.
|
// if the backend chunked encoded response ends prematurely.
|
||||||
func TestH1H1ChunkedEndsPrematurely(t *testing.T) {
|
func TestH1H1ChunkedEndsPrematurely(t *testing.T) {
|
||||||
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
opts := options{
|
||||||
hj, ok := w.(http.Hijacker)
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
if !ok {
|
hj, ok := w.(http.Hijacker)
|
||||||
http.Error(w, "Could not hijack the connection", http.StatusInternalServerError)
|
if !ok {
|
||||||
return
|
http.Error(w, "Could not hijack the connection", http.StatusInternalServerError)
|
||||||
}
|
return
|
||||||
conn, bufrw, err := hj.Hijack()
|
}
|
||||||
if err != nil {
|
conn, bufrw, err := hj.Hijack()
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
if err != nil {
|
||||||
return
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
return
|
||||||
defer conn.Close()
|
}
|
||||||
bufrw.WriteString("HTTP/1.1 200\r\nTransfer-Encoding: chunked\r\n\r\n")
|
defer conn.Close()
|
||||||
bufrw.Flush()
|
bufrw.WriteString("HTTP/1.1 200\r\nTransfer-Encoding: chunked\r\n\r\n")
|
||||||
})
|
bufrw.Flush()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
st := newServerTester(t, opts)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
_, err := st.http1(requestParam{
|
_, err := st.http1(requestParam{
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,12 +7,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/tatsuhiro-t/go-nghttp2"
|
|
||||||
"golang.org/x/net/http2"
|
|
||||||
"golang.org/x/net/http2/hpack"
|
|
||||||
"golang.org/x/net/websocket"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
@ -25,6 +20,11 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/tatsuhiro-t/go-nghttp2"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
"golang.org/x/net/http2/hpack"
|
||||||
|
"golang.org/x/net/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -62,46 +62,37 @@ type serverTester struct {
|
||||||
errCh chan error
|
errCh chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
// newServerTester creates test context for plain TCP frontend
|
type options struct {
|
||||||
// connection.
|
// args is the additional arguments to nghttpx.
|
||||||
func newServerTester(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
args []string
|
||||||
return newServerTesterInternal(args, t, handler, false, serverPort, nil)
|
// handler is the handler to handle the request. It defaults
|
||||||
|
// to noopHandler.
|
||||||
|
handler http.HandlerFunc
|
||||||
|
// connectPort is the server side port where client connection
|
||||||
|
// is made. It defaults to serverPort.
|
||||||
|
connectPort int
|
||||||
|
// tls, if set to true, sets up TLS frontend connection.
|
||||||
|
tls bool
|
||||||
|
// tlsConfig is the client side TLS configuration that is used
|
||||||
|
// when tls is true.
|
||||||
|
tlsConfig *tls.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServerTesterConnectPort(args []string, t *testing.T, handler http.HandlerFunc, port int) *serverTester {
|
// newServerTester creates test context.
|
||||||
return newServerTesterInternal(args, t, handler, false, port, nil)
|
func newServerTester(t *testing.T, opts options) *serverTester {
|
||||||
}
|
if opts.handler == nil {
|
||||||
|
opts.handler = noopHandler
|
||||||
|
}
|
||||||
|
if opts.connectPort == 0 {
|
||||||
|
opts.connectPort = serverPort
|
||||||
|
}
|
||||||
|
|
||||||
func newServerTesterHandler(args []string, t *testing.T, handler http.Handler) *serverTester {
|
ts := httptest.NewUnstartedServer(opts.handler)
|
||||||
return newServerTesterInternal(args, t, handler, false, serverPort, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// newServerTester creates test context for TLS frontend connection.
|
|
||||||
func newServerTesterTLS(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
|
||||||
return newServerTesterInternal(args, t, handler, true, serverPort, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newServerTesterTLSConnectPort(args []string, t *testing.T, handler http.HandlerFunc, port int) *serverTester {
|
|
||||||
return newServerTesterInternal(args, t, handler, true, port, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// newServerTester creates test context for TLS frontend connection
|
|
||||||
// with given clientConfig
|
|
||||||
func newServerTesterTLSConfig(args []string, t *testing.T, handler http.HandlerFunc, clientConfig *tls.Config) *serverTester {
|
|
||||||
return newServerTesterInternal(args, t, handler, true, serverPort, clientConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// newServerTesterInternal creates test context. If frontendTLS is
|
|
||||||
// true, set up TLS frontend connection. connectPort is the server
|
|
||||||
// side port where client connection is made.
|
|
||||||
func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handler, frontendTLS bool, connectPort int, clientConfig *tls.Config) *serverTester {
|
|
||||||
ts := httptest.NewUnstartedServer(handler)
|
|
||||||
|
|
||||||
args := []string{}
|
|
||||||
|
|
||||||
|
var args []string
|
||||||
var backendTLS, dns, externalDNS, acceptProxyProtocol, redirectIfNotTLS, affinityCookie, alpnH1 bool
|
var backendTLS, dns, externalDNS, acceptProxyProtocol, redirectIfNotTLS, affinityCookie, alpnH1 bool
|
||||||
|
|
||||||
for _, k := range src_args {
|
for _, k := range opts.args {
|
||||||
switch k {
|
switch k {
|
||||||
case "--http2-bridge":
|
case "--http2-bridge":
|
||||||
backendTLS = true
|
backendTLS = true
|
||||||
|
@ -135,7 +126,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
||||||
ts.Start()
|
ts.Start()
|
||||||
}
|
}
|
||||||
scheme := "http"
|
scheme := "http"
|
||||||
if frontendTLS {
|
if opts.tls {
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
args = append(args, testDir+"/server.key", testDir+"/server.crt")
|
args = append(args, testDir+"/server.key", testDir+"/server.crt")
|
||||||
}
|
}
|
||||||
|
@ -175,7 +166,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
||||||
}
|
}
|
||||||
|
|
||||||
noTLS := ";no-tls"
|
noTLS := ";no-tls"
|
||||||
if frontendTLS {
|
if opts.tls {
|
||||||
noTLS = ""
|
noTLS = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +178,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
||||||
args = append(args, fmt.Sprintf("-f127.0.0.1,%v%v%v", serverPort, noTLS, proxyProto), b,
|
args = append(args, fmt.Sprintf("-f127.0.0.1,%v%v%v", serverPort, noTLS, proxyProto), b,
|
||||||
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
|
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
|
||||||
|
|
||||||
authority := fmt.Sprintf("127.0.0.1:%v", connectPort)
|
authority := fmt.Sprintf("127.0.0.1:%v", opts.connectPort)
|
||||||
|
|
||||||
st := &serverTester{
|
st := &serverTester{
|
||||||
cmd: exec.Command(serverBin, args...),
|
cmd: exec.Command(serverBin, args...),
|
||||||
|
@ -215,12 +206,12 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
||||||
|
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
var err error
|
var err error
|
||||||
if frontendTLS {
|
if opts.tls {
|
||||||
var tlsConfig *tls.Config
|
var tlsConfig *tls.Config
|
||||||
if clientConfig == nil {
|
if opts.tlsConfig == nil {
|
||||||
tlsConfig = new(tls.Config)
|
tlsConfig = new(tls.Config)
|
||||||
} else {
|
} else {
|
||||||
tlsConfig = clientConfig
|
tlsConfig = opts.tlsConfig.Clone()
|
||||||
}
|
}
|
||||||
tlsConfig.InsecureSkipVerify = true
|
tlsConfig.InsecureSkipVerify = true
|
||||||
if alpnH1 {
|
if alpnH1 {
|
||||||
|
@ -240,7 +231,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if frontendTLS {
|
if opts.tls {
|
||||||
tlsConn := conn.(*tls.Conn)
|
tlsConn := conn.(*tls.Conn)
|
||||||
cs := tlsConn.ConnectionState()
|
cs := tlsConn.ConnectionState()
|
||||||
if !cs.NegotiatedProtocolIsMutual {
|
if !cs.NegotiatedProtocolIsMutual {
|
||||||
|
@ -430,7 +421,7 @@ func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
respBody, err := ioutil.ReadAll(resp.Body)
|
respBody, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -561,7 +552,7 @@ loop:
|
||||||
var status int
|
var status int
|
||||||
status, err = strconv.Atoi(sr.header.Get(":status"))
|
status, err = strconv.Atoi(sr.header.Get(":status"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, fmt.Errorf("Error parsing status code: %v", err)
|
return res, fmt.Errorf("Error parsing status code: %w", err)
|
||||||
}
|
}
|
||||||
sr.status = status
|
sr.status = status
|
||||||
if f.StreamEnded() {
|
if f.StreamEnded() {
|
||||||
|
@ -664,7 +655,7 @@ func cloneHeader(h http.Header) http.Header {
|
||||||
}
|
}
|
||||||
|
|
||||||
func noopHandler(w http.ResponseWriter, r *http.Request) {
|
func noopHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
ioutil.ReadAll(r.Body)
|
io.ReadAll(r.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
type APIResponse struct {
|
type APIResponse struct {
|
||||||
|
|
Loading…
Reference in New Issue