mirror of https://github.com/harness/drone.git
[GITHA] Move `server.Server` out of `internal` (#145)
parent
d80fc15753
commit
deb9cf473a
|
@ -0,0 +1,156 @@
|
|||
// Copyright 2022 Harness Inc. All rights reserved.
|
||||
// Use of this source code is governed by the Polyform Free Trial License
|
||||
// that can be found in the LICENSE.md file for this repository.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultReadHeaderTimeout defines the default timeout for reading headers.
|
||||
DefaultReadHeaderTimeout = 2 * time.Second
|
||||
)
|
||||
|
||||
// Config defines the config of an http server.
|
||||
// TODO: expose via options?
|
||||
type Config struct {
|
||||
Acme bool
|
||||
Addr string
|
||||
Cert string
|
||||
Key string
|
||||
Host string
|
||||
ReadHeaderTimeout time.Duration
|
||||
}
|
||||
|
||||
// Server is a wrapper around http.Server that exposes different async ListenAndServe methods
|
||||
// that return corresponding ShutdownFunctions.
|
||||
type Server struct {
|
||||
config Config
|
||||
handler http.Handler
|
||||
}
|
||||
|
||||
// ShutdownFunction defines a function that is called to shutdown the server.
|
||||
type ShutdownFunction func(context.Context) error
|
||||
|
||||
func NewServer(config Config, handler http.Handler) *Server {
|
||||
if config.ReadHeaderTimeout == 0 {
|
||||
config.ReadHeaderTimeout = DefaultReadHeaderTimeout
|
||||
}
|
||||
|
||||
return &Server{
|
||||
config: config,
|
||||
handler: handler,
|
||||
}
|
||||
}
|
||||
|
||||
// ListenAndServe initializes a server to respond to HTTP network requests.
|
||||
func (s *Server) ListenAndServe() (*errgroup.Group, ShutdownFunction) {
|
||||
if s.config.Acme {
|
||||
return s.listenAndServeAcme()
|
||||
} else if s.config.Key != "" {
|
||||
return s.listenAndServeTLS()
|
||||
}
|
||||
return s.listenAndServe()
|
||||
}
|
||||
|
||||
func (s *Server) listenAndServe() (*errgroup.Group, ShutdownFunction) {
|
||||
var g errgroup.Group
|
||||
s1 := &http.Server{
|
||||
Addr: s.config.Addr,
|
||||
ReadHeaderTimeout: s.config.ReadHeaderTimeout,
|
||||
Handler: s.handler,
|
||||
}
|
||||
g.Go(func() error {
|
||||
return s1.ListenAndServe()
|
||||
})
|
||||
|
||||
return &g, s1.Shutdown
|
||||
}
|
||||
|
||||
func (s *Server) listenAndServeTLS() (*errgroup.Group, ShutdownFunction) {
|
||||
var g errgroup.Group
|
||||
s1 := &http.Server{
|
||||
Addr: ":http",
|
||||
ReadHeaderTimeout: s.config.ReadHeaderTimeout,
|
||||
Handler: http.HandlerFunc(redirect),
|
||||
}
|
||||
s2 := &http.Server{
|
||||
Addr: ":https",
|
||||
ReadHeaderTimeout: s.config.ReadHeaderTimeout,
|
||||
Handler: s.handler,
|
||||
}
|
||||
g.Go(func() error {
|
||||
return s1.ListenAndServe()
|
||||
})
|
||||
g.Go(func() error {
|
||||
return s2.ListenAndServeTLS(
|
||||
s.config.Cert,
|
||||
s.config.Key,
|
||||
)
|
||||
})
|
||||
|
||||
return &g, func(ctx context.Context) error {
|
||||
var sg errgroup.Group
|
||||
sg.Go(func() error {
|
||||
return s1.Shutdown(ctx)
|
||||
})
|
||||
sg.Go(func() error {
|
||||
return s2.Shutdown(ctx)
|
||||
})
|
||||
return sg.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
func (s Server) listenAndServeAcme() (*errgroup.Group, ShutdownFunction) {
|
||||
var g errgroup.Group
|
||||
m := &autocert.Manager{
|
||||
Cache: autocert.DirCache(".cache"),
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist(s.config.Host),
|
||||
}
|
||||
s1 := &http.Server{
|
||||
Addr: ":http",
|
||||
ReadHeaderTimeout: s.config.ReadHeaderTimeout,
|
||||
Handler: m.HTTPHandler(nil),
|
||||
}
|
||||
s2 := &http.Server{
|
||||
Addr: ":https",
|
||||
Handler: s.handler,
|
||||
ReadHeaderTimeout: s.config.ReadHeaderTimeout,
|
||||
TLSConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
GetCertificate: m.GetCertificate,
|
||||
NextProtos: []string{"h2", "http/1.1"},
|
||||
},
|
||||
}
|
||||
g.Go(func() error {
|
||||
return s1.ListenAndServe()
|
||||
})
|
||||
g.Go(func() error {
|
||||
return s2.ListenAndServeTLS("", "")
|
||||
})
|
||||
|
||||
return &g, func(ctx context.Context) error {
|
||||
var sg errgroup.Group
|
||||
sg.Go(func() error {
|
||||
return s1.Shutdown(ctx)
|
||||
})
|
||||
sg.Go(func() error {
|
||||
return s2.Shutdown(ctx)
|
||||
})
|
||||
return sg.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
func redirect(w http.ResponseWriter, req *http.Request) {
|
||||
target := "https://" + req.Host + req.URL.Path
|
||||
http.Redirect(w, req, target, http.StatusTemporaryRedirect)
|
||||
}
|
|
@ -6,135 +6,10 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/harness/gitness/internal/router"
|
||||
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"github.com/harness/gitness/http"
|
||||
)
|
||||
|
||||
const (
|
||||
// ReadHeaderTimeout defines the max time the server waits for request headers.
|
||||
ReadHeaderTimeout = 2 * time.Second
|
||||
)
|
||||
|
||||
// A Server defines parameters for running an HTTP server.
|
||||
// Server is the http server for gitness.
|
||||
type Server struct {
|
||||
Acme bool
|
||||
Addr string
|
||||
Cert string
|
||||
Key string
|
||||
Host string
|
||||
router *router.Router
|
||||
}
|
||||
|
||||
// ShutdownFunction defines a function that is called to shutdown the server.
|
||||
type ShutdownFunction func(context.Context) error
|
||||
|
||||
// ListenAndServe initializes a server to respond to HTTP network requests.
|
||||
func (s *Server) ListenAndServe() (*errgroup.Group, ShutdownFunction) {
|
||||
if s.Acme {
|
||||
return s.listenAndServeAcme()
|
||||
} else if s.Key != "" {
|
||||
return s.listenAndServeTLS()
|
||||
}
|
||||
return s.listenAndServe()
|
||||
}
|
||||
|
||||
func (s *Server) listenAndServe() (*errgroup.Group, ShutdownFunction) {
|
||||
var g errgroup.Group
|
||||
s1 := &http.Server{
|
||||
Addr: s.Addr,
|
||||
ReadHeaderTimeout: ReadHeaderTimeout,
|
||||
Handler: s.router,
|
||||
}
|
||||
g.Go(func() error {
|
||||
return s1.ListenAndServe()
|
||||
})
|
||||
|
||||
return &g, s1.Shutdown
|
||||
}
|
||||
|
||||
func (s *Server) listenAndServeTLS() (*errgroup.Group, ShutdownFunction) {
|
||||
var g errgroup.Group
|
||||
s1 := &http.Server{
|
||||
Addr: ":http",
|
||||
ReadHeaderTimeout: ReadHeaderTimeout,
|
||||
Handler: http.HandlerFunc(redirect),
|
||||
}
|
||||
s2 := &http.Server{
|
||||
Addr: ":https",
|
||||
ReadHeaderTimeout: ReadHeaderTimeout,
|
||||
Handler: s.router,
|
||||
}
|
||||
g.Go(func() error {
|
||||
return s1.ListenAndServe()
|
||||
})
|
||||
g.Go(func() error {
|
||||
return s2.ListenAndServeTLS(
|
||||
s.Cert,
|
||||
s.Key,
|
||||
)
|
||||
})
|
||||
|
||||
return &g, func(ctx context.Context) error {
|
||||
var sg errgroup.Group
|
||||
sg.Go(func() error {
|
||||
return s1.Shutdown(ctx)
|
||||
})
|
||||
sg.Go(func() error {
|
||||
return s2.Shutdown(ctx)
|
||||
})
|
||||
return sg.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
func (s Server) listenAndServeAcme() (*errgroup.Group, ShutdownFunction) {
|
||||
var g errgroup.Group
|
||||
m := &autocert.Manager{
|
||||
Cache: autocert.DirCache(".cache"),
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist(s.Host),
|
||||
}
|
||||
s1 := &http.Server{
|
||||
Addr: ":http",
|
||||
ReadHeaderTimeout: ReadHeaderTimeout,
|
||||
Handler: m.HTTPHandler(nil),
|
||||
}
|
||||
s2 := &http.Server{
|
||||
Addr: ":https",
|
||||
Handler: s.router,
|
||||
ReadHeaderTimeout: ReadHeaderTimeout,
|
||||
TLSConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
GetCertificate: m.GetCertificate,
|
||||
NextProtos: []string{"h2", "http/1.1"},
|
||||
},
|
||||
}
|
||||
g.Go(func() error {
|
||||
return s1.ListenAndServe()
|
||||
})
|
||||
g.Go(func() error {
|
||||
return s2.ListenAndServeTLS("", "")
|
||||
})
|
||||
|
||||
return &g, func(ctx context.Context) error {
|
||||
var sg errgroup.Group
|
||||
sg.Go(func() error {
|
||||
return s1.Shutdown(ctx)
|
||||
})
|
||||
sg.Go(func() error {
|
||||
return s2.Shutdown(ctx)
|
||||
})
|
||||
return sg.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
func redirect(w http.ResponseWriter, req *http.Request) {
|
||||
target := "https://" + req.Host + req.URL.Path
|
||||
http.Redirect(w, req, target, http.StatusTemporaryRedirect)
|
||||
*http.Server
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"github.com/harness/gitness/http"
|
||||
"github.com/harness/gitness/internal/router"
|
||||
"github.com/harness/gitness/types"
|
||||
|
||||
|
@ -17,9 +18,13 @@ var WireSet = wire.NewSet(ProvideServer)
|
|||
// ProvideServer provides a server instance.
|
||||
func ProvideServer(config *types.Config, router *router.Router) *Server {
|
||||
return &Server{
|
||||
Acme: config.Server.Acme.Enabled,
|
||||
Addr: config.Server.HTTP.Bind,
|
||||
Host: config.Server.HTTP.Host,
|
||||
router: router,
|
||||
http.NewServer(
|
||||
http.Config{
|
||||
Acme: config.Server.Acme.Enabled,
|
||||
Addr: config.Server.HTTP.Bind,
|
||||
Host: config.Server.HTTP.Host,
|
||||
},
|
||||
router,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue