Skip to content

Commit ffe3e97

Browse files
committed
Add glob support on webhook proxy host rules
1 parent 2b0b629 commit ffe3e97

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

modules/webhook/deliver.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import (
1212
"net/http"
1313
"net/url"
1414
"strings"
15+
"sync"
1516
"time"
1617

1718
"code.gitea.io/gitea/models"
1819
"code.gitea.io/gitea/modules/log"
1920
"code.gitea.io/gitea/modules/setting"
21+
"github.com/gobwas/glob"
2022
"github.com/unknwon/com"
2123
)
2224

@@ -182,16 +184,34 @@ func DeliverHooks() {
182184
}
183185
}
184186

185-
var webhookHTTPClient *http.Client
187+
var (
188+
webhookHTTPClient *http.Client
189+
once sync.Once
190+
hostMatchers []glob.Glob
191+
)
186192

187193
func webhookProxy() func(req *http.Request) (*url.URL, error) {
188194
if setting.Webhook.ProxyURL == "" {
189195
return http.ProxyFromEnvironment
190196
}
191197

198+
once.Do(func() {
199+
for _, h := range setting.Webhook.ProxyHosts {
200+
if g, err := glob.Compile(h); err == nil {
201+
hostMatchers = append(hostMatchers, g)
202+
} else {
203+
log.Error("glob.Compile %s failed: %v", h, err)
204+
}
205+
}
206+
})
207+
192208
return func(req *http.Request) (*url.URL, error) {
193-
for _, v := range setting.Webhook.ProxyHosts {
194-
if strings.EqualFold(v, req.URL.Host) {
209+
if len(setting.Webhook.ProxyHosts) == 1 && setting.Webhook.ProxyHosts[0] == "*" {
210+
return http.ProxyURL(setting.Webhook.ProxyURLFixed)(req)
211+
}
212+
213+
for _, v := range hostMatchers {
214+
if v.Match(req.URL.Host) {
195215
return http.ProxyURL(setting.Webhook.ProxyURLFixed)(req)
196216
}
197217
}

modules/webhook/deliver_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2019 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package webhook
6+
7+
import (
8+
"net/http"
9+
"net/url"
10+
"testing"
11+
12+
"code.gitea.io/gitea/modules/setting"
13+
"github.com/stretchr/testify/assert"
14+
)
15+
16+
func TestWebhookProxy(t *testing.T) {
17+
setting.Webhook.ProxyURL = "http://localhost:8080"
18+
setting.Webhook.ProxyURLFixed, _ = url.Parse(setting.Webhook.ProxyURL)
19+
setting.Webhook.ProxyHosts = []string{"*.discordapp.com", "discordapp.com"}
20+
21+
var kases = map[string]string{
22+
"https://discordapp.com/api/webhooks/xxxxxxxxx/xxxxxxxxxxxxxxxxxxx": "http://localhost:8080",
23+
"http://s.discordapp.com/assets/xxxxxx": "http://localhost:8080",
24+
"http://github.com/a/b": "",
25+
}
26+
27+
for reqURL, proxyURL := range kases {
28+
req, err := http.NewRequest("POST", reqURL, nil)
29+
assert.NoError(t, err)
30+
31+
u, err := webhookProxy()(req)
32+
assert.NoError(t, err)
33+
if proxyURL == "" {
34+
assert.Nil(t, u)
35+
} else {
36+
assert.EqualValues(t, proxyURL, u.String())
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)