rest_client.go (2336B)
1 package github 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 ) 9 10 type HTTPRequester interface { 11 Do(req *http.Request) (*http.Response, error) 12 } 13 14 type BearerAuthClient struct { 15 HTTPRequester 16 Username string 17 Password string 18 } 19 20 func WithBearerAuth( 21 cli HTTPRequester, 22 username, password string, 23 ) *BearerAuthClient { 24 return &BearerAuthClient{cli, username, password} 25 } 26 27 func (s *BearerAuthClient) Do(req *http.Request) (*http.Response, error) { 28 if s.Username != "" && s.Password != "" { 29 value := fmt.Sprintf("Bearer %s:%s", s.Username, s.Password) 30 req.Header.Set("Authorization", value) 31 } 32 return s.HTTPRequester.Do(req) 33 } 34 35 type jsonClient struct { 36 Client HTTPRequester 37 basePath string 38 } 39 40 func newJSONClient( 41 cli HTTPRequester, 42 basePath string, 43 ) *jsonClient { 44 return &jsonClient{ 45 Client: cli, 46 basePath: basePath, 47 } 48 } 49 50 func newHTTPJSONReq( 51 method string, 52 url string, 53 req interface{}, 54 ) (*http.Request, error) { 55 body := &bytes.Buffer{} 56 if req != nil { 57 buf, err := json.Marshal(req) 58 if err != nil { 59 return nil, err 60 } 61 body = bytes.NewBuffer(buf) 62 } 63 httpReq, err := http.NewRequest(method, url, body) 64 if err != nil { 65 return nil, err 66 } 67 httpReq.Header.Set("Content-Type", "application/json") 68 httpReq.Header.Set("Accept", "application/json") 69 return httpReq, nil 70 } 71 72 func decodeJSONResponse(httpResp *http.Response, resp interface{}) error { 73 if httpResp.StatusCode/100 != 2 { 74 return fmt.Errorf( 75 "received HTTP status code %d (%s)", 76 httpResp.StatusCode, 77 httpResp.Status, 78 ) 79 } 80 if resp == nil { 81 return nil 82 } 83 err := json.NewDecoder(httpResp.Body).Decode(resp) 84 if err != nil { 85 return err 86 } 87 return err 88 } 89 90 func (s *jsonClient) Request( 91 method string, 92 statusCode *int, 93 path string, 94 req, resp interface{}, 95 ) (int, error) { 96 url := fmt.Sprintf("%s/%s", s.basePath, path) 97 httpReq, err := newHTTPJSONReq(method, url, req) 98 if err != nil { 99 return 0, err 100 } 101 httpResp, err := s.Client.Do(httpReq) 102 if err != nil { 103 return 0, err 104 } 105 defer httpResp.Body.Close() 106 107 err = decodeJSONResponse(httpResp, resp) 108 if err != nil { 109 return httpResp.StatusCode, err 110 } 111 if statusCode != nil && httpResp.StatusCode != *statusCode { 112 return httpResp.StatusCode, fmt.Errorf("expected status code %d but got %d", *statusCode, httpResp.StatusCode) 113 } 114 return httpResp.StatusCode, nil 115 }