diff --git a/README.md b/README.md
index 5707d65..b694e29 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,11 @@
# Codeberg Pages
+[](https://opensource.org/license/eupl-1-2/)
+[](https://ci.codeberg.org/Codeberg/pages-server)
+
+
+
+
Gitea lacks the ability to host static pages from Git.
The Codeberg Pages Server addresses this lack by implementing a standalone service
that connects to Gitea via API.
@@ -8,6 +14,9 @@ It is suitable to be deployed by other Gitea instances, too, to offer static pag
**End user documentation** can mainly be found at the [Wiki](https://codeberg.org/Codeberg/pages-server/wiki/Overview)
and the [Codeberg Documentation](https://docs.codeberg.org/codeberg-pages/).
+
+
+
## Quickstart
This is the new Codeberg Pages server, a solution for serving static pages from Gitea repositories.
@@ -29,6 +38,10 @@ record that points to your repo (just like the CNAME record):
Certificates are generated, updated and cleaned up automatically via Let's Encrypt through a TLS challenge.
+## Chat for admins & devs
+
+[matrix: #gitea-pages-server:matrix.org](https://matrix.to/#/#gitea-pages-server:matrix.org)
+
## Deployment
**Warning: Some Caveats Apply**
diff --git a/integration/get_test.go b/integration/get_test.go
index 3a7190a..9d97390 100644
--- a/integration/get_test.go
+++ b/integration/get_test.go
@@ -64,7 +64,7 @@ func TestGetContent(t *testing.T) {
assert.True(t, getSize(resp.Body) > 100)
assert.Len(t, resp.Header.Get("ETag"), 44)
- // TODO: test get of non cachable content (content size > fileCacheSizeLimit)
+ // TODO: test get of non cacheable content (content size > fileCacheSizeLimit)
}
func TestCustomDomain(t *testing.T) {
@@ -124,7 +124,7 @@ func TestRawCustomDomain(t *testing.T) {
}
func TestRawIndex(t *testing.T) {
- log.Println("=== TestRawCustomDomain ===")
+ log.Println("=== TestRawIndex ===")
// test raw domain response for index.html
resp, err := getTestHTTPSClient().Get("https://raw.localhost.mock.directory:4430/cb_pages_tests/raw-test/@branch-test/index.html") // need cb_pages_tests fork
assert.NoError(t, err)
@@ -154,6 +154,7 @@ func TestGetNotFound(t *testing.T) {
func TestFollowSymlink(t *testing.T) {
log.Printf("=== TestFollowSymlink ===\n")
+ // file symlink
resp, err := getTestHTTPSClient().Get("https://cb_pages_tests.localhost.mock.directory:4430/tests_for_pages-server/@main/link")
assert.NoError(t, err)
if !assert.NotNil(t, resp) {
@@ -165,6 +166,16 @@ func TestFollowSymlink(t *testing.T) {
body := getBytes(resp.Body)
assert.EqualValues(t, 4, len(body))
assert.EqualValues(t, "abc\n", string(body))
+
+ // relative file links (../index.html file in this case)
+ resp, err = getTestHTTPSClient().Get("https://cb_pages_tests.localhost.mock.directory:4430/tests_for_pages-server/@main/dir_aim/some/")
+ assert.NoError(t, err)
+ if !assert.NotNil(t, resp) {
+ t.FailNow()
+ }
+ assert.EqualValues(t, http.StatusOK, resp.StatusCode)
+ assert.EqualValues(t, "text/html; charset=utf-8", resp.Header.Get("Content-Type"))
+ assert.EqualValues(t, "an index\n", string(getBytes(resp.Body)))
}
func TestLFSSupport(t *testing.T) {
diff --git a/integration/main_test.go b/integration/main_test.go
index a397110..6566f78 100644
--- a/integration/main_test.go
+++ b/integration/main_test.go
@@ -23,7 +23,7 @@ func TestMain(m *testing.M) {
}
defer func() {
serverCancel()
- log.Println("=== TestMain: Server STOPED ===")
+ log.Println("=== TestMain: Server STOPPED ===")
}()
time.Sleep(10 * time.Second)
diff --git a/server/certificates/acme_client.go b/server/certificates/acme_client.go
index 7737396..ba83e50 100644
--- a/server/certificates/acme_client.go
+++ b/server/certificates/acme_client.go
@@ -89,7 +89,7 @@ func NewAcmeClient(acmeAccountConf, acmeAPI, acmeMail, acmeEabHmac, acmeEabKID,
acmeClientRequestLimit: equalizer.NewTokenBucket(5, 1*time.Second),
// rate limit is 5 / hour https://letsencrypt.org/docs/failed-validation-limit/
acmeClientFailLimit: equalizer.NewTokenBucket(5, 1*time.Hour),
- // checkUserLimit() use this to rate als per user
+ // checkUserLimit() use this to rate also per user
acmeClientCertificateLimitPerUser: map[string]*equalizer.TokenBucket{},
}, nil
}
diff --git a/server/database/xorm.go b/server/database/xorm.go
index 4b43cbb..217b6d1 100644
--- a/server/database/xorm.go
+++ b/server/database/xorm.go
@@ -37,7 +37,7 @@ func NewXormDB(dbType, dbConn string) (CertDB, error) {
}
if err := e.Sync2(new(Cert)); err != nil {
- return nil, fmt.Errorf("cound not sync db model :%w", err)
+ return nil, fmt.Errorf("could not sync db model :%w", err)
}
return &xDB{
@@ -64,7 +64,7 @@ func (x xDB) Put(domain string, cert *certificate.Resource) error {
}
defer sess.Close()
- if exist, _ := sess.ID(c.Domain).Exist(); exist {
+ if exist, _ := sess.ID(c.Domain).Exist(new(Cert)); exist {
if _, err := sess.ID(c.Domain).Update(c); err != nil {
return err
}
diff --git a/server/database/xorm_test.go b/server/database/xorm_test.go
index 9c032ee..50d8a7f 100644
--- a/server/database/xorm_test.go
+++ b/server/database/xorm_test.go
@@ -37,7 +37,7 @@ func TestSanitizeWildcardCerts(t *testing.T) {
}))
// update existing cert
- assert.Error(t, certDB.Put(".wildcard.de", &certificate.Resource{
+ assert.NoError(t, certDB.Put(".wildcard.de", &certificate.Resource{
Domain: "*.wildcard.de",
Certificate: localhost_mock_directory_certificate,
}))
diff --git a/server/gitea/client.go b/server/gitea/client.go
index 51647ba..7a2bf63 100644
--- a/server/gitea/client.go
+++ b/server/gitea/client.go
@@ -112,7 +112,7 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
if cache, ok := client.responseCache.Get(cacheKey); ok {
cache := cache.(FileResponse)
cachedHeader, cachedStatusCode := cache.createHttpResponse(cacheKey)
- // TODO: check against some timestamp missmatch?!?
+ // TODO: check against some timestamp mismatch?!?
if cache.Exists {
if cache.IsSymlink {
linkDest := string(cache.Body)
@@ -145,6 +145,10 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
}
linkDest := strings.TrimSpace(string(linkDestBytes))
+ // handle relative links
+ // we first remove the link from the path, and make a relative join (resolve parent paths like "/../" too)
+ linkDest = path.Join(path.Dir(resource), linkDest)
+
// we store symlink not content to reduce duplicates in cache
if err := client.responseCache.Set(cacheKey, FileResponse{
Exists: true,