mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2024-11-18 10:29:43 +00:00
implement custom 404 pages (#81)
solves #56. - The expected filename is `404.html`, like GitHub Pages - Each repo/branch can have one `404.html` file at it's root - If a repo does not have a `pages` branch, the 404.html file from the `pages` repository is used - You get status code 404 (unless you request /404.html which returns 200) - The error page is cached --- close #56 Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/81 Reviewed-by: 6543 <6543@noreply.codeberg.org> Co-authored-by: crystal <crystal@noreply.codeberg.org> Co-committed-by: crystal <crystal@noreply.codeberg.org>
This commit is contained in:
parent
35b35c5d67
commit
38fb28f84f
2 changed files with 37 additions and 2 deletions
|
@ -49,6 +49,19 @@ func TestGetContent(t *testing.T) {
|
||||||
assert.True(t, getSize(resp.Body) > 1000)
|
assert.True(t, getSize(resp.Body) > 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetNotFound(t *testing.T) {
|
||||||
|
log.Printf("== TestGetNotFound ==\n")
|
||||||
|
// test custom not found pages
|
||||||
|
resp, err := getTestHTTPSClient().Get("https://crystal.localhost.mock.directory:4430/pages-404-demo/blah")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if !assert.EqualValues(t, http.StatusNotFound, resp.StatusCode) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
assert.EqualValues(t, "text/html; charset=utf-8", resp.Header["Content-Type"][0])
|
||||||
|
assert.EqualValues(t, "37", resp.Header["Content-Length"][0])
|
||||||
|
assert.EqualValues(t, 37, getSize(resp.Body))
|
||||||
|
}
|
||||||
|
|
||||||
func getTestHTTPSClient() *http.Client {
|
func getTestHTTPSClient() *http.Client {
|
||||||
cookieJar, _ := cookiejar.New(nil)
|
cookieJar, _ := cookiejar.New(nil)
|
||||||
return &http.Client{
|
return &http.Client{
|
||||||
|
|
|
@ -21,6 +21,11 @@ var upstreamIndexPages = []string{
|
||||||
"index.html",
|
"index.html",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// upstreamNotFoundPages lists pages that may be considered as custom 404 Not Found pages.
|
||||||
|
var upstreamNotFoundPages = []string{
|
||||||
|
"404.html",
|
||||||
|
}
|
||||||
|
|
||||||
// Options provides various options for the upstream request.
|
// Options provides various options for the upstream request.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
TargetOwner,
|
TargetOwner,
|
||||||
|
@ -107,6 +112,21 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, giteaClient *gitea.Client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.Response.SetStatusCode(fasthttp.StatusNotFound)
|
ctx.Response.SetStatusCode(fasthttp.StatusNotFound)
|
||||||
|
if o.TryIndexPages {
|
||||||
|
// copy the o struct & try if a not found page exists
|
||||||
|
optionsForNotFoundPages := *o
|
||||||
|
optionsForNotFoundPages.TryIndexPages = false
|
||||||
|
optionsForNotFoundPages.appendTrailingSlash = false
|
||||||
|
for _, notFoundPage := range upstreamNotFoundPages {
|
||||||
|
optionsForNotFoundPages.TargetPath = "/" + notFoundPage
|
||||||
|
if optionsForNotFoundPages.Upstream(ctx, giteaClient, branchTimestampCache, fileResponseCache) {
|
||||||
|
_ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{
|
||||||
|
Exists: false,
|
||||||
|
}, fileCacheTimeout)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if res != nil {
|
if res != nil {
|
||||||
// Update cache if the request is fresh
|
// Update cache if the request is fresh
|
||||||
_ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{
|
_ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{
|
||||||
|
@ -141,8 +161,10 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, giteaClient *gitea.Client,
|
||||||
mimeType := o.getMimeTypeByExtension()
|
mimeType := o.getMimeTypeByExtension()
|
||||||
ctx.Response.Header.SetContentType(mimeType)
|
ctx.Response.Header.SetContentType(mimeType)
|
||||||
|
|
||||||
|
if ctx.Response.StatusCode() != fasthttp.StatusNotFound {
|
||||||
// Everything's okay so far
|
// Everything's okay so far
|
||||||
ctx.Response.SetStatusCode(fasthttp.StatusOK)
|
ctx.Response.SetStatusCode(fasthttp.StatusOK)
|
||||||
|
}
|
||||||
ctx.Response.Header.SetLastModified(o.BranchTimestamp)
|
ctx.Response.Header.SetLastModified(o.BranchTimestamp)
|
||||||
|
|
||||||
log.Debug().Msg("response preparations")
|
log.Debug().Msg("response preparations")
|
||||||
|
|
Loading…
Reference in a new issue