@@ -19,13 +19,23 @@ import (
1919
2020 "gitea.com/go-chi/session"
2121 "github.com/chi-middleware/proxy"
22- chi "github.com/go-chi/chi/v5"
22+ "github.com/go-chi/chi/v5"
2323)
2424
2525// ProtocolMiddlewares returns HTTP protocol related middlewares, and it provides a global panic recovery
2626func ProtocolMiddlewares () (handlers []any ) {
27- // first, normalize the URL path
28- handlers = append (handlers , normalizeRequestPathMiddleware )
27+ // make sure chi uses EscapedPath(RawPath) as RoutePath, then "%2f" could be handled correctly
28+ handlers = append (handlers , func (next http.Handler ) http.Handler {
29+ return http .HandlerFunc (func (resp http.ResponseWriter , req * http.Request ) {
30+ ctx := chi .RouteContext (req .Context ())
31+ if req .URL .RawPath == "" {
32+ ctx .RoutePath = req .URL .EscapedPath ()
33+ } else {
34+ ctx .RoutePath = req .URL .RawPath
35+ }
36+ next .ServeHTTP (resp , req )
37+ })
38+ })
2939
3040 // prepare the ContextData and panic recovery
3141 handlers = append (handlers , func (next http.Handler ) http.Handler {
@@ -75,58 +85,6 @@ func ProtocolMiddlewares() (handlers []any) {
7585 return handlers
7686}
7787
78- func normalizeRequestPathMiddleware (next http.Handler ) http.Handler {
79- return http .HandlerFunc (func (resp http.ResponseWriter , req * http.Request ) {
80- // escape the URL RawPath to ensure that all routing is done using a correctly escaped URL
81- req .URL .RawPath = req .URL .EscapedPath ()
82-
83- urlPath := req .URL .RawPath
84- rctx := chi .RouteContext (req .Context ())
85- if rctx != nil && rctx .RoutePath != "" {
86- urlPath = rctx .RoutePath
87- }
88-
89- normalizedPath := strings .TrimRight (urlPath , "/" )
90- // the following code block is a slow-path for replacing all repeated slashes "//" to one single "/"
91- // if the path doesn't have repeated slashes, then no need to execute it
92- if strings .Contains (normalizedPath , "//" ) {
93- buf := & strings.Builder {}
94- prevWasSlash := false
95- for _ , chr := range normalizedPath {
96- if chr != '/' || ! prevWasSlash {
97- buf .WriteRune (chr )
98- }
99- prevWasSlash = chr == '/'
100- }
101- normalizedPath = buf .String ()
102- }
103-
104- if setting .UseSubURLPath {
105- remainingPath , ok := strings .CutPrefix (normalizedPath , setting .AppSubURL + "/" )
106- if ok {
107- normalizedPath = "/" + remainingPath
108- } else if normalizedPath == setting .AppSubURL {
109- normalizedPath = "/"
110- } else if ! strings .HasPrefix (normalizedPath + "/" , "/v2/" ) {
111- // do not respond to other requests, to simulate a real sub-path environment
112- http .Error (resp , "404 page not found, sub-path is: " + setting .AppSubURL , http .StatusNotFound )
113- return
114- }
115- // TODO: it's not quite clear about how req.URL and rctx.RoutePath work together.
116- // Fortunately, it is only used for debug purpose, we have enough time to figure it out in the future.
117- req .URL .RawPath = normalizedPath
118- req .URL .Path = normalizedPath
119- }
120-
121- if rctx == nil {
122- req .URL .Path = normalizedPath
123- } else {
124- rctx .RoutePath = normalizedPath
125- }
126- next .ServeHTTP (resp , req )
127- })
128- }
129-
13088func Sessioner () func (next http.Handler ) http.Handler {
13189 return session .Sessioner (session.Options {
13290 Provider : setting .SessionConfig .Provider ,
0 commit comments