44package common
55
66import (
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
1820type 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.
4244func 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}
0 commit comments