mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2025-04-24 22:06:57 +00:00
Add gzip compression
This commit is contained in:
parent
dd6d8bd60f
commit
6f7e694fd4
2 changed files with 41 additions and 28 deletions
|
@ -2,6 +2,7 @@ package gitea
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -9,7 +10,6 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -101,7 +101,7 @@ func (client *Client) ContentWebLink(targetOwner, targetRepo, branch, resource s
|
|||
}
|
||||
|
||||
func (client *Client) GiteaRawContent(targetOwner, targetRepo, ref, resource string) ([]byte, error) {
|
||||
reader, _, _, err := client.ServeRawContent(targetOwner, targetRepo, ref, resource)
|
||||
reader, _, _, err := client.ServeRawContent(targetOwner, targetRepo, ref, resource, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ func (client *Client) GiteaRawContent(targetOwner, targetRepo, ref, resource str
|
|||
return io.ReadAll(reader)
|
||||
}
|
||||
|
||||
func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource string) (io.ReadCloser, http.Header, int, error) {
|
||||
func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource string, acceptsGzip bool) (io.ReadCloser, http.Header, int, error) {
|
||||
cacheKey := fmt.Sprintf("%s/%s/%s|%s|%s", rawContentCacheKeyPrefix, targetOwner, targetRepo, ref, resource)
|
||||
log := log.With().Str("cache_key", cacheKey).Logger()
|
||||
log.Trace().Msg("try file in cache")
|
||||
|
@ -123,7 +123,7 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
|
|||
if cache.IsSymlink {
|
||||
linkDest := string(cache.Body)
|
||||
log.Debug().Msgf("[cache] follow symlink from %q to %q", resource, linkDest)
|
||||
return client.ServeRawContent(targetOwner, targetRepo, ref, linkDest)
|
||||
return client.ServeRawContent(targetOwner, targetRepo, ref, linkDest, acceptsGzip)
|
||||
} else if !cache.IsEmpty() {
|
||||
log.Debug().Msgf("[cache] return %d bytes", len(cache.Body))
|
||||
return io.NopCloser(bytes.NewReader(cache.Body)), cachedHeader, cachedStatusCode, nil
|
||||
|
@ -168,7 +168,7 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
|
|||
}
|
||||
|
||||
log.Debug().Msgf("follow symlink from %q to %q", resource, linkDest)
|
||||
return client.ServeRawContent(targetOwner, targetRepo, ref, linkDest)
|
||||
return client.ServeRawContent(targetOwner, targetRepo, ref, linkDest, acceptsGzip)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,22 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
|
|||
mimeType := client.getMimeTypeByExtension(resource)
|
||||
resp.Response.Header.Set(ContentTypeHeader, mimeType)
|
||||
|
||||
if !shouldRespBeSavedToCache(resp.Response) {
|
||||
// Compress file response
|
||||
buf := new(bytes.Buffer)
|
||||
gw := gzip.NewWriter(buf)
|
||||
_, err := io.Copy(gw, reader)
|
||||
gw.Close()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error on response compression")
|
||||
}
|
||||
|
||||
// Check if size of gzipped response is greater than fileCacheSizeLimit and return gzipped
|
||||
// response but uncached or return non-gzip response if not supported
|
||||
len := int64(buf.Len());
|
||||
shouldRespBeSavedToCache := len < fileCacheSizeLimit
|
||||
if !shouldRespBeSavedToCache {
|
||||
return io.NopCloser(buf), resp.Response.Header, resp.StatusCode, err
|
||||
} else if !shouldRespBeSavedToCache && !acceptsGzip {
|
||||
return reader, resp.Response.Header, resp.StatusCode, err
|
||||
}
|
||||
|
||||
|
@ -186,7 +201,7 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
|
|||
ETag: resp.Header.Get(ETagHeader),
|
||||
MimeType: mimeType,
|
||||
}
|
||||
return fileResp.CreateCacheReader(reader, client.responseCache, cacheKey), resp.Response.Header, resp.StatusCode, nil
|
||||
return fileResp.CreateCacheReader(io.NopCloser(buf), client.responseCache, cacheKey), resp.Response.Header, resp.StatusCode, nil
|
||||
|
||||
case http.StatusNotFound:
|
||||
if err := client.responseCache.Set(cacheKey, FileResponse{
|
||||
|
@ -275,22 +290,3 @@ func (client *Client) getMimeTypeByExtension(resource string) string {
|
|||
log.Trace().Msgf("probe mime of %q is %q", resource, mimeType)
|
||||
return mimeType
|
||||
}
|
||||
|
||||
func shouldRespBeSavedToCache(resp *http.Response) bool {
|
||||
if resp == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
contentLengthRaw := resp.Header.Get(ContentLengthHeader)
|
||||
if contentLengthRaw == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
contentLength, err := strconv.ParseInt(contentLengthRaw, 10, 64)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("could not parse content length")
|
||||
}
|
||||
|
||||
// if content to big or could not be determined we not cache it
|
||||
return contentLength > 0 && contentLength < fileCacheSizeLimit
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue