Add Support to Follow Symlinks

This commit is contained in:
6543 2022-07-21 22:13:18 +02:00
parent 61b959a93b
commit 69c2532026
No known key found for this signature in database
GPG key ID: C99B82E40B027BAE

View file

@ -11,7 +11,10 @@ import (
"github.com/valyala/fastjson" "github.com/valyala/fastjson"
) )
const giteaAPIRepos = "/api/v1/repos/" const (
giteaAPIRepos = "/api/v1/repos/"
giteaObjectTypeHeader = "X-Gitea-Object-Type"
)
var ErrorNotFound = errors.New("not found") var ErrorNotFound = errors.New("not found")
@ -21,6 +24,8 @@ type Client struct {
fastClient *fasthttp.Client fastClient *fasthttp.Client
infoTimeout time.Duration infoTimeout time.Duration
contentTimeout time.Duration contentTimeout time.Duration
followSymlinks bool
} }
// TODO: once golang v1.19 is min requirement, we can switch to 'JoinPath()' of 'net/url' package // TODO: once golang v1.19 is min requirement, we can switch to 'JoinPath()' of 'net/url' package
@ -47,6 +52,8 @@ func NewClient(giteaRoot, giteaAPIToken string) (*Client, error) {
infoTimeout: 5 * time.Second, infoTimeout: 5 * time.Second,
contentTimeout: 10 * time.Second, contentTimeout: 10 * time.Second,
fastClient: getFastHTTPClient(), fastClient: getFastHTTPClient(),
followSymlinks: true,
}, err }, err
} }
@ -60,7 +67,7 @@ func (client *Client) GiteaRawContent(targetOwner, targetRepo, ref, resource str
func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource string) (*fasthttp.Response, error) { func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource string) (*fasthttp.Response, error) {
url := joinURL(client.giteaRoot, giteaAPIRepos, targetOwner, targetRepo, "raw", resource+"?ref="+url.QueryEscape(ref)) url := joinURL(client.giteaRoot, giteaAPIRepos, targetOwner, targetRepo, "raw", resource+"?ref="+url.QueryEscape(ref))
res, err := client.do(client.contentTimeout, url) resp, err := client.do(client.contentTimeout, url)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -69,13 +76,19 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
return nil, err return nil, err
} }
switch res.StatusCode() { switch resp.StatusCode() {
case fasthttp.StatusOK: case fasthttp.StatusOK:
return res, nil if client.followSymlinks && string(resp.Header.Peek(giteaObjectTypeHeader)) == "symlink" {
return client.ServeRawContent(targetOwner, targetRepo, ref, strings.TrimSpace(string(resp.Body())))
}
return resp, nil
case fasthttp.StatusNotFound: case fasthttp.StatusNotFound:
return nil, ErrorNotFound return nil, ErrorNotFound
default: default:
return nil, fmt.Errorf("unexpected status code '%d'", res.StatusCode()) return nil, fmt.Errorf("unexpected status code '%d'", resp.StatusCode())
} }
} }