mirror

Mirror free and open-source projects you like with minimal effort
git clone git://git.server.ky/slackcoder/mirror
Log | Files | Refs | README

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 }