aboutsummaryrefslogtreecommitdiffsponsor
path: root/internal/github/rest_client.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/github/rest_client.go')
-rw-r--r--internal/github/rest_client.go115
1 files changed, 115 insertions, 0 deletions
diff --git a/internal/github/rest_client.go b/internal/github/rest_client.go
new file mode 100644
index 0000000..6fdd31c
--- /dev/null
+++ b/internal/github/rest_client.go
@@ -0,0 +1,115 @@
+package github
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "net/http"
+)
+
+type HTTPRequester interface {
+ Do(req *http.Request) (*http.Response, error)
+}
+
+type BearerAuthClient struct {
+ HTTPRequester
+ Username string
+ Password string
+}
+
+func WithBearerAuth(
+ cli HTTPRequester,
+ username, password string,
+) *BearerAuthClient {
+ return &BearerAuthClient{cli, username, password}
+}
+
+func (s *BearerAuthClient) Do(req *http.Request) (*http.Response, error) {
+ if s.Username != "" && s.Password != "" {
+ value := fmt.Sprintf("Bearer %s:%s", s.Username, s.Password)
+ req.Header.Set("Authorization", value)
+ }
+ return s.HTTPRequester.Do(req)
+}
+
+type jsonClient struct {
+ Client HTTPRequester
+ basePath string
+}
+
+func newJSONClient(
+ cli HTTPRequester,
+ basePath string,
+) *jsonClient {
+ return &jsonClient{
+ Client: cli,
+ basePath: basePath,
+ }
+}
+
+func newHTTPJSONReq(
+ method string,
+ url string,
+ req interface{},
+) (*http.Request, error) {
+ body := &bytes.Buffer{}
+ if req != nil {
+ buf, err := json.Marshal(req)
+ if err != nil {
+ return nil, err
+ }
+ body = bytes.NewBuffer(buf)
+ }
+ httpReq, err := http.NewRequest(method, url, body)
+ if err != nil {
+ return nil, err
+ }
+ httpReq.Header.Set("Content-Type", "application/json")
+ httpReq.Header.Set("Accept", "application/json")
+ return httpReq, nil
+}
+
+func decodeJSONResponse(httpResp *http.Response, resp interface{}) error {
+ if httpResp.StatusCode/100 != 2 {
+ return fmt.Errorf(
+ "received HTTP status code %d (%s)",
+ httpResp.StatusCode,
+ httpResp.Status,
+ )
+ }
+ if resp == nil {
+ return nil
+ }
+ err := json.NewDecoder(httpResp.Body).Decode(resp)
+ if err != nil {
+ return err
+ }
+ return err
+}
+
+func (s *jsonClient) Request(
+ method string,
+ statusCode *int,
+ path string,
+ req, resp interface{},
+) (int, error) {
+ url := fmt.Sprintf("%s/%s", s.basePath, path)
+ httpReq, err := newHTTPJSONReq(method, url, req)
+ if err != nil {
+ return 0, err
+ }
+ httpResp, err := s.Client.Do(httpReq)
+ if err != nil {
+ return 0, err
+ }
+ defer httpResp.Body.Close()
+
+ err = decodeJSONResponse(httpResp, resp)
+ if err != nil {
+ return httpResp.StatusCode, err
+ }
+ if statusCode != nil && httpResp.StatusCode != *statusCode {
+ return httpResp.StatusCode, fmt.Errorf("expected status code %d but got %d", *statusCode, httpResp.StatusCode)
+ }
+ return httpResp.StatusCode, nil
+}