From c9050e5722120f03fc5c8e632aa785d790f2b513 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 11 Mar 2023 05:07:17 +0000 Subject: [PATCH 1/5] Handle Relative Symlinks (#205) enhance #114 Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/205 --- integration/get_test.go | 13 ++++++++++++- integration/main_test.go | 2 +- server/certificates/acme_client.go | 2 +- server/database/xorm.go | 2 +- server/gitea/client.go | 6 +++++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/integration/get_test.go b/integration/get_test.go index 3a7190a..c0a3a47 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) { @@ -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..fb1dc17 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{ 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, From 26d59b71f049d459b663ec885156bfb8b89aa0c9 Mon Sep 17 00:00:00 2001 From: Crystal Date: Mon, 20 Mar 2023 22:52:42 +0000 Subject: [PATCH 2/5] Fix typo in integration test log (#210) I forgot to update the name of this function in the CI log so it looks like it's running the same test twice even though it's not. Co-authored-by: crystal Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/210 Reviewed-by: 6543 <6543@obermui.de> Co-authored-by: Crystal Co-committed-by: Crystal --- integration/get_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/get_test.go b/integration/get_test.go index c0a3a47..9d97390 100644 --- a/integration/get_test.go +++ b/integration/get_test.go @@ -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) From c40dddf471277260ee3ca95c5701cf723c1e24cb Mon Sep 17 00:00:00 2001 From: Crystal Date: Mon, 20 Mar 2023 22:57:26 +0000 Subject: [PATCH 3/5] Fix certificate renewal (#209) A database bug in xorm.go prevents the pages-server from saving a renewed certificate for a domain that already has one in the database. Co-authored-by: crystal Co-authored-by: 6543 <6543@obermui.de> Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/209 Reviewed-by: 6543 <6543@obermui.de> Co-authored-by: Crystal Co-committed-by: Crystal --- server/database/xorm.go | 2 +- server/database/xorm_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/database/xorm.go b/server/database/xorm.go index fb1dc17..217b6d1 100644 --- a/server/database/xorm.go +++ b/server/database/xorm.go @@ -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, })) From 98d7a771be9783a333a3f9abd8d6e08d1ad4a46f Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 21 Mar 2023 01:53:07 +0100 Subject: [PATCH 4/5] Readme.md: add link to chat & main repo --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 5707d65..7e1b2c5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # Codeberg Pages +[![License: EUPL-1.2](https://img.shields.io/badge/License-EUPL--1.2-blue)](https://opensource.org/license/eupl-1-2/) +[![status-badge](https://ci.codeberg.org/api/badges/Codeberg/pages-server/status.svg)](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/). + + Get It On Codeberg + ## 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:obermui.de](https://matrix.to/#/#gitea-pages-server:obermui.de) + ## Deployment **Warning: Some Caveats Apply** From 970c13cf5c006dfa1011ba9e6721baafa3f1ad55 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 21 Mar 2023 02:32:25 +0100 Subject: [PATCH 5/5] Readme.md: use matrix.org for room alias --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7e1b2c5..b694e29 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ [![License: EUPL-1.2](https://img.shields.io/badge/License-EUPL--1.2-blue)](https://opensource.org/license/eupl-1-2/) [![status-badge](https://ci.codeberg.org/api/badges/Codeberg/pages-server/status.svg)](https://ci.codeberg.org/Codeberg/pages-server) - - + + Gitea lacks the ability to host static pages from Git. @@ -40,7 +40,7 @@ Certificates are generated, updated and cleaned up automatically via Let's Encry ## Chat for admins & devs -[matrix: #gitea-pages-server:obermui.de](https://matrix.to/#/#gitea-pages-server:obermui.de) +[matrix: #gitea-pages-server:matrix.org](https://matrix.to/#/#gitea-pages-server:matrix.org) ## Deployment