1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2024-12-12 11:15:02 +02:00
oauth2-proxy/pkg/http/server_test.go
Andrew Hamade 7fe6384f38
Fix Linting Errors (#1835)
* initial commit: add groups to azure

Signed-off-by: andrewphamade@gmail.com <andrewphamade@gmail.com>

* fix deprecations and linting errors

Signed-off-by: Andrew Hamade <andrewphamade@gmail.com>

* remove groups testing from azure provider

Signed-off-by: Andrew Hamade <andrewphamade@gmail.com>

* fix test error

Signed-off-by: Andrew Hamade <andrewphamade@gmail.com>

* verify-generate

Signed-off-by: Andrew Hamade <andrewphamade@gmail.com>

Signed-off-by: andrewphamade@gmail.com <andrewphamade@gmail.com>
Signed-off-by: Andrew Hamade <andrewphamade@gmail.com>
2022-10-21 11:57:51 +01:00

968 lines
29 KiB
Go

package http
import (
"context"
"errors"
"fmt"
"io"
"net/http"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
)
const hello = "Hello World!"
var _ = Describe("Server", func() {
handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(hello))
})
Context("NewServer", func() {
type newServerTableInput struct {
opts Opts
expectedErr error
expectHTTPListener bool
expectTLSListener bool
}
DescribeTable("When creating the new server from the options", func(in *newServerTableInput) {
srv, err := NewServer(in.opts)
if in.expectedErr != nil {
Expect(err).To(MatchError(ContainSubstring(in.expectedErr.Error())))
Expect(srv).To(BeNil())
return
}
Expect(err).ToNot(HaveOccurred())
s, ok := srv.(*server)
Expect(ok).To(BeTrue())
Expect(s.listener != nil).To(Equal(in.expectHTTPListener))
if in.expectHTTPListener {
Expect(s.listener.Close()).To(Succeed())
}
Expect(s.tlsListener != nil).To(Equal(in.expectTLSListener))
if in.expectTLSListener {
Expect(s.tlsListener.Close()).To(Succeed())
}
},
Entry("with an ipv4 valid http bind address", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "127.0.0.1:0",
},
expectedErr: nil,
expectHTTPListener: true,
expectTLSListener: false,
}),
Entry("with an ipv4 valid https bind address, with no TLS config", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
},
expectedErr: errors.New("error setting up TLS listener: no TLS config provided"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv4 valid https bind address, and valid TLS config", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
},
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with a both a ipv4 valid http and ipv4 valid https bind address, and valid TLS config", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "127.0.0.1:0",
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
},
},
expectedErr: nil,
expectHTTPListener: true,
expectTLSListener: true,
}),
Entry("with a \"-\" for the bind address", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "-",
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with a \"-\" for the secure bind address", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "-",
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv4 invalid bind address scheme", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "invalid://127.0.0.1:0",
},
expectedErr: errors.New("error setting up listener: listen (invalid, 127.0.0.1:0) failed: listen invalid: unknown network invalid"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv4 invalid secure bind address scheme", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "invalid://127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
},
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv4 invalid bind address port", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "127.0.0.1:a",
},
expectedErr: errors.New("error setting up listener: listen (tcp, 127.0.0.1:a) failed: listen tcp: "),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv4 invalid secure bind address port", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:a",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
},
},
expectedErr: errors.New("error setting up TLS listener: listen (127.0.0.1:a) failed: listen tcp: "),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv4 invalid TLS key", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &options.SecretSource{
Value: []byte("invalid"),
},
Cert: &ipv4CertDataSource,
},
},
expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not parse certificate data: tls: failed to find any PEM data in key input"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv4 invalid TLS cert", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &options.SecretSource{
Value: []byte("invalid"),
},
},
},
expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not parse certificate data: tls: failed to find any PEM data in certificate input"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv4 address, with no TLS key", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Cert: &ipv4CertDataSource,
},
},
expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not load key data: no configuration provided"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv4 address, with no TLS cert", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
},
},
expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not load cert data: no configuration provided"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("when the ipv4 bind address is prefixed with the http scheme", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "http://127.0.0.1:0",
},
expectedErr: nil,
expectHTTPListener: true,
expectTLSListener: false,
}),
Entry("when the ipv4 secure bind address is prefixed with the https scheme", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "https://127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
},
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv4 valid https bind address, and valid TLS config with MinVersion", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
MinVersion: "TLS1.3",
},
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv4 valid https bind address, and invalid TLS config with unknown MinVersion", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
MinVersion: "TLS1.42",
},
},
expectedErr: errors.New("error setting up TLS listener: unknown TLS MinVersion config provided"),
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv4 valid https bind address, and valid TLS config with CipherSuites", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
CipherSuites: []string{
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
},
},
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv4 valid https bind address, and invalid TLS config with unknown CipherSuites", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
CipherSuites: []string{
"TLS_RSA_WITH_RC4_64_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
},
},
},
expectedErr: errors.New("error setting up TLS listener: could not parse cipher suites: unknown TLS cipher suite name specified \"TLS_RSA_WITH_RC4_64_SHA\""),
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv6 valid http bind address", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "[::1]:0",
},
expectedErr: nil,
expectHTTPListener: true,
expectTLSListener: false,
}),
Entry("with an ipv6 valid https bind address, with no TLS config", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
},
expectedErr: errors.New("error setting up TLS listener: no TLS config provided"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv6 valid https bind address, and valid TLS config", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
Cert: &ipv6CertDataSource,
},
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with a both a ipv6 valid http and ipv6 valid https bind address, and valid TLS config", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "[::1]:0",
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
Cert: &ipv6CertDataSource,
},
},
expectedErr: nil,
expectHTTPListener: true,
expectTLSListener: true,
}),
Entry("with an ipv6 invalid bind address scheme", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "invalid://[::1]:0",
},
expectedErr: errors.New("error setting up listener: listen (invalid, [::1]:0) failed: listen invalid: unknown network invalid"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv6 invalid secure bind address scheme", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "invalid://[::1]:0",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
Cert: &ipv6CertDataSource,
},
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv6 invalid bind address port", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "[::1]:a",
},
expectedErr: errors.New("error setting up listener: listen (tcp, [::1]:a) failed: listen tcp: "),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv6 invalid secure bind address port", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:a",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
Cert: &ipv6CertDataSource,
},
},
expectedErr: errors.New("error setting up TLS listener: listen ([::1]:a) failed: listen tcp: "),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv6 invalid TLS key", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &options.SecretSource{
Value: []byte("invalid"),
},
Cert: &ipv6CertDataSource,
},
},
expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not parse certificate data: tls: failed to find any PEM data in key input"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv6 invalid TLS cert", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
Cert: &options.SecretSource{
Value: []byte("invalid"),
},
},
},
expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not parse certificate data: tls: failed to find any PEM data in certificate input"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv6 address, with no TLS key", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Cert: &ipv6CertDataSource,
},
},
expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not load key data: no configuration provided"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("with an ipv6 address, with no TLS cert", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
},
},
expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not load cert data: no configuration provided"),
expectHTTPListener: false,
expectTLSListener: false,
}),
Entry("when the ipv6 bind address is prefixed with the http scheme", &newServerTableInput{
opts: Opts{
Handler: handler,
BindAddress: "http://[::1]:0",
},
expectedErr: nil,
expectHTTPListener: true,
expectTLSListener: false,
}),
Entry("when the ipv6 secure bind address is prefixed with the https scheme", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "https://[::1]:0",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
Cert: &ipv6CertDataSource,
},
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv6 valid https bind address, and valid TLS config with MinVersion", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
Cert: &ipv6CertDataSource,
MinVersion: "TLS1.3",
},
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv6 valid https bind address, and invalid TLS config with unknown MinVersion", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
Cert: &ipv6CertDataSource,
MinVersion: "TLS1.42",
},
},
expectedErr: errors.New("error setting up TLS listener: unknown TLS MinVersion config provided"),
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv6 valid https bind address, and valid TLS config with CipherSuites", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
CipherSuites: []string{
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
},
},
},
expectedErr: nil,
expectHTTPListener: false,
expectTLSListener: true,
}),
Entry("with an ipv6 valid https bind address, and invalid TLS config with unknown CipherSuites", &newServerTableInput{
opts: Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
CipherSuites: []string{
"TLS_RSA_WITH_RC4_64_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
},
},
},
expectedErr: errors.New("error setting up TLS listener: could not parse cipher suites: unknown TLS cipher suite name specified \"TLS_RSA_WITH_RC4_64_SHA\""),
expectHTTPListener: false,
expectTLSListener: true,
}),
)
})
Context("Start", func() {
var srv Server
var ctx context.Context
var cancel context.CancelFunc
BeforeEach(func() {
ctx, cancel = context.WithCancel(context.Background())
})
AfterEach(func() {
cancel()
})
Context("with an ipv4 http server", func() {
var listenAddr string
BeforeEach(func() {
var err error
srv, err = NewServer(Opts{
Handler: handler,
BindAddress: "127.0.0.1:0",
})
Expect(err).ToNot(HaveOccurred())
s, ok := srv.(*server)
Expect(ok).To(BeTrue())
listenAddr = fmt.Sprintf("http://%s/", s.listener.Addr().String())
})
It("Starts the server and serves the handler", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
resp, err := client.Get(listenAddr)
Expect(err).ToNot(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
body, err := io.ReadAll(resp.Body)
Expect(err).ToNot(HaveOccurred())
Expect(string(body)).To(Equal(hello))
})
It("Stops the server when the context is cancelled", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
_, err := client.Get(listenAddr)
Expect(err).ToNot(HaveOccurred())
cancel()
Eventually(func() error {
_, err := client.Get(listenAddr)
return err
}).Should(HaveOccurred())
})
})
Context("with an ipv4 https server", func() {
var secureListenAddr string
BeforeEach(func() {
var err error
srv, err = NewServer(Opts{
Handler: handler,
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
},
})
Expect(err).ToNot(HaveOccurred())
s, ok := srv.(*server)
Expect(ok).To(BeTrue())
secureListenAddr = fmt.Sprintf("https://%s/", s.tlsListener.Addr().String())
})
It("Starts the server and serves the handler", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
resp, err := client.Get(secureListenAddr)
Expect(err).ToNot(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
body, err := io.ReadAll(resp.Body)
Expect(err).ToNot(HaveOccurred())
Expect(string(body)).To(Equal(hello))
})
It("Stops the server when the context is cancelled", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
_, err := client.Get(secureListenAddr)
Expect(err).ToNot(HaveOccurred())
cancel()
Eventually(func() error {
_, err := client.Get(secureListenAddr)
return err
}).Should(HaveOccurred())
})
It("Serves the certificate provided", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
resp, err := client.Get(secureListenAddr)
Expect(err).ToNot(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
Expect(resp.TLS.VerifiedChains).Should(HaveLen(1))
Expect(resp.TLS.VerifiedChains[0]).Should(HaveLen(1))
Expect(resp.TLS.VerifiedChains[0][0].Raw).Should(Equal(ipv4CertData))
})
})
Context("with both an ipv4 http and an ipv4 https server", func() {
var listenAddr, secureListenAddr string
BeforeEach(func() {
var err error
srv, err = NewServer(Opts{
Handler: handler,
BindAddress: "127.0.0.1:0",
SecureBindAddress: "127.0.0.1:0",
TLS: &options.TLS{
Key: &ipv4KeyDataSource,
Cert: &ipv4CertDataSource,
},
})
Expect(err).ToNot(HaveOccurred())
s, ok := srv.(*server)
Expect(ok).To(BeTrue())
listenAddr = fmt.Sprintf("http://%s/", s.listener.Addr().String())
secureListenAddr = fmt.Sprintf("https://%s/", s.tlsListener.Addr().String())
})
It("Starts the server and serves the handler on http", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
resp, err := client.Get(listenAddr)
Expect(err).ToNot(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
body, err := io.ReadAll(resp.Body)
Expect(err).ToNot(HaveOccurred())
Expect(string(body)).To(Equal(hello))
})
It("Starts the server and serves the handler on https", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
resp, err := client.Get(secureListenAddr)
Expect(err).ToNot(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
body, err := io.ReadAll(resp.Body)
Expect(err).ToNot(HaveOccurred())
Expect(string(body)).To(Equal(hello))
})
It("Stops both servers when the context is cancelled", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
_, err := client.Get(listenAddr)
Expect(err).ToNot(HaveOccurred())
_, err = client.Get(secureListenAddr)
Expect(err).ToNot(HaveOccurred())
cancel()
Eventually(func() error {
_, err := client.Get(listenAddr)
return err
}).Should(HaveOccurred())
Eventually(func() error {
_, err := client.Get(secureListenAddr)
return err
}).Should(HaveOccurred())
})
})
Context("with an ipv6 http server", func() {
var listenAddr string
BeforeEach(func() {
var err error
srv, err = NewServer(Opts{
Handler: handler,
BindAddress: "[::1]:0",
})
Expect(err).ToNot(HaveOccurred())
s, ok := srv.(*server)
Expect(ok).To(BeTrue())
listenAddr = fmt.Sprintf("http://%s/", s.listener.Addr().String())
})
It("Starts the server and serves the handler", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
resp, err := client.Get(listenAddr)
Expect(err).ToNot(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
body, err := io.ReadAll(resp.Body)
Expect(err).ToNot(HaveOccurred())
Expect(string(body)).To(Equal(hello))
})
It("Stops the server when the context is cancelled", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
_, err := client.Get(listenAddr)
Expect(err).ToNot(HaveOccurred())
cancel()
Eventually(func() error {
_, err := client.Get(listenAddr)
return err
}).Should(HaveOccurred())
})
})
Context("with an ipv6 https server", func() {
var secureListenAddr string
BeforeEach(func() {
var err error
srv, err = NewServer(Opts{
Handler: handler,
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
Cert: &ipv6CertDataSource,
},
})
Expect(err).ToNot(HaveOccurred())
s, ok := srv.(*server)
Expect(ok).To(BeTrue())
secureListenAddr = fmt.Sprintf("https://%s/", s.tlsListener.Addr().String())
})
It("Starts the server and serves the handler", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
resp, err := client.Get(secureListenAddr)
Expect(err).ToNot(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
body, err := io.ReadAll(resp.Body)
Expect(err).ToNot(HaveOccurred())
Expect(string(body)).To(Equal(hello))
})
It("Stops the server when the context is cancelled", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
_, err := client.Get(secureListenAddr)
Expect(err).ToNot(HaveOccurred())
cancel()
Eventually(func() error {
_, err := client.Get(secureListenAddr)
return err
}).Should(HaveOccurred())
})
It("Serves the certificate provided", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
resp, err := client.Get(secureListenAddr)
Expect(err).ToNot(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
Expect(resp.TLS.VerifiedChains).Should(HaveLen(1))
Expect(resp.TLS.VerifiedChains[0]).Should(HaveLen(1))
Expect(resp.TLS.VerifiedChains[0][0].Raw).Should(Equal(ipv6CertData))
})
})
Context("with both an ipv6 http and an ipv6 https server", func() {
var listenAddr, secureListenAddr string
BeforeEach(func() {
var err error
srv, err = NewServer(Opts{
Handler: handler,
BindAddress: "[::1]:0",
SecureBindAddress: "[::1]:0",
TLS: &options.TLS{
Key: &ipv6KeyDataSource,
Cert: &ipv6CertDataSource,
},
})
Expect(err).ToNot(HaveOccurred())
s, ok := srv.(*server)
Expect(ok).To(BeTrue())
listenAddr = fmt.Sprintf("http://%s/", s.listener.Addr().String())
secureListenAddr = fmt.Sprintf("https://%s/", s.tlsListener.Addr().String())
})
It("Starts the server and serves the handler on http", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
resp, err := client.Get(listenAddr)
Expect(err).ToNot(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
body, err := io.ReadAll(resp.Body)
Expect(err).ToNot(HaveOccurred())
Expect(string(body)).To(Equal(hello))
})
It("Starts the server and serves the handler on https", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
resp, err := client.Get(secureListenAddr)
Expect(err).ToNot(HaveOccurred())
Expect(resp.StatusCode).To(Equal(http.StatusOK))
body, err := io.ReadAll(resp.Body)
Expect(err).ToNot(HaveOccurred())
Expect(string(body)).To(Equal(hello))
})
It("Stops both servers when the context is cancelled", func() {
go func() {
defer GinkgoRecover()
Expect(srv.Start(ctx)).To(Succeed())
}()
_, err := client.Get(listenAddr)
Expect(err).ToNot(HaveOccurred())
_, err = client.Get(secureListenAddr)
Expect(err).ToNot(HaveOccurred())
cancel()
Eventually(func() error {
_, err := client.Get(listenAddr)
return err
}).Should(HaveOccurred())
Eventually(func() error {
_, err := client.Get(secureListenAddr)
return err
}).Should(HaveOccurred())
})
})
})
Context("getNetworkScheme", func() {
DescribeTable("should return the scheme", func(in, expected string) {
Expect(getNetworkScheme(in)).To(Equal(expected))
},
Entry("ipv4 address with no scheme", "127.0.0.1:0", "tcp"),
Entry("ipv4 address with a tcp scheme", "tcp://127.0.0.1:0", "tcp"),
Entry("ipv4 address with a http scheme", "http://192.168.0.1:1", "tcp"),
Entry("ipv4 address with a unix scheme", "unix://172.168.16.2:2", "unix"),
Entry("ipv4 address with a random scheme", "random://10.10.10.10:10", "random"),
Entry("ipv6 address with no scheme", "[::1]:0", "tcp"),
Entry("ipv6 address with a tcp scheme", "tcp://[::1]:0", "tcp"),
Entry("ipv6 address with a http scheme", "http://[::ffff:c0a8:1]:1", "tcp"),
Entry("ipv6 address with a unix scheme", "unix://[::ffff:aca8:1002]:2", "unix"),
Entry("ipv6 address with a random scheme", "random://[::ffff:a0a:a0a]:10", "random"),
)
})
Context("getListenAddress", func() {
DescribeTable("should remove the scheme", func(in, expected string) {
Expect(getListenAddress(in)).To(Equal(expected))
},
Entry("ipv4 address with no scheme", "127.0.0.1:0", "127.0.0.1:0"),
Entry("ipv4 address with a tcp scheme", "tcp://127.0.0.1:0", "127.0.0.1:0"),
Entry("ipv4 address with a http scheme", "http://192.168.0.1:1", "192.168.0.1:1"),
Entry("ipv4 address with a unix scheme", "unix://172.168.16.2:2", "172.168.16.2:2"),
Entry("ipv4 address with a random scheme", "random://10.10.10.10:10", "10.10.10.10:10"),
Entry("ipv6 address with no scheme", "[::1]:0", "[::1]:0"),
Entry("ipv6 address with a tcp scheme", "tcp://[::1]:0", "[::1]:0"),
Entry("ipv6 address with a http scheme", "http://[::ffff:c0a8:1]:1", "[::ffff:c0a8:1]:1"),
Entry("ipv6 address with a unix scheme", "unix://[::ffff:aca8:1002]:2", "[::ffff:aca8:1002]:2"),
Entry("ipv6 address with a random scheme", "random://[::ffff:a0a:a0a]:10", "[::ffff:a0a:a0a]:10"),
)
})
})