Reputation: 1423
I am writing an app that uses the GitHub API to look at repositories in my GitHub orgs. I am using the github.com/google/go-github
library.
I am also using the github.com/gregjones/httpcache
so that I can do token based authentication as well as set the conditional headers for the API calls. I have got authentication working thus:
ctx := context.Background()
// GitHUb API authentication
transport = &oauth2.Transport{
Source: oauth2.StaticTokenSource(
&oauth2.Token{
AccessToken: gh.tokens.GitHub.Token,
},
),
}
// Configure HTTP memory caching
transport = &httpcache.Transport{
Transport: transport,
Cache: httpcache.NewMemoryCache(),
MarkCachedResponses: true,
}
// Create the http client that GutHUb will use
httpClient := &http.Client{
Transport: transport,
}
// Attempt to login to GitHub
client := github.NewClient(httpClient)
However I am unable to work out how to add the necessary If-Match
header when I use client.Repositories.Get
for example. This is so I can work out if the repo has changed in the last 24 hours for exampple.
I have searched how to do this, but the examples I come across show how to create an HTTP client and then create a request (so the headers can be added) and then do a Do
action on it. However As I am using the client directly I do not have that option.
The documentation for go-github
states that for conditional requests:
The GitHub API has good support for conditional requests which will help prevent you from burning through your rate limit, as well as help speed up your application. go-github does not handle conditional requests directly, but is instead designed to work with a caching http.Transport. We recommend using https://github.com/gregjones/httpcache for that.
Learn more about GitHub conditional requests at https://developer.github.com/v3/#conditional-requests.
I do not know how to add it in my code, any help is greatly appreciated.
Upvotes: 0
Views: 830
Reputation: 1423
As tends to be the case with these things, shortly after posting my question I found the answer.
The trick is to set the headers using the Base
in the Oauth2 transport thus:
transport = &oauth2.Transport{
Source: oauth2.StaticTokenSource(
&oauth2.Token{
AccessToken: gh.tokens.GitHub.Token,
},
),
Base: &transportHeaders{
modifiedSince: modifiedSince,
},
}
The struct and method look like:
type transportHeaders struct {
modifiedSince string
}
func (t *transportHeaders) RoundTrip(req *http.Request) (*http.Response, error) {
// Determine the last modified date based on the transportHeader options
// Do not add any headers if blank or zero
if t.modifiedSince != "" {
req.Header.Set("If-Modified-Since", t.modifiedSince)
}
return http.DefaultTransport.RoundTrip(req)
}
So by doing this I can intercept the call to RoundTrip and add my own header. This now means I can check the resources and see if they return a 304 HTTP status code. For example:
ERRO[0001] Error retrieving repository error="GET https://api.github.com/repos/chef-partners/camsa-setup: 304 []" name=camsa-setup vcs=github
I worked out how to do this after coming across this page - https://github.com/rmichela/go-reddit/blob/bd882abbb7496c54dbde66d92c35ad95d4db1211/authenticator.go#L117
Upvotes: 0