Skip to content

Commit

Permalink
renames, add some additional functions for ease of use
Browse files Browse the repository at this point in the history
Signed-off-by: Sarah Funkhouser <147884153+golanglemonade@users.noreply.github.com>
  • Loading branch information
golanglemonade committed Sep 4, 2024
1 parent c373422 commit 95c61d9
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 64 deletions.
3 changes: 3 additions & 0 deletions headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const (
HeaderProxyAuthorization = "Proxy-Authorization"
HeaderWWWAuthenticate = "WWW-Authenticate"

BearerAuthHeader = "Bearer "
BasicAuthHeader = "Basic "

// Caching
HeaderAge = "Age"
HeaderCacheControl = "Cache-Control"
Expand Down
2 changes: 1 addition & 1 deletion mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func MockHandler(statusCode int, options ...Option) http.Handler {
r := MustNew(options...)

return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
req, err := r.RequestContext(request.Context())
req, err := r.RequestWithContext(request.Context())
if err != nil {
panic(err)
}
Expand Down
4 changes: 2 additions & 2 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func BasicAuth(username, password string) Option {
return DeleteHeader(HeaderAuthorization)
}

return Header(HeaderAuthorization, "Basic "+basicAuth(username, password))
return Header(HeaderAuthorization, BearerAuthHeader+basicAuth(username, password))
}

// basicAuth returns the base64 encoded username:password for basic auth copied from net/http
Expand All @@ -166,7 +166,7 @@ func BearerAuth(token string) Option {
return DeleteHeader(HeaderAuthorization)
}

return Header(HeaderAuthorization, "Bearer "+token)
return Header(HeaderAuthorization, BearerAuthHeader+token)
}

// URL sets the request URL
Expand Down
2 changes: 1 addition & 1 deletion options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ func TestBasicAuth(t *testing.T) {
reqs, err := New(c.options...)
require.NoError(t, err)

req, err := reqs.RequestContext(context.Background())
req, err := reqs.RequestWithContext(context.Background())
require.NoError(t, err)

username, password, ok := req.BasicAuth()
Expand Down
22 changes: 11 additions & 11 deletions packagefunctions.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,27 @@ func Request(opts ...Option) (*http.Request, error) {
return DefaultRequester.Request(opts...)
}

// RequestContext does the same as Request(), but attaches a Context to the request
func RequestContext(ctx context.Context, opts ...Option) (*http.Request, error) {
return DefaultRequester.RequestContext(ctx, opts...)
// RequestWithContext does the same as Request(), but attaches a Context to the request
func RequestWithContext(ctx context.Context, opts ...Option) (*http.Request, error) {
return DefaultRequester.RequestWithContext(ctx, opts...)
}

// Send uses the DefaultRequester to create a request and execute it
func Send(opts ...Option) (*http.Response, error) {
return DefaultRequester.Send(opts...)
}

// SendContext does the same as Send(), but attaches a Context to the request
func SendContext(ctx context.Context, opts ...Option) (*http.Response, error) {
return DefaultRequester.SendContext(ctx, opts...)
}

// ReceiveContext does the same as Receive(), but attaches a Context to the request
func ReceiveContext(ctx context.Context, into interface{}, opts ...Option) (*http.Response, error) {
return DefaultRequester.ReceiveContext(ctx, into, opts...)
// SendWithContext does the same as Send(), but attaches a Context to the request
func SendWithContext(ctx context.Context, opts ...Option) (*http.Response, error) {
return DefaultRequester.SendWithContext(ctx, opts...)
}

// Receive uses the DefaultRequester to create a request, execute it, and read the response
func Receive(into interface{}, opts ...Option) (*http.Response, error) {
return DefaultRequester.Receive(into, opts...)
}

// ReceiveWithContext does the same as Receive(), but attaches a Context to the request
func ReceiveWithContext(ctx context.Context, into interface{}, opts ...Option) (*http.Response, error) {
return DefaultRequester.ReceiveWithContext(ctx, into, opts...)
}
6 changes: 3 additions & 3 deletions packagefunctions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type testContextKey string
const colorContextKey = testContextKey("color")

func TestRequestContext(t *testing.T) {
req, err := RequestContext(
req, err := RequestWithContext(
context.WithValue(context.Background(), colorContextKey, "green"),
Get("http://blue.com/red"),
)
Expand All @@ -47,7 +47,7 @@ func TestSend(t *testing.T) {
func TestSendContext(t *testing.T) {
i := Inspector{}

resp, err := SendContext(
resp, err := SendWithContext(
context.WithValue(context.Background(), colorContextKey, "blue"),
Get("/profile"),
WithDoer(MockDoer(204)),
Expand Down Expand Up @@ -82,7 +82,7 @@ func TestReceive(t *testing.T) {

i := Inspector{}

resp, err := ReceiveContext(
resp, err := ReceiveWithContext(
context.WithValue(context.Background(), colorContextKey, "yellow"),
&m,
Get("/red"),
Expand Down
55 changes: 35 additions & 20 deletions requester.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@ func (r *Requester) Clone() *Requester {

// Request returns a new http.Request
func (r *Requester) Request(opts ...Option) (*http.Request, error) {
return r.RequestContext(context.Background(), opts...)
return r.RequestWithContext(context.Background(), opts...)
}

// RequestContext does the same as Request, but requires a context
func (r *Requester) RequestContext(ctx context.Context, opts ...Option) (*http.Request, error) {
// RequestWithContext does the same as Request, but requires a context
func (r *Requester) RequestWithContext(ctx context.Context, opts ...Option) (*http.Request, error) {
requester, err := r.withOpts(opts...)
if err != nil {
return nil, err
Expand Down Expand Up @@ -208,7 +208,7 @@ func (r *Requester) getRequestBody() (body io.Reader, contentType string, _ erro

// Send executes a request with the Doer
func (r *Requester) Send(opts ...Option) (*http.Response, error) {
return r.SendContext(context.Background(), opts...)
return r.SendWithContext(context.Background(), opts...)
}

// withOpts is like With(), but skips the clone if there are no options to apply
Expand All @@ -220,14 +220,14 @@ func (r *Requester) withOpts(opts ...Option) (*Requester, error) {
return r, nil
}

// SendContext does the same as Send, but requires a context
func (r *Requester) SendContext(ctx context.Context, opts ...Option) (*http.Response, error) {
// SendWithContext does the same as Send, but requires a context
func (r *Requester) SendWithContext(ctx context.Context, opts ...Option) (*http.Response, error) {
reqs, err := r.withOpts(opts...)
if err != nil {
return nil, err
}

req, err := reqs.RequestContext(ctx)
req, err := reqs.RequestWithContext(ctx)
if err != nil {
return nil, err
}
Expand All @@ -249,35 +249,38 @@ func (r *Requester) Do(req *http.Request) (*http.Response, error) {

// Receive creates a new HTTP request and returns the response
func (r *Requester) Receive(into interface{}, opts ...Option) (resp *http.Response, err error) {
return r.ReceiveContext(context.Background(), into, opts...)
return r.ReceiveWithContext(context.Background(), into, opts...)
}

// ReceiveContext does the same as Receive, but requires a context
func (r *Requester) ReceiveContext(ctx context.Context, into interface{}, opts ...Option) (resp *http.Response, err error) {
// ReceiveWithContext does the same as Receive, but requires a context
func (r *Requester) ReceiveWithContext(ctx context.Context, into interface{}, opts ...Option) (resp *http.Response, err error) {
// if the first option is an Option, we need to copy those over and set into to nil
if opt, ok := into.(Option); ok {
opts = append(opts, nil)
copy(opts[1:], opts)
opts[0] = opt
into = nil
}

// apply the options to the requester
r, err = r.withOpts(opts...)
if err != nil {
return nil, err
}

resp, err = r.SendContext(ctx)

body, bodyReadError := readBody(resp)

// send the request
resp, err = r.SendWithContext(ctx)
if err != nil {
return resp, err
}

// read the body
body, bodyReadError := readBody(resp)
if bodyReadError != nil {
return resp, bodyReadError
}

// if the into is not nil, unmarshal the body into it
if into != nil {
unmarshaler := r.Unmarshaler
if unmarshaler == nil {
Expand All @@ -290,24 +293,26 @@ func (r *Requester) ReceiveContext(ctx context.Context, into interface{}, opts .
return resp, err
}

// readBody reads the body of an HTTP response
func readBody(resp *http.Response) ([]byte, error) {
// check for a nil response
if resp == nil || resp.Body == nil || resp.Body == http.NoBody {
return nil, nil
}

defer resp.Body.Close()

cls := resp.Header.Get(HeaderContentLength)
contentLengthHeader := resp.Header.Get(HeaderContentLength)

var cl int64
var contentLength int64

if cls != "" {
cl, _ = strconv.ParseInt(cls, 10, 0)
if contentLengthHeader != "" {
contentLength, _ = strconv.ParseInt(contentLengthHeader, 10, 0)
}

buf := bytes.Buffer{}
if cl > 0 {
buf.Grow(int(cl))
if contentLength > 0 {
buf.Grow(int(contentLength))
}

if _, err := buf.ReadFrom(resp.Body); err != nil {
Expand Down Expand Up @@ -353,3 +358,13 @@ func (r *Requester) HTTPClient() *http.Client {

return client
}

// CookieJar returns the CookieJar used by the Requester, if it exists
func (r *Requester) CookieJar() http.CookieJar {
client := r.HTTPClient()
if client == nil {
return nil
}

return client.Jar
}
Loading

0 comments on commit 95c61d9

Please sign in to comment.