Files
request/github/github.go
T
Sirherobrine23 1903a79482
Golang test / go-test (push) Successful in 1m59s
Update to V3 packages
2025-10-26 16:50:10 -03:00

126 lines
3.7 KiB
Go

// Client to Github APIs
package github
import (
"errors"
"fmt"
"io"
"net/http"
"net/url"
"strconv"
"time"
"sirherobrine23.com.br/go-bds/request/v3"
)
var (
GithubAPI = &url.URL{Scheme: "https", Host: "api.github.com", Path: "/"} // Defaut github api
ErrToken error = errors.New("require Token to request")
err500 = request.ProcessRequest(func(req *request.RequestStatus) (res *http.Response, err error) {
buffLog, _ := io.ReadAll(req.Res.Body)
if res.Body != nil {
res.Body.Close()
}
if len(buffLog) == 0 {
buffLog = []byte("not body response")
}
return nil, fmt.Errorf("cannot process request (%s), github api is down: %s", res.Request.URL.String(), buffLog)
})
processCodes = request.CodeProcess{
500: err500,
501: err500,
401: func(req *request.RequestStatus) (res *http.Response, err error) {
if res.Body != nil {
res.Body.Close()
}
return nil, ErrToken
},
403: func(req *request.RequestStatus) (res *http.Response, err error) {
if res.Body != nil {
res.Body.Close()
}
if retryAfter := res.Header.Get("retry-after"); retryAfter != "" && retryAfter != "0" {
if dateSec, err := strconv.ParseInt(retryAfter, 10, 64); err == nil {
<-time.After(time.Until(time.Unix(dateSec, dateSec*int64(time.Second))))
return request.Request(req.URL, req.Options)
}
} else if remining := res.Header.Get("x-ratelimit-remaining"); remining == "0" {
if reset := res.Header.Get("x-ratelimit-reset"); reset != "" {
if dateSec, err := strconv.ParseInt(reset, 10, 64); err == nil {
<-time.After(time.Until(time.Unix(dateSec, dateSec*int64(time.Second))))
return request.Request(req.URL, req.Options)
}
}
}
return nil, errors.New("cannot process request, authorization or not have permission")
},
429: func(req *request.RequestStatus) (res *http.Response, err error) {
if res.Body != nil {
res.Body.Close()
}
if retryAfter := res.Header.Get("retry-after"); retryAfter != "" && retryAfter != "0" {
if dateSec, err := strconv.ParseInt(retryAfter, 10, 64); err == nil {
<-time.After(time.Until(time.Unix(dateSec, dateSec*int64(time.Second))))
return request.Request(req.URL, req.Options)
}
} else if remining := res.Header.Get("x-ratelimit-remaining"); remining == "0" {
if reset := res.Header.Get("x-ratelimit-reset"); reset != "" {
if dateSec, err := strconv.ParseInt(reset, 10, 64); err == nil {
<-time.After(time.Until(time.Unix(dateSec, dateSec*int64(time.Second))))
return request.Request(req.URL, req.Options)
}
}
}
return nil, errors.New("many requests to github api")
},
}
)
// Create new Github Client with Github.com API host
func NewClient(Username, Repository, Token string) *Github {
return &Github{
Host: GithubAPI,
Repository: Repository,
Username: Username,
Token: Token,
}
}
// Create new Github Client
func NewClientHost(apiHost, Username, Repository, Token string) (*Github, error) {
hostUrl, err := url.Parse(apiHost)
if err != nil {
return nil, err
}
return &Github{
Host: hostUrl,
Repository: Repository,
Username: Username,
Token: Token,
}, nil
}
// Basic client to Github APIs
type Github struct {
Host *url.URL // Github API host
Token string // Github Token
// User and Repository name
Username, Repository string
}
// Return escapated Owner+/+Repository
func (client Github) repoPath() string {
return fmt.Sprintf("%s/%s", url.PathEscape(client.Username), url.PathEscape(client.Repository))
}
// Set token to header
func (client Github) authHeader(header *http.Header) {
if client.Token != "" {
(*header)["Authorization"] = []string{fmt.Sprintf("Bearer %s", client.Token)}
}
}