GetFile: Use "ref" in-query if posible #491

Merged
6543 merged 9 commits from 6543/go-sdk:GetFile_use-ref_in-query_if-posible into master 2021-02-16 20:07:45 +00:00
2 changed files with 57 additions and 13 deletions

View File

@ -9,6 +9,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"net/url"
"strings"
)
@ -115,32 +116,49 @@ type FileDeleteResponse struct {
Verification *PayloadCommitVerification `json:"verification"`
}
// pathEscapeSegments escapes segments of a path while not escaping forward slash
func pathEscapeSegments(path string) string {
slice := strings.Split(path, "/")
for index := range slice {
slice[index] = url.PathEscape(slice[index])
}
6543 marked this conversation as resolved Outdated

tree and ref should both be escaped properly.

ref is simple as it's url.QueryEscape but tree needs escaping using the partial pathescape.

tree and ref should both be escaped properly. ref is simple as it's url.QueryEscape but tree needs escaping using the partial pathescape.
escapedPath := strings.Join(slice, "/")
6543 marked this conversation as resolved Outdated

tree needs to be util.PathEscapeSegments or something like it.

e.g. from Gitea modules/util

// PathEscapeSegments escapes segments of a path while not escaping forward slash
func PathEscapeSegments(path string) string {
	slice := strings.Split(path, "/")
	for index := range slice {
		slice[index] = url.PathEscape(slice[index])
	}
	escapedPath := strings.Join(slice, "/")
	return escapedPath
}

as does ref and tree on line 123

tree needs to be `util.PathEscapeSegments` or something like it. e.g. from Gitea modules/util ``` // PathEscapeSegments escapes segments of a path while not escaping forward slash func PathEscapeSegments(path string) string { slice := strings.Split(path, "/") for index := range slice { slice[index] = url.PathEscape(slice[index]) } escapedPath := strings.Join(slice, "/") return escapedPath } ``` as does ref and tree on line 123
Outdated
Review

this is a more genneral issue witch I like to catch with #273 since we need this not only for this function...

this is a more genneral issue witch I like to catch with #273 since we need this not only for this function...
return escapedPath
}
// GetFile downloads a file of repository, ref can be branch/tag/commit.
// e.g.: ref -> master, tree -> macaron.go(no leading slash)
func (c *Client) GetFile(user, repo, ref, tree string) ([]byte, *Response, error) {
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", user, repo, ref, tree), nil, nil)
// e.g.: ref -> master, filepath -> README.md (no leading slash)
func (c *Client) GetFile(owner, repo, ref, filepath string) ([]byte, *Response, error) {
filepath = pathEscapeSegments(filepath)
if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil {
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", owner, repo, ref, filepath), nil, nil)
}
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), nil, nil)
}
// GetContents get the metadata and contents of a file in a repository
// ref is optional
func (c *Client) GetContents(owner, repo, ref, filepath string) (*ContentsResponse, *Response, error) {
filepath = pathEscapeSegments(filepath)
cr := new(ContentsResponse)
filepath = strings.TrimPrefix(filepath, "/")
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, ref), jsonHeader, nil, cr)
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), jsonHeader, nil, cr)
return cr, resp, err
}
// ListContents gets a list of entries in a dir
// ref is optional
func (c *Client) ListContents(owner, repo, ref, filepath string) ([]*ContentsResponse, *Response, error) {
filepath = pathEscapeSegments(filepath)
cr := make([]*ContentsResponse, 0)
filepath = strings.TrimPrefix(filepath, "/")
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, ref), jsonHeader, nil, &cr)
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), jsonHeader, nil, &cr)
return cr, resp, err
}
// CreateFile create a file in a repository
func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions) (*FileResponse, *Response, error) {
filepath = pathEscapeSegments(filepath)
var err error
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
return nil, nil, err
@ -157,6 +175,7 @@ func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions)
// UpdateFile update a file in a repository
func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions) (*FileResponse, *Response, error) {
filepath = pathEscapeSegments(filepath)
var err error
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
return nil, nil, err
@ -173,6 +192,7 @@ func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions)
// DeleteFile delete a file from repository
func (c *Client) DeleteFile(owner, repo, filepath string, opt DeleteFileOptions) (*Response, error) {
filepath = pathEscapeSegments(filepath)
var err error
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
return nil, err

View File

@ -5,6 +5,7 @@
package gitea
import (
"bytes"
"encoding/base64"
"log"
"testing"
@ -24,17 +25,18 @@ func TestFileCreateUpdateGet(t *testing.T) {
assert.NoError(t, err)
assert.EqualValues(t, "IyBDaGFuZ2VGaWxlcwoKQSB0ZXN0IFJlcG86IENoYW5nZUZpbGVz", base64.StdEncoding.EncodeToString(raw))
newFile, _, err := c.CreateFile(repo.Owner.UserName, repo.Name, "A", CreateFileOptions{
testFileName := "A+#&ä"
newFile, _, err := c.CreateFile(repo.Owner.UserName, repo.Name, testFileName, CreateFileOptions{
FileOptions: FileOptions{
Message: "create file A",
Message: "create file " + testFileName,
},
Content: "ZmlsZUEK",
})
assert.NoError(t, err)
raw, _, _ = c.GetFile(repo.Owner.UserName, repo.Name, "master", "A")
raw, _, _ = c.GetFile(repo.Owner.UserName, repo.Name, "master", testFileName)
assert.EqualValues(t, "ZmlsZUEK", base64.StdEncoding.EncodeToString(raw))
updatedFile, _, err := c.UpdateFile(repo.Owner.UserName, repo.Name, "A", UpdateFileOptions{
updatedFile, _, err := c.UpdateFile(repo.Owner.UserName, repo.Name, testFileName, UpdateFileOptions{
FileOptions: FileOptions{
Message: "add a new line",
},
@ -44,18 +46,40 @@ func TestFileCreateUpdateGet(t *testing.T) {
assert.NoError(t, err)
assert.NotNil(t, updatedFile)
file, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "master", "A")
file, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "master", testFileName)
assert.NoError(t, err)
assert.EqualValues(t, updatedFile.Content.SHA, file.SHA)
assert.EqualValues(t, &updatedFile.Content.Content, &file.Content)
_, err = c.DeleteFile(repo.Owner.UserName, repo.Name, "A", DeleteFileOptions{
_, err = c.DeleteFile(repo.Owner.UserName, repo.Name, testFileName, DeleteFileOptions{
FileOptions: FileOptions{
Message: "Delete File A",
Message: "Delete File " + testFileName,
},
SHA: updatedFile.Content.SHA,
})
assert.NoError(t, err)
_, _, err = c.GetFile(repo.Owner.UserName, repo.Name, "master", "A")
_, resp, err := c.GetFile(repo.Owner.UserName, repo.Name, "master", testFileName)
assert.EqualValues(t, "404 Not Found", err.Error())
assert.EqualValues(t, 404, resp.StatusCode)
licence, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "", "LICENSE")
assert.NoError(t, err)
licenceRaw, _, err := c.GetFile(repo.Owner.UserName, repo.Name, "", "LICENSE")
testContent := "Tk9USElORyBJUyBIRVJFIEFOWU1PUkUKSUYgWU9VIExJS0UgVE8gRklORCBTT01FVEhJTkcKV0FJVCBGT1IgVEhFIEZVVFVSRQo="
updatedFile, _, err = c.UpdateFile(repo.Owner.UserName, repo.Name, "LICENSE", UpdateFileOptions{
FileOptions: FileOptions{
Message: "Overwrite",
BranchName: "master",
NewBranchName: "overwrite-a+/&licence",
},
SHA: licence.SHA,
Content: testContent,
})
assert.NoError(t, err)
assert.NotNil(t, updatedFile)
licenceRawNew, _, err := c.GetFile(repo.Owner.UserName, repo.Name, "overwrite-a+/&licence", "LICENSE")
assert.NoError(t, err)
assert.NotNil(t, licence)
assert.False(t, bytes.Equal(licenceRaw, licenceRawNew))
assert.EqualValues(t, testContent, base64.StdEncoding.EncodeToString(licenceRawNew))
}