Skip to content

Commit 5e5a764

Browse files
committed
Support system proxy
1 parent eee30d5 commit 5e5a764

File tree

12 files changed

+157
-7
lines changed

12 files changed

+157
-7
lines changed

custom/conf/app.example.ini

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,3 +1302,11 @@ STORAGE_TYPE = local
13021302
;MINIO_LOCATION = us-east-1
13031303
; Minio enabled ssl only available when STORAGE_TYPE is `minio`
13041304
;MINIO_USE_SSL = false
1305+
1306+
[proxy]
1307+
; Enable the proxy, all requests to external via HTTP will be affected
1308+
PROXY_ENABLED = false
1309+
; Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
1310+
PROXY_URL =
1311+
; Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
1312+
PROXY_HOSTS =

docs/content/doc/advanced/config-cheat-sheet.en-us.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,8 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
523523
- `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks.
524524
- `SKIP_TLS_VERIFY`: **false**: Allow insecure certification.
525525
- `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page.
526-
- `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
527-
- `PROXY_HOSTS`: ****: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
526+
- `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy. If not given, will use global proxy setting.
527+
- `PROXY_HOSTS`: ****: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts. If not given, will use global proxy setting.
528528

529529
## Mailer (`mailer`)
530530

@@ -902,6 +902,7 @@ Task queue configuration has been moved to `queue.task`. However, the below conf
902902
- `ALLOWED_DOMAINS`: **\<empty\>**: Domains allowlist for migrating repositories, default is blank. It means everything will be allowed. Multiple domains could be separated by commas.
903903
- `BLOCKED_DOMAINS`: **\<empty\>**: Domains blocklist for migrating repositories, default is blank. Multiple domains could be separated by commas. When `ALLOWED_DOMAINS` is not blank, this option will be ignored.
904904
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291
905+
- `SKIP_TLS_VERIFY`: **false**: Allow skip tls verify
905906

906907
## Mirror (`mirror`)
907908

@@ -958,6 +959,19 @@ MINIO_USE_SSL = false
958959

959960
And used by `[attachment]`, `[lfs]` and etc. as `STORAGE_TYPE`.
960961

962+
## Proxy (`proxy`)
963+
964+
- `PROXY_ENABLED`: **true**: Enable the proxy, all requests to external via HTTP will be affected
965+
- `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
966+
- `PROXY_HOSTS`: ****: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
967+
968+
i.e.
969+
```ini
970+
PROXY_ENABLED = true
971+
PROXY_URL = socks://127.0.0.1:1080
972+
PROXY_HOSTS = *.github.com
973+
```
974+
961975
## Other (`other`)
962976

963977
- `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer.

docs/content/doc/advanced/config-cheat-sheet.zh-cn.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,8 @@ IS_INPUT_FILE = false
326326
- `RETRY_BACKOFF`: **3**: 等待下一次重试的时间,单位秒。
327327
- `ALLOWED_DOMAINS`: **\<empty\>**: 迁移仓库的域名白名单,默认为空,表示允许从任意域名迁移仓库,多个域名用逗号分隔。
328328
- `BLOCKED_DOMAINS`: **\<empty\>**: 迁移仓库的域名黑名单,默认为空,多个域名用逗号分隔。如果 `ALLOWED_DOMAINS` 不为空,此选项将会被忽略。
329-
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918
329+
- `ALLOW_LOCALNETWORKS`: **false**: 允许访问私有地址,定义在 RFC 1918
330+
- `SKIP_TLS_VERIFY`: **false**: 允许忽略 TLS 认证
330331

331332
## LFS (`lfs`)
332333

@@ -377,6 +378,19 @@ MINIO_USE_SSL = false
377378

378379
然后你在 `[attachment]`, `[lfs]` 等中可以把这个名字用作 `STORAGE_TYPE` 的值。
379380

381+
## Proxy (`proxy`)
382+
383+
- `PROXY_ENABLED`: **true**: 是否启用全局代理
384+
- `PROXY_URL`: ****: 代理服务器地址,支持 http://, https//, socks://,为空则不启用代理而使用环境变量中的 http_proxy/https_proxy
385+
- `PROXY_HOSTS`: ****: 逗号分隔的多个需要代理的网址,支持 * 号匹配符号, ** 表示匹配所有网站
386+
387+
i.e.
388+
```ini
389+
PROXY_ENABLED = true
390+
PROXY_URL = socks://127.0.0.1:1080
391+
PROXY_HOSTS = *.github.com
392+
```
393+
380394
## Other (`other`)
381395

382396
- `SHOW_FOOTER_BRANDING`: 为真则在页面底部显示Gitea的字样。

modules/migrations/gitea_downloader.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package migrations
66

77
import (
88
"context"
9+
"crypto/tls"
910
"errors"
1011
"fmt"
1112
"io"
@@ -17,6 +18,8 @@ import (
1718
"code.gitea.io/gitea/models"
1819
"code.gitea.io/gitea/modules/log"
1920
"code.gitea.io/gitea/modules/migrations/base"
21+
"code.gitea.io/gitea/modules/proxy"
22+
"code.gitea.io/gitea/modules/setting"
2023
"code.gitea.io/gitea/modules/structs"
2124

2225
gitea_sdk "code.gitea.io/sdk/gitea"
@@ -87,6 +90,12 @@ func NewGiteaDownloader(ctx context.Context, baseURL, repoPath, username, passwo
8790
gitea_sdk.SetToken(token),
8891
gitea_sdk.SetBasicAuth(username, password),
8992
gitea_sdk.SetContext(ctx),
93+
gitea_sdk.SetHTTPClient(&http.Client{
94+
Transport: &http.Transport{
95+
TLSClientConfig: &tls.Config{InsecureSkipVerify: setting.Migrations.SkipTLSVerify},
96+
Proxy: proxy.SystemProxy(),
97+
},
98+
}),
9099
)
91100
if err != nil {
92101
log.Error(fmt.Sprintf("Failed to create NewGiteaDownloader for: %s. Error: %v", baseURL, err))

modules/migrations/github.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"code.gitea.io/gitea/modules/log"
1818
"code.gitea.io/gitea/modules/migrations/base"
19+
"code.gitea.io/gitea/modules/proxy"
1920
"code.gitea.io/gitea/modules/structs"
2021
"code.gitea.io/gitea/modules/util"
2122

@@ -89,7 +90,7 @@ func NewGithubDownloaderV3(ctx context.Context, baseURL, userName, password, tok
8990
Transport: &http.Transport{
9091
Proxy: func(req *http.Request) (*url.URL, error) {
9192
req.SetBasicAuth(userName, password)
92-
return nil, nil
93+
return proxy.SystemProxy()(req)
9394
},
9495
},
9596
}

modules/migrations/gitlab.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package migrations
66

77
import (
88
"context"
9+
"crypto/tls"
910
"errors"
1011
"fmt"
1112
"io"
@@ -17,6 +18,8 @@ import (
1718

1819
"code.gitea.io/gitea/modules/log"
1920
"code.gitea.io/gitea/modules/migrations/base"
21+
"code.gitea.io/gitea/modules/proxy"
22+
"code.gitea.io/gitea/modules/setting"
2023
"code.gitea.io/gitea/modules/structs"
2124

2225
"github.com/xanzy/go-gitlab"
@@ -77,7 +80,12 @@ type GitlabDownloader struct {
7780
// Use either a username/password, personal token entered into the username field, or anonymous/public access
7881
// Note: Public access only allows very basic access
7982
func NewGitlabDownloader(ctx context.Context, baseURL, repoPath, username, password, token string) (*GitlabDownloader, error) {
80-
gitlabClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseURL))
83+
gitlabClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseURL), gitlab.WithHTTPClient(&http.Client{
84+
Transport: &http.Transport{
85+
TLSClientConfig: &tls.Config{InsecureSkipVerify: setting.Migrations.SkipTLSVerify},
86+
Proxy: proxy.SystemProxy(),
87+
},
88+
}))
8189
// Only use basic auth if token is blank and password is NOT
8290
// Basic auth will fail with empty strings, but empty token will allow anonymous public API usage
8391
if token == "" && password != "" {

modules/migrations/gogs.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package migrations
66

77
import (
88
"context"
9+
"crypto/tls"
910
"fmt"
1011
"net/http"
1112
"net/url"
@@ -14,6 +15,8 @@ import (
1415

1516
"code.gitea.io/gitea/modules/log"
1617
"code.gitea.io/gitea/modules/migrations/base"
18+
"code.gitea.io/gitea/modules/proxy"
19+
"code.gitea.io/gitea/modules/setting"
1720
"code.gitea.io/gitea/modules/structs"
1821

1922
"github.com/gogs/go-gogs-client"
@@ -95,9 +98,10 @@ func NewGogsDownloader(ctx context.Context, baseURL, userName, password, token,
9598
downloader.userName = token
9699
} else {
97100
downloader.transport = &http.Transport{
101+
TLSClientConfig: &tls.Config{InsecureSkipVerify: setting.Migrations.SkipTLSVerify},
98102
Proxy: func(req *http.Request) (*url.URL, error) {
99103
req.SetBasicAuth(userName, password)
100-
return nil, nil
104+
return proxy.SystemProxy()(req)
101105
},
102106
}
103107

modules/proxy/proxy.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2021 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 proxy
6+
7+
import (
8+
"net/http"
9+
"net/url"
10+
"sync"
11+
12+
"code.gitea.io/gitea/modules/log"
13+
"code.gitea.io/gitea/modules/setting"
14+
15+
"github.com/gobwas/glob"
16+
)
17+
18+
var (
19+
once sync.Once
20+
hostMatchers []glob.Glob
21+
)
22+
23+
// SystemProxy returns the system proxy
24+
func SystemProxy() func(req *http.Request) (*url.URL, error) {
25+
if !setting.Proxy.Enabled || setting.Proxy.ProxyURL == "" {
26+
return http.ProxyFromEnvironment
27+
}
28+
29+
once.Do(func() {
30+
for _, h := range setting.Proxy.ProxyHosts {
31+
if g, err := glob.Compile(h); err == nil {
32+
hostMatchers = append(hostMatchers, g)
33+
} else {
34+
log.Error("glob.Compile %s failed: %v", h, err)
35+
}
36+
}
37+
})
38+
39+
return func(req *http.Request) (*url.URL, error) {
40+
for _, v := range hostMatchers {
41+
if v.Match(req.URL.Host) {
42+
return http.ProxyURL(setting.Proxy.ProxyURLFixed)(req)
43+
}
44+
}
45+
return http.ProxyFromEnvironment(req)
46+
}
47+
}

modules/setting/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var (
1616
AllowedDomains []string
1717
BlockedDomains []string
1818
AllowLocalNetworks bool
19+
SkipTLSVerify bool
1920
}{
2021
MaxAttempts: 3,
2122
RetryBackoff: 3,
@@ -37,4 +38,5 @@ func newMigrationsService() {
3738
}
3839

3940
Migrations.AllowLocalNetworks = sec.Key("ALLOW_LOCALNETWORKS").MustBool(false)
41+
Migrations.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool(false)
4042
}

modules/setting/proxy.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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 setting
6+
7+
import (
8+
"net/url"
9+
10+
"code.gitea.io/gitea/modules/log"
11+
)
12+
13+
var (
14+
// Proxy settings
15+
Proxy = struct {
16+
Enabled bool
17+
ProxyURL string
18+
ProxyURLFixed *url.URL
19+
ProxyHosts []string
20+
}{
21+
Enabled: false,
22+
ProxyURL: "",
23+
ProxyHosts: []string{},
24+
}
25+
)
26+
27+
func newProxyService() {
28+
sec := Cfg.Section("proxy")
29+
Proxy.Enabled = sec.Key("PROXY_ENABLED").MustBool(false)
30+
Proxy.ProxyURL = sec.Key("PROXY_URL").MustString("")
31+
if Proxy.ProxyURL != "" {
32+
var err error
33+
Proxy.ProxyURLFixed, err = url.Parse(Proxy.ProxyURL)
34+
if err != nil {
35+
log.Error("Global PROXY_URL is not valid")
36+
Proxy.ProxyURL = ""
37+
}
38+
}
39+
Proxy.ProxyHosts = sec.Key("PROXY_HOSTS").Strings(",")
40+
}

modules/setting/setting.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,7 @@ func NewServices() {
11711171
newMailService()
11721172
newRegisterMailService()
11731173
newNotifyMailService()
1174+
newProxyService()
11741175
newWebhookService()
11751176
newMigrationsService()
11761177
newIndexerService()

services/webhook/deliver.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import (
2020
"code.gitea.io/gitea/models"
2121
"code.gitea.io/gitea/modules/graceful"
2222
"code.gitea.io/gitea/modules/log"
23+
"code.gitea.io/gitea/modules/proxy"
2324
"code.gitea.io/gitea/modules/setting"
25+
2426
"github.com/gobwas/glob"
2527
)
2628

@@ -239,7 +241,7 @@ var (
239241

240242
func webhookProxy() func(req *http.Request) (*url.URL, error) {
241243
if setting.Webhook.ProxyURL == "" {
242-
return http.ProxyFromEnvironment
244+
return proxy.SystemProxy()
243245
}
244246

245247
once.Do(func() {

0 commit comments

Comments
 (0)