kopia lustrzana https://codeberg.org/Codeberg/pages-server
				
				
				
			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>pull/90/head
							rodzic
							
								
									35b35c5d67
								
							
						
					
					
						commit
						38fb28f84f
					
				|  | @ -49,6 +49,19 @@ func TestGetContent(t *testing.T) { | |||
| 	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 { | ||||
| 	cookieJar, _ := cookiejar.New(nil) | ||||
| 	return &http.Client{ | ||||
|  |  | |||
|  | @ -21,6 +21,11 @@ var upstreamIndexPages = []string{ | |||
| 	"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.
 | ||||
| type Options struct { | ||||
| 	TargetOwner, | ||||
|  | @ -107,6 +112,21 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, giteaClient *gitea.Client, | |||
| 			} | ||||
| 		} | ||||
| 		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 { | ||||
| 			// Update cache if the request is fresh
 | ||||
| 			_ = 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() | ||||
| 	ctx.Response.Header.SetContentType(mimeType) | ||||
| 
 | ||||
| 	// Everything's okay so far
 | ||||
| 	ctx.Response.SetStatusCode(fasthttp.StatusOK) | ||||
| 	if ctx.Response.StatusCode() != fasthttp.StatusNotFound { | ||||
| 		// Everything's okay so far
 | ||||
| 		ctx.Response.SetStatusCode(fasthttp.StatusOK) | ||||
| 	} | ||||
| 	ctx.Response.Header.SetLastModified(o.BranchTimestamp) | ||||
| 
 | ||||
| 	log.Debug().Msg("response preparations") | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 crystal
						crystal