Skip to content

Use middleware but not new routers for http cors #16566

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ In addition there is _`StaticRootPath`_ which can be set as a built-in at build
- `USE_COMPAT_SSH_URI`: **false**: Force ssh:// clone url instead of scp-style uri when
default SSH port is used.
- `ACCESS_CONTROL_ALLOW_ORIGIN`: **\<empty\>**: Value for Access-Control-Allow-Origin header,
default is not to present. **WARNING**: This maybe harmful to you website if you do not
give it a right value.
default is not to present. You can give `*` to allow requests from any website or `null` to not allow any.
This allow multiple websites via comma an no space. i.e. `https://gitea.com,https://api.gitea.com`
**WARNING**: This maybe harmful to you website if you do not give it a right value.
- `DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH`: **false**: Close an issue if a commit on a non default branch marks it as closed.
- `ENABLE_PUSH_CREATE_USER`: **false**: Allow users to push local repositories to Gitea and have them automatically created for a user.
- `ENABLE_PUSH_CREATE_ORG`: **false**: Allow users to push local repositories to Gitea and have them automatically created for an org.
Expand Down
3 changes: 3 additions & 0 deletions docs/content/doc/advanced/config-cheat-sheet.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ menu:
- `DEFAULT_PUSH_CREATE_PRIVATE`: **true**: 通过 ``push-to-create`` 方式创建的仓库是否默认为私有仓库.
- `MAX_CREATION_LIMIT`: 全局最大每个用户创建的git工程数目, `-1` 表示没限制。
- `PULL_REQUEST_QUEUE_LENGTH`: 小心:合并请求测试队列的长度,尽量放大。
- `ACCESS_CONTROL_ALLOW_ORIGIN`: **\<empty\>**: `Access-Control-Allow-Origin`请求头的值,默认为空。
设置为 `*` 将允许来自任意网站的请求,为 `null` 则屏蔽所有网站的请求。也可以允许用逗号连接的多个网址,比如: `https://gitea.com,https://api.gitea.com`
**警告**: 如果此项设置不正确,可能会对你的网站产生负面影响。

### Repository - Release (`repository.release`)

Expand Down
42 changes: 32 additions & 10 deletions routers/web/repo/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,51 @@ import (
repo_service "code.gitea.io/gitea/services/repository"
)

// httpBase implementation git smart HTTP protocol
func httpBase(ctx *context.Context) (h *serviceHandler) {
if setting.Repository.DisableHTTPGit {
// HTTPMustEnabled check if http enabled
func HTTPMustEnabled() func(ctx *context.Context) {
if !setting.Repository.DisableHTTPGit {
return func(ctx *context.Context) {}
}

return func(ctx *context.Context) {
ctx.Resp.WriteHeader(http.StatusForbidden)
_, err := ctx.Resp.Write([]byte("Interacting with repositories by HTTP protocol is not allowed"))
if err != nil {
log.Error(err.Error())
}
return
}
}

if len(setting.Repository.AccessControlAllowOrigin) > 0 {
allowedOrigin := setting.Repository.AccessControlAllowOrigin
// HTTPCors check if cors matched
func HTTPCors() func(ctx *context.Context) {
var allowedOrigins = setting.Repository.AccessControlAllowOrigin
if len(allowedOrigins) == 0 {
return func(ctx *context.Context) {}
}

return func(ctx *context.Context) {
// Set CORS headers for browser-based git clients
ctx.Resp.Header().Set("Access-Control-Allow-Origin", allowedOrigin)
allowedOriginSlices := strings.Split(allowedOrigins, ",")
var matchAll util.OptionalBool //
for _, allowedOrigin := range allowedOriginSlices {
if allowedOrigin == "*" {
matchAll = util.OptionalBoolTrue
} else if allowedOrigin == "null" {
matchAll = util.OptionalBoolFalse
}
ctx.Resp.Header().Set("Access-Control-Allow-Origin", allowedOrigin)
}
ctx.Resp.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, User-Agent")

// Handle preflight OPTIONS request
if ctx.Req.Method == "OPTIONS" {
if allowedOrigin == "*" {
if matchAll.IsTrue() {
ctx.Status(http.StatusOK)
} else if allowedOrigin == "null" {
} else if matchAll.IsFalse() {
ctx.Status(http.StatusForbidden)
} else {
origin := ctx.Req.Header.Get("Origin")
if len(origin) > 0 && origin == allowedOrigin {
if len(origin) > 0 && util.IsStringInSlice(origin, allowedOriginSlices) {
ctx.Status(http.StatusOK)
} else {
ctx.Status(http.StatusForbidden)
Expand All @@ -67,7 +86,10 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
return
}
}
}

// httpBase implementation git smart HTTP protocol
func httpBase(ctx *context.Context) (h *serviceHandler) {
username := ctx.Params(":username")
reponame := strings.TrimSuffix(ctx.Params(":reponame"), ".git")

Expand Down
27 changes: 15 additions & 12 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -1346,18 +1346,21 @@ func RegisterRoutes(m *web.Route) {
}, ignSignInAndCsrf, lfsServerEnabled)

m.Group("", func() {
m.PostOptions("/git-upload-pack", repo.ServiceUploadPack)
m.PostOptions("/git-receive-pack", repo.ServiceReceivePack)
m.GetOptions("/info/refs", repo.GetInfoRefs)
m.GetOptions("/HEAD", repo.GetTextFile("HEAD"))
m.GetOptions("/objects/info/alternates", repo.GetTextFile("objects/info/alternates"))
m.GetOptions("/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates"))
m.GetOptions("/objects/info/packs", repo.GetInfoPacks)
m.GetOptions("/objects/info/{file:[^/]*}", repo.GetTextFile(""))
m.GetOptions("/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject)
m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile)
m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile)
}, ignSignInAndCsrf, context_service.UserAssignmentWeb())
m.Post("/git-upload-pack", repo.ServiceUploadPack)
m.Post("/git-receive-pack", repo.ServiceReceivePack)
m.Get("/info/refs", repo.GetInfoRefs)
m.Get("/HEAD", repo.GetTextFile("HEAD"))
m.Get("/objects/info/alternates", repo.GetTextFile("objects/info/alternates"))
m.Get("/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates"))
m.Get("/objects/info/packs", repo.GetInfoPacks)
m.Get("/objects/info/{file:[^/]*}", repo.GetTextFile(""))
m.Get("/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject)
m.Get("/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile)
m.Get("/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile)
m.Options("/*", func(ctx *context.Context) {
ctx.Resp.WriteHeader(http.StatusMethodNotAllowed)
}) // to ensure middlewares could handle options requests
}, repo.HTTPMustEnabled(), ignSignInAndCsrf, repo.HTTPCors(), context_service.UserAssignmentWeb())
})
})
// ***** END: Repository *****
Expand Down