Skip to content

Commit 967073e

Browse files
authored
Merge branch 'main' into fix-azureblob-seek
2 parents e7bfa40 + 973363f commit 967073e

File tree

5 files changed

+284
-159
lines changed

5 files changed

+284
-159
lines changed

modules/packages/maven/metadata.go

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"encoding/xml"
88
"io"
99

10+
"code.gitea.io/gitea/modules/util"
1011
"code.gitea.io/gitea/modules/validation"
1112

1213
"golang.org/x/net/html/charset"
@@ -31,18 +32,27 @@ type Dependency struct {
3132
}
3233

3334
type pomStruct struct {
34-
XMLName xml.Name `xml:"project"`
35-
GroupID string `xml:"groupId"`
36-
ArtifactID string `xml:"artifactId"`
37-
Version string `xml:"version"`
38-
Name string `xml:"name"`
39-
Description string `xml:"description"`
40-
URL string `xml:"url"`
41-
Licenses []struct {
35+
XMLName xml.Name `xml:"project"`
36+
37+
Parent struct {
38+
GroupID string `xml:"groupId"`
39+
ArtifactID string `xml:"artifactId"`
40+
Version string `xml:"version"`
41+
} `xml:"parent"`
42+
43+
GroupID string `xml:"groupId"`
44+
ArtifactID string `xml:"artifactId"`
45+
Version string `xml:"version"`
46+
Name string `xml:"name"`
47+
Description string `xml:"description"`
48+
URL string `xml:"url"`
49+
50+
Licenses []struct {
4251
Name string `xml:"name"`
4352
URL string `xml:"url"`
4453
Distribution string `xml:"distribution"`
4554
} `xml:"licenses>license"`
55+
4656
Dependencies []struct {
4757
GroupID string `xml:"groupId"`
4858
ArtifactID string `xml:"artifactId"`
@@ -81,8 +91,16 @@ func ParsePackageMetaData(r io.Reader) (*Metadata, error) {
8191
})
8292
}
8393

94+
pomGroupID := pom.GroupID
95+
if pomGroupID == "" {
96+
// the current module could inherit parent: https://maven.apache.org/pom.html#Inheritance
97+
pomGroupID = pom.Parent.GroupID
98+
}
99+
if pomGroupID == "" {
100+
return nil, util.ErrInvalidArgument
101+
}
84102
return &Metadata{
85-
GroupID: pom.GroupID,
103+
GroupID: pomGroupID,
86104
ArtifactID: pom.ArtifactID,
87105
Name: pom.Name,
88106
Description: pom.Description,

modules/packages/maven/metadata_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import (
77
"strings"
88
"testing"
99

10+
"code.gitea.io/gitea/modules/util"
11+
1012
"github.com/stretchr/testify/assert"
13+
"github.com/stretchr/testify/require"
1114
"golang.org/x/text/encoding/charmap"
1215
)
1316

@@ -86,4 +89,35 @@ func TestParsePackageMetaData(t *testing.T) {
8689
assert.NoError(t, err)
8790
assert.NotNil(t, m)
8891
})
92+
93+
t.Run("ParentInherit", func(t *testing.T) {
94+
pom := `<?xml version="1.0"?>
95+
<project>
96+
<modelVersion>4.0.0</modelVersion>
97+
<parent>
98+
<groupId>com.mycompany.app</groupId>
99+
<artifactId>my-app</artifactId>
100+
<version>1.0-SNAPSHOT</version>
101+
</parent>
102+
<artifactId>submodule1</artifactId>
103+
</project>
104+
`
105+
m, err := ParsePackageMetaData(strings.NewReader(pom))
106+
require.NoError(t, err)
107+
require.NotNil(t, m)
108+
109+
assert.Equal(t, "com.mycompany.app", m.GroupID)
110+
assert.Equal(t, "submodule1", m.ArtifactID)
111+
})
112+
113+
t.Run("ParentInherit", func(t *testing.T) {
114+
pom := `<?xml version="1.0"?>
115+
<project>
116+
<modelVersion>4.0.0</modelVersion>
117+
<artifactId></artifactId>
118+
</project>
119+
`
120+
_, err := ParsePackageMetaData(strings.NewReader(pom))
121+
require.ErrorIs(t, err, util.ErrInvalidArgument)
122+
})
89123
}

modules/web/route.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
package web
55

66
import (
7+
"fmt"
78
"net/http"
89
"net/url"
910
"reflect"
11+
"regexp"
1012
"strings"
1113

14+
"code.gitea.io/gitea/modules/container"
1215
"code.gitea.io/gitea/modules/htmlutil"
1316
"code.gitea.io/gitea/modules/reqctx"
1417
"code.gitea.io/gitea/modules/setting"
18+
"code.gitea.io/gitea/modules/util"
1519
"code.gitea.io/gitea/modules/web/middleware"
1620

1721
"gitea.com/go-chi/binding"
@@ -181,6 +185,17 @@ func (r *Router) NotFound(h http.HandlerFunc) {
181185
r.chiRouter.NotFound(h)
182186
}
183187

188+
type pathProcessorParam struct {
189+
name string
190+
captureGroup int
191+
}
192+
193+
type PathProcessor struct {
194+
methods container.Set[string]
195+
re *regexp.Regexp
196+
params []pathProcessorParam
197+
}
198+
184199
func (r *Router) normalizeRequestPath(resp http.ResponseWriter, req *http.Request, next http.Handler) {
185200
normalized := false
186201
normalizedPath := req.URL.EscapedPath()
@@ -238,6 +253,83 @@ func (r *Router) normalizeRequestPath(resp http.ResponseWriter, req *http.Reques
238253
next.ServeHTTP(resp, req)
239254
}
240255

256+
func (p *PathProcessor) ProcessRequestPath(chiCtx *chi.Context, path string) bool {
257+
if !p.methods.Contains(chiCtx.RouteMethod) {
258+
return false
259+
}
260+
if !strings.HasPrefix(path, "/") {
261+
path = "/" + path
262+
}
263+
pathMatches := p.re.FindStringSubmatchIndex(path) // Golang regexp match pairs [start, end, start, end, ...]
264+
if pathMatches == nil {
265+
return false
266+
}
267+
var paramMatches [][]int
268+
for i := 2; i < len(pathMatches); {
269+
paramMatches = append(paramMatches, []int{pathMatches[i], pathMatches[i+1]})
270+
pmIdx := len(paramMatches) - 1
271+
end := pathMatches[i+1]
272+
i += 2
273+
for ; i < len(pathMatches); i += 2 {
274+
if pathMatches[i] >= end {
275+
break
276+
}
277+
paramMatches[pmIdx] = append(paramMatches[pmIdx], pathMatches[i], pathMatches[i+1])
278+
}
279+
}
280+
for i, pm := range paramMatches {
281+
groupIdx := p.params[i].captureGroup * 2
282+
chiCtx.URLParams.Add(p.params[i].name, path[pm[groupIdx]:pm[groupIdx+1]])
283+
}
284+
return true
285+
}
286+
287+
func NewPathProcessor(methods, pattern string) *PathProcessor {
288+
p := &PathProcessor{methods: make(container.Set[string])}
289+
for _, method := range strings.Split(methods, ",") {
290+
p.methods.Add(strings.TrimSpace(method))
291+
}
292+
re := []byte{'^'}
293+
lastEnd := 0
294+
for lastEnd < len(pattern) {
295+
start := strings.IndexByte(pattern[lastEnd:], '<')
296+
if start == -1 {
297+
re = append(re, pattern[lastEnd:]...)
298+
break
299+
}
300+
end := strings.IndexByte(pattern[lastEnd+start:], '>')
301+
if end == -1 {
302+
panic(fmt.Sprintf("invalid pattern: %s", pattern))
303+
}
304+
re = append(re, pattern[lastEnd:lastEnd+start]...)
305+
partName, partExp, _ := strings.Cut(pattern[lastEnd+start+1:lastEnd+start+end], ":")
306+
lastEnd += start + end + 1
307+
308+
// TODO: it could support to specify a "capture group" for the name, for example: "/<name[2]:(\d)-(\d)>"
309+
// it is not used so no need to implement it now
310+
param := pathProcessorParam{}
311+
if partExp == "*" {
312+
re = append(re, "(.*?)/?"...)
313+
if lastEnd < len(pattern) {
314+
if pattern[lastEnd] == '/' {
315+
lastEnd++
316+
}
317+
}
318+
} else {
319+
partExp = util.IfZero(partExp, "[^/]+")
320+
re = append(re, '(')
321+
re = append(re, partExp...)
322+
re = append(re, ')')
323+
}
324+
param.name = partName
325+
p.params = append(p.params, param)
326+
}
327+
re = append(re, '$')
328+
reStr := string(re)
329+
p.re = regexp.MustCompile(reStr)
330+
return p
331+
}
332+
241333
// Combo delegates requests to Combo
242334
func (r *Router) Combo(pattern string, h ...any) *Combo {
243335
return &Combo{r, pattern, h}

0 commit comments

Comments
 (0)