Ref: #24638
IMO, parallelizing might run out server resources more quickly. Gitea
shouldn't use a lot of go-routine in a web handler.
And add a comment about how many repositories there could be at most.
Co-authored-by: Yarden Shoham <git@yardenshoham.com>
`http.ServeFile/ServeContent` handles `If-xxx`, `Content-Length`,
`Range` and `Etag` correctly
After this PR, storage files (eg: avatar) could be responded with
correct Content-Length.
Although some features are mixed together in this PR, this PR is not
that large, and these features are all related.
Actually there are more than 70 lines are for a toy "test queue", so
this PR is quite simple.
Major features:
1. Allow site admin to clear a queue (remove all items in a queue)
* Because there is no transaction, the "unique queue" could be corrupted
in rare cases, that's unfixable.
* eg: the item is in the "set" but not in the "list", so the item would
never be able to be pushed into the queue.
* Now site admin could simply clear the queue, then everything becomes
correct, the lost items could be re-pushed into queue by future
operations.
3. Split the "admin/monitor" to separate pages
4. Allow to download diagnosis report
* In history, there were many users reporting that Gitea queue gets
stuck, or Gitea's CPU is 100%
* With diagnosis report, maintainers could know what happens clearly
The diagnosis report sample:
[gitea-diagnosis-20230510-192913.zip](https://github.com/go-gitea/gitea/files/11441346/gitea-diagnosis-20230510-192913.zip)
, use "go tool pprof profile.dat" to view the report.
Screenshots:



---------
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: Giteabot <teabot@gitea.io>
According to the discussion with DanielGibson, the default "20m" seems
too short. It would make LFS fail if the file is large / network is
slow.
I think relaxing this timeout doesn't have side affect. So change the
default value to 24h, IMO that should be long enough.
## ⚠️ BREAKING
If admins want the previous timeout, they should set the setting
`[server].LFS_HTTP_AUTH_EXPIRY`.
Co-author: @pboguslawski
"registration success email" is only used for notifying a user that "you
have a new account now" when the account is created by admin manually.
When a user uses external auth source, they already knows that they has
the account, so do not send such email.
Co-authored-by: Giteabot <teabot@gitea.io>
Close#23711, thanks to @ghnp5 !
Close #24612, thanks to @DanielGibson !
Major changes:
* the default value of nginx's client_max_body_size is too small, so put
a 512M here
* move `Resolving Error: 413 Request Entity Too Large` to a sub-section
of `Nginx` section
* make nginx use unescaped the URI and keep "%2F" as is when using
sub-path
* add details for General sub-path configuration
1. Remove unused fields/methods in web context.
2. Make callers call target function directly instead of the light
wrapper like "IsUserRepoReaderSpecific"
3. The "issue template" code shouldn't be put in the "modules/context"
package, so move them to the service package.
---------
Co-authored-by: Giteabot <teabot@gitea.io>
# ⚠️ Breaking
Many deprecated queue config options are removed (actually, they should
have been removed in 1.18/1.19).
If you see the fatal message when starting Gitea: "Please update your
app.ini to remove deprecated config options", please follow the error
messages to remove these options from your app.ini.
Example:
```
2023/05/06 19:39:22 [E] Removed queue option: `[indexer].ISSUE_INDEXER_QUEUE_TYPE`. Use new options in `[queue.issue_indexer]`
2023/05/06 19:39:22 [E] Removed queue option: `[indexer].UPDATE_BUFFER_LEN`. Use new options in `[queue.issue_indexer]`
2023/05/06 19:39:22 [F] Please update your app.ini to remove deprecated config options
```
Many options in `[queue]` are are dropped, including:
`WRAP_IF_NECESSARY`, `MAX_ATTEMPTS`, `TIMEOUT`, `WORKERS`,
`BLOCK_TIMEOUT`, `BOOST_TIMEOUT`, `BOOST_WORKERS`, they can be removed
from app.ini.
# The problem
The old queue package has some legacy problems:
* complexity: I doubt few people could tell how it works.
* maintainability: Too many channels and mutex/cond are mixed together,
too many different structs/interfaces depends each other.
* stability: due to the complexity & maintainability, sometimes there
are strange bugs and difficult to debug, and some code doesn't have test
(indeed some code is difficult to test because a lot of things are mixed
together).
* general applicability: although it is called "queue", its behavior is
not a well-known queue.
* scalability: it doesn't seem easy to make it work with a cluster
without breaking its behaviors.
It came from some very old code to "avoid breaking", however, its
technical debt is too heavy now. It's a good time to introduce a better
"queue" package.
# The new queue package
It keeps using old config and concept as much as possible.
* It only contains two major kinds of concepts:
* The "base queue": channel, levelqueue, redis
* They have the same abstraction, the same interface, and they are
tested by the same testing code.
* The "WokerPoolQueue", it uses the "base queue" to provide "worker
pool" function, calls the "handler" to process the data in the base
queue.
* The new code doesn't do "PushBack"
* Think about a queue with many workers, the "PushBack" can't guarantee
the order for re-queued unhandled items, so in new code it just does
"normal push"
* The new code doesn't do "pause/resume"
* The "pause/resume" was designed to handle some handler's failure: eg:
document indexer (elasticsearch) is down
* If a queue is paused for long time, either the producers blocks or the
new items are dropped.
* The new code doesn't do such "pause/resume" trick, it's not a common
queue's behavior and it doesn't help much.
* If there are unhandled items, the "push" function just blocks for a
few seconds and then re-queue them and retry.
* The new code doesn't do "worker booster"
* Gitea's queue's handlers are light functions, the cost is only the
go-routine, so it doesn't make sense to "boost" them.
* The new code only use "max worker number" to limit the concurrent
workers.
* The new "Push" never blocks forever
* Instead of creating more and more blocking goroutines, return an error
is more friendly to the server and to the end user.
There are more details in code comments: eg: the "Flush" problem, the
strange "code.index" hanging problem, the "immediate" queue problem.
Almost ready for review.
TODO:
* [x] add some necessary comments during review
* [x] add some more tests if necessary
* [x] update documents and config options
* [x] test max worker / active worker
* [x] re-run the CI tasks to see whether any test is flaky
* [x] improve the `handleOldLengthConfiguration` to provide more
friendly messages
* [x] fine tune default config values (eg: length?)
## Code coverage:

The "modules/context.go" is too large to maintain.
This PR splits it to separate files, eg: context_request.go,
context_response.go, context_serve.go
This PR will help:
1. The future refactoring for Gitea's web context (eg: simplify the context)
2. Introduce proper "range request" support
3. Introduce context function
This PR only moves code, doesn't change any logic.
Help some users like #16832#1851
There are many users reporting similar problem: if the SECRET_KEY
mismatches, some operations (like 2FA login) only reports unclear 500
error and unclear "base64 decode error" log (some maintainers ever spent
a lot of time on debugging such problem)
The SECRET_KEY was not well-designed and it is also a kind of technical
debt. Since it couldn't be fixed easily, it's good to add clearer error
messages, then at least users could know what the real problem is.
---------
Co-authored-by: delvh <dev.lh@web.de>
The `..` should be covered by TestUserTitleToWebPath.
Otherwise, if the random string is "..", it causes unnecessary failure
in TestUserWebGitPathConsistency
Some old code doesn't respect the definition of `RequireSignInView` (the
`ignSignIn` is forgotten).
After #24413, this PR will do more fixes, ~~and rename the strange
`ignSignIn` to `optSignIn`.~~
This PR is ready for review, I think we can postpone the "ignSignIn"
renaming to another, to make this PR simple and clear.
---------
Co-authored-by: Giteabot <teabot@gitea.io>
Partially for #24457
Major changes:
1. The old `signedUserNameStringPointerKey` is quite hacky, use
`ctx.Data[SignedUser]` instead
2. Move duplicate code from `Contexter` to `CommonTemplateContextData`
3. Remove incorrect copying&pasting code `ctx.Data["Err_Password"] =
true` in API handlers
4. Use one unique `RenderPanicErrorPage` for panic error page rendering
5. Move `stripSlashesMiddleware` to be the first middleware
6. Install global panic recovery handler, it works for both `install`
and `web`
7. Make `500.tmpl` only depend minimal template functions/variables,
avoid triggering new panics
Screenshot:
<details>

</details>
I am not sure what "new-menu" means, but I think we need to fix these
problems:
1. it shouldn't have "stackable", which makes the items stacked when
width is small. the `new-menu` already has `overflow: auto`
2. `justify-content: center` doesn't work with `overflow: auto` (for
small width), so use `margin: auto`
*
https://bhch.github.io/posts/2021/04/centring-flex-items-and-allowing-overflow-scroll/
3. `runner-new-menu` is dead code (copying & pasting ?)
Partial regression of #24393, not only regression, but broken for long
time, 24393 didn't really improve it but used wrong `overflow: scroll`.
Actually, that "ui secondary filter menu labels" shouldn't be set as
scrollable (I missed that at that time), the problem is: if a "ui menu"
has "dropdown" items, then it should not be scrollable. Otherwise the
dropdown menu can't be shown correctly.
And there are more problems:
* The "issue-filters" shouldn't be used anywhere else (copying&pasting
problem again ....)
* There is also an "issue-actions" container, it should also be fixed.
* There are similar problems on the milestone page.
* The old comment in code: "grid column" doesn't work well.
The major changes of this PR are: use "flex: 1" instead of "ui grid
column".
After this PR, not 100% perfect but much better than before.
The old `HTMLRender` is not ideal.
1. It shouldn't be initialized multiple times, it consumes a lot of
memory and is slow.
2. It shouldn't depend on short-lived requests, the `WatchLocalChanges`
needs a long-running context.
3. It doesn't make sense to use FuncsMap slice.
HTMLRender was designed to only work for GItea's specialized 400+
templates, so it's good to make it a global shared instance.
There was only one `IsRepositoryExist` function, it did: `has && isDir`
However it's not right, and it would cause 500 error when creating a new
repository if the dir exists.
Then, it was changed to `has || isDir`, it is still incorrect, it
affects the "adopt repo" logic.
To make the logic clear:
* IsRepositoryModelOrDirExist
* IsRepositoryModelExist
Follow #22719
### Major changes
1. `ServerError` doesn't do format, so remove the `%s`
2. Simplify `RenderBranchFeed` (slightly)
3. Remove unused `BranchFeedRSS`
4. Make `feed.RenderBranchFeed` respect `EnableFeed` config
5. Make `RepoBranchTagSelector.vue` respect `EnableFeed` setting,
otherwise there is always RSS icon
6. The `(branchURLPrefix + item.url).replace('src', 'rss')` doesn't seem
right for all cases, for example, the string `src` could appear in
`branchURLPrefix`, so we need a separate `rssURLPrefix`
7. The `<a>` in Vue menu needs `@click.stop`, otherwise the menu itself
would be triggered at the same time
8. Change `<a><button></button></a>` to `<a role=button>`
9. Use `{{PathEscapeSegments .TreePath}}` instead of `{{range $i, $v :=
.TreeNames}}/{{$v}}{{end}}`
Screenshot of changed parts:
<details>



</details>
### Other thoughts
Should we remove the RSS icon from the branch dropdown list? It seems
too complex for a list UI, and users already have the chance to get the
RSS feed URL from "branches" page.
---------
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: silverwind <me@silverwind.io>
The Infinite Monkey Random Typing catches a bug, inconsistent wiki path
converting.
Close#24276
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Giteabot <teabot@gitea.io>
The `SHOW_FOOTER_BRANDING` came from year 2015, and it seems nobody ever
uses it. It only shows an GitHub icon which seems unrelated to Gitea, it
doesn't do what document says. So, remove it.
## ⚠️ Breaking
Users can now remove the key `[other].SHOW_FOOTER_BRANDING` from their
app.ini.
Follow #23328
The improvements:
1. The `contains` functions are covered by tests
2. The inconsistent behavior of `containGeneric` is replaced by
`StringUtils.Contains` and `SliceUtils.Contains`
3. In the future we can move more help functions into XxxUtils to
simplify the `helper.go` and reduce unnecessary global functions.
FAQ:
1. Why it's called `StringUtils.Contains` but not `strings.Contains`
like Golang?
Because our `StringUtils` is not Golang's `strings` package. There will
be our own string functions.
---------
Co-authored-by: silverwind <me@silverwind.io>
Before, there was a `log/buffer.go`, but that design is not general, and
it introduces a lot of irrelevant `Content() (string, error) ` and
`return "", fmt.Errorf("not supported")` .
And the old `log/buffer.go` is difficult to use, developers have to
write a lot of `Contains` and `Sleep` code.
The new `LogChecker` is designed to be a general approach to help to
assert some messages appearing or not appearing in logs.
The old code is unnecessarily complex, and has many misuses.
Old code "wraps" a lot, wrap wrap wrap, it's difficult to understand
which kind of handler is used.
The new code uses a general approach, we do not need to write all kinds
of handlers into the "wrapper", do not need to wrap them again and
again.
New code, there are only 2 concepts:
1. HandlerProvider: `func (h any) (handlerProvider func (next)
http.Handler)`, it can be used as middleware
2. Use HandlerProvider to get the final HandlerFunc, and use it for
`r.Get()`
And we can decouple the route package from context package (see the
TODO).
# FAQ
## Is `reflect` safe?
Yes, all handlers are checked during startup, see the `preCheckHandler`
comment. If any handler is wrong, developers could know it in the first
time.
## Does `reflect` affect performance?
No. https://github.com/go-gitea/gitea/pull/24080#discussion_r1164825901
1. This reflect code only runs for each web handler call, handler is far
more slower: 10ms-50ms
2. The reflect is pretty fast (comparing to other code): 0.000265ms
3. XORM has more reflect operations already
# Background
Golang template is not friendly for large projects, and Golang template
team is quite slow, related:
* `https://github.com/golang/go/issues/54450`
Without upstream support, we can also have our solution to make HTML
template functions support context.
It helps a lot, the above Golang template issue `#54450` explains a lot:
1. It makes `{{Locale.Tr}}` could be used in any template, without
passing unclear `(dict "root" . )` anymore.
2. More and more functions need `context`, like `avatar`, etc, we do not
need to do `(dict "Context" $.Context)` anymore.
3. Many request-related functions could be shared by parent&children
templates, like "user setting" / "system setting"
See the test `TestScopedTemplateSetFuncMap`, one template set, two
`Execute` calls with different `CtxFunc`.
# The Solution
Instead of waiting for upstream, this PR re-uses the escaped HTML
template trees, use `AddParseTree` to add related templates/trees to a
new template instance, then the new template instance can have its own
FuncMap , the function calls in the template trees will always use the
new template's FuncMap.
`template.New` / `template.AddParseTree` / `adding-FuncMap` are all
quite fast, so the performance is not affected.
The details:
1. Make a new `html/template/Template` for `all` templates
2. Add template code to the `all` template
3. Freeze the `all` template, reset its exec func map, it shouldn't
execute any template.
4. When a router wants to render a template by its `name`
1. Find the `name` in `all`
2. Find all its related sub templates
3. Escape all related templates (just like what the html template
package does)
4. Add the escaped parse-trees of related templates into a new (scoped)
`text/template/Template`
5. Add context-related func map into the new (scoped) text template
6. Execute the new (scoped) text template
7. To improve performance, the escaped templates are cached to `template
sets`
# FAQ
## There is a `unsafe` call, is this PR unsafe?
This PR is safe. Golang has strict language definition, it's safe to do
so: https://pkg.go.dev/unsafe#Pointer (1) Conversion of a *T1 to Pointer
to *T2
## What if Golang template supports such feature in the future?
The public structs/interfaces/functions introduced by this PR is quite
simple, the code of `HTMLRender` is not changed too much. It's very easy
to switch to the official mechanism if there would be one.
## Does this PR change the template execution behavior?
No, see the tests (welcome to design more tests if it's necessary)
---------
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Close#24195
Some of the changes are taken from my another fix
https://github.com/go-gitea/gitea/pull/20147/commits/f07b0de997125c9b79cc5af27966a7cdd1803a4d
in #20147 (although that PR was discarded ....)
The bug is:
1. The old code doesn't handle `removedfile` event correctly
2. The old code doesn't provide attachments for type=CommentTypeReview
This PR doesn't intend to refactor the "upload" code to a perfect state
(to avoid making the review difficult), so some legacy styles are kept.
---------
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Giteabot <teabot@gitea.io>
Close#7570
1. Clearly define the wiki path behaviors, see
`services/wiki/wiki_path.go` and tests
2. Keep compatibility with old contents
3. Allow to use dashes in titles, eg: "2000-01-02 Meeting record"
4. Add a "Pages" link in the dropdown, otherwise users can't go to the
Pages page easily.
5. Add a "View original git file" link in the Pages list, even if some
file names are broken, users still have a chance to edit or remove it,
without cloning the wiki repo to local.
6. Fix 500 error when the name contains prefix spaces.
This PR also introduces the ability to support sub-directories, but it
can't be done at the moment due to there are a lot of legacy wiki data,
which use "%2F" in file names.


Co-authored-by: Giteabot <teabot@gitea.io>
The old code has a lot of technical debts, eg: `repo/wiki/view.tmpl` /
`Iterate`
This PR improves the Wiki TOC display and improves the code.
---------
Co-authored-by: delvh <dev.lh@web.de>
According to erion's feedback, the 1.18 approach works with Safari
(`role=menu` on the parent container), while the 1.19's approach doesn't
work well with Safari+VoiceOver (although I tested it worked with Chrome
a little better).
I have tested this 1.18 approach could work for all
Safari/Chrome+VoiceOver and Chrome+Talkback.
Let's try to make it on try.gitea.io to see whether it helps Safari
users.
Close#24062
At the beginning, I just wanted to fix the warning mentioned by #24062
But, the cookie code really doesn't look good to me, so clean up them.
Complete the TODO on `SetCookie`:
> TODO: Copied from gitea.com/macaron/macaron and should be improved
after macaron removed.
The idea is to use a Layered Asset File-system (modules/assetfs/layered.go)
For example: when there are 2 layers: "custom", "builtin", when access
to asset "my/page.tmpl", the Layered Asset File-system will first try to
use "custom" assets, if not found, then use "builtin" assets.
This approach will hugely simplify a lot of code, make them testable.
Other changes:
* Simplify the AssetsHandlerFunc code
* Simplify the `gitea embedded` sub-command code
---------
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
1. Remove unnecessary `btn-link` `muted` classes
* Link is link, button is button, I can't see a real requirement to make
a button like a link.
* If anyone insists, please help to show me real example from modern
frameworks / websites, how and why they do so.
* No need to duplicate a lot of class names on similar elements
* Declare styles clearly, for example, `markdown-toolbar` itself should
have `display: flex`, but not use `gt-df` to overwrite the `display:
block`.
2. Remove unnecessary `role` attribute
* https://github.com/github/markdown-toolbar-element/issues/70
* The `markdown-toolbar-element` does want to add `role=button`, but
there is a bug.
* So we do the similar thing as upstream does (add the role by JS),
until they fix their bugs.
3. Indent `markdown-switch-easymde` (before it doesn't have a proper
indent)
Screenshot:

Close#24002
Two problems before:
1. The `log.Fatal` is missing after these `wrapFatal` calls, so the
error is not shown to users.
2. `GetTemplateAssetNames` has different behaviors for local files and
builtin assets, for builtin assets, it also returns directories, so we
need to check the extension again.
I have tested with `TAGS="bindata sqlite sqlite_unlock_notify" make
build && ./gitea` , it works well now. Before, the server responds
internal server error (because it doesn't complete the template parsing)
None of the features of `unrolled/render` package is used.
The Golang builtin "html/template" just works well. Then we can improve
our HTML render to resolve the "$.root.locale.Tr" problem as much as
possible.
Next step: we can have a template render pool (by Clone), then we can
inject global functions with dynamic context to every `Execute` calls.
Then we can use `{{Locale.Tr ....}}` directly in all templates , no need
to pass the `$.root.locale` again and again.
One of the steps in #23328
Before there were 3 different but similar functions: dict/Dict/mergeinto
The code was just copied & pasted, no test.
This PR defines a new stable `dict` function, it covers all the 3 old
functions behaviors, only +160 -171
Future developers do not need to think about or guess the different dict
functions, just use one: `dict`
Why use `dict` but not `Dict`? Because there are far more `dict` than
`Dict` in code already ......
One of the proposals in #23328
This PR introduces a simple expression calculator
(templates/eval/eval.go), it can do basic expression calculations.
Many untested template helper functions like `Mul` `Add` can be replaced
by this new approach.
Then these `Add` / `Mul` / `percentage` / `Subtract` / `DiffStatsWidth`
could all use this `Eval`.
And it provides enhancements for Golang templates, and improves
readability.
Some examples:
----
* Before: `{{Add (Mul $glyph.Row 12) 12}}`
* After: `{{Eval $glyph.Row "*" 12 "+" 12}}`
----
* Before: `{{if lt (Add $i 1) (len $.Topics)}}`
* After: `{{if Eval $i "+" 1 "<" (len $.Topics)}}`
## FAQ
### Why not use an existing expression package?
We need a highly customized expression engine:
* do the calculation on the fly, without pre-compiling
* deal with int/int64/float64 types, to make the result could be used in
Golang template.
* make the syntax could be used in the Golang template directly
* do not introduce too much complex or strange syntax, we just need a
simple calculator.
* it needs to strictly follow Golang template's behavior, for example,
Golang template treats all non-zero values as truth, but many 3rd
packages don't do so.
### What's the benefit?
* Developers don't need to add more `Add`/`Mul`/`Sub`-like functions,
they were getting more and more.
Now, only one `Eval` is enough for all cases.
* The new code reads better than old `{{Add (Mul $glyph.Row 12) 12}}`,
the old one isn't familiar to most procedural programming developers
(eg, the Golang expression syntax).
* The `Eval` is fully covered by tests, many old `Add`/`Mul`-like
functions were never tested.
### The performance?
It doesn't use `reflect`, it doesn't need to parse or compile when used
in Golang template, the performance is as fast as native Go template.
### Is it too complex? Could it be unstable?
The expression calculator program is a common homework for computer
science students, and it's widely used as a teaching and practicing
purpose for developers. The algorithm is pretty well-known.
The behavior can be clearly defined, it is stable.
The first step of #23328
This PR cleans:
1. Dead function like `SubStr`
2. Unnecessary function like `UseHTTPS`, it should be provided by
`window.origin`
3. Duplicate function like `IsShowFullName`, there was already a
`DeafultShowFullName`
I have searched these removed functions globally, no use in code.
When doing the refactoring:
* #22950
I added some debug mode code (assertShown) to help to catch bugs, it did
catch some bugs like:
* #23074
If it has been proved that there is no more bugs, this assertion could
be removed easily and clearly.
Feel free to decide when to remove it (feel free to convert it from
Draft to Ready for Review).
cc: @silverwind
Caught by @justusbunsi
An old bug from #6488
In `pullrequest_targetbranch_change`, the `data` might be empty, because
`UpdatePullRequestTarget` may respond `http.StatusNoContent`.
And the old code's `$branchTarget.text(data.base_branch);` doesn't make
sense, because in the end, the page will be always reloaded.
So, just remove the `$branchTarget.text(data.base_branch);`, everything
should be fine.
Close#23680
Some CLI programs use "\r" and control chars to print new content in
current line.
So, the strings in one line are actually from
`\rReading...1%\rReading...5%\rReading...100%`
This PR tries to make the output better.