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
126141func (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
135151func (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
143160func (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
159177func (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
175194func (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
0 commit comments