Skip to content

Commit ed4fd1e

Browse files
authored
Merge pull request #40 from switchboardOp/master
pagination support
2 parents 5111b3b + 446f2f3 commit ed4fd1e

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

exporter/http.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ import (
44
"fmt"
55
"io/ioutil"
66
"net/http"
7+
"strconv"
8+
"strings"
79
"time"
810

911
log "github.com/sirupsen/logrus"
12+
"github.com/tomnomnom/linkheader"
1013
)
1114

1215
func asyncHTTPGets(targets []string, token string) ([]*Response, error) {
16+
// Expand targets by following GitHub pagination links
17+
targets = paginateTargets(targets, token)
1318

1419
// Channels used to enable concurrent requests
1520
ch := make(chan *Response, len(targets))
@@ -44,6 +49,46 @@ func asyncHTTPGets(targets []string, token string) ([]*Response, error) {
4449
}
4550
}
4651

52+
// paginateTargets returns all pages for the provided targets
53+
func paginateTargets(targets []string, token string) []string {
54+
55+
paginated := targets
56+
57+
for _, url := range targets {
58+
59+
// make a request to the original target to get link header if it exists
60+
resp, err := getHTTPResponse(url, token)
61+
if err != nil {
62+
log.Errorf("Error retrieving Link headers, Error: %s", err)
63+
}
64+
65+
if resp.Header["Link"] != nil {
66+
links := linkheader.Parse(resp.Header["Link"][0])
67+
68+
for _, link := range links {
69+
if link.Rel == "last" {
70+
71+
subs := strings.Split(link.URL, "&page=")
72+
73+
lastPage, err := strconv.Atoi(subs[len(subs)-1])
74+
if err != nil {
75+
log.Errorf("Unable to convert page substring to int, Error: %s", err)
76+
}
77+
78+
// add all pages to the slice of targets to return
79+
for page := 2; page <= lastPage; page++ {
80+
pageURL := fmt.Sprintf("%s&page=%v", url, page)
81+
paginated = append(paginated, pageURL)
82+
}
83+
84+
break
85+
}
86+
}
87+
}
88+
}
89+
return paginated
90+
}
91+
4792
// getResponse collects an individual http.response and returns a *Response
4893
func getResponse(url string, token string, ch chan<- *Response) error {
4994

0 commit comments

Comments
 (0)