Skip to content

Commit

Permalink
feat: with auth-basic header
Browse files Browse the repository at this point in the history
  • Loading branch information
sonirico committed Sep 7, 2022
1 parent bfe3afb commit 70149ed
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 2 deletions.
28 changes: 28 additions & 0 deletions adapter_fasthttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ func (a *fastHttpReqAdapter) SetHeader(key, value string) {
a.req.Header.Set(key, value)
}

func (a *fastHttpReqAdapter) GetHeader(key string) (string, bool) {
data := a.req.Header.Peek(key)
if data == nil || len(data) == 0 {
return "", false
}
bts := make([]byte, len(data))
copy(bts, data)
return string(bts), true
}

func (a *fastHttpReqAdapter) SetMethod(method string) {
a.req.Header.SetMethod(method)
}
Expand Down Expand Up @@ -151,3 +161,21 @@ func (a *fastHttpResAdapter) StatusText() string {
func (a *fastHttpResAdapter) Body() io.ReadCloser {
return io.NopCloser(bytes.NewReader(a.res.Body()))
}

func (a *fastHttpResAdapter) AddHeader(key, value string) {
a.res.Header.Add(key, value)
}

func (a *fastHttpResAdapter) SetHeader(key, value string) {
a.res.Header.Set(key, value)
}

func (a *fastHttpResAdapter) GetHeader(key string) (string, bool) {
data := a.res.Header.Peek(key)
if data == nil || len(data) == 0 {
return "", false
}
bts := make([]byte, len(data))
copy(bts, data)
return string(bts), true
}
18 changes: 18 additions & 0 deletions adapter_native.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ func (a *nativeReqAdapter) SetHeader(key, value string) {
a.req.Header.Set(key, value)
}

func (a *nativeReqAdapter) GetHeader(key string) (string, bool) {
s := a.req.Header.Get(key)
return s, len(s) > 0
}

func (a *nativeReqAdapter) SetMethod(method string) {
a.req.Method = method
}
Expand Down Expand Up @@ -112,3 +117,16 @@ func (a *nativeResAdapter) StatusText() string {
func (a *nativeResAdapter) Body() io.ReadCloser {
return a.res.Body
}

func (a *nativeResAdapter) AddHeader(key, value string) {
a.res.Header.Add(key, value)
}

func (a *nativeResAdapter) SetHeader(key, value string) {
a.res.Header.Set(key, value)
}

func (a *nativeResAdapter) GetHeader(key string) (string, bool) {
s := a.res.Header.Get(key)
return s, len(s) > 0
}
4 changes: 4 additions & 0 deletions call_req.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ func (c *Call[T]) WithHeaderFunc(fn func() (key, value string, override bool)) *
return c.withReq(WithHeaderFunc[T](fn))
}

func (c *Call[T]) WithBasicAuth(user, pass string) *Call[T] {
return c.withReq(WithBasicAuth[T](user, pass))
}

func (c *Call[T]) WithContentType(ct ContentType) *Call[T] {
return c.withReq(WithContentType[T](ct))
}
12 changes: 10 additions & 2 deletions endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ import (
)

type (
Request interface {
SetMethod(string)
Header interface {
SetHeader(k, v string)
AddHeader(k, v string)
GetHeader(k string) (string, bool)
}

Request interface {
Header

SetMethod(string)
SetURL(*url.URL)
// SetBodyStream sets the stream of body data belonging to a request. bodySize parameter is needed
// when using fasthttp implementation.
Expand All @@ -24,6 +30,8 @@ type (
}

Response interface {
Header

Status() int
StatusText() string
Body() io.ReadCloser
Expand Down
1 change: 1 addition & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import "github.com/pkg/errors"
var (
ErrAssertion = errors.New("assertion was unmet")
ErrUnexpectedStatusCode = errors.Wrap(ErrAssertion, "unexpected status code")
ErrInsufficientParams = errors.New("insufficient params")
)
3 changes: 3 additions & 0 deletions examples/mock/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func main() {
call := withttp.NewCall[Order](withttp.WithFasthttp()).
WithURL("https://github.com/").
WithMethod(http.MethodGet).
WithBasicAuth("pepito", "secret").
WithHeader("User-Agent", "withttp/0.1.0 See https://github.com/sonirico/withttp", false).
WithHeaderFunc(func() (key, value string, override bool) {
key = "X-Date"
Expand All @@ -58,4 +59,6 @@ func main() {
if err != nil {
panic(err)
}

log.Println(call.Req.GetHeader("Authorization"))
}
19 changes: 19 additions & 0 deletions utils_nalloc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package withttp

import (
"reflect"
"unsafe"
)

func S2B(s string) (bts []byte) {
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
bh := (*reflect.SliceHeader)(unsafe.Pointer(&bts))
bh.Data = sh.Data
bh.Cap = sh.Len
bh.Len = sh.Len
return
}

func B2S(data []byte) string {
return *(*string)(unsafe.Pointer(&data))
}
46 changes: 46 additions & 0 deletions with_req.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ package withttp
import (
"bytes"
"context"
"encoding/base64"
"fmt"
"io"
"net/url"
"sync"

"github.com/pkg/errors"

"github.com/sonirico/withttp/codec"
)

Expand All @@ -16,6 +20,16 @@ func WithHeader[T any](k, v string, override bool) CallReqOptionFunc[T] {
}
}

func WithBasicAuth[T any](user, pass string) CallReqOptionFunc[T] {
return func(_ *Call[T], req Request) error {
header, err := CreateAuthorizationHeader(authHeaderKindBasic, user, pass)
if err != nil {
return err
}
return ConfigureHeader(req, "authorization", header, true)
}
}

func WithHeaderFunc[T any](fn func() (string, string, bool)) CallReqOptionFunc[T] {
return func(_ *Call[T], req Request) error {
k, v, override := fn()
Expand All @@ -30,6 +44,38 @@ func WithContentType[T any](ct ContentType) CallReqOptionFunc[T] {
}
}

type authHeaderKind string

var (
authHeaderKindBasic authHeaderKind = "Basic"
)

func (a authHeaderKind) Codec() func(...string) (string, error) {
switch a {
case authHeaderKindBasic:
return func(s ...string) (string, error) {
if len(s) < 2 {
return "", errors.Wrapf(ErrAssertion, "header kind: %s", a)
}
user := s[0]
pass := s[1]

return base64.StdEncoding.EncodeToString(S2B(user + ":" + pass)), nil
}
default:
panic("unknown auth header kind")
}
}

func CreateAuthorizationHeader(kind authHeaderKind, user, pass string) (string, error) {
fn := kind.Codec()
header, err := fn(user, pass)
if err != nil {
return header, err
}
return fmt.Sprintf("%s %s", kind, header), nil
}

func ConfigureHeader(req Request, key, value string, override bool) error {
if override {
req.SetHeader(key, value)
Expand Down

0 comments on commit 70149ed

Please sign in to comment.