Skip to content

Commit 2fee014

Browse files
committed
fix
1 parent 6708343 commit 2fee014

File tree

5 files changed

+94
-228
lines changed

5 files changed

+94
-228
lines changed

modules/web/router_path.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package web
66
import (
77
"net/http"
88
"regexp"
9+
"slices"
910
"strings"
1011

1112
"code.gitea.io/gitea/modules/container"
@@ -36,12 +37,22 @@ func (g *RouterPathGroup) ServeHTTP(resp http.ResponseWriter, req *http.Request)
3637
g.r.chiRouter.NotFoundHandler().ServeHTTP(resp, req)
3738
}
3839

40+
type RouterPathRegexp struct {
41+
re *regexp.Regexp
42+
params []routerPathParam
43+
middlewares []any
44+
}
45+
3946
// MatchPath matches the request method, and uses regexp to match the path.
40-
// The pattern uses "<...>" to define path parameters, for example: "/<name>" (different from chi router)
41-
// It is only designed to resolve some special cases which chi router can't handle.
47+
// The pattern uses "<...>" to define path parameters, for example, "/<name>" (different from chi router)
48+
// It is only designed to resolve some special cases that chi router can't handle.
4249
// For most cases, it shouldn't be used because it needs to iterate all rules to find the matched one (inefficient).
4350
func (g *RouterPathGroup) MatchPath(methods, pattern string, h ...any) {
44-
g.matchers = append(g.matchers, newRouterPathMatcher(methods, pattern, h...))
51+
g.MatchRegexp(methods, g.PatternRegexp(pattern), h...)
52+
}
53+
54+
func (g *RouterPathGroup) MatchRegexp(methods string, patternRegexp *RouterPathRegexp, h ...any) {
55+
g.matchers = append(g.matchers, newRouterPathMatcher(methods, patternRegexp, h...))
4556
}
4657

4758
type routerPathParam struct {
@@ -96,8 +107,8 @@ func isValidMethod(name string) bool {
96107
return false
97108
}
98109

99-
func newRouterPathMatcher(methods, pattern string, h ...any) *routerPathMatcher {
100-
middlewares, handlerFunc := wrapMiddlewareAndHandler(nil, h)
110+
func newRouterPathMatcher(methods string, patternRegexp *RouterPathRegexp, h ...any) *routerPathMatcher {
111+
middlewares, handlerFunc := wrapMiddlewareAndHandler(patternRegexp.middlewares, h)
101112
p := &routerPathMatcher{methods: make(container.Set[string]), middlewares: middlewares, handlerFunc: handlerFunc}
102113
for method := range strings.SplitSeq(methods, ",") {
103114
method = strings.TrimSpace(method)
@@ -106,6 +117,12 @@ func newRouterPathMatcher(methods, pattern string, h ...any) *routerPathMatcher
106117
}
107118
p.methods.Add(method)
108119
}
120+
p.re, p.params = patternRegexp.re, patternRegexp.params
121+
return p
122+
}
123+
124+
func patternRegexp(pattern string, h ...any) *RouterPathRegexp {
125+
p := &RouterPathRegexp{middlewares: slices.Clone(h)}
109126
re := []byte{'^'}
110127
lastEnd := 0
111128
for lastEnd < len(pattern) {
@@ -144,3 +161,7 @@ func newRouterPathMatcher(methods, pattern string, h ...any) *routerPathMatcher
144161
p.re = regexp.MustCompile(reStr)
145162
return p
146163
}
164+
165+
func (g *RouterPathGroup) PatternRegexp(pattern string, h ...any) *RouterPathRegexp {
166+
return patternRegexp(pattern, h...)
167+
}

modules/web/router_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func TestPathProcessor(t *testing.T) {
3434
testProcess := func(pattern, uri string, expectedPathParams map[string]string) {
3535
chiCtx := chi.NewRouteContext()
3636
chiCtx.RouteMethod = "GET"
37-
p := newRouterPathMatcher("GET", pattern, http.NotFound)
37+
p := newRouterPathMatcher("GET", patternRegexp(pattern), http.NotFound)
3838
assert.True(t, p.matchPath(chiCtx, uri), "use pattern %s to process uri %s", pattern, uri)
3939
assert.Equal(t, expectedPathParams, chiURLParamsToMap(chiCtx), "use pattern %s to process uri %s", pattern, uri)
4040
}
@@ -108,7 +108,7 @@ func TestRouter(t *testing.T) {
108108
m.Delete("", h())
109109
})
110110
m.PathGroup("/*", func(g *RouterPathGroup) {
111-
g.MatchPath("GET", `/<dir:*>/<file:[a-z]{1,2}>`, stopMark("s2"), h("match-path"))
111+
g.MatchRegexp("GET", g.PatternRegexp(`/<dir:*>/<file:[a-z]{1,2}>`, stopMark("s3")), stopMark("s2"), h("match-path"))
112112
}, stopMark("s1"))
113113
})
114114
})
@@ -205,6 +205,12 @@ func TestRouter(t *testing.T) {
205205
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn", "dir": "d1/d2", "file": "fn"},
206206
handlerMark: "s2",
207207
})
208+
209+
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches/d1/d2/fn?stop=s3", resultStruct{
210+
method: "GET",
211+
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn", "dir": "d1/d2", "file": "fn"},
212+
handlerMark: "s3",
213+
})
208214
})
209215
}
210216

options/locale/locale_uk-UA.ini

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,6 @@ editor.new_branch_name_desc=Назва нової гілки…
13341334
editor.cancel=Відмінити
13351335
editor.filename_cannot_be_empty=Назва файлу не може бути порожньою.
13361336
editor.filename_is_invalid=Назва файлу недійсна: "%s".
1337-
editor.commit_email=Електронна пошта коміту
13381337
editor.invalid_commit_email=Адреса електронної пошти для коміту недійсна.
13391338
editor.file_is_a_symlink=`"%s" - це символічне посилання. Символічні посилання не можна редагувати у веб-редакторі`
13401339
editor.filename_is_a_directory=Назва файлу '%s' вже використовується як назва каталогу у цьому сховищі.
@@ -1370,7 +1369,6 @@ commits.signed_by_untrusted_user=Підписаний недовіреним к
13701369
commits.signed_by_untrusted_user_unmatched=Підписано недовіреним користувачем, який не відповідає комітеру
13711370
commits.gpg_key_id=Ідентифікатор GPG ключа
13721371
commits.ssh_key_fingerprint=Відбиток ключа SSH
1373-
commits.view_path=Переглянути в історії
13741372
commits.view_file_diff=Переглянути зміни до цього файлу в цьому коміті
13751373

13761374
commit.revert=Повернути до попереднього стану
@@ -1499,7 +1497,6 @@ issues.filter_project=Проєкт
14991497
issues.filter_project_all=Всі проєкти
15001498
issues.filter_project_none=Проєкт відсутній
15011499
issues.filter_assignee=Виконавець
1502-
issues.filter_assignee_any_assignee=Призначено будь-кому
15031500
issues.filter_poster=Автор
15041501
issues.filter_user_placeholder=Пошук користувачів
15051502
issues.filter_user_no_select=Усі користувачі
@@ -1530,16 +1527,13 @@ issues.action_milestone=Етап
15301527
issues.action_milestone_no_select=Етап відсутній
15311528
issues.action_assignee=Виконавець
15321529
issues.action_assignee_no_select=Немає виконавця
1533-
issues.action_check=Встановити/зняти позначку
1534-
issues.action_check_all=Встановити/зняти позначку з усіх елементів
15351530
issues.opened_by=%[1]s відкрито <a href="%[2]s">%[3]s</a>
15361531
issues.opened_by_fake=%[1]s відкрито користувачем %[2]s
15371532
issues.previous=Попередній
15381533
issues.next=Далі
15391534
issues.open_title=Відкрито
15401535
issues.closed_title=Закрито
15411536
issues.draft_title=Чернетка
1542-
issues.num_comments_1=%d коментар
15431537
issues.num_comments=%d коментарів
15441538
issues.commented_at=`прокоментував(ла) <a href="#%s">%s</a>`
15451539
issues.delete_comment_confirm=Ви впевнені, що хочете видалити цей коментар?
@@ -1548,7 +1542,6 @@ issues.context.quote_reply=Цитувати відповідь
15481542
issues.context.reference_issue=Посилання в новій задачі
15491543
issues.context.edit=Редагувати
15501544
issues.context.delete=Видалити
1551-
issues.close=Закрити задачу
15521545
issues.comment_manually_pull_merged_at=вручну об'єднав(-ла) коміти %[1]s в %[2]s %[3]s
15531546
issues.close_comment_issue=Закрити з коментарем
15541547
issues.reopen_issue=Відкрити знову
@@ -1575,7 +1568,6 @@ issues.role.collaborator=Співавтор
15751568
issues.role.collaborator_helper=Цей користувач був запрошений до співпраці у сховищі.
15761569
issues.role.first_time_contributor=Учасник, який вперше долучився
15771570
issues.role.first_time_contributor_helper=Це перший внесок цього користувача в сховищі.
1578-
issues.role.contributor=Співавтор
15791571
issues.role.contributor_helper=Цей користувач раніше вже вносив зміни до сховища.
15801572
issues.re_request_review=Повторно попросити рецензію
15811573
issues.is_stale=З часу останньої перевірки в цей PR було внесено деякі зміни
@@ -2198,7 +2190,6 @@ settings.webhook.response=Відповідь
21982190
settings.webhook.headers=Заголовки
21992191
settings.webhook.payload=Зміст
22002192
settings.webhook.body=Тіло
2201-
settings.webhook.replay.description=Повторити цей веб-хук.
22022193
settings.githook_edit_desc=Якщо хук неактивний, буде показано зразок вмісту. Якщо залишити вміст порожнім, хук буде вимкнено.
22032194
settings.githook_name=Назва хуку
22042195
settings.githook_content=Зміст хука
@@ -2255,7 +2246,6 @@ settings.event_pull_request_sync=Запит на злиття синхроніз
22552246
settings.event_pull_request_sync_desc=Запит до злиття синхронізовано.
22562247
settings.event_package=Пакет
22572248
settings.branch_filter=Фільтр гілок
2258-
settings.authorization_header=Заголовок авторизації
22592249
settings.active=Активний
22602250
settings.active_helper=Інформацію про викликані події буде надіслано за цією веб-хук URL-адресою.
22612251
settings.add_hook_success=Веб-хук було додано.
@@ -2304,7 +2294,6 @@ settings.protect_disable_push=Заборонити Push
23042294
settings.protect_disable_push_desc=Для цієї гілки буде заборонено виконання push.
23052295
settings.protect_enable_push=Дозволити Push
23062296
settings.protect_enable_push_desc=Будь-хто із правом запису зможе виконувати push для цієї гілки (за виключенням force push).
2307-
settings.protect_enable_merge=Увімкнути об’єднання
23082297
settings.protect_check_status_contexts=Увімкнути перевірку стану
23092298
settings.protect_status_check_patterns=Шаблони перевірки стану:
23102299
settings.protect_status_check_patterns_desc=Введіть шаблони, щоб вказати, які перевірки стану повинні пройти гілки, перш ніж їх буде об'єднано у гілку, що відповідає цьому правилу. Кожен рядок визначає шаблон. Шаблони не можуть бути порожніми.
@@ -2338,8 +2327,6 @@ settings.block_outdated_branch_desc=Об'єднання буде неможли
23382327
settings.block_admin_merge_override=Адміністратори повинні дотримуватися правил захисту гілки
23392328
settings.block_admin_merge_override_desc=Адміністратори повинні дотримуватися правил захисту гілки і не можуть їх обійти.
23402329
settings.default_branch_desc=Обрати типову гілку сховища для запитів на злиття і комітів:
2341-
settings.merge_style_desc=Стилі об'єднання
2342-
settings.default_merge_style_desc=Типовий стиль об'єднання
23432330
settings.choose_branch=Оберіть гілку…
23442331
settings.no_protected_branch=Немає захищених гілок.
23452332
settings.edit_protected_branch=Редагувати
@@ -2361,14 +2348,12 @@ settings.chat_id=ID чату
23612348
settings.matrix.homeserver_url=URL домашньої сторінки
23622349
settings.matrix.room_id=ID кімнати
23632350
settings.matrix.message_type=Тип повідомлення
2364-
settings.visibility.public.button=Зробити публічним
23652351
settings.archive.header=Відправити репозиторій в архів
23662352
settings.archive.success=Сховище успішно заархівовано.
23672353
settings.archive.error=Сталася помилка при спробі архівувати репозиторій. Докладнішу інформацію дивіться у журналі.
23682354
settings.archive.error_ismirror=Неможливо архівувати дзеркальне сховище.
23692355
settings.archive.branchsettings_unavailable=Параметри гілки не доступні, якщо репозиторій архівний.
23702356
settings.archive.tagsettings_unavailable=Параметри міток недоступні, якщо репозиторій архівний.
2371-
settings.unarchive.header=Розархівувати це сховище
23722357
settings.unarchive.success=Сховище успішно розархівовано.
23732358
settings.update_avatar_success=Аватар репозиторію оновлений.
23742359
settings.lfs=LFS
@@ -2452,7 +2437,6 @@ diff.protected=Захищений
24522437
diff.image.side_by_side=Поруч
24532438
diff.image.swipe=Провести пальцем
24542439
diff.image.overlay=Накласти
2455-
diff.has_escaped=Цей рядок містить приховані символи Юнікоду
24562440
diff.show_file_tree=Показати дерево файлів
24572441
diff.hide_file_tree=Сховати дерево файлів
24582442
diff.submodule_added=Підмодуль %[1]s додано в %[2]s
@@ -2765,7 +2749,6 @@ dashboard.resync_all_hooks=Заново синхронізувати хуки п
27652749
dashboard.reinit_missing_repos=Заново ініціалізувати всі відсутні сховища Git'а, для яких існують записи
27662750
dashboard.sync_external_users=Синхронізувати дані зовнішніх користувачів
27672751
dashboard.cleanup_hook_task_table=Очистити таблицю hook_task
2768-
dashboard.cleanup_actions=Очищення ресурсів прострочених дій
27692752
dashboard.server_uptime=Час роботи сервера
27702753
dashboard.current_goroutine=Поточна кількість Goroutines
27712754
dashboard.current_memory_usage=Поточне використання пам'яті
@@ -2795,11 +2778,7 @@ dashboard.total_gc_time=Загальна пауза збирача сміття
27952778
dashboard.total_gc_pause=Загальна пауза збирача сміття (GC)
27962779
dashboard.last_gc_pause=Остання пауза збирача сміття (GC)
27972780
dashboard.gc_times=Кількість запусків збирача сміття (GC)
2798-
dashboard.delete_old_actions=Видалити всі старі дії з бази даних
27992781
dashboard.update_checker=Перевірка оновлень
2800-
dashboard.gc_lfs=Збір сміття мета-об'єктів LFS
2801-
dashboard.cancel_abandoned_jobs=Скасувати покинуті завдання
2802-
dashboard.start_schedule_tasks=Запуск запланованих завдань
28032782
dashboard.sync_branch.started=Розпочато синхронізацію гілок
28042783
dashboard.rebuild_issue_indexer=Перебудувати індексатор задач
28052784
dashboard.sync_repo_licenses=Синхронізувати ліцензії сховища
@@ -2872,7 +2851,6 @@ emails.not_updated=Не вдалось оновити адресу електр
28722851
emails.duplicate_active=Ця адреса електронної пошти вже активна для іншого користувача.
28732852
emails.change_email_header=Редагувати властивості електронної пошти
28742853
emails.change_email_text=Ви впевнені, що хочете оновити адресу електронної пошти?
2875-
emails.delete=Видалити адресу електронної пошти
28762854
emails.delete_desc=Ви впевнені, що хочете видалити адресу електронної пошти?
28772855
emails.deletion_success=Адресу електронної пошти видалено.
28782856
emails.delete_primary_email_error=Ви не можете видалити основну адресу електронної пошти.
@@ -2893,7 +2871,6 @@ repos.issues=Задачі
28932871
repos.size=Розмір
28942872
repos.lfs_size=Розмір LFS
28952873
2896-
packages.package_manage_panel=Керування пакетами
28972874
packages.total_size=Загальний розмір: %s
28982875
packages.unreferenced_size=Розмір без посилань: %s
28992876
packages.cleanup=Очистити прострочені дані
@@ -3416,7 +3393,6 @@ settings.link=Прив'язати пакет до сховища
34163393
settings.link.description=Якщо ви зв'яжете пакет зі сховищем, його буде вказано у списку пакетів сховища.
34173394
settings.link.select=Обрати сховище
34183395
settings.link.button=Оновити посилання на сховище
3419-
settings.link.error=Не вдалося оновити посилання на сховище.
34203396
settings.delete=Видалити пакет
34213397
settings.delete.description=Видалення пакета є остаточним і не може бути скасоване.
34223398
settings.delete.notice=Ви збираєтесь видалити %s (%s). Цю операцію неможливо скасувати, ви впевнені?
@@ -3540,7 +3516,6 @@ logs.always_expand_running=Завжди розгортати поточні жу
35403516
[projects]
35413517
deleted.display_name=Видалений проєкт
35423518
type-1.display_name=Індивідуальний проєкт
3543-
type-2.display_name=Проєкт сховища
35443519
type-3.display_name=Проєкт організації
35453520
enter_fullscreen=Повноекранний режим
35463521
exit_fullscreen=Вийти з повноекранного режиму

0 commit comments

Comments
 (0)