diff --git a/modules/httplib/serve.go b/modules/httplib/serve.go index a193ed901c..6e147d76f5 100644 --- a/modules/httplib/serve.go +++ b/modules/httplib/serve.go @@ -17,11 +17,14 @@ import ( "time" charsetModule "code.gitea.io/gitea/modules/charset" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/typesniffer" "code.gitea.io/gitea/modules/util" + + "github.com/klauspost/compress/gzhttp" ) type ServeHeaderOptions struct { @@ -38,6 +41,11 @@ type ServeHeaderOptions struct { func ServeSetHeaders(w http.ResponseWriter, opts *ServeHeaderOptions) { header := w.Header() + skipCompressionExts := container.SetOf(".gz", ".bz2", ".zip", ".xz", ".zst", ".deb", ".apk", ".jar", ".png", ".jpg", ".webp") + if skipCompressionExts.Contains(strings.ToLower(path.Ext(opts.Filename))) { + w.Header().Add(gzhttp.HeaderNoCompression, "1") + } + contentType := typesniffer.ApplicationOctetStream if opts.ContentType != "" { if opts.ContentTypeCharset != "" { diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go index bd844205a6..8056b58ec2 100644 --- a/modules/indexer/code/bleve/bleve.go +++ b/modules/indexer/code/bleve/bleve.go @@ -39,8 +39,6 @@ import ( const ( unicodeNormalizeName = "unicodeNormalize" maxBatchSize = 16 - // fuzzyDenominator determines the levenshtein distance per each character of a keyword - fuzzyDenominator = 4 ) func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error { @@ -245,7 +243,7 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int phraseQuery.Analyzer = repoIndexerAnalyzer keywordQuery = phraseQuery if opts.IsKeywordFuzzy { - phraseQuery.Fuzziness = len(opts.Keyword) / fuzzyDenominator + phraseQuery.Fuzziness = inner_bleve.GuessFuzzinessByKeyword(opts.Keyword) } if len(opts.RepoIDs) > 0 { diff --git a/modules/indexer/internal/bleve/util.go b/modules/indexer/internal/bleve/util.go index 43a7c3c5ec..a2265f86e6 100644 --- a/modules/indexer/internal/bleve/util.go +++ b/modules/indexer/internal/bleve/util.go @@ -47,3 +47,15 @@ func openIndexer(path string, latestVersion int) (bleve.Index, int, error) { return index, 0, nil } + +func GuessFuzzinessByKeyword(s string) int { + // according to https://github.com/blevesearch/bleve/issues/1563, the supported max fuzziness is 2 + // magic number 4 was chosen to determine the levenshtein distance per each character of a keyword + // BUT, when using CJK (eg: `갃갃갃` `啊啊啊`), it mismatches a lot. + for _, r := range s { + if r >= 128 { + return 0 + } + } + return min(2, len(s)/4) +} diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go index 1f54be721b..d7957b266a 100644 --- a/modules/indexer/issues/bleve/bleve.go +++ b/modules/indexer/issues/bleve/bleve.go @@ -35,11 +35,7 @@ func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error { }) } -const ( - maxBatchSize = 16 - // fuzzyDenominator determines the levenshtein distance per each character of a keyword - fuzzyDenominator = 4 -) +const maxBatchSize = 16 // IndexerData an update to the issue indexer type IndexerData internal.IndexerData @@ -162,7 +158,7 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( if options.Keyword != "" { fuzziness := 0 if options.IsFuzzyKeyword { - fuzziness = len(options.Keyword) / fuzzyDenominator + fuzziness = inner_bleve.GuessFuzzinessByKeyword(options.Keyword) } queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{ diff --git a/modules/markup/html.go b/modules/markup/html.go index cef643bf18..5ae0cc8755 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -591,17 +591,16 @@ func replaceContentList(node *html.Node, i, j int, newNodes []*html.Node) { func mentionProcessor(ctx *RenderContext, node *html.Node) { start := 0 - next := node.NextSibling - for node != nil && node != next && start < len(node.Data) { - // We replace only the first mention; other mentions will be addressed later - found, loc := references.FindFirstMentionBytes([]byte(node.Data[start:])) + for node != nil { + found, loc := references.FindFirstMentionBytes(util.UnsafeStringToBytes(node.Data[start:])) if !found { - return + node = node.NextSibling + start = 0 + continue } loc.Start += start loc.End += start mention := node.Data[loc.Start:loc.End] - var teams string teams, ok := ctx.Metas["teams"] // FIXME: util.URLJoin may not be necessary here: // - setting.AppURL is defined to have a terminal '/' so unless mention[1:] @@ -623,10 +622,10 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) { if DefaultProcessorHelper.IsUsernameMentionable != nil && DefaultProcessorHelper.IsUsernameMentionable(ctx.Ctx, mentionedUsername) { replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), mentionedUsername), mention, "mention")) node = node.NextSibling.NextSibling + start = 0 } else { - node = node.NextSibling + start = loc.End } - start = 0 } } diff --git a/modules/references/references.go b/modules/references/references.go index 761d6ee3d1..1b656ed4cb 100644 --- a/modules/references/references.go +++ b/modules/references/references.go @@ -29,7 +29,7 @@ var ( // TODO: fix invalid linking issue // mentionPattern matches all mentions in the form of "@user" or "@org/team" - mentionPattern = regexp.MustCompile(`(?:\s|^|\(|\[)(@[0-9a-zA-Z-_]+|@[0-9a-zA-Z-_]+\/?[0-9a-zA-Z-_]+|@[0-9a-zA-Z-_][0-9a-zA-Z-_.]+\/?[0-9a-zA-Z-_.]+[0-9a-zA-Z-_])(?:\s|[:,;.?!]\s|[:,;.?!]?$|\)|\])`) + mentionPattern = regexp.MustCompile(`(?:\s|^|\(|\[)(@[-\w][-.\w]*?|@[-\w][-.\w]*?/[-\w][-.\w]*?)(?:\s|$|[:,;.?!](\s|$)|'|\)|\])`) // issueNumericPattern matches string that references to a numeric issue, e.g. #1287 issueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[|\'|\")([#!][0-9]+)(?:\s|$|\)|\]|\'|\"|[:;,.?!]\s|[:;,.?!]$)`) // issueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234 diff --git a/modules/references/references_test.go b/modules/references/references_test.go index 0c32933619..e5a0d60fe3 100644 --- a/modules/references/references_test.go +++ b/modules/references/references_test.go @@ -392,6 +392,7 @@ func TestRegExp_mentionPattern(t *testing.T) { {"@gitea,", "@gitea"}, {"@gitea;", "@gitea"}, {"@gitea/team1;", "@gitea/team1"}, + {"@user's idea", "@user"}, } falseTestCases := []string{ "@ 0", @@ -412,7 +413,6 @@ func TestRegExp_mentionPattern(t *testing.T) { for _, testCase := range trueTestCases { found := mentionPattern.FindStringSubmatch(testCase.pat) - assert.Len(t, found, 2) assert.Equal(t, testCase.exp, found[1]) } for _, testCase := range falseTestCases { diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go index 47c5da6485..f493b899e3 100644 --- a/modules/templates/util_render_test.go +++ b/modules/templates/util_render_test.go @@ -207,3 +207,8 @@ func TestRenderLabels(t *testing.T) { expected = `/owner/repo/pulls?labels=123` assert.Contains(t, RenderLabels(ctx, locale, []*issues.Label{label}, "/owner/repo", issue), expected) } + +func TestUserMention(t *testing.T) { + rendered := RenderMarkdownToHtml(context.Background(), "@no-such-user @mention-user @mention-user") + assert.EqualValues(t, `

@no-such-user @mention-user @mention-user

`, strings.TrimSpace(string(rendered))) +} diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go index 23cf898630..d7854b2499 100644 --- a/routers/web/repo/search.go +++ b/routers/web/repo/search.go @@ -28,6 +28,7 @@ func Search(ctx *context.Context) { ctx.Data["Language"] = language ctx.Data["IsFuzzy"] = isFuzzy ctx.Data["PageIsViewCode"] = true + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled if keyword == "" { ctx.HTML(http.StatusOK, tplSearch) @@ -86,7 +87,6 @@ func Search(ctx *context.Context) { } } - ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["Repo"] = ctx.Repo.Repository ctx.Data["SearchResults"] = searchResults ctx.Data["SearchResultLanguages"] = searchResultLanguages diff --git a/routers/web/web.go b/routers/web/web.go index 9a6687059b..91ab378d97 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -54,7 +54,7 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -const GzipMinSize = 1400 // min size to compress for the body size of response +var GzipMinSize = 1400 // min size to compress for the body size of response // optionsCorsHandler return a http handler which sets CORS options if enabled by config, it blocks non-CORS OPTIONS requests. func optionsCorsHandler() func(next http.Handler) http.Handler { diff --git a/templates/repo/branch_dropdown.tmpl b/templates/repo/branch_dropdown.tmpl index 7b39830df8..8f58826c6a 100644 --- a/templates/repo/branch_dropdown.tmpl +++ b/templates/repo/branch_dropdown.tmpl @@ -69,9 +69,9 @@
{{/* show dummy elements before Vue componment is mounted, this code must match the code in BranchTagSelector.vue */}} -
diff --git a/templates/repo/issue/branch_selector_field.tmpl b/templates/repo/issue/branch_selector_field.tmpl index ed0d58cf27..e9e5574cd7 100644 --- a/templates/repo/issue/branch_selector_field.tmpl +++ b/templates/repo/issue/branch_selector_field.tmpl @@ -4,10 +4,12 @@
{{$.CsrfTokenHtml}}
-{{/* TODO: share this branch selector dropdown with the same in repo page */}} -