From 9219534447411f6ffe507fee64f89c619c29d501 Mon Sep 17 00:00:00 2001
From: wxiaoguang <wxiaoguang@gmail.com>
Date: Wed, 26 Apr 2023 02:35:50 +0800
Subject: [PATCH] Fix incorrect CORS response in Http Git handler (#24303)

Use the general `cors.Handler` for CORS
---
 routers/web/repo/http.go | 54 ++++++++++++++++------------------------
 routers/web/web.go       |  2 +-
 2 files changed, 22 insertions(+), 34 deletions(-)

diff --git a/routers/web/repo/http.go b/routers/web/repo/http.go
index cd32d99533..a01bb4f28e 100644
--- a/routers/web/repo/http.go
+++ b/routers/web/repo/http.go
@@ -32,43 +32,31 @@ import (
 	"code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/util"
 	repo_service "code.gitea.io/gitea/services/repository"
+
+	"github.com/go-chi/cors"
 )
 
+func HTTPGitEnabledHandler(ctx *context.Context) {
+	if setting.Repository.DisableHTTPGit {
+		ctx.Resp.WriteHeader(http.StatusForbidden)
+		_, _ = ctx.Resp.Write([]byte("Interacting with repositories by HTTP protocol is not allowed"))
+	}
+}
+
+func CorsHandler() func(next http.Handler) http.Handler {
+	if setting.Repository.AccessControlAllowOrigin != "" {
+		return cors.Handler(cors.Options{
+			AllowedOrigins: []string{setting.Repository.AccessControlAllowOrigin},
+			AllowedHeaders: []string{"Content-Type", "Authorization", "User-Agent"},
+		})
+	}
+	return func(next http.Handler) http.Handler {
+		return next
+	}
+}
+
 // httpBase implementation git smart HTTP protocol
 func httpBase(ctx *context.Context) (h *serviceHandler) {
-	if setting.Repository.DisableHTTPGit {
-		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
-		// Set CORS headers for browser-based git clients
-		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 == "*" {
-				ctx.Status(http.StatusOK)
-			} else if allowedOrigin == "null" {
-				ctx.Status(http.StatusForbidden)
-			} else {
-				origin := ctx.Req.Header.Get("Origin")
-				if len(origin) > 0 && origin == allowedOrigin {
-					ctx.Status(http.StatusOK)
-				} else {
-					ctx.Status(http.StatusForbidden)
-				}
-			}
-			return
-		}
-	}
-
 	username := ctx.Params(":username")
 	reponame := strings.TrimSuffix(ctx.Params(":reponame"), ".git")
 
diff --git a/routers/web/web.go b/routers/web/web.go
index 9d1bd90d93..af39059325 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -1515,7 +1515,7 @@ func RegisterRoutes(m *web.Route) {
 				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())
+			}, ignSignInAndCsrf, repo.HTTPGitEnabledHandler, repo.CorsHandler(), context_service.UserAssignmentWeb())
 		})
 	})
 	// ***** END: Repository *****