Skip to content

Commit

Permalink
feat: TLS listening (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
vm-001 authored Feb 28, 2025
1 parent 5b1f970 commit 52481d6
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 65 deletions.
22 changes: 15 additions & 7 deletions admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (

// Admin is an HTTP Server
type Admin struct {
s *http.Server
cfg *config.AdminConfig
s *http.Server
}

func NewAdmin(cfg config.AdminConfig, handler http.Handler) *Admin {
Expand All @@ -21,12 +22,11 @@ func NewAdmin(cfg config.AdminConfig, handler http.Handler) *Admin {

WriteTimeout: 60 * time.Second,
ReadTimeout: 60 * time.Second,

// TODO: expose more to be configurable
}

admin := &Admin{
s: s,
cfg: &cfg,
s: s,
}

return admin
Expand All @@ -35,9 +35,17 @@ func NewAdmin(cfg config.AdminConfig, handler http.Handler) *Admin {
// Start starts an HTTP server
func (a *Admin) Start() {
go func() {
if err := a.s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
zap.S().Errorf("Failed to start Admin : %v", err)
os.Exit(1)
tls := a.cfg.TLS
if tls.Enabled() {
if err := a.s.ListenAndServeTLS(tls.Cert, tls.Key); err != nil && err != http.ErrServerClosed {
zap.S().Errorf("Failed to start Admin : %v", err)
os.Exit(1)
}
} else {
if err := a.s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
zap.S().Errorf("Failed to start Admin : %v", err)
os.Exit(1)
}
}
}()
}
Expand Down
6 changes: 6 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ redis:

admin:
#listen: 127.0.0.1:8080
#tls:
# cert: /path/to/server.crt
# key: /path/to/server.key

#------------------------------------------------------------------------------
# WORKER
Expand All @@ -50,6 +53,9 @@ worker:
#------------------------------------------------------------------------------
proxy:
#listen: 127.0.0.1:8081
#tls:
# cert: /path/to/server.crt
# key: /path/to/server.key
timeout_read: 10 # read timeout (in seconds), 0 indicates unlimited.
timeout_write: 60 # write timeout (in seconds), 0 indicates unlimited.
max_request_body_size: 1048576
Expand Down
10 changes: 10 additions & 0 deletions config/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config

type AdminConfig struct {
Listen string `yaml:"listen"`
TLS TLS `yaml:"tls"`
}

func (cfg AdminConfig) Validate() error {
Expand All @@ -14,3 +15,12 @@ func (cfg AdminConfig) IsEnabled() bool {
}
return true
}

type TLS struct {
Cert string `yaml:"cert"`
Key string `yaml:"key"`
}

func (cfg TLS) Enabled() bool {
return cfg.Cert != "" && cfg.Key != ""
}
4 changes: 2 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ var (
NODE = uuid.NewV4().String()
)

var cfg Config

type Config struct {
Log LogConfig `yaml:"log" envconfig:"LOG"`
Database DatabaseConfig `yaml:"database" envconfig:"DATABASE"`
Expand Down Expand Up @@ -66,6 +64,7 @@ func (cfg Config) Validate() error {
}

func Init() (*Config, error) {
var cfg Config
if err := defaults.Set(&cfg); err != nil {
return nil, err
}
Expand All @@ -79,6 +78,7 @@ func Init() (*Config, error) {
}

func InitWithFile(filename string) (*Config, error) {
var cfg Config
if err := defaults.Set(&cfg); err != nil {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions config/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func (cfg Queue) Validate() error {

type ProxyConfig struct {
Listen string `yaml:"listen"`
TLS TLS `yaml:"tls"`
TimeoutRead int64 `yaml:"timeout_read" default:"10"`
TimeoutWrite int64 `yaml:"timeout_write" default:"10"`
MaxRequestBodySize int64 `yaml:"max_request_body_size" default:"1048576"`
Expand Down
14 changes: 11 additions & 3 deletions proxy/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,17 @@ func (gw *Gateway) Start() {
gw.ctx, gw.cancel = context.WithCancel(context.Background())

go func() {
if err := gw.s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
zap.S().Errorf("Failed to start Gateway : %v", err)
os.Exit(1)
tls := gw.cfg.TLS
if tls.Enabled() {
if err := gw.s.ListenAndServeTLS(tls.Cert, tls.Key); err != nil && err != http.ErrServerClosed {
zap.S().Errorf("Failed to start Admin : %v", err)
os.Exit(1)
}
} else {
if err := gw.s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
zap.S().Errorf("Failed to start Gateway : %v", err)
os.Exit(1)
}
}
}()

Expand Down
62 changes: 46 additions & 16 deletions test/admin/listen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,59 @@ import (
. "github.com/onsi/ginkgo/v2"
"github.com/stretchr/testify/assert"
"github.com/webhookx-io/webhookx/app"
"github.com/webhookx-io/webhookx/test"
"github.com/webhookx-io/webhookx/test/helper"
"github.com/webhookx-io/webhookx/utils"
)

var _ = Describe("admin", Ordered, func() {
var app *app.Application
var adminClient *resty.Client

BeforeAll(func() {
helper.InitDB(true, nil)
app = utils.Must(helper.Start(map[string]string{
"WEBHOOKX_ADMIN_LISTEN": "0.0.0.0:8080",
}))
adminClient = helper.AdminClient()
})

AfterAll(func() {
app.Stop()
Context("listen", func() {
var app *app.Application
var adminClient *resty.Client

BeforeAll(func() {
helper.InitDB(true, nil)
app = utils.Must(helper.Start(map[string]string{
"WEBHOOKX_ADMIN_LISTEN": "0.0.0.0:8080",
}))
adminClient = helper.AdminClient()
})

AfterAll(func() {
app.Stop()
})

It("admin listen", func() {
resp, err := adminClient.R().Get("/")
assert.Nil(GinkgoT(), err)
assert.Equal(GinkgoT(), 200, resp.StatusCode())
})
})

It("proxy listen", func() {
resp, err := adminClient.R().Get("/")
assert.Nil(GinkgoT(), err)
assert.Equal(GinkgoT(), 200, resp.StatusCode())
Context("tls listen", func() {
var app *app.Application
var adminClient *resty.Client

BeforeAll(func() {
helper.InitDB(true, nil)
app = utils.Must(helper.Start(map[string]string{
"WEBHOOKX_ADMIN_LISTEN": "0.0.0.0:8080",
"WEBHOOKX_ADMIN_TLS_CERT": test.FilePath("server.crt"),
"WEBHOOKX_ADMIN_TLS_KEY": test.FilePath("server.key"),
}))
adminClient = helper.AdminTLSClient()
})

AfterAll(func() {
app.Stop()
})

It("admin tls listen", func() {
resp, err := adminClient.R().Get("/")
assert.Nil(GinkgoT(), err)
assert.Equal(GinkgoT(), 200, resp.StatusCode())
})
})

})
48 changes: 35 additions & 13 deletions test/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"context"
"crypto/rand"
"crypto/tls"
"encoding/hex"
"github.com/go-resty/resty/v2"
"github.com/webhookx-io/webhookx/app"
Expand Down Expand Up @@ -38,21 +39,23 @@ var defaultEnvs = map[string]string{
"WEBHOOKX_LOG_FILE": "webhookx.log",
}

func setEnvs(envs map[string]string) error {
for name, value := range envs {
if err := os.Setenv(name, value); err != nil {
return err
}
}
return nil
}

// Start starts WebhookX with given environment variables
func Start(envs map[string]string) (*app.Application, error) {
for name, value := range defaultEnvs {
if _, ok := envs[name]; !ok {
err := os.Setenv(name, value)
if err != nil {
return nil, err
}
}
if err := setEnvs(defaultEnvs); err != nil {
return nil, err
}
for name, value := range envs {
err := os.Setenv(name, value)
if err != nil {
return nil, err
}

if err := setEnvs(envs); err != nil {
return nil, err
}

cfg, err := config.Init()
Expand All @@ -72,7 +75,12 @@ func Start(envs map[string]string) (*app.Application, error) {
return nil, err
}

go app.Wait()
go func() {
app.Wait()
for name := range envs {
os.Unsetenv(name)
}
}()

time.Sleep(time.Second)
return app, nil
Expand All @@ -84,12 +92,26 @@ func AdminClient() *resty.Client {
return c
}

func AdminTLSClient() *resty.Client {
c := resty.New()
c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
c.SetBaseURL("https://localhost:8080")
return c
}

func ProxyClient() *resty.Client {
c := resty.New()
c.SetBaseURL("http://localhost:8081")
return c
}

func ProxyTLSClient() *resty.Client {
c := resty.New()
c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
c.SetBaseURL("https://localhost:8081")
return c
}

func DB() *db.DB {
cfg, err := config.Init()
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions test/log/log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
. "github.com/onsi/gomega"
"github.com/stretchr/testify/assert"
"github.com/webhookx-io/webhookx/app"
"github.com/webhookx-io/webhookx/test"
"github.com/webhookx-io/webhookx/test/helper"
"github.com/webhookx-io/webhookx/utils"
"go.uber.org/zap"
"testing"
)
Expand All @@ -19,11 +19,11 @@ var _ = Describe("logging", Ordered, func() {

BeforeAll(func() {
var err error
app, err = test.Start(map[string]string{
app = utils.Must(helper.Start(map[string]string{
"WEBHOOKX_LOG_LEVEL": "debug",
"WEBHOOKX_LOG_FORMAT": "text",
"WEBHOOKX_LOG_FILE": "webhookx.log",
})
}))
assert.Nil(GinkgoT(), err)
})

Expand All @@ -49,11 +49,11 @@ var _ = Describe("logging", Ordered, func() {
var app *app.Application
BeforeAll(func() {
var err error
app, err = test.Start(map[string]string{
app = utils.Must(helper.Start(map[string]string{
"WEBHOOKX_LOG_LEVEL": "debug",
"WEBHOOKX_LOG_FORMAT": "json",
"WEBHOOKX_LOG_FILE": "webhookx.log",
})
}))
assert.Nil(GinkgoT(), err)
})

Expand Down
Loading

0 comments on commit 52481d6

Please sign in to comment.