git.iko.soy/typeable/oauth2-proxy
on dd4fa41 help sign in
117 lines 2.9 kB history raw
1package requests
3import (
4 "context"
5 "fmt"
6 "io"
7 "net/http"
8)
10// Builder allows users to construct a request and then execute the
11// request via Do().
12// Do returns a Result which allows the user to get the body,
13// unmarshal the body into an interface, or into a simplejson.Json.
14type Builder interface {
15 WithContext(context.Context) Builder
16 WithBody(io.Reader) Builder
17 WithMethod(string) Builder
18 WithHeaders(http.Header) Builder
19 SetHeader(key, value string) Builder
20 Do() Result
23type builder struct {
24 context context.Context
25 method string
26 endpoint string
27 body io.Reader
28 header http.Header
29 result *result
32// New provides a new Builder for the given endpoint.
33func New(endpoint string) Builder {
34 return &builder{
35 endpoint: endpoint,
36 method: "GET",
37 }
40// WithContext adds a context to the request.
41// If no context is provided, context.Background() is used instead.
42func (r *builder) WithContext(ctx context.Context) Builder {
43 r.context = ctx
44 return r
47// WithBody adds a body to the request.
48func (r *builder) WithBody(body io.Reader) Builder {
49 r.body = body
50 return r
53// WithMethod sets the request method. Defaults to "GET".
54func (r *builder) WithMethod(method string) Builder {
55 r.method = method
56 return r
59// WithHeaders replaces the request header map with the given header map.
60func (r *builder) WithHeaders(header http.Header) Builder {
61 r.header = header
62 return r
65// SetHeader sets a single header to the given value.
66// May be used to add multiple headers.
67func (r *builder) SetHeader(key, value string) Builder {
68 if r.header == nil {
69 r.header = make(http.Header)
70 }
71 r.header.Set(key, value)
72 return r
75// Do performs the request and returns the response in its raw form.
76// If the request has already been performed, returns the previous result.
77// This will not allow you to repeat a request.
78func (r *builder) Do() Result {
79 if r.result != nil {
80 // Request has already been done
81 return r.result
82 }
84 // Must provide a non-nil context to NewRequestWithContext
85 if r.context == nil {
86 r.context = context.Background()
87 }
89 return r.do()
92// do creates the request, executes it with the default client and extracts the
93// the body into the response
94func (r *builder) do() Result {
95 req, err := http.NewRequestWithContext(r.context, r.method, r.endpoint, r.body)
96 if err != nil {
97 r.result = &result{err: fmt.Errorf("error creating request: %v", err)}
98 return r.result
99 }
100 req.Header = r.header
102 resp, err := http.DefaultClient.Do(req)
103 if err != nil {
104 r.result = &result{err: fmt.Errorf("error performing request: %v", err)}
105 return r.result
106 }
108 defer resp.Body.Close()
109 body, err := io.ReadAll(resp.Body)
110 if err != nil {
111 r.result = &result{err: fmt.Errorf("error reading response body: %v", err)}
112 return r.result
113 }
115 r.result = &result{response: resp, body: body}
116 return r.result