Skip to content

Commit 85c59d6

Browse files
KN4CK3Rsilverwind
andauthored
Use relative links for commits, mentions, and issues in markdown (#29427)
Fixes #29404 Use relative links for - commits - mentions - issues --------- Co-authored-by: silverwind <[email protected]>
1 parent 66edc88 commit 85c59d6

File tree

9 files changed

+65
-26
lines changed

9 files changed

+65
-26
lines changed

modules/markup/html.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) {
609609
if ok && strings.Contains(mention, "/") {
610610
mentionOrgAndTeam := strings.Split(mention, "/")
611611
if mentionOrgAndTeam[0][1:] == ctx.Metas["org"] && strings.Contains(teams, ","+strings.ToLower(mentionOrgAndTeam[1])+",") {
612-
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, "org", ctx.Metas["org"], "teams", mentionOrgAndTeam[1]), mention, "mention"))
612+
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), "org", ctx.Metas["org"], "teams", mentionOrgAndTeam[1]), mention, "mention"))
613613
node = node.NextSibling.NextSibling
614614
start = 0
615615
continue
@@ -620,7 +620,7 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) {
620620
mentionedUsername := mention[1:]
621621

622622
if DefaultProcessorHelper.IsUsernameMentionable != nil && DefaultProcessorHelper.IsUsernameMentionable(ctx.Ctx, mentionedUsername) {
623-
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, mentionedUsername), mention, "mention"))
623+
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), mentionedUsername), mention, "mention"))
624624
node = node.NextSibling.NextSibling
625625
} else {
626626
node = node.NextSibling
@@ -898,9 +898,9 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
898898
path = "pulls"
899899
}
900900
if ref.Owner == "" {
901-
link = createLink(util.URLJoin(setting.AppURL, ctx.Metas["user"], ctx.Metas["repo"], path, ref.Issue), reftext, "ref-issue")
901+
link = createLink(util.URLJoin(ctx.Links.Prefix(), ctx.Metas["user"], ctx.Metas["repo"], path, ref.Issue), reftext, "ref-issue")
902902
} else {
903-
link = createLink(util.URLJoin(setting.AppURL, ref.Owner, ref.Name, path, ref.Issue), reftext, "ref-issue")
903+
link = createLink(util.URLJoin(ctx.Links.Prefix(), ref.Owner, ref.Name, path, ref.Issue), reftext, "ref-issue")
904904
}
905905
}
906906

@@ -939,7 +939,7 @@ func commitCrossReferencePatternProcessor(ctx *RenderContext, node *html.Node) {
939939
}
940940

941941
reftext := ref.Owner + "/" + ref.Name + "@" + base.ShortSha(ref.CommitSha)
942-
link := createLink(util.URLJoin(setting.AppSubURL, ref.Owner, ref.Name, "commit", ref.CommitSha), reftext, "commit")
942+
link := createLink(util.URLJoin(ctx.Links.Prefix(), ref.Owner, ref.Name, "commit", ref.CommitSha), reftext, "commit")
943943

944944
replaceContent(node, ref.RefLocation.Start, ref.RefLocation.End, link)
945945
node = node.NextSibling.NextSibling
@@ -1166,7 +1166,7 @@ func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
11661166
continue
11671167
}
11681168

1169-
link := util.URLJoin(setting.AppURL, ctx.Metas["user"], ctx.Metas["repo"], "commit", hash)
1169+
link := util.URLJoin(ctx.Links.Prefix(), ctx.Metas["user"], ctx.Metas["repo"], "commit", hash)
11701170
replaceContent(node, m[2], m[3], createCodeLink(link, base.ShortSha(hash), "commit"))
11711171
start = 0
11721172
node = node.NextSibling.NextSibling

modules/markup/html_internal_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ func TestRender_IssueIndexPattern_Document(t *testing.T) {
287287
}
288288

289289
func testRenderIssueIndexPattern(t *testing.T, input, expected string, ctx *RenderContext) {
290+
ctx.Links.AbsolutePrefix = true
290291
if ctx.Links.Base == "" {
291292
ctx.Links.Base = TestRepoURL
292293
}

modules/markup/html_test.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ func TestRender_Commits(t *testing.T) {
4343
Ctx: git.DefaultContext,
4444
RelativePath: ".md",
4545
Links: markup.Links{
46-
Base: markup.TestRepoURL,
46+
AbsolutePrefix: true,
47+
Base: markup.TestRepoURL,
4748
},
4849
Metas: localMetas,
4950
}, input)
@@ -96,7 +97,8 @@ func TestRender_CrossReferences(t *testing.T) {
9697
Ctx: git.DefaultContext,
9798
RelativePath: "a.md",
9899
Links: markup.Links{
99-
Base: setting.AppSubURL,
100+
AbsolutePrefix: true,
101+
Base: setting.AppSubURL,
100102
},
101103
Metas: localMetas,
102104
}, input)
@@ -588,7 +590,8 @@ func TestPostProcess_RenderDocument(t *testing.T) {
588590
err := markup.PostProcess(&markup.RenderContext{
589591
Ctx: git.DefaultContext,
590592
Links: markup.Links{
591-
Base: "https://example.com",
593+
AbsolutePrefix: true,
594+
Base: "https://example.com",
592595
},
593596
Metas: localMetas,
594597
}, strings.NewReader(input), &res)

modules/markup/markdown/markdown_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
130130
<li><a href="` + baseURLContent + `/Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li>
131131
<li><a href="` + baseURLContent + `/Tips" rel="nofollow">Tips</a></li>
132132
</ul>
133-
<p>See commit <a href="http://localhost:3000/gogits/gogs/commit/65f1bf27bc" rel="nofollow"><code>65f1bf27bc</code></a></p>
133+
<p>See commit <a href="/gogits/gogs/commit/65f1bf27bc" rel="nofollow"><code>65f1bf27bc</code></a></p>
134134
<p>Ideas and codes</p>
135135
<ul>
136-
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/ocornut/imgui/issues/786" class="ref-issue" rel="nofollow">ocornut/imgui#786</a></li>
137-
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/gogits/gogs/issues/786" class="ref-issue" rel="nofollow">#786</a></li>
136+
<li>Bezier widget (by <a href="/r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/ocornut/imgui/issues/786" class="ref-issue" rel="nofollow">ocornut/imgui#786</a></li>
137+
<li>Bezier widget (by <a href="/r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/gogits/gogs/issues/786" class="ref-issue" rel="nofollow">#786</a></li>
138138
<li>Node graph editors <a href="https://github.com/ocornut/imgui/issues/306" rel="nofollow">https://github.com/ocornut/imgui/issues/306</a></li>
139139
<li><a href="` + baseURLContent + `/memory_editor_example" rel="nofollow">Memory Editor</a></li>
140140
<li><a href="` + baseURLContent + `/plot_var_example" rel="nofollow">Plot var helper</a></li>

modules/markup/renderer.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,17 @@ type RenderContext struct {
8282
}
8383

8484
type Links struct {
85-
Base string
86-
BranchPath string
87-
TreePath string
85+
AbsolutePrefix bool
86+
Base string
87+
BranchPath string
88+
TreePath string
89+
}
90+
91+
func (l *Links) Prefix() string {
92+
if l.AbsolutePrefix {
93+
return setting.AppURL
94+
}
95+
return setting.AppSubURL
8896
}
8997

9098
func (l *Links) HasBranchInfo() bool {

modules/templates/util_render_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,21 +117,21 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a582
117117
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
118118
<span class="emoji" aria-label="thumbs up">👍</span>
119119
<a href="mailto:[email protected]" class="mailto">[email protected]</a>
120-
<a href="http://localhost:3000/mention-user" class="mention">@mention-user</a> test
121-
<a href="http://localhost:3000/user13/repo11/issues/123" class="ref-issue">#123</a>
120+
<a href="/mention-user" class="mention">@mention-user</a> test
121+
<a href="/user13/repo11/issues/123" class="ref-issue">#123</a>
122122
space`
123123

124124
assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput, testMetas))
125125
}
126126

127127
func TestRenderCommitMessage(t *testing.T) {
128-
expected := `space <a href="http://localhost:3000/mention-user" class="mention">@mention-user</a> `
128+
expected := `space <a href="/mention-user" class="mention">@mention-user</a> `
129129

130130
assert.EqualValues(t, expected, RenderCommitMessage(context.Background(), testInput, testMetas))
131131
}
132132

133133
func TestRenderCommitMessageLinkSubject(t *testing.T) {
134-
expected := `<a href="https://example.com/link" class="default-link muted">space </a><a href="http://localhost:3000/mention-user" class="mention">@mention-user</a>`
134+
expected := `<a href="https://example.com/link" class="default-link muted">space </a><a href="/mention-user" class="mention">@mention-user</a>`
135135

136136
assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput, "https://example.com/link", testMetas))
137137
}
@@ -155,14 +155,14 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
155155
<span class="emoji" aria-label="thumbs up">👍</span>
156156
157157
@mention-user test
158-
<a href="http://localhost:3000/user13/repo11/issues/123" class="ref-issue">#123</a>
158+
<a href="/user13/repo11/issues/123" class="ref-issue">#123</a>
159159
space
160160
`
161161
assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput, testMetas))
162162
}
163163

164164
func TestRenderMarkdownToHtml(t *testing.T) {
165-
expected := `<p>space <a href="http://localhost:3000/mention-user" rel="nofollow">@mention-user</a><br/>
165+
expected := `<p>space <a href="/mention-user" rel="nofollow">@mention-user</a><br/>
166166
/just/a/path.bin
167167
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a>
168168
<a href="/file.bin" rel="nofollow">local link</a>
@@ -179,7 +179,7 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a582
179179
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
180180
<span class="emoji" aria-label="thumbs up">👍</span>
181181
<a href="mailto:[email protected]" rel="nofollow">[email protected]</a>
182-
<a href="http://localhost:3000/mention-user" rel="nofollow">@mention-user</a> test
182+
<a href="/mention-user" rel="nofollow">@mention-user</a> test
183183
#123
184184
space</p>
185185
`

routers/common/markup.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
3434
if err := markdown.RenderRaw(&markup.RenderContext{
3535
Ctx: ctx,
3636
Links: markup.Links{
37-
Base: urlPrefix,
37+
AbsolutePrefix: true,
38+
Base: urlPrefix,
3839
},
3940
}, strings.NewReader(text), ctx.Resp); err != nil {
4041
ctx.Error(http.StatusInternalServerError, err.Error())
@@ -79,7 +80,8 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
7980
if err := markup.Render(&markup.RenderContext{
8081
Ctx: ctx,
8182
Links: markup.Links{
82-
Base: urlPrefix,
83+
AbsolutePrefix: true,
84+
Base: urlPrefix,
8385
},
8486
Metas: meta,
8587
IsWiki: wiki,

services/mailer/mail.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
222222
body, err := markdown.RenderString(&markup.RenderContext{
223223
Ctx: ctx,
224224
Links: markup.Links{
225-
Base: ctx.Issue.Repo.HTMLURL(),
225+
AbsolutePrefix: true,
226+
Base: ctx.Issue.Repo.HTMLURL(),
226227
},
227228
Metas: ctx.Issue.Repo.ComposeMetas(ctx),
228229
}, ctx.Content)

services/mailer/mail_test.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"context"
99
"fmt"
1010
"html/template"
11+
"io"
12+
"mime/quotedprintable"
1113
"regexp"
1214
"strings"
1315
"testing"
@@ -19,6 +21,7 @@ import (
1921
repo_model "code.gitea.io/gitea/models/repo"
2022
"code.gitea.io/gitea/models/unittest"
2123
user_model "code.gitea.io/gitea/models/user"
24+
"code.gitea.io/gitea/modules/markup"
2225
"code.gitea.io/gitea/modules/setting"
2326

2427
"github.com/stretchr/testify/assert"
@@ -67,6 +70,12 @@ func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Re
6770
func TestComposeIssueCommentMessage(t *testing.T) {
6871
doer, _, issue, comment := prepareMailerTest(t)
6972

73+
markup.Init(&markup.ProcessorHelper{
74+
IsUsernameMentionable: func(ctx context.Context, username string) bool {
75+
return username == doer.Name
76+
},
77+
})
78+
7079
setting.IncomingEmail.Enabled = true
7180
defer func() { setting.IncomingEmail.Enabled = false }()
7281

@@ -77,7 +86,8 @@ func TestComposeIssueCommentMessage(t *testing.T) {
7786
msgs, err := composeIssueCommentMessages(&mailCommentContext{
7887
Context: context.TODO(), // TODO: use a correct context
7988
Issue: issue, Doer: doer, ActionType: activities_model.ActionCommentIssue,
80-
Content: "test body", Comment: comment,
89+
Content: fmt.Sprintf("test @%s %s#%d body", doer.Name, issue.Repo.FullName(), issue.Index),
90+
Comment: comment,
8191
}, "en-US", recipients, false, "issue comment")
8292
assert.NoError(t, err)
8393
assert.Len(t, msgs, 2)
@@ -96,6 +106,20 @@ func TestComposeIssueCommentMessage(t *testing.T) {
96106
assert.Equal(t, "<user2/repo1/issues/1/comment/2@localhost>", gomailMsg.GetHeader("Message-ID")[0], "Message-ID header doesn't match")
97107
assert.Equal(t, "<mailto:"+replyTo+">", gomailMsg.GetHeader("List-Post")[0])
98108
assert.Len(t, gomailMsg.GetHeader("List-Unsubscribe"), 2) // url + mailto
109+
110+
var buf bytes.Buffer
111+
gomailMsg.WriteTo(&buf)
112+
113+
b, err := io.ReadAll(quotedprintable.NewReader(&buf))
114+
assert.NoError(t, err)
115+
116+
// text/plain
117+
assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, doer.HTMLURL()))
118+
assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, issue.HTMLURL()))
119+
120+
// text/html
121+
assert.Contains(t, string(b), fmt.Sprintf(`href="%s"`, doer.HTMLURL()))
122+
assert.Contains(t, string(b), fmt.Sprintf(`href="%s"`, issue.HTMLURL()))
99123
}
100124

101125
func TestComposeIssueMessage(t *testing.T) {

0 commit comments

Comments
 (0)