mirror of
https://github.com/zhufuyi/sponge.git
synced 2025-12-24 10:40:55 +08:00
feat: web service support TLS
This commit is contained in:
@@ -18,6 +18,7 @@ func CreateServices() []app.IServer {
|
||||
// case 1, create a http service without registry
|
||||
httpServer := server.NewHTTPServer_pbExample(httpAddr,
|
||||
server.WithHTTPIsProd(cfg.App.Env == "prod"),
|
||||
server.WithHTTPTLS(cfg.HTTP.TLS),
|
||||
)
|
||||
|
||||
// case 2, Create a http service and register it with consul or etcd or nacos
|
||||
@@ -25,6 +26,7 @@ func CreateServices() []app.IServer {
|
||||
//httpServer := server.NewHTTPServer_pbExample(httpAddr,
|
||||
// server.WithHTTPRegistry(httpRegistry, httpInstance),
|
||||
// server.WithHTTPIsProd(cfg.App.Env == "prod"),
|
||||
// server.WithHTTPTLS(cfg.HTTP.TLS),
|
||||
//)
|
||||
|
||||
servers = append(servers, httpServer)
|
||||
|
||||
@@ -19,6 +19,7 @@ func CreateServices() []app.IServer {
|
||||
// case 1, create http and grpc services without registry
|
||||
httpServer := server.NewHTTPServer(httpAddr,
|
||||
server.WithHTTPIsProd(cfg.App.Env == "prod"),
|
||||
server.WithHTTPTLS(cfg.HTTP.TLS),
|
||||
)
|
||||
grpcServer := server.NewGRPCServer(grpcAddr)
|
||||
|
||||
@@ -27,6 +28,7 @@ func CreateServices() []app.IServer {
|
||||
//httpServer := server.NewHTTPServer(httpAddr,
|
||||
// server.WithHTTPRegistry(httpRegistry, httpInstance),
|
||||
// server.WithHTTPIsProd(cfg.App.Env == "prod"),
|
||||
// server.WithHTTPTLS(cfg.HTTP.TLS),
|
||||
//)
|
||||
//grpcRegistry, grpcInstance := registerService("grpc", cfg.App.Host, cfg.Grpc.Port)
|
||||
//grpcServer := server.NewGRPCServer(grpcAddr,
|
||||
|
||||
@@ -18,6 +18,7 @@ func CreateServices() []app.IServer {
|
||||
httpAddr := ":" + strconv.Itoa(cfg.HTTP.Port)
|
||||
httpServer := server.NewHTTPServer(httpAddr,
|
||||
server.WithHTTPIsProd(cfg.App.Env == "prod"),
|
||||
server.WithHTTPTLS(cfg.HTTP.TLS),
|
||||
)
|
||||
servers = append(servers, httpServer)
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ func CreateServices() []app.IServer {
|
||||
httpAddr := ":" + strconv.Itoa(cfg.HTTP.Port)
|
||||
httpServer := server.NewHTTPServer_pbExample(httpAddr,
|
||||
server.WithHTTPIsProd(cfg.App.Env == "prod"),
|
||||
server.WithHTTPTLS(cfg.HTTP.TLS),
|
||||
)
|
||||
servers = append(servers, httpServer)
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ func CreateServices() []app.IServer {
|
||||
httpServer := server.NewHTTPServer(httpAddr,
|
||||
server.WithHTTPRegistry(httpRegistry, httpInstance),
|
||||
server.WithHTTPIsProd(cfg.App.Env == "prod"),
|
||||
server.WithHTTPTLS(cfg.HTTP.TLS),
|
||||
)
|
||||
servers = append(servers, httpServer)
|
||||
|
||||
|
||||
@@ -212,10 +212,6 @@ func (g *rpcGwPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
|
||||
Old: appConfigFileMark2,
|
||||
New: getDBConfigCode(""), // no db config
|
||||
},
|
||||
{ // replace the configuration of the *.yml file
|
||||
Old: appConfigFileMark,
|
||||
New: "",
|
||||
},
|
||||
//{ // replace the contents of the model/init.go file
|
||||
// Old: modelInitDBFileMark,
|
||||
// New: getInitDBCode(DBDriverMysql), // default is mysql
|
||||
|
||||
@@ -370,7 +370,17 @@ func NewCenter(configFile string) (*Center, error) {
|
||||
httpServerConfigCode = `# http server settings
|
||||
http:
|
||||
port: 8080 # listen port
|
||||
timeout: 0 # request timeout, unit(second), if 0 means not set, if greater than 0 means set timeout, if enableHTTPProfile is true, it needs to set 0 or greater than 60s`
|
||||
timeout: 0 # request timeout, unit(second), if 0 means not set, if greater than 0 means set timeout, if enableHTTPProfile is true, it needs to set 0 or greater than 60s
|
||||
tls:
|
||||
# TLS mode options:
|
||||
# self-signed - Use localhost self-signed certificate
|
||||
# encrypt - Use Let's Encrypt (requires domain & email)
|
||||
# external - Use external certificates (requires certFile & keyFile)
|
||||
enableMode: ""
|
||||
domain: "" # Required if enableMode = encrypt
|
||||
email: "" # Required if enableMode = encrypt
|
||||
certFile: "" # Required if enableMode = external, absolute path of cert file
|
||||
keyFile: "" # Required if enableMode = external, absolute path of key file`
|
||||
|
||||
rpcServerConfigCode = `# grpc server settings
|
||||
grpc:
|
||||
@@ -414,6 +424,16 @@ grpcClient:
|
||||
http:
|
||||
port: 8080 # listen port
|
||||
timeout: 0 # request timeout, unit(second), if 0 means not set, if greater than 0 means set timeout, if enableHTTPProfile is true, it needs to set 0 or greater than 60s
|
||||
tls:
|
||||
# TLS mode options:
|
||||
# self-signed - Use localhost self-signed certificate
|
||||
# encrypt - Use Let's Encrypt (requires domain & email)
|
||||
# external - Use external certificates (requires certFile & keyFile)
|
||||
enableMode: ""
|
||||
domain: "" # Required if enableMode = encrypt
|
||||
email: "" # Required if enableMode = encrypt
|
||||
certFile: "" # Required if enableMode = external, absolute path of cert file
|
||||
keyFile: "" # Required if enableMode = external, absolute path of key file
|
||||
|
||||
|
||||
# grpc client-side settings, support for setting up multiple grpc clients.
|
||||
@@ -441,7 +461,17 @@ grpcClient:
|
||||
grpcAndHTTPServerConfigCode = `# http server settings
|
||||
http:
|
||||
port: 8080 # listen port
|
||||
timeout: 0 # request timeout, unit(second), if 0 means not set, if greater than 0 means set timeout, if enableHTTPProfile is true, it needs to set 0 or greater than 60s
|
||||
timeout: 0 # request timeout, unit(second), if 0 means not set, if greater than 0 means set timeout, if enableHTTPProfile is true, it needs to set 0 or greater than 60s
|
||||
tls:
|
||||
# TLS mode options:
|
||||
# self-signed - Use localhost self-signed certificate
|
||||
# encrypt - Use Let's Encrypt (requires domain & email)
|
||||
# external - Use external certificates (requires certFile & keyFile)
|
||||
enableMode: ""
|
||||
domain: "" # Required if enableMode = encrypt
|
||||
email: "" # Required if enableMode = encrypt
|
||||
certFile: "" # Required if enableMode = external, absolute path of cert file
|
||||
keyFile: "" # Required if enableMode = external, absolute path of key file
|
||||
|
||||
|
||||
# grpc server settings
|
||||
|
||||
@@ -23,7 +23,16 @@ app:
|
||||
http:
|
||||
port: 8080 # listen port
|
||||
timeout: 0 # request timeout, unit(second), if 0 means not set, if greater than 0 means set timeout, if enableHTTPProfile is true, it needs to set 0 or greater than 60s
|
||||
|
||||
tls:
|
||||
# TLS mode options:
|
||||
# self-signed - Use localhost self-signed certificate
|
||||
# encrypt - Use Let's Encrypt (requires domain & email)
|
||||
# external - Use external certificates (requires certFile & keyFile)
|
||||
enableMode: ""
|
||||
domain: "" # Required if enableMode = encrypt
|
||||
email: "" # Required if enableMode = encrypt
|
||||
certFile: "" # Required if enableMode = external, absolute path of cert file
|
||||
keyFile: "" # Required if enableMode = external, absolute path of key file
|
||||
|
||||
# grpc server settings
|
||||
grpc:
|
||||
|
||||
@@ -76,6 +76,14 @@ type ServerSecure struct {
|
||||
Type string `yaml:"type" json:"type"`
|
||||
}
|
||||
|
||||
type TLS struct {
|
||||
CertFile string `yaml:"certFile" json:"certFile"`
|
||||
Domain string `yaml:"domain" json:"domain"`
|
||||
Email string `yaml:"email" json:"email"`
|
||||
EnableMode string `yaml:"enableMode" json:"enableMode"`
|
||||
KeyFile string `yaml:"keyFile" json:"keyFile"`
|
||||
}
|
||||
|
||||
type App struct {
|
||||
CacheType string `yaml:"cacheType" json:"cacheType"`
|
||||
EnableCircuitBreaker bool `yaml:"enableCircuitBreaker" json:"enableCircuitBreaker"`
|
||||
@@ -169,4 +177,5 @@ type NacosRd struct {
|
||||
type HTTP struct {
|
||||
Port int `yaml:"port" json:"port"`
|
||||
Timeout int `yaml:"timeout" json:"timeout"`
|
||||
TLS TLS `yaml:"tls" json:"tls"`
|
||||
}
|
||||
|
||||
@@ -9,8 +9,10 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/go-dev-frame/sponge/pkg/app"
|
||||
"github.com/go-dev-frame/sponge/pkg/httpsrv"
|
||||
"github.com/go-dev-frame/sponge/pkg/servicerd/registry"
|
||||
|
||||
"github.com/go-dev-frame/sponge/internal/config"
|
||||
"github.com/go-dev-frame/sponge/internal/routers"
|
||||
)
|
||||
|
||||
@@ -18,7 +20,7 @@ var _ app.IServer = (*httpServer)(nil)
|
||||
|
||||
type httpServer struct {
|
||||
addr string
|
||||
server *http.Server
|
||||
server *httpsrv.Server
|
||||
|
||||
instance *registry.ServiceInstance
|
||||
iRegistry registry.Registry
|
||||
@@ -33,8 +35,8 @@ func (s *httpServer) Start() error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
return fmt.Errorf("listen server error: %v", err)
|
||||
if err := s.server.Run(); err != nil {
|
||||
return fmt.Errorf("run %s service error: %v", s.server.Scheme(), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -56,7 +58,29 @@ func (s *httpServer) Stop() error {
|
||||
|
||||
// String comment
|
||||
func (s *httpServer) String() string {
|
||||
return "http service address " + s.addr
|
||||
return s.server.Scheme() + " service address is " + s.addr
|
||||
}
|
||||
|
||||
func newServer(server *http.Server, tls config.TLS) *httpsrv.Server {
|
||||
var c *httpsrv.Server
|
||||
switch httpsrv.Mode(tls.EnableMode) {
|
||||
case httpsrv.ModeTLSSelfSigned:
|
||||
c = httpsrv.New(server, httpsrv.NewTLSSelfSignedConfig())
|
||||
case httpsrv.ModeTLSEncrypt:
|
||||
c = httpsrv.New(server,
|
||||
httpsrv.NewTLSEAutoEncryptConfig(
|
||||
tls.Domain,
|
||||
tls.Email,
|
||||
// enable http redirect to https, port 80 to 443, default is false
|
||||
//httpsrv.WithTLSEncryptEnableRedirect(),
|
||||
),
|
||||
)
|
||||
case httpsrv.ModeTLSExternal:
|
||||
c = httpsrv.New(server, httpsrv.NewTLSExternalConfig(tls.CertFile, tls.KeyFile))
|
||||
default:
|
||||
c = httpsrv.New(server) // default is http, no tls
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// NewHTTPServer creates a new http server
|
||||
@@ -82,7 +106,7 @@ func NewHTTPServer(addr string, opts ...HTTPOption) app.IServer {
|
||||
|
||||
return &httpServer{
|
||||
addr: addr,
|
||||
server: server,
|
||||
server: newServer(server, o.tls),
|
||||
iRegistry: o.iRegistry,
|
||||
instance: o.instance,
|
||||
}
|
||||
@@ -113,7 +137,7 @@ func NewHTTPServer_pbExample(addr string, opts ...HTTPOption) app.IServer { //no
|
||||
|
||||
return &httpServer{
|
||||
addr: addr,
|
||||
server: server,
|
||||
server: newServer(server, o.tls),
|
||||
iRegistry: o.iRegistry,
|
||||
instance: o.instance,
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/go-dev-frame/sponge/pkg/app"
|
||||
"github.com/go-dev-frame/sponge/pkg/httpsrv"
|
||||
|
||||
"github.com/go-dev-frame/sponge/internal/config"
|
||||
"github.com/go-dev-frame/sponge/internal/routers"
|
||||
)
|
||||
|
||||
@@ -17,13 +19,13 @@ var _ app.IServer = (*httpServer)(nil)
|
||||
|
||||
type httpServer struct {
|
||||
addr string
|
||||
server *http.Server
|
||||
server *httpsrv.Server
|
||||
}
|
||||
|
||||
// Start http service
|
||||
func (s *httpServer) Start() error {
|
||||
if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
return fmt.Errorf("listen server error: %v", err)
|
||||
if err := s.server.Run(); err != nil {
|
||||
return fmt.Errorf("run %s service error: %v", s.server.Scheme(), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -36,7 +38,29 @@ func (s *httpServer) Stop() error {
|
||||
|
||||
// String comment
|
||||
func (s *httpServer) String() string {
|
||||
return "http service address " + s.addr
|
||||
return s.server.Scheme() + " service address is " + s.addr
|
||||
}
|
||||
|
||||
func newServer(server *http.Server, tls config.TLS) *httpsrv.Server {
|
||||
var c *httpsrv.Server
|
||||
switch httpsrv.Mode(tls.EnableMode) {
|
||||
case httpsrv.ModeTLSSelfSigned:
|
||||
c = httpsrv.New(server, httpsrv.NewTLSSelfSignedConfig())
|
||||
case httpsrv.ModeTLSEncrypt:
|
||||
c = httpsrv.New(server,
|
||||
httpsrv.NewTLSEAutoEncryptConfig(
|
||||
tls.Domain,
|
||||
tls.Email,
|
||||
// enable http redirect to https, port 80 to 443, default is false
|
||||
//httpsrv.WithTLSEncryptEnableRedirect(),
|
||||
),
|
||||
)
|
||||
case httpsrv.ModeTLSExternal:
|
||||
c = httpsrv.New(server, httpsrv.NewTLSExternalConfig(tls.CertFile, tls.KeyFile))
|
||||
default:
|
||||
c = httpsrv.New(server)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// NewHTTPServer creates a new http server
|
||||
@@ -54,39 +78,14 @@ func NewHTTPServer(addr string, opts ...HTTPOption) app.IServer {
|
||||
server := &http.Server{
|
||||
Addr: addr,
|
||||
Handler: router,
|
||||
//ReadTimeout: time.Second*30,
|
||||
//WriteTimeout: time.Second*60,
|
||||
IdleTimeout: time.Second * 60,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
|
||||
return &httpServer{
|
||||
addr: addr,
|
||||
server: server,
|
||||
server: newServer(server, o.tls),
|
||||
}
|
||||
}
|
||||
|
||||
// delete the templates code start
|
||||
|
||||
// NewHTTPServer_pbExample creates a new web server
|
||||
func NewHTTPServer_pbExample(addr string, opts ...HTTPOption) app.IServer { //nolint
|
||||
o := defaultHTTPOptions()
|
||||
o.apply(opts...)
|
||||
|
||||
if o.isProd {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
} else {
|
||||
gin.SetMode(gin.DebugMode)
|
||||
}
|
||||
|
||||
router := routers.NewRouter_pbExample()
|
||||
server := &http.Server{
|
||||
Addr: addr,
|
||||
Handler: router,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
|
||||
return &httpServer{
|
||||
addr: addr,
|
||||
server: server,
|
||||
}
|
||||
}
|
||||
|
||||
// delete the templates code end
|
||||
|
||||
@@ -2,6 +2,8 @@ package server
|
||||
|
||||
import (
|
||||
"github.com/go-dev-frame/sponge/pkg/servicerd/registry"
|
||||
|
||||
"github.com/go-dev-frame/sponge/internal/config"
|
||||
)
|
||||
|
||||
// HTTPOption setting up http
|
||||
@@ -11,6 +13,7 @@ type httpOptions struct {
|
||||
isProd bool
|
||||
instance *registry.ServiceInstance
|
||||
iRegistry registry.Registry
|
||||
tls config.TLS
|
||||
}
|
||||
|
||||
func defaultHTTPOptions() *httpOptions {
|
||||
@@ -41,3 +44,10 @@ func WithHTTPRegistry(iRegistry registry.Registry, instance *registry.ServiceIns
|
||||
o.instance = instance
|
||||
}
|
||||
}
|
||||
|
||||
// WithHTTPTLS setting up tls
|
||||
func WithHTTPTLS(tls config.TLS) HTTPOption {
|
||||
return func(o *httpOptions) {
|
||||
o.tls = tls
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/go-dev-frame/sponge/internal/config"
|
||||
)
|
||||
|
||||
// HTTPOption setting up http
|
||||
type HTTPOption func(*httpOptions)
|
||||
|
||||
type httpOptions struct {
|
||||
isProd bool
|
||||
tls config.TLS
|
||||
}
|
||||
|
||||
func defaultHTTPOptions() *httpOptions {
|
||||
@@ -25,3 +30,10 @@ func WithHTTPIsProd(isProd bool) HTTPOption {
|
||||
o.isProd = isProd
|
||||
}
|
||||
}
|
||||
|
||||
// WithHTTPTLS setting up tls
|
||||
func WithHTTPTLS(tls config.TLS) HTTPOption {
|
||||
return func(o *httpOptions) {
|
||||
o.tls = tls
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,11 +85,12 @@ func TestHTTPServerMock(t *testing.T) {
|
||||
instance: ®istry.ServiceInstance{},
|
||||
iRegistry: &iRegistry{},
|
||||
}
|
||||
s.server = &http.Server{
|
||||
server := &http.Server{
|
||||
Addr: addr,
|
||||
Handler: http.NewServeMux(),
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
s.server = newServer(server, config.Get().HTTP.TLS)
|
||||
|
||||
go func() {
|
||||
time.Sleep(time.Second * 3)
|
||||
@@ -113,3 +114,48 @@ func (i *iRegistry) Register(ctx context.Context, service *registry.ServiceInsta
|
||||
func (i *iRegistry) Deregister(ctx context.Context, service *registry.ServiceInstance) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Test_newServer(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
tls config.TLS
|
||||
scheme string
|
||||
}{
|
||||
{
|
||||
name: "no_tls",
|
||||
tls: config.TLS{},
|
||||
scheme: "http",
|
||||
},
|
||||
{
|
||||
name: "tls_self_signed",
|
||||
tls: config.TLS{
|
||||
EnableMode: "self-signed",
|
||||
},
|
||||
scheme: "https",
|
||||
},
|
||||
{
|
||||
name: "tls_encrypt",
|
||||
tls: config.TLS{
|
||||
EnableMode: "encrypt",
|
||||
Domain: "example.com",
|
||||
Email: "admin@example.com",
|
||||
},
|
||||
scheme: "https",
|
||||
},
|
||||
{
|
||||
name: "tls_external",
|
||||
tls: config.TLS{
|
||||
EnableMode: "external",
|
||||
CertFile: "cert.pem",
|
||||
KeyFile: "key.pem",
|
||||
},
|
||||
scheme: "https",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
server := newServer(&http.Server{}, tt.tls)
|
||||
assert.Equal(t, tt.scheme, server.Scheme())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user