diff options
Diffstat (limited to 'services/webhook/deliver.go')
-rw-r--r-- | services/webhook/deliver.go | 38 |
1 files changed, 12 insertions, 26 deletions
diff --git a/services/webhook/deliver.go b/services/webhook/deliver.go index da7052fd9b..36169baad4 100644 --- a/services/webhook/deliver.go +++ b/services/webhook/deliver.go @@ -13,17 +13,16 @@ import ( "encoding/hex" "fmt" "io" - "net" "net/http" "net/url" "strconv" "strings" "sync" - "syscall" "time" webhook_model "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/graceful" + "code.gitea.io/gitea/modules/hostmatcher" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/proxy" "code.gitea.io/gitea/modules/setting" @@ -31,8 +30,6 @@ import ( "github.com/gobwas/glob" ) -var contextKeyWebhookRequest interface{} = "contextKeyWebhookRequest" - // Deliver deliver hook task func Deliver(t *webhook_model.HookTask) error { w, err := webhook_model.GetWebhookByID(t.HookID) @@ -98,10 +95,10 @@ func Deliver(t *webhook_model.HookTask) error { return err } default: - return fmt.Errorf("Invalid http method for webhook: [%d] %v", t.ID, w.HTTPMethod) + return fmt.Errorf("invalid http method for webhook: [%d] %v", t.ID, w.HTTPMethod) } default: - return fmt.Errorf("Invalid http method for webhook: [%d] %v", t.ID, w.HTTPMethod) + return fmt.Errorf("invalid http method for webhook: [%d] %v", t.ID, w.HTTPMethod) } var signatureSHA1 string @@ -172,10 +169,10 @@ func Deliver(t *webhook_model.HookTask) error { }() if setting.DisableWebhooks { - return fmt.Errorf("Webhook task skipped (webhooks disabled): [%d]", t.ID) + return fmt.Errorf("webhook task skipped (webhooks disabled): [%d]", t.ID) } - resp, err := webhookHTTPClient.Do(req.WithContext(context.WithValue(req.Context(), contextKeyWebhookRequest, req))) + resp, err := webhookHTTPClient.Do(req.WithContext(graceful.GetManager().ShutdownContext())) if err != nil { t.ResponseInfo.Body = fmt.Sprintf("Delivery: %v", err) return err @@ -296,29 +293,18 @@ func webhookProxy() func(req *http.Request) (*url.URL, error) { func InitDeliverHooks() { timeout := time.Duration(setting.Webhook.DeliverTimeout) * time.Second + allowedHostListValue := setting.Webhook.AllowedHostList + if allowedHostListValue == "" { + allowedHostListValue = hostmatcher.MatchBuiltinExternal + } + allowedHostMatcher := hostmatcher.ParseHostMatchList("webhook.ALLOWED_HOST_LIST", allowedHostListValue) + webhookHTTPClient = &http.Client{ Timeout: timeout, Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify}, Proxy: webhookProxy(), - DialContext: func(ctx context.Context, network, addrOrHost string) (net.Conn, error) { - dialer := net.Dialer{ - Timeout: timeout, - Control: func(network, ipAddr string, c syscall.RawConn) error { - // in Control func, the addr was already resolved to IP:PORT format, there is no cost to do ResolveTCPAddr here - tcpAddr, err := net.ResolveTCPAddr(network, ipAddr) - req := ctx.Value(contextKeyWebhookRequest).(*http.Request) - if err != nil { - return fmt.Errorf("webhook can only call HTTP servers via TCP, deny '%s(%s:%s)', err=%v", req.Host, network, ipAddr, err) - } - if !setting.Webhook.AllowedHostList.MatchesHostOrIP(req.Host, tcpAddr.IP) { - return fmt.Errorf("webhook can only call allowed HTTP servers (check your webhook.ALLOWED_HOST_LIST setting), deny '%s(%s)'", req.Host, ipAddr) - } - return nil - }, - } - return dialer.DialContext(ctx, network, addrOrHost) - }, + DialContext: hostmatcher.NewDialContext("webhook", allowedHostMatcher, nil), }, } |