diff --git a/github/repos_contents.go b/github/repos_contents.go index 520cf2f..6202f19 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -127,9 +127,11 @@ func (s *RepositoriesService) DownloadContents(owner, repo, filepath string, opt // value and the other will be nil. // // GitHub API docs: http://developer.github.com/v3/repos/contents/#get-contents -func (s *RepositoriesService) GetContents(owner, repo, path string, opt *RepositoryContentGetOptions) (fileContent *RepositoryContent, - directoryContent []*RepositoryContent, resp *Response, err error) { - u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) +func (s *RepositoriesService) GetContents(owner, repo, path string, opt *RepositoryContentGetOptions) (fileContent *RepositoryContent, directoryContent []*RepositoryContent, resp *Response, err error) { + // escape characters not allowed in URL path. This actually escapes a + // lot more, but seems to be harmless. + escapedPath := url.QueryEscape(path) + u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, escapedPath) u, err = addOptions(u, opt) if err != nil { return nil, nil, nil, err diff --git a/github/repos_contents_test.go b/github/repos_contents_test.go index 8ab3ecd..c09775c 100644 --- a/github/repos_contents_test.go +++ b/github/repos_contents_test.go @@ -141,6 +141,19 @@ func TestRepositoriesService_GetContents_File(t *testing.T) { } } +func TestRepositoriesService_GetContents_FilenameNeedsEscape(t *testing.T) { + setup() + defer teardown() + mux.HandleFunc("/repos/o/r/contents/p#?%/中.go", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{}`) + }) + _, _, _, err := client.Repositories.GetContents("o", "r", "p#?%/中.go", &RepositoryContentGetOptions{}) + if err != nil { + t.Fatalf("Repositories.GetContents returned error: %v", err) + } +} + func TestRepositoriesService_GetContents_Directory(t *testing.T) { setup() defer teardown()