Skip to content

Commit 351be38

Browse files
committed
apply review feedback
1 parent a38d71b commit 351be38

File tree

3 files changed

+84
-39
lines changed

3 files changed

+84
-39
lines changed

routers/common/qos.go

+25-34
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package common
55

66
import (
7+
"context"
78
"fmt"
89
"net/http"
910
"strings"
@@ -13,6 +14,7 @@ import (
1314
"code.gitea.io/gitea/modules/web/middleware"
1415

1516
"github.com/bohde/codel"
17+
"github.com/go-chi/chi/v5"
1618
)
1719

1820
type Priority int
@@ -40,6 +42,10 @@ const (
4042
// or not the user is logged in. All traffic may get dropped, and
4143
// anonymous users are deprioritized.
4244
func QoS() func(next http.Handler) http.Handler {
45+
if !setting.Service.QoS.Enabled {
46+
return nil
47+
}
48+
4349
maxOutstanding := setting.Service.QoS.MaxInFlightRequests
4450
if maxOutstanding <= 0 {
4551
maxOutstanding = 10
@@ -59,16 +65,7 @@ func QoS() func(next http.Handler) http.Handler {
5965
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
6066
ctx := req.Context()
6167

62-
priority := DefaultPriority
63-
64-
// If the user is logged in, assign high priority.
65-
data := middleware.GetContextData(req.Context())
66-
if _, ok := data[middleware.ContextDataKeySignedUser].(*user_model.User); ok {
67-
priority = HighPriority
68-
} else if IsGitContents(req.URL.Path) {
69-
// Otherwise, if the path would is accessing git contents directly, mark as low priority
70-
priority = LowPriority
71-
}
68+
priority := requestPriority(ctx)
7269

7370
// Check if the request can begin processing.
7471
err := c.Acquire(ctx, int(priority))
@@ -91,31 +88,25 @@ func QoS() func(next http.Handler) http.Handler {
9188
}
9289
}
9390

94-
func IsGitContents(path string) bool {
95-
parts := []string{
96-
"refs",
97-
"archive",
98-
"commit",
99-
"graph",
100-
"blame",
101-
"branches",
102-
"tags",
103-
"labels",
104-
"stars",
105-
"search",
106-
"activity",
107-
"wiki",
108-
"watchers",
109-
"compare",
110-
"raw",
111-
"src",
112-
"commits",
91+
// requestPriority assigns a priority value for a request based upon
92+
// whether the user is logged in and how expensive the endpoint is
93+
func requestPriority(ctx context.Context) Priority {
94+
// If the user is logged in, assign high priority.
95+
data := middleware.GetContextData(ctx)
96+
if _, ok := data[middleware.ContextDataKeySignedUser].(*user_model.User); ok {
97+
return HighPriority
11398
}
11499

115-
for _, p := range parts {
116-
if strings.Contains(path, p) {
117-
return true
118-
}
100+
rctx := chi.RouteContext(ctx)
101+
if rctx == nil {
102+
return DefaultPriority
119103
}
120-
return false
104+
105+
// If we're operating in the context of a repo, assign low priority
106+
routePattern := rctx.RoutePattern()
107+
if strings.HasPrefix(routePattern, "/{username}/{reponame}") {
108+
return LowPriority
109+
}
110+
111+
return DefaultPriority
121112
}

routers/common/qos_test.go

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package common
5+
6+
import (
7+
"testing"
8+
9+
user_model "code.gitea.io/gitea/models/user"
10+
"code.gitea.io/gitea/modules/web/middleware"
11+
"code.gitea.io/gitea/services/contexttest"
12+
13+
"github.com/go-chi/chi/v5"
14+
"github.com/stretchr/testify/assert"
15+
)
16+
17+
func TestRequestPriority(t *testing.T) {
18+
type test struct {
19+
Name string
20+
User *user_model.User
21+
RoutePattern string
22+
Expected Priority
23+
}
24+
25+
cases := []test{
26+
{
27+
Name: "Logged In",
28+
User: &user_model.User{},
29+
Expected: HighPriority,
30+
},
31+
{
32+
Name: "Sign In",
33+
RoutePattern: "/user/login",
34+
Expected: DefaultPriority,
35+
},
36+
{
37+
Name: "User Repo",
38+
RoutePattern: "/{username}/{reponame}/src/branch/main",
39+
Expected: LowPriority,
40+
},
41+
}
42+
43+
for _, tc := range cases {
44+
t.Run(tc.Name, func(t *testing.T) {
45+
ctx, _ := contexttest.MockContext(t, "")
46+
47+
if tc.User != nil {
48+
data := middleware.GetContextData(ctx)
49+
data[middleware.ContextDataKeySignedUser] = tc.User
50+
}
51+
52+
rctx := chi.RouteContext(ctx)
53+
rctx.RoutePatterns = []string{tc.RoutePattern}
54+
55+
assert.Exactly(t, tc.Expected, requestPriority(ctx))
56+
})
57+
}
58+
}

routers/web/web.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,6 @@ func Routes() *web.Router {
272272
// Get user from session if logged in.
273273
mid = append(mid, webAuth(buildAuthGroup()))
274274

275-
if setting.Service.QoS.Enabled {
276-
mid = append(mid, common.QoS())
277-
}
278-
279275
// GetHead allows a HEAD request redirect to GET if HEAD method is not defined for that route
280276
mid = append(mid, chi_middleware.GetHead)
281277

@@ -289,7 +285,7 @@ func Routes() *web.Router {
289285

290286
webRoutes := web.NewRouter()
291287
webRoutes.Use(mid...)
292-
webRoutes.Group("", func() { registerWebRoutes(webRoutes) }, common.BlockExpensive())
288+
others.Group("", func() { webRoutes.Group("", func() { registerWebRoutes(webRoutes) }, common.BlockExpensive()) }, common.QoS())
293289
routes.Mount("", webRoutes)
294290
return routes
295291
}

0 commit comments

Comments
 (0)