diff --git a/server/context/context.go b/server/context/context.go index 464f84f..aee3e95 100644 --- a/server/context/context.go +++ b/server/context/context.go @@ -23,3 +23,7 @@ func (c *Context) Response() *http.Response { } return nil } + +func (c *Context) Redirect(uri string, statusCode int) { + http.Redirect(c.RespWriter, c.Req, uri, statusCode) +} diff --git a/server/gitea/client_std.go b/server/gitea/client_std.go index d8d1f9f..7e1194e 100644 --- a/server/gitea/client_std.go +++ b/server/gitea/client_std.go @@ -83,6 +83,7 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str // cachedResponse.Body = cacheBodyWriter.Bytes() // _ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), cachedResponse, fileCacheTimeout) // } + // store ETag in resp !!!! objType := resp.Header.Get(giteaObjectTypeHeader) log.Trace().Msgf("server raw content object: %s", objType) diff --git a/server/upstream/upstream_std.go b/server/upstream/upstream_std.go index 3d8aefe..28ca272 100644 --- a/server/upstream/upstream_std.go +++ b/server/upstream/upstream_std.go @@ -3,22 +3,25 @@ package upstream import ( - "bytes" "errors" - "fmt" "io" "net/http" "strings" "time" "github.com/rs/zerolog/log" - "github.com/valyala/fasthttp" "codeberg.org/codeberg/pages/html" "codeberg.org/codeberg/pages/server/context" "codeberg.org/codeberg/pages/server/gitea" ) +const ( + headerContentType = "Content-Type" + headerETag = "ETag" + headerLastModified = "Last-Modified" +) + // Upstream requests a file from the Gitea API at GiteaRoot and writes it to the request context. func (o *Options) Upstream(ctx *context.Context, giteaClient *gitea.Client) (final bool) { log := log.With().Strs("upstream", []string{o.TargetOwner, o.TargetRepo, o.TargetBranch, o.TargetPath}).Logger() @@ -73,7 +76,8 @@ func (o *Options) Upstream(ctx *context.Context, giteaClient *gitea.Client) (fin return true } } - ctx.Response().SetStatusCode(http.StatusNotFound) + + ctx.Response().StatusCode = http.StatusNotFound if o.TryIndexPages { // copy the o struct & try if a not found page exists optionsForNotFoundPages := *o @@ -88,20 +92,20 @@ func (o *Options) Upstream(ctx *context.Context, giteaClient *gitea.Client) (fin } return false } - if res != nil && (err != nil || res.StatusCode() != http.StatusOK) { - fmt.Printf("Couldn't fetch contents from \"%s\": %s (status code %d)\n", uri, err, res.StatusCode()) + if res != nil && (err != nil || res.StatusCode != http.StatusOK) { + log.Printf("Couldn't fetch contents (status code %d): %v\n", res.StatusCode, err) html.ReturnErrorPage(ctx, http.StatusInternalServerError) return true } // Append trailing slash if missing (for index files), and redirect to fix filenames in general // o.appendTrailingSlash is only true when looking for index pages - if o.appendTrailingSlash && !bytes.HasSuffix(ctx.Request().URI().Path(), []byte{'/'}) { - ctx.Redirect(string(ctx.Request.URI().Path())+"/", http.StatusTemporaryRedirect) + if o.appendTrailingSlash && !strings.HasSuffix(ctx.Req.URL.Path, "/") { + ctx.Redirect(ctx.Req.URL.Path+"/", http.StatusTemporaryRedirect) return true } - if bytes.HasSuffix(ctx.Request.URI().Path(), []byte("/index.html")) { - ctx.Redirect(strings.TrimSuffix(string(ctx.Request.URI().Path()), "index.html"), http.StatusTemporaryRedirect) + if strings.HasSuffix(ctx.Req.URL.Path, "/index.html") { + ctx.Redirect(strings.TrimSuffix(ctx.Req.URL.Path, "index.html"), http.StatusTemporaryRedirect) return true } if o.redirectIfExists != "" { @@ -112,21 +116,18 @@ func (o *Options) Upstream(ctx *context.Context, giteaClient *gitea.Client) (fin // Set the MIME type mimeType := o.getMimeTypeByExtension() - ctx.Response.Header.SetContentType(mimeType) + ctx.Response().Header.Set(headerContentType, mimeType) // Set ETag - if cachedResponse.Exists { - ctx.Response().Header.SetBytesV(fasthttp.HeaderETag, cachedResponse.ETag) - } else if res != nil { - cachedResponse.ETag = res.Header.Peek(fasthttp.HeaderETag) - ctx.Response().Header.SetBytesV(fasthttp.HeaderETag, cachedResponse.ETag) + if res != nil { + ctx.Response().Header.Set(headerETag, res.Header.Get(headerETag)) } - if ctx.Response().StatusCode() != http.StatusNotFound { + if ctx.Response().StatusCode != http.StatusNotFound { // Everything's okay so far - ctx.Response().SetStatusCode(http.StatusOK) + ctx.Response().StatusCode = http.StatusOK } - ctx.Response().Header.SetLastModified(o.BranchTimestamp) + ctx.Response().Header.Set(headerLastModified, o.BranchTimestamp.In(time.UTC).Format(time.RFC1123)) log.Debug().Msg("response preparations") @@ -134,7 +135,7 @@ func (o *Options) Upstream(ctx *context.Context, giteaClient *gitea.Client) (fin if reader != nil { _, err := io.Copy(ctx.RespWriter, reader) if err != nil { - fmt.Printf("Couldn't write body for \"%s\": %s\n", uri, err) + log.Printf("Couldn't write body: %s\n", err) html.ReturnErrorPage(ctx, http.StatusInternalServerError) return true }