Skip to content

Commit 188dbb1

Browse files
authored
Merge branch 'main' into appearance-prefs
2 parents 11f5acc + 649e1d0 commit 188dbb1

File tree

29 files changed

+1491
-64
lines changed

29 files changed

+1491
-64
lines changed

docs/content/doc/usage/reverse-proxies.en-us.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,50 @@ If you wish to run Gitea with IIS. You will need to setup IIS with URL Rewrite a
292292
</system.webServer>
293293
</configuration>
294294
```
295+
296+
## HAProxy
297+
298+
If you want HAProxy to serve your Gitea instance, you can add the following to your HAProxy configuration
299+
300+
add an acl in the frontend section to redirect calls to gitea.example.com to the correct backend
301+
```
302+
frontend http-in
303+
...
304+
acl acl_gitea hdr(host) -i gitea.example.com
305+
use_backend gitea if acl_gitea
306+
...
307+
```
308+
309+
add the previously defined backend section
310+
```
311+
backend gitea
312+
server localhost:3000 check
313+
```
314+
315+
If you redirect the http content to https, the configuration work the same way, just remember that the connexion between HAProxy and Gitea will be done via http so you do not have to enable https in Gitea's configuration.
316+
317+
## HAProxy with a sub-path
318+
319+
In case you already have a site, and you want Gitea to share the domain name, you can setup HAProxy to serve Gitea under a sub-path by adding the following to you HAProxy configuration:
320+
321+
```
322+
frontend http-in
323+
...
324+
acl acl_gitea path_beg /gitea
325+
use_backend gitea if acl_gitea
326+
...
327+
```
328+
329+
With that configuration http://example.com/gitea/ will redirect to your Gitea instance.
330+
331+
then for the backend section
332+
```
333+
backend gitea
334+
http-request replace-path /gitea\/?(.*) \/\1
335+
server localhost:3000 check
336+
```
337+
338+
The added http-request will automatically add a trailing slash if needed and internally remove /gitea from the path to allow it to work correctly with Gitea by setting properly http://example.com/gitea as the root.
339+
340+
Then you **MUST** set something like `[server] ROOT_URL = http://example.com/gitea/` correctly in your configuration.
341+

integrations/api_wiki_test.go

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package integrations
6+
7+
import (
8+
"encoding/base64"
9+
"fmt"
10+
"net/http"
11+
"testing"
12+
13+
api "code.gitea.io/gitea/modules/structs"
14+
15+
"github.com/stretchr/testify/assert"
16+
)
17+
18+
func TestAPIGetWikiPage(t *testing.T) {
19+
defer prepareTestEnv(t)()
20+
21+
username := "user2"
22+
session := loginUser(t, username)
23+
24+
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/page/Home", username, "repo1")
25+
26+
req := NewRequest(t, "GET", urlStr)
27+
resp := session.MakeRequest(t, req, http.StatusOK)
28+
var page *api.WikiPage
29+
DecodeJSON(t, resp, &page)
30+
31+
assert.Equal(t, &api.WikiPage{
32+
WikiPageMetaData: &api.WikiPageMetaData{
33+
Title: "Home",
34+
HTMLURL: page.HTMLURL,
35+
SubURL: "Home",
36+
LastCommit: &api.WikiCommit{
37+
ID: "2c54faec6c45d31c1abfaecdab471eac6633738a",
38+
Author: &api.CommitUser{
39+
Identity: api.Identity{
40+
Name: "Ethan Koenig",
41+
42+
},
43+
Date: "2017-11-27T04:31:18Z",
44+
},
45+
Committer: &api.CommitUser{
46+
Identity: api.Identity{
47+
Name: "Ethan Koenig",
48+
49+
},
50+
Date: "2017-11-27T04:31:18Z",
51+
},
52+
Message: "Add Home.md\n",
53+
},
54+
},
55+
ContentBase64: base64.RawStdEncoding.EncodeToString(
56+
[]byte("# Home page\n\nThis is the home page!\n"),
57+
),
58+
CommitCount: 1,
59+
Sidebar: "",
60+
Footer: "",
61+
}, page)
62+
}
63+
64+
func TestAPIListWikiPages(t *testing.T) {
65+
defer prepareTestEnv(t)()
66+
67+
username := "user2"
68+
session := loginUser(t, username)
69+
70+
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/pages", username, "repo1")
71+
72+
req := NewRequest(t, "GET", urlStr)
73+
resp := session.MakeRequest(t, req, http.StatusOK)
74+
75+
var meta []*api.WikiPageMetaData
76+
DecodeJSON(t, resp, &meta)
77+
78+
dummymeta := []*api.WikiPageMetaData{
79+
{
80+
Title: "Home",
81+
HTMLURL: meta[0].HTMLURL,
82+
SubURL: "Home",
83+
LastCommit: &api.WikiCommit{
84+
ID: "2c54faec6c45d31c1abfaecdab471eac6633738a",
85+
Author: &api.CommitUser{
86+
Identity: api.Identity{
87+
Name: "Ethan Koenig",
88+
89+
},
90+
Date: "2017-11-27T04:31:18Z",
91+
},
92+
Committer: &api.CommitUser{
93+
Identity: api.Identity{
94+
Name: "Ethan Koenig",
95+
96+
},
97+
Date: "2017-11-27T04:31:18Z",
98+
},
99+
Message: "Add Home.md\n",
100+
},
101+
},
102+
{
103+
Title: "Page With Image",
104+
HTMLURL: meta[1].HTMLURL,
105+
SubURL: "Page-With-Image",
106+
LastCommit: &api.WikiCommit{
107+
ID: "0cf15c3f66ec8384480ed9c3cf87c9e97fbb0ec3",
108+
Author: &api.CommitUser{
109+
Identity: api.Identity{
110+
Name: "Gabriel Silva Simões",
111+
112+
},
113+
Date: "2019-01-25T01:41:55Z",
114+
},
115+
Committer: &api.CommitUser{
116+
Identity: api.Identity{
117+
Name: "Gabriel Silva Simões",
118+
119+
},
120+
Date: "2019-01-25T01:41:55Z",
121+
},
122+
Message: "Add jpeg.jpg and page with image\n",
123+
},
124+
},
125+
{
126+
Title: "Page With Spaced Name",
127+
HTMLURL: meta[2].HTMLURL,
128+
SubURL: "Page-With-Spaced-Name",
129+
LastCommit: &api.WikiCommit{
130+
ID: "c10d10b7e655b3dab1f53176db57c8219a5488d6",
131+
Author: &api.CommitUser{
132+
Identity: api.Identity{
133+
Name: "Gabriel Silva Simões",
134+
135+
},
136+
Date: "2019-01-25T01:39:51Z",
137+
},
138+
Committer: &api.CommitUser{
139+
Identity: api.Identity{
140+
Name: "Gabriel Silva Simões",
141+
142+
},
143+
Date: "2019-01-25T01:39:51Z",
144+
},
145+
Message: "Add page with spaced name\n",
146+
},
147+
},
148+
{
149+
Title: "Unescaped File",
150+
HTMLURL: meta[3].HTMLURL,
151+
SubURL: "Unescaped-File",
152+
LastCommit: &api.WikiCommit{
153+
ID: "0dca5bd9b5d7ef937710e056f575e86c0184ba85",
154+
Author: &api.CommitUser{
155+
Identity: api.Identity{
156+
Name: "6543",
157+
158+
},
159+
Date: "2021-07-19T16:42:46Z",
160+
},
161+
Committer: &api.CommitUser{
162+
Identity: api.Identity{
163+
Name: "6543",
164+
165+
},
166+
Date: "2021-07-19T16:42:46Z",
167+
},
168+
Message: "add unescaped file\n",
169+
},
170+
},
171+
}
172+
173+
assert.Equal(t, dummymeta, meta)
174+
}
175+
176+
func TestAPINewWikiPage(t *testing.T) {
177+
for _, title := range []string{
178+
"New page",
179+
"&&&&",
180+
} {
181+
defer prepareTestEnv(t)()
182+
username := "user2"
183+
session := loginUser(t, username)
184+
token := getTokenForLoggedInUser(t, session)
185+
186+
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/new?token=%s", username, "repo1", token)
187+
188+
req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateWikiPageOptions{
189+
Title: title,
190+
ContentBase64: base64.StdEncoding.EncodeToString([]byte("Wiki page content for API unit tests")),
191+
Message: "",
192+
})
193+
session.MakeRequest(t, req, http.StatusCreated)
194+
}
195+
}
196+
197+
func TestAPIEditWikiPage(t *testing.T) {
198+
defer prepareTestEnv(t)()
199+
username := "user2"
200+
session := loginUser(t, username)
201+
token := getTokenForLoggedInUser(t, session)
202+
203+
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/page/Page-With-Spaced-Name?token=%s", username, "repo1", token)
204+
205+
req := NewRequestWithJSON(t, "PATCH", urlStr, &api.CreateWikiPageOptions{
206+
Title: "edited title",
207+
ContentBase64: base64.StdEncoding.EncodeToString([]byte("Edited wiki page content for API unit tests")),
208+
Message: "",
209+
})
210+
session.MakeRequest(t, req, http.StatusOK)
211+
}
212+
213+
func TestAPIListPageRevisions(t *testing.T) {
214+
defer prepareTestEnv(t)()
215+
username := "user2"
216+
session := loginUser(t, username)
217+
218+
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/revisions/Home", username, "repo1")
219+
220+
req := NewRequest(t, "GET", urlStr)
221+
resp := session.MakeRequest(t, req, http.StatusOK)
222+
223+
var revisions *api.WikiCommitList
224+
DecodeJSON(t, resp, &revisions)
225+
226+
dummyrevisions := &api.WikiCommitList{
227+
WikiCommits: []*api.WikiCommit{
228+
{
229+
ID: "2c54faec6c45d31c1abfaecdab471eac6633738a",
230+
Author: &api.CommitUser{
231+
Identity: api.Identity{
232+
Name: "Ethan Koenig",
233+
234+
},
235+
Date: "2017-11-27T04:31:18Z",
236+
},
237+
Committer: &api.CommitUser{
238+
Identity: api.Identity{
239+
Name: "Ethan Koenig",
240+
241+
},
242+
Date: "2017-11-27T04:31:18Z",
243+
},
244+
Message: "Add Home.md\n",
245+
},
246+
},
247+
Count: 1,
248+
}
249+
250+
assert.Equal(t, dummyrevisions, revisions)
251+
}

integrations/user_avatar_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func TestUserAvatar(t *testing.T) {
7373

7474
user2 = db.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) // owner of the repo3, is an org
7575

76-
req = NewRequest(t, "GET", user2.AvatarLink())
76+
req = NewRequest(t, "GET", user2.AvatarLinkWithSize(0))
7777
_ = session.MakeRequest(t, req, http.StatusOK)
7878

7979
// Can't test if the response matches because the image is re-generated on upload but checking that this at least doesn't give a 404 should be enough.

models/user_avatar.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"fmt"
1010
"image/png"
1111
"io"
12+
"strings"
1213

1314
"code.gitea.io/gitea/models/avatars"
1415
"code.gitea.io/gitea/models/db"
@@ -91,9 +92,13 @@ func (u *User) AvatarLinkWithSize(size int) string {
9192
return avatars.GenerateEmailAvatarFastLink(u.AvatarEmail, size)
9293
}
9394

94-
// AvatarLink returns a avatar link with default size
95+
// AvatarLink returns the full avatar link with http host
9596
func (u *User) AvatarLink() string {
96-
return u.AvatarLinkWithSize(0)
97+
link := u.AvatarLinkWithSize(0)
98+
if !strings.HasPrefix(link, "//") && !strings.Contains(link, "://") {
99+
return setting.AppURL + strings.TrimPrefix(link, setting.AppSubURL+"/")
100+
}
101+
return link
97102
}
98103

99104
// UploadAvatar saves custom avatar for user.

modules/charset/charset.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"code.gitea.io/gitea/modules/log"
1515
"code.gitea.io/gitea/modules/setting"
16+
"code.gitea.io/gitea/modules/util"
1617

1718
"github.com/gogs/chardet"
1819
"golang.org/x/net/html/charset"
@@ -25,9 +26,9 @@ var UTF8BOM = []byte{'\xef', '\xbb', '\xbf'}
2526
// ToUTF8WithFallbackReader detects the encoding of content and coverts to UTF-8 reader if possible
2627
func ToUTF8WithFallbackReader(rd io.Reader) io.Reader {
2728
var buf = make([]byte, 2048)
28-
n, err := rd.Read(buf)
29+
n, err := util.ReadAtMost(rd, buf)
2930
if err != nil {
30-
return rd
31+
return io.MultiReader(bytes.NewReader(RemoveBOMIfPresent(buf[:n])), rd)
3132
}
3233

3334
charsetLabel, err := DetectEncoding(buf[:n])

modules/convert/user_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func TestUser_ToUser(t *testing.T) {
2121

2222
apiUser := toUser(user1, true, true)
2323
assert.True(t, apiUser.IsAdmin)
24+
assert.Contains(t, apiUser.AvatarURL, "://")
2425

2526
user2 := db.AssertExistsAndLoadBean(t, &models.User{ID: 2, IsAdmin: false}).(*models.User)
2627

0 commit comments

Comments
 (0)