iris/_examples/auth/jwt/tutorial/go-client/client.go

109 lines
2.8 KiB
Go
Raw Permalink Normal View History

2020-11-04 20:12:13 +01:00
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strconv"
"strings"
)
// Client is the default http client instance used by the following methods.
var Client = http.DefaultClient
// RequestOption is a function which can be used to modify
// a request instance before Do.
type RequestOption func(*http.Request) error
// WithAccessToken sets the given "token" to the authorization request header.
func WithAccessToken(token []byte) RequestOption {
bearer := "Bearer " + string(token)
return func(req *http.Request) error {
req.Header.Add("Authorization", bearer)
return nil
}
}
// WithContentType sets the content-type request header.
func WithContentType(cType string) RequestOption {
return func(req *http.Request) error {
req.Header.Set("Content-Type", cType)
return nil
}
}
// WithContentLength sets the content-length request header.
func WithContentLength(length int) RequestOption {
return func(req *http.Request) error {
req.Header.Set("Content-Length", strconv.Itoa(length))
return nil
}
}
// Do fires a request to the server.
func Do(method, url string, body io.Reader, opts ...RequestOption) (*http.Response, error) {
req, err := http.NewRequest(method, url, body)
if err != nil {
return nil, err
}
for _, opt := range opts {
if err = opt(req); err != nil {
return nil, err
}
}
return Client.Do(req)
}
// JSON fires a request with "v" as client json data.
func JSON(method, url string, v interface{}, opts ...RequestOption) (*http.Response, error) {
buf := new(bytes.Buffer)
err := json.NewEncoder(buf).Encode(v)
if err != nil {
return nil, err
}
opts = append(opts, WithContentType("application/json; charset=utf-8"))
return Do(method, url, buf, opts...)
}
// Form fires a request with "formData" as client form data.
func Form(method, url string, formData url.Values, opts ...RequestOption) (*http.Response, error) {
encoded := formData.Encode()
body := strings.NewReader(encoded)
opts = append([]RequestOption{
WithContentType("application/x-www-form-urlencoded"),
WithContentLength(len(encoded)),
}, opts...)
return Do(method, url, body, opts...)
}
// BindResponse binds a response body to the "dest" pointer and closes the body.
func BindResponse(resp *http.Response, dest interface{}) error {
contentType := resp.Header.Get("Content-Type")
if idx := strings.IndexRune(contentType, ';'); idx > 0 {
contentType = contentType[0:idx]
}
switch contentType {
case "application/json":
defer resp.Body.Close()
return json.NewDecoder(resp.Body).Decode(dest)
default:
return fmt.Errorf("unsupported content type: %s", contentType)
}
}
// RawResponse simply returns the raw response body.
func RawResponse(resp *http.Response) ([]byte, error) {
defer resp.Body.Close()
return io.ReadAll(resp.Body)
2020-11-04 20:12:13 +01:00
}