Skip to content

Commit 32b0722

Browse files
committed
GetFile: Use "ref" in-query if posible (#491)
based on go-gitea/gitea#14563 Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/491 Reviewed-by: techknowlogick <[email protected]> Reviewed-by: Andrew Thornton <[email protected]> Co-authored-by: 6543 <[email protected]> Co-committed-by: 6543 <[email protected]>
1 parent 757f8bd commit 32b0722

File tree

2 files changed

+57
-13
lines changed

2 files changed

+57
-13
lines changed

gitea/repo_file.go

+25-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"bytes"
1010
"encoding/json"
1111
"fmt"
12+
"net/url"
1213
"strings"
1314
)
1415

@@ -115,32 +116,49 @@ type FileDeleteResponse struct {
115116
Verification *PayloadCommitVerification `json:"verification"`
116117
}
117118

119+
// pathEscapeSegments escapes segments of a path while not escaping forward slash
120+
func pathEscapeSegments(path string) string {
121+
slice := strings.Split(path, "/")
122+
for index := range slice {
123+
slice[index] = url.PathEscape(slice[index])
124+
}
125+
escapedPath := strings.Join(slice, "/")
126+
return escapedPath
127+
}
128+
118129
// GetFile downloads a file of repository, ref can be branch/tag/commit.
119-
// e.g.: ref -> master, tree -> macaron.go(no leading slash)
120-
func (c *Client) GetFile(user, repo, ref, tree string) ([]byte, *Response, error) {
121-
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", user, repo, ref, tree), nil, nil)
130+
// e.g.: ref -> master, filepath -> README.md (no leading slash)
131+
func (c *Client) GetFile(owner, repo, ref, filepath string) ([]byte, *Response, error) {
132+
filepath = pathEscapeSegments(filepath)
133+
if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil {
134+
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", owner, repo, ref, filepath), nil, nil)
135+
}
136+
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), nil, nil)
122137
}
123138

124139
// GetContents get the metadata and contents of a file in a repository
125140
// ref is optional
126141
func (c *Client) GetContents(owner, repo, ref, filepath string) (*ContentsResponse, *Response, error) {
142+
filepath = pathEscapeSegments(filepath)
127143
cr := new(ContentsResponse)
128144
filepath = strings.TrimPrefix(filepath, "/")
129-
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, ref), jsonHeader, nil, cr)
145+
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), jsonHeader, nil, cr)
130146
return cr, resp, err
131147
}
132148

133149
// ListContents gets a list of entries in a dir
134150
// ref is optional
135151
func (c *Client) ListContents(owner, repo, ref, filepath string) ([]*ContentsResponse, *Response, error) {
152+
filepath = pathEscapeSegments(filepath)
136153
cr := make([]*ContentsResponse, 0)
137154
filepath = strings.TrimPrefix(filepath, "/")
138-
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, ref), jsonHeader, nil, &cr)
155+
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), jsonHeader, nil, &cr)
139156
return cr, resp, err
140157
}
141158

142159
// CreateFile create a file in a repository
143160
func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions) (*FileResponse, *Response, error) {
161+
filepath = pathEscapeSegments(filepath)
144162
var err error
145163
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
146164
return nil, nil, err
@@ -157,6 +175,7 @@ func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions)
157175

158176
// UpdateFile update a file in a repository
159177
func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions) (*FileResponse, *Response, error) {
178+
filepath = pathEscapeSegments(filepath)
160179
var err error
161180
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
162181
return nil, nil, err
@@ -173,6 +192,7 @@ func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions)
173192

174193
// DeleteFile delete a file from repository
175194
func (c *Client) DeleteFile(owner, repo, filepath string, opt DeleteFileOptions) (*Response, error) {
195+
filepath = pathEscapeSegments(filepath)
176196
var err error
177197
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
178198
return nil, err

gitea/repo_file_test.go

+32-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package gitea
66

77
import (
8+
"bytes"
89
"encoding/base64"
910
"log"
1011
"testing"
@@ -24,17 +25,18 @@ func TestFileCreateUpdateGet(t *testing.T) {
2425
assert.NoError(t, err)
2526
assert.EqualValues(t, "IyBDaGFuZ2VGaWxlcwoKQSB0ZXN0IFJlcG86IENoYW5nZUZpbGVz", base64.StdEncoding.EncodeToString(raw))
2627

27-
newFile, _, err := c.CreateFile(repo.Owner.UserName, repo.Name, "A", CreateFileOptions{
28+
testFileName := "A+#&ä"
29+
newFile, _, err := c.CreateFile(repo.Owner.UserName, repo.Name, testFileName, CreateFileOptions{
2830
FileOptions: FileOptions{
29-
Message: "create file A",
31+
Message: "create file " + testFileName,
3032
},
3133
Content: "ZmlsZUEK",
3234
})
3335
assert.NoError(t, err)
34-
raw, _, _ = c.GetFile(repo.Owner.UserName, repo.Name, "master", "A")
36+
raw, _, _ = c.GetFile(repo.Owner.UserName, repo.Name, "master", testFileName)
3537
assert.EqualValues(t, "ZmlsZUEK", base64.StdEncoding.EncodeToString(raw))
3638

37-
updatedFile, _, err := c.UpdateFile(repo.Owner.UserName, repo.Name, "A", UpdateFileOptions{
39+
updatedFile, _, err := c.UpdateFile(repo.Owner.UserName, repo.Name, testFileName, UpdateFileOptions{
3840
FileOptions: FileOptions{
3941
Message: "add a new line",
4042
},
@@ -44,18 +46,40 @@ func TestFileCreateUpdateGet(t *testing.T) {
4446
assert.NoError(t, err)
4547
assert.NotNil(t, updatedFile)
4648

47-
file, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "master", "A")
49+
file, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "master", testFileName)
4850
assert.NoError(t, err)
4951
assert.EqualValues(t, updatedFile.Content.SHA, file.SHA)
5052
assert.EqualValues(t, &updatedFile.Content.Content, &file.Content)
5153

52-
_, err = c.DeleteFile(repo.Owner.UserName, repo.Name, "A", DeleteFileOptions{
54+
_, err = c.DeleteFile(repo.Owner.UserName, repo.Name, testFileName, DeleteFileOptions{
5355
FileOptions: FileOptions{
54-
Message: "Delete File A",
56+
Message: "Delete File " + testFileName,
5557
},
5658
SHA: updatedFile.Content.SHA,
5759
})
5860
assert.NoError(t, err)
59-
_, _, err = c.GetFile(repo.Owner.UserName, repo.Name, "master", "A")
61+
_, resp, err := c.GetFile(repo.Owner.UserName, repo.Name, "master", testFileName)
6062
assert.EqualValues(t, "404 Not Found", err.Error())
63+
assert.EqualValues(t, 404, resp.StatusCode)
64+
65+
licence, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "", "LICENSE")
66+
assert.NoError(t, err)
67+
licenceRaw, _, err := c.GetFile(repo.Owner.UserName, repo.Name, "", "LICENSE")
68+
testContent := "Tk9USElORyBJUyBIRVJFIEFOWU1PUkUKSUYgWU9VIExJS0UgVE8gRklORCBTT01FVEhJTkcKV0FJVCBGT1IgVEhFIEZVVFVSRQo="
69+
updatedFile, _, err = c.UpdateFile(repo.Owner.UserName, repo.Name, "LICENSE", UpdateFileOptions{
70+
FileOptions: FileOptions{
71+
Message: "Overwrite",
72+
BranchName: "master",
73+
NewBranchName: "overwrite-a+/&licence",
74+
},
75+
SHA: licence.SHA,
76+
Content: testContent,
77+
})
78+
assert.NoError(t, err)
79+
assert.NotNil(t, updatedFile)
80+
licenceRawNew, _, err := c.GetFile(repo.Owner.UserName, repo.Name, "overwrite-a+/&licence", "LICENSE")
81+
assert.NoError(t, err)
82+
assert.NotNil(t, licence)
83+
assert.False(t, bytes.Equal(licenceRaw, licenceRawNew))
84+
assert.EqualValues(t, testContent, base64.StdEncoding.EncodeToString(licenceRawNew))
6185
}

0 commit comments

Comments
 (0)