diff options
Diffstat (limited to 'modules/proxy/proxy.go')
-rw-r--r-- | modules/proxy/proxy.go | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/modules/proxy/proxy.go b/modules/proxy/proxy.go new file mode 100644 index 00000000..1a6bdad7 --- /dev/null +++ b/modules/proxy/proxy.go @@ -0,0 +1,98 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package proxy + +import ( + "net/http" + "net/url" + "os" + "strings" + "sync" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + "github.com/gobwas/glob" +) + +var ( + once sync.Once + hostMatchers []glob.Glob +) + +// GetProxyURL returns proxy url +func GetProxyURL() string { + if !setting.Proxy.Enabled { + return "" + } + + if setting.Proxy.ProxyURL == "" { + if os.Getenv("http_proxy") != "" { + return os.Getenv("http_proxy") + } + return os.Getenv("https_proxy") + } + return setting.Proxy.ProxyURL +} + +// Match return true if url needs to be proxied +func Match(u string) bool { + if !setting.Proxy.Enabled { + return false + } + + // enforce do once + Proxy() + + for _, v := range hostMatchers { + if v.Match(u) { + return true + } + } + return false +} + +// Proxy returns the system proxy +func Proxy() func(req *http.Request) (*url.URL, error) { + if !setting.Proxy.Enabled { + return func(req *http.Request) (*url.URL, error) { + return nil, nil + } + } + if setting.Proxy.ProxyURL == "" { + return http.ProxyFromEnvironment + } + + once.Do(func() { + for _, h := range setting.Proxy.ProxyHosts { + if g, err := glob.Compile(h); err == nil { + hostMatchers = append(hostMatchers, g) + } else { + log.Error("glob.Compile %s failed: %v", h, err) + } + } + }) + + return func(req *http.Request) (*url.URL, error) { + for _, v := range hostMatchers { + if v.Match(req.URL.Host) { + return http.ProxyURL(setting.Proxy.ProxyURLFixed)(req) + } + } + return http.ProxyFromEnvironment(req) + } +} + +// EnvWithProxy returns os.Environ(), with a https_proxy env, if the given url +// needs to be proxied. +func EnvWithProxy(u *url.URL) []string { + envs := os.Environ() + if strings.EqualFold(u.Scheme, "http") || strings.EqualFold(u.Scheme, "https") { + if Match(u.Host) { + envs = append(envs, "https_proxy="+GetProxyURL()) + } + } + + return envs +} |