Skip to content

Commit 11217af

Browse files
committed
fix: fail if repo has too many star
Signed-off-by: Carlos Alexandro Becker <[email protected]>
1 parent 7f5f63b commit 11217af

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

controller/repositories.go

+21-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package controller
22

33
import (
4+
"errors"
45
"fmt"
56
"html/template"
67
"io/fs"
@@ -45,7 +46,7 @@ func IntValueFormatter(v interface{}) string {
4546
//
4647
// nolint: funlen
4748
// TODO: refactor.
48-
func GetRepoChart(github *github.GitHub, cache *cache.Redis) http.HandlerFunc {
49+
func GetRepoChart(gh *github.GitHub, cache *cache.Redis) http.HandlerFunc {
4950
return func(w http.ResponseWriter, r *http.Request) {
5051
name := fmt.Sprintf(
5152
"%s/%s",
@@ -54,13 +55,24 @@ func GetRepoChart(github *github.GitHub, cache *cache.Redis) http.HandlerFunc {
5455
)
5556
log := log.WithField("repo", name)
5657
defer log.Trace("collect_stars").Stop(nil)
57-
repo, err := github.RepoDetails(r.Context(), name)
58+
repo, err := gh.RepoDetails(r.Context(), name)
5859
if err != nil {
5960
http.Error(w, err.Error(), http.StatusBadRequest)
6061
return
6162
}
62-
stargazers, err := github.Stargazers(r.Context(), repo)
63+
64+
w.Header().Add("content-type", "image/svg+xml;charset=utf-8")
65+
w.Header().Add("cache-control", "public, max-age=86400")
66+
w.Header().Add("date", time.Now().Format(time.RFC1123))
67+
w.Header().Add("expires", time.Now().Format(time.RFC1123))
68+
69+
stargazers, err := gh.Stargazers(r.Context(), repo)
70+
if errors.Is(err, github.ErrTooManyStars) {
71+
w.Write([]byte(errSvg(err)))
72+
return
73+
}
6374
if err != nil {
75+
log.WithError(err).Error("failed to get stars")
6476
http.Error(w, err.Error(), http.StatusServiceUnavailable)
6577
return
6678
}
@@ -119,12 +131,14 @@ func GetRepoChart(github *github.GitHub, cache *cache.Redis) http.HandlerFunc {
119131
Series: []chart.Series{series},
120132
}
121133
defer log.Trace("chart").Stop(&err)
122-
w.Header().Add("content-type", "image/svg+xml;charset=utf-8")
123-
w.Header().Add("cache-control", "public, max-age=86400")
124-
w.Header().Add("date", time.Now().Format(time.RFC1123))
125-
w.Header().Add("expires", time.Now().Format(time.RFC1123))
126134
if err := graph.Render(chart.SVG, w); err != nil {
127135
log.WithError(err).Error("failed to render graph")
128136
}
129137
}
130138
}
139+
140+
func errSvg(err error) string {
141+
return fmt.Sprintf(`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="50">
142+
<text xmlns="http://www.w3.org/2000/svg" y="20" x="100" fill="red">%s</text>
143+
</svg>`, err.Error())
144+
}

internal/github/stars.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
)
1717

1818
var errNoMorePages = errors.New("no more pages to get")
19+
var ErrTooManyStars = errors.New("repo has too many stargazers, github won't allow us to list all stars")
1920

2021
// Stargazer is a star at a given time.
2122
type Stargazer struct {
@@ -25,6 +26,11 @@ type Stargazer struct {
2526
// Stargazers returns all the stargazers of a given repo.
2627
func (gh *GitHub) Stargazers(ctx context.Context, repo Repository) (stars []Stargazer, err error) {
2728
sem := make(chan bool, 4)
29+
30+
if gh.totalPages(repo) > 400 {
31+
return stars, ErrTooManyStars
32+
}
33+
2834
var g errgroup.Group
2935
var lock sync.Mutex
3036
for page := 1; page <= gh.lastPage(repo); page++ {
@@ -130,8 +136,13 @@ func (gh *GitHub) getStargazersPage(ctx context.Context, repo Repository, page i
130136
}
131137
}
132138

139+
func (gh *GitHub) totalPages(repo Repository) int {
140+
return repo.StargazersCount / gh.pageSize
141+
}
142+
143+
133144
func (gh *GitHub) lastPage(repo Repository) int {
134-
return (repo.StargazersCount / gh.pageSize) + 1
145+
return gh.totalPages(repo) + 1
135146
}
136147

137148
func (gh *GitHub) makeStarPageRequest(ctx context.Context, repo Repository, page int, etag string) (*http.Response, error) {

0 commit comments

Comments
 (0)