Skip to content

Commit 18cd39c

Browse files
author
mirkobrombin
committed
refactor: enhance plugin system and middleware integration
- Improved integration of site-specific plugins with middleware chains - Added support for plugin-specific configurations in `SiteConfig` - Enhanced logging with FieldHook for consistent and useful log fields - Improved error handling and validation in server setup and plugin initialization
1 parent 434a433 commit 18cd39c

File tree

13 files changed

+200
-56
lines changed

13 files changed

+200
-56
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ module github.com/mirkobrombin/goup
33
go 1.22
44

55
require (
6+
github.com/mitchellh/mapstructure v1.5.0
67
github.com/quic-go/quic-go v0.48.1
78
github.com/rivo/tview v0.0.0-20241103174730-c76f7879f592
89
github.com/sirupsen/logrus v1.9.3
910
github.com/spf13/cobra v1.8.1
11+
github.com/yookoala/gofast v0.8.0
1012
)
1113

1214
require (

go.sum

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ github.com/gdamore/tcell/v2 v2.7.1 h1:TiCcmpWHiAU7F0rA2I3S2Y4mmLmO9KHxJ7E1QhYzQb
1111
github.com/gdamore/tcell/v2 v2.7.1/go.mod h1:dSXtXTSK0VsW1biw65DZLZ2NKr7j0qP/0J7ONmsraWg=
1212
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
1313
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
14+
github.com/go-restit/lzjson v0.0.0-20161206095556-efe3c53acc68/go.mod h1:7vXSKQt83WmbPeyVjCfNT9YDJ5BUFmcwFsEjI9SCvYM=
1415
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
1516
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
1617
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
@@ -19,13 +20,18 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
1920
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
2021
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
2122
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
23+
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
24+
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
2225
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
2326
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
2427
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
28+
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
2529
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
2630
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
2731
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
2832
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
33+
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
34+
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
2935
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
3036
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
3137
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
@@ -45,6 +51,9 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc
4551
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
4652
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
4753
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
54+
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
55+
github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
56+
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
4857
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
4958
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
5059
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@@ -54,32 +63,44 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
5463
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
5564
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
5665
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
66+
github.com/yookoala/gofast v0.8.0 h1:UmGTeBj2EF5gvS58ByE9HFdQ9MeYSUIwf7JN9aFno3Y=
67+
github.com/yookoala/gofast v0.8.0/go.mod h1:OJU201Q6HCaE1cASckaTbMm3KB6e0cZxK0mgqfwOKvQ=
68+
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
5769
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
5870
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
5971
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
6072
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
73+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
74+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
6175
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
6276
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
6377
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
6478
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
6579
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
80+
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
6681
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
6782
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
6883
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
6984
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
85+
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
86+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
7087
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
88+
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
7189
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
7290
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
7391
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
7492
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
7593
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
7694
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
95+
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7796
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7897
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7998
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
8099
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
81100
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
101+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
82102
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
103+
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
83104
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
84105
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
85106
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -105,15 +126,20 @@ golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
105126
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
106127
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
107128
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
129+
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
108130
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
131+
golang.org/x/tools v0.0.0-20200908211811-12e1bf57a112/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
109132
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
110133
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
111134
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
112135
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
113136
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
137+
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
138+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
114139
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
115140
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
116141
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
142+
gopkg.in/ini.v1 v1.38.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
117143
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
118144
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
119145
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

internal/config/config.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ import (
66
"os"
77
"path/filepath"
88
"runtime"
9+
"strings"
910
)
1011

1112
// customLogDir is used to override the default log directory, e.g. for testing.
1213
var customLogDir string
1314

15+
// SiteConfigs is a global map of site configurations keyed by domain.
16+
var SiteConfigs = make(map[string]SiteConfig)
17+
1418
// SSLConfig represents the SSL configuration for a site.
1519
type SSLConfig struct {
1620
Enabled bool `json:"enabled"`
@@ -27,6 +31,8 @@ type SiteConfig struct {
2731
ProxyPass string `json:"proxy_pass"`
2832
SSL SSLConfig `json:"ssl"`
2933
RequestTimeout int `json:"request_timeout"` // in seconds
34+
35+
PluginConfigs map[string]interface{} `json:"plugin_configs"` // Plugin-specific configurations
3036
}
3137

3238
// GetConfigDir returns the directory where configuration files are stored.
@@ -89,6 +95,9 @@ func LoadAllConfigs() ([]SiteConfig, error) {
8995
continue
9096
}
9197
configs = append(configs, conf)
98+
99+
// Populate the global SiteConfigs map
100+
SiteConfigs[conf.Domain] = conf
92101
}
93102
}
94103
return configs, nil
@@ -103,6 +112,18 @@ func (conf *SiteConfig) Save(filePath string) error {
103112
return os.WriteFile(filePath, data, 0644)
104113
}
105114

115+
// GetSiteConfigByHost returns the site configuration based on the host.
116+
func GetSiteConfigByHost(host string) (SiteConfig, error) {
117+
if colonIndex := strings.Index(host, ":"); colonIndex != -1 {
118+
host = host[:colonIndex]
119+
}
120+
121+
if conf, ok := SiteConfigs[host]; ok {
122+
return conf, nil
123+
}
124+
return SiteConfig{}, fmt.Errorf("site configuration not found for host: %s", host)
125+
}
126+
106127
// SetCustomLogDir allows setting a custom log directory for testing.
107128
func SetCustomLogDir(dir string) {
108129
customLogDir = dir

internal/logger/logger.go

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,49 @@ import (
1111
log "github.com/sirupsen/logrus"
1212
)
1313

14-
// NewLogger sets up a new logger for the given identifier.
15-
func NewLogger(identifier string) (*log.Logger, error) {
14+
// FieldHook is a custom Logrus hook that adds predefined fields to every log entry.
15+
type FieldHook struct {
16+
Fields log.Fields
17+
}
18+
19+
// Levels defines the log levels where the hook is applied.
20+
func (hook *FieldHook) Levels() []log.Level {
21+
return log.AllLevels
22+
}
23+
24+
// Fire adds the predefined fields to the log entry.
25+
func (hook *FieldHook) Fire(entry *log.Entry) error {
26+
for k, v := range hook.Fields {
27+
entry.Data[k] = v
28+
}
29+
return nil
30+
}
31+
32+
// NewLogger creates a new logger with optional predefined fields.
33+
func NewLogger(identifier string, fields log.Fields) (*log.Logger, error) {
1634
logger := log.New()
1735

18-
// Log directory: ~/.local/share/goup/logs/identifier/year/month/
36+
// Directory for logs: ~/.local/share/goup/logs/identifier/year/month/
1937
logDir := filepath.Join(config.GetLogDir(), identifier, fmt.Sprintf("%d", time.Now().Year()), fmt.Sprintf("%02d", time.Now().Month()))
2038
if err := os.MkdirAll(logDir, os.ModePerm); err != nil {
2139
return nil, err
2240
}
2341

24-
// Log name format: day.log
42+
// Log file name: day.log
2543
logFile := filepath.Join(logDir, fmt.Sprintf("%02d.log", time.Now().Day()))
2644
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
2745
if err != nil {
2846
return nil, err
2947
}
3048

31-
// Setting up output in both stdout and file
49+
// Set output to both stdout and the log file
3250
logger.SetOutput(io.MultiWriter(os.Stdout, file))
3351
logger.SetFormatter(&log.JSONFormatter{})
3452

53+
// Add the FieldHook if fields are provided
54+
if fields != nil {
55+
logger.AddHook(&FieldHook{Fields: fields})
56+
}
57+
3558
return logger, nil
3659
}

internal/logger/logger_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@ import (
88
"time"
99

1010
"github.com/mirkobrombin/goup/internal/config"
11+
log "github.com/sirupsen/logrus"
1112
)
1213

1314
func TestNewLogger(t *testing.T) {
1415
identifier := "test_identifier"
1516

1617
tmpDir := t.TempDir()
1718
config.SetCustomLogDir(tmpDir)
18-
logger, err := NewLogger(identifier)
19+
fields := log.Fields{
20+
"test_field": "test_value",
21+
}
22+
logger, err := NewLogger(identifier, fields)
1923
if err != nil {
2024
t.Fatalf("Error creating new logger: %v", err)
2125
}

internal/plugin/plugin.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ package plugin
33
import (
44
"sync"
55

6+
"github.com/mirkobrombin/goup/internal/config"
67
"github.com/mirkobrombin/goup/internal/server/middleware"
8+
log "github.com/sirupsen/logrus"
79
)
810

911
// Plugin defines the interface for GoUP plugins.
1012
type Plugin interface {
1113
Name() string
1214
Init(mwManager *middleware.MiddlewareManager) error
15+
InitForSite(mwManager *middleware.MiddlewareManager, logger *log.Logger, conf config.SiteConfig) error
1316
}
1417

1518
// PluginManager manages loading and initialization of plugins.
@@ -52,7 +55,25 @@ func (pm *PluginManager) InitPlugins(mwManager *middleware.MiddlewareManager) er
5255
return nil
5356
}
5457

55-
// GetRegisteredPlugins returns the registered plugins.
58+
// InitPluginsForSite initializes all registered plugins for a specific site.
59+
func (pm *PluginManager) InitPluginsForSite(mwManager *middleware.MiddlewareManager, baseLogger *log.Logger, conf config.SiteConfig) error {
60+
pm.mu.Lock()
61+
defer pm.mu.Unlock()
62+
63+
for _, plugin := range pm.plugins {
64+
pluginLogger := baseLogger.WithFields(log.Fields{
65+
"plugin": plugin.Name(),
66+
"domain": conf.Domain,
67+
})
68+
69+
if err := plugin.InitForSite(mwManager, pluginLogger.Logger, conf); err != nil {
70+
return err
71+
}
72+
}
73+
return nil
74+
}
75+
76+
// GetRegisteredPlugins returns the names of all registered plugins.
5677
func (pm *PluginManager) GetRegisteredPlugins() []string {
5778
pm.mu.Lock()
5879
defer pm.mu.Unlock()

internal/server/handler.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ import (
99
"time"
1010

1111
"github.com/mirkobrombin/goup/internal/config"
12+
"github.com/mirkobrombin/goup/internal/plugin"
1213
"github.com/mirkobrombin/goup/internal/server/middleware"
1314
log "github.com/sirupsen/logrus"
1415
)
1516

1617
// createHandler creates the HTTP handler for a site configuration.
17-
func createHandler(conf config.SiteConfig, logger *log.Logger, identifier string) (http.Handler, error) {
18+
func createHandler(conf config.SiteConfig, logger *log.Logger, identifier string, globalMwManager *middleware.MiddlewareManager) (http.Handler, error) {
1819
var handler http.Handler
1920

2021
if conf.ProxyPass != "" {
@@ -37,13 +38,23 @@ func createHandler(conf config.SiteConfig, logger *log.Logger, identifier string
3738
})
3839
}
3940

40-
// Set up site-specific middleware.
41-
mwManager := middleware.NewMiddlewareManager()
41+
// Set up middleware manager copy for this site
42+
siteMwManager := globalMwManager.Copy()
43+
44+
// Initialize plugins for this site
45+
pluginManager := plugin.GetPluginManagerInstance()
46+
if err := pluginManager.InitPluginsForSite(siteMwManager, logger, conf); err != nil {
47+
return nil, fmt.Errorf("error initializing plugins for site %s: %v", conf.Domain, err)
48+
}
49+
50+
// Add per-site middleware
4251
timeout := time.Duration(conf.RequestTimeout) * time.Second
43-
mwManager.Use(middleware.TimeoutMiddleware(timeout))
44-
mwManager.Use(middleware.LoggingMiddleware(logger, conf.Domain, identifier))
52+
siteMwManager.Use(middleware.TimeoutMiddleware(timeout))
53+
54+
// Add logging middleware last to ensure it wraps the entire request
55+
siteMwManager.Use(middleware.LoggingMiddleware(logger, conf.Domain, identifier))
4556

46-
handler = mwManager.Apply(handler)
57+
handler = siteMwManager.Apply(handler)
4758

4859
return handler, nil
4960
}

internal/server/handler_test.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ func TestCreateHandler_Static(t *testing.T) {
1919
defer os.RemoveAll(tmpDir)
2020

2121
testFilePath := filepath.Join(tmpDir, "testfile.txt")
22-
os.WriteFile(testFilePath, []byte("Test content"), 0644)
22+
err = os.WriteFile(testFilePath, []byte("Test content"), 0644)
23+
if err != nil {
24+
t.Fatalf("Error creating test file: %v", err)
25+
}
2326

2427
conf := config.SiteConfig{
2528
Domain: "example.com",
@@ -30,9 +33,10 @@ func TestCreateHandler_Static(t *testing.T) {
3033
RequestTimeout: 60,
3134
}
3235
logger := log.New()
36+
logger.Out = os.Stderr
3337
identifier := "test"
3438

35-
handler, err := createHandler(conf, logger, identifier)
39+
handler, err := createHandler(conf, logger, identifier, nil)
3640
if err != nil {
3741
t.Fatalf("Error creating handler: %v", err)
3842
}
@@ -42,12 +46,12 @@ func TestCreateHandler_Static(t *testing.T) {
4246

4347
handler.ServeHTTP(w, req)
4448

45-
if w.Code != 200 {
46-
t.Errorf("Expected status code 200, got %d", w.Code)
49+
if w.Code != http.StatusOK {
50+
t.Errorf("Expected status code %d, got %d", http.StatusOK, w.Code)
4751
}
4852

4953
if w.Header().Get("X-Test-Header") != "TestValue" {
50-
t.Errorf("Expected custom header X-Test-Header to be 'TestValue', got %s", w.Header().Get("X-Test-Header"))
54+
t.Errorf("Expected custom header 'X-Test-Header' to be 'TestValue', got %q", w.Header().Get("X-Test-Header"))
5155
}
5256

5357
expectedBody := "Test content"
@@ -69,9 +73,10 @@ func TestCreateHandler_ProxyPass(t *testing.T) {
6973
RequestTimeout: 60,
7074
}
7175
logger := log.New()
76+
logger.Out = os.Stderr
7277
identifier := "test"
7378

74-
handler, err := createHandler(conf, logger, identifier)
79+
handler, err := createHandler(conf, logger, identifier, nil)
7580
if err != nil {
7681
t.Fatalf("Error creating handler: %v", err)
7782
}
@@ -81,8 +86,8 @@ func TestCreateHandler_ProxyPass(t *testing.T) {
8186

8287
handler.ServeHTTP(w, req)
8388

84-
if w.Code != 200 {
85-
t.Errorf("Expected status code 200, got %d", w.Code)
89+
if w.Code != http.StatusOK {
90+
t.Errorf("Expected status code %d, got %d", http.StatusOK, w.Code)
8691
}
8792

8893
expectedBody := "Backend Response"

0 commit comments

Comments
 (0)