13 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
14 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options/util"
15 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
16 "golang.org/x/sync/errgroup"
19// Server represents an HTTP or HTTPS server.
20type Server interface {
21 // Start blocks and runs the server.
22 Start(ctx context.Context) error
25// Opts contains the information required to set up the server.
27 // Handler is the http.Handler to be used to serve http pages by the server.
30 // BindAddress is the address the HTTP server should listen on.
33 // SecureBindAddress is the address the HTTPS server should listen on.
34 SecureBindAddress string
36 // TLS is the TLS configuration for the server.
40// NewServer creates a new Server from the options given.
41func NewServer(opts Opts) (Server, error) {
43 handler: opts.Handler,
45 if err := s.setupListener(opts); err != nil {
46 return nil, fmt.Errorf("error setting up listener: %v", err)
48 if err := s.setupTLSListener(opts); err != nil {
49 return nil, fmt.Errorf("error setting up TLS listener: %v", err)
55// server is an implementation of the Server interface.
60 tlsListener net.Listener
63// setupListener sets the server listener if the HTTP server is enabled.
64// The HTTP server can be disabled by setting the BindAddress to "-" or by
66func (s *server) setupListener(opts Opts) error {
67 if opts.BindAddress == "" || opts.BindAddress == "-" {
68 // No HTTP listener required
72 networkType := getNetworkScheme(opts.BindAddress)
73 listenAddr := getListenAddress(opts.BindAddress)
75 listener, err := net.Listen(networkType, listenAddr)
77 return fmt.Errorf("listen (%s, %s) failed: %v", networkType, listenAddr, err)
84// setupTLSListener sets the server TLS listener if the HTTPS server is enabled.
85// The HTTPS server can be disabled by setting the SecureBindAddress to "-" or by
87func (s *server) setupTLSListener(opts Opts) error {
88 if opts.SecureBindAddress == "" || opts.SecureBindAddress == "-" {
89 // No HTTPS listener required
93 config := &tls.Config{
94 MinVersion: tls.VersionTLS12, // default, override below
95 MaxVersion: tls.VersionTLS13,
96 NextProtos: []string{"http/1.1"},
99 return errors.New("no TLS config provided")
101 cert, err := getCertificate(opts.TLS)
103 return fmt.Errorf("could not load certificate: %v", err)
105 config.Certificates = []tls.Certificate{cert}
107 if len(opts.TLS.MinVersion) > 0 {
108 switch opts.TLS.MinVersion {
110 config.MinVersion = tls.VersionTLS12
112 config.MinVersion = tls.VersionTLS13
114 return errors.New("unknown TLS MinVersion config provided")
118 listenAddr := getListenAddress(opts.SecureBindAddress)
120 listener, err := net.Listen("tcp", listenAddr)
122 return fmt.Errorf("listen (%s) failed: %v", listenAddr, err)
125 s.tlsListener = tls.NewListener(tcpKeepAliveListener{listener.(*net.TCPListener)}, config)
129// Start starts the HTTP and HTTPS server if applicable.
130// It will block until the context is cancelled.
131// If any errors occur, only the first error will be returned.
132func (s *server) Start(ctx context.Context) error {
133 g, groupCtx := errgroup.WithContext(ctx)
135 if s.listener != nil {
137 if err := s.startServer(groupCtx, s.listener); err != nil {
138 return fmt.Errorf("error starting insecure server: %v", err)
144 if s.tlsListener != nil {
146 if err := s.startServer(groupCtx, s.tlsListener); err != nil {
147 return fmt.Errorf("error starting secure server: %v", err)
156// startServer creates and starts a new server with the given listener.
157// When the given context is cancelled the server will be shutdown.
158// If any errors occur, only the first error will be returned.
159func (s *server) startServer(ctx context.Context, listener net.Listener) error {
160 srv := &http.Server{Handler: s.handler}
161 g, groupCtx := errgroup.WithContext(ctx)
166 if err := srv.Shutdown(context.Background()); err != nil {
167 return fmt.Errorf("error shutting down server: %v", err)
173 if err := srv.Serve(listener); err != nil && !errors.Is(err, http.ErrServerClosed) {
174 return fmt.Errorf("could not start server: %v", err)
182// getNetworkScheme gets the scheme for the HTTP server.
183func getNetworkScheme(addr string) string {
185 i := strings.Index(addr, "://")
198// getListenAddress gets the address for the HTTP server.
199func getListenAddress(addr string) string {
200 slice := strings.SplitN(addr, "//", 2)
201 return slice[len(slice)-1]
204// getCertificate loads the certificate data from the TLS config.
205func getCertificate(opts *options.TLS) (tls.Certificate, error) {
206 keyData, err := getSecretValue(opts.Key)
208 return tls.Certificate{}, fmt.Errorf("could not load key data: %v", err)
211 certData, err := getSecretValue(opts.Cert)
213 return tls.Certificate{}, fmt.Errorf("could not load cert data: %v", err)
216 cert, err := tls.X509KeyPair(certData, keyData)
218 return tls.Certificate{}, fmt.Errorf("could not parse certificate data: %v", err)
224// getSecretValue wraps util.GetSecretValue so that we can return an error if no
225// source is provided.
226func getSecretValue(src *options.SecretSource) ([]byte, error) {
228 return nil, errors.New("no configuration provided")
230 return util.GetSecretValue(src)
233// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
234// connections. It's used by so that dead TCP connections (e.g. closing laptop
235// mid-download) eventually go away.
236type tcpKeepAliveListener struct {
240// Accept implements the TCPListener interface.
241// It sets the keep alive period to 3 minutes for each connection.
242func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
243 tc, err := ln.AcceptTCP()
247 err = tc.SetKeepAlive(true)
249 logger.Errorf("Error setting Keep-Alive: %v", err)
251 err = tc.SetKeepAlivePeriod(3 * time.Minute)
253 logger.Printf("Error setting Keep-Alive period: %v", err)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list