@@ -744,7 +744,7 @@ func downloadFileViaGitClone(owner, repo, path, ref, host string) ([]byte, error
744744// Returns the symlink target and true if it is a symlink, or empty string and false otherwise.
745745// A nil error with false means the path is not a symlink (e.g., it's a directory or file).
746746func checkRemoteSymlink (client * api.RESTClient , owner , repo , dirPath , ref string ) (string , bool , error ) {
747- endpoint := fmt . Sprintf ( "repos/%s/%s/contents/%s?ref=%s" , owner , repo , dirPath , ref )
747+ endpoint := buildContentsAPIPath ( owner , repo , dirPath , ref )
748748 remoteLog .Printf ("Checking if path component is symlink: %s/%s/%s@%s" , owner , repo , dirPath , ref )
749749
750750 // The Contents API returns a JSON object for files/symlinks but a JSON array for directories.
@@ -951,14 +951,29 @@ func downloadFileFromGitHubWithDepth(owner, repo, path, ref string, symlinkDepth
951951}
952952
953953func createRESTClientForHost (host string ) (* api.RESTClient , error ) {
954+ opts := api.ClientOptions {Timeout : constants .DefaultHTTPClientTimeout }
954955 if host != "" {
955- return api . NewRESTClient (api. ClientOptions { Host : host })
956+ opts . Host = host
956957 }
957- return api .DefaultRESTClient ()
958+ return api .NewRESTClient (opts )
959+ }
960+
961+ func buildContentsAPIPath (owner , repo , path , ref string ) string {
962+ pathSegments := strings .Split (path , "/" )
963+ for i := range pathSegments {
964+ pathSegments [i ] = url .PathEscape (pathSegments [i ])
965+ }
966+ return fmt .Sprintf (
967+ "repos/%s/%s/contents/%s?ref=%s" ,
968+ owner ,
969+ repo ,
970+ strings .Join (pathSegments , "/" ),
971+ url .QueryEscape (ref ),
972+ )
958973}
959974
960975func fetchRemoteFileContent (client * api.RESTClient , owner , repo , path , ref string , fileContent any ) error {
961- return client .Get (fmt . Sprintf ( "repos/%s/%s/contents/%s?ref=%s" , owner , repo , path , ref ), fileContent )
976+ return client .Get (buildContentsAPIPath ( owner , repo , path , ref ), fileContent )
962977}
963978
964979// downloadFileViaPublicAPI downloads a file from a public GitHub repository
@@ -1020,16 +1035,7 @@ func ListWorkflowFilesForHost(owner, repo, ref, workflowPath, host string) ([]st
10201035func listWorkflowFilesForHost (owner , repo , ref , workflowPath , host string ) ([]string , error ) {
10211036 remoteLog .Printf ("Listing workflow files for %s/%s@%s (path: %s)" , owner , repo , ref , workflowPath )
10221037
1023- // Create REST client
1024- var (
1025- client * api.RESTClient
1026- err error
1027- )
1028- if host != "" {
1029- client , err = api .NewRESTClient (api.ClientOptions {Host : host })
1030- } else {
1031- client , err = api .DefaultRESTClient ()
1032- }
1038+ client , err := createRESTClientForHost (host )
10331039 if err != nil {
10341040 remoteLog .Printf ("Failed to create REST client, attempting git fallback: %v" , err )
10351041 return listWorkflowFilesViaGitForHost (owner , repo , ref , workflowPath , host )
@@ -1043,7 +1049,7 @@ func listWorkflowFilesForHost(owner, repo, ref, workflowPath, host string) ([]st
10431049 }
10441050
10451051 // Fetch directory contents from GitHub API
1046- endpoint := fmt . Sprintf ( "repos/%s/%s/contents/%s?ref=%s" , owner , repo , workflowPath , ref )
1052+ endpoint := buildContentsAPIPath ( owner , repo , workflowPath , ref )
10471053 err = client .Get (endpoint , & contents )
10481054 if err != nil {
10491055 errStr := err .Error ()
@@ -1088,15 +1094,7 @@ func ListDirAllFilesForHost(owner, repo, ref, dirPath, host string) ([]string, e
10881094func listDirAllFilesForHost (owner , repo , ref , dirPath , host string ) ([]string , error ) {
10891095 remoteLog .Printf ("Listing all files in dir for %s/%s@%s (path: %s)" , owner , repo , ref , dirPath )
10901096
1091- var (
1092- client * api.RESTClient
1093- err error
1094- )
1095- if host != "" {
1096- client , err = api .NewRESTClient (api.ClientOptions {Host : host })
1097- } else {
1098- client , err = api .DefaultRESTClient ()
1099- }
1097+ client , err := createRESTClientForHost (host )
11001098 if err != nil {
11011099 remoteLog .Printf ("Failed to create REST client, attempting git fallback: %v" , err )
11021100 return listDirAllFilesViaGitForHost (owner , repo , ref , dirPath , host )
@@ -1108,7 +1106,7 @@ func listDirAllFilesForHost(owner, repo, ref, dirPath, host string) ([]string, e
11081106 Type string `json:"type"`
11091107 }
11101108
1111- endpoint := fmt . Sprintf ( "repos/%s/%s/contents/%s?ref=%s" , owner , repo , dirPath , ref )
1109+ endpoint := buildContentsAPIPath ( owner , repo , dirPath , ref )
11121110 err = client .Get (endpoint , & contents )
11131111 if err != nil {
11141112 errStr := err .Error ()
@@ -1209,15 +1207,7 @@ func ListDirAllFilesRecursivelyForHost(owner, repo, ref, dirPath, host string) (
12091207func listDirAllFilesRecursivelyForHost (owner , repo , ref , dirPath , host string ) ([]string , error ) {
12101208 remoteLog .Printf ("Listing all files recursively in dir for %s/%s@%s (path: %s)" , owner , repo , ref , dirPath )
12111209
1212- var (
1213- client * api.RESTClient
1214- err error
1215- )
1216- if host != "" {
1217- client , err = api .NewRESTClient (api.ClientOptions {Host : host })
1218- } else {
1219- client , err = api .DefaultRESTClient ()
1220- }
1210+ client , err := createRESTClientForHost (host )
12211211 if err != nil {
12221212 remoteLog .Printf ("Failed to create REST client, attempting git fallback: %v" , err )
12231213 return listDirAllFilesRecursivelyViaGitForHost (owner , repo , ref , dirPath , host )
@@ -1262,7 +1252,7 @@ func listContentsRecursivelyWithDepth(client *api.RESTClient, owner, repo, ref,
12621252 Type string `json:"type"`
12631253 }
12641254
1265- endpoint := fmt . Sprintf ( "repos/%s/%s/contents/%s?ref=%s" , owner , repo , dirPath , ref )
1255+ endpoint := buildContentsAPIPath ( owner , repo , dirPath , ref )
12661256 if err := client .Get (endpoint , & contents ); err != nil {
12671257 return nil , fmt .Errorf ("failed to list dir files from %s/%s (path: %s): %w" , owner , repo , dirPath , err )
12681258 }
@@ -1363,15 +1353,7 @@ func ListDirSubdirsForHost(owner, repo, ref, dirPath, host string) ([]string, er
13631353func listDirSubdirsForHost (owner , repo , ref , dirPath , host string ) ([]string , error ) {
13641354 remoteLog .Printf ("Listing subdirs in %s/%s@%s (path: %s)" , owner , repo , ref , dirPath )
13651355
1366- var (
1367- client * api.RESTClient
1368- err error
1369- )
1370- if host != "" {
1371- client , err = api .NewRESTClient (api.ClientOptions {Host : host })
1372- } else {
1373- client , err = api .DefaultRESTClient ()
1374- }
1356+ client , err := createRESTClientForHost (host )
13751357 if err != nil {
13761358 remoteLog .Printf ("Failed to create REST client, attempting git fallback: %v" , err )
13771359 return listDirSubdirsViaGitForHost (owner , repo , ref , dirPath , host )
@@ -1383,7 +1365,7 @@ func listDirSubdirsForHost(owner, repo, ref, dirPath, host string) ([]string, er
13831365 Type string `json:"type"`
13841366 }
13851367
1386- endpoint := fmt . Sprintf ( "repos/%s/%s/contents/%s?ref=%s" , owner , repo , dirPath , ref )
1368+ endpoint := buildContentsAPIPath ( owner , repo , dirPath , ref )
13871369 err = client .Get (endpoint , & contents )
13881370 if err != nil {
13891371 errStr := err .Error ()
0 commit comments