Skip to content

Commit

Permalink
Add OptionalHeader, OptionalParam
Browse files Browse the repository at this point in the history
See #99
  • Loading branch information
earthboundkid committed Feb 24, 2024
1 parent 4d62ef5 commit d0a8e03
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 9 deletions.
14 changes: 14 additions & 0 deletions builder_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,26 @@ func (rb *Builder) Param(key string, values ...string) *Builder {
return rb
}

// OptionalParam sets a query parameter on a Builder's URL
// only if it is not set by some other call to Param or OptionalParam.
func (rb *Builder) OptionalParam(key string, values ...string) *Builder {
rb.ub.OptionalParam(key, values...)
return rb
}

// Header sets a header on a request. It overwrites the existing values of a key.
func (rb *Builder) Header(key string, values ...string) *Builder {
rb.rb.Header(key, values...)
return rb
}

// OptionalHeader sets a header on a request
// only if it has not already been set by another call to Header or OptionalHeader.
func (rb *Builder) OptionalHeader(key string, values ...string) *Builder {
rb.rb.OptionalHeader(key, values...)
return rb
}

// Cookie adds a cookie to a request.
// Unlike other headers, adding a cookie does not overwrite existing values.
func (rb *Builder) Cookie(name, value string) *Builder {
Expand Down
5 changes: 3 additions & 2 deletions builder_extras.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,12 @@ func (rb *Builder) BodySerializer(s Serializer, v any) *Builder {

// BodyJSON sets the Builder's request body to the marshaled JSON.
// It uses [JSONSerializer] to marshal the object.
// It also sets ContentType to "application/json".
// It also sets ContentType to "application/json"
// if it is not otherwise set.
func (rb *Builder) BodyJSON(v any) *Builder {
return rb.
Body(BodyJSON(v)).
ContentType("application/json")
OptionalHeader("Content-Type", "application/json")
}

// BodyForm sets the Builder's request body to the encoded form.
Expand Down
15 changes: 13 additions & 2 deletions core_req.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ type requestBuilder struct {
}

func (rb *requestBuilder) Header(key string, values ...string) {
rb.headers = append(rb.headers, multimap{key, values})
rb.headers = append(rb.headers, multimap{key, values, false})
}

func (rb *requestBuilder) OptionalHeader(key string, values ...string) {
rb.headers = append(rb.headers, multimap{key, values, true})
}

func (rb *requestBuilder) Cookie(name, value string) {
Expand Down Expand Up @@ -80,7 +84,14 @@ func (rb *requestBuilder) Request(ctx context.Context, u *url.URL) (req *http.Re
req.GetBody = rb.getBody

for _, kv := range rb.headers {
req.Header[http.CanonicalHeaderKey(kv.key)] = kv.values
if !kv.optional {
req.Header[http.CanonicalHeaderKey(kv.key)] = kv.values
}
}
for _, kv := range rb.headers {
if kv.optional && req.Header.Get(kv.key) == "" {
req.Header[http.CanonicalHeaderKey(kv.key)] = kv.values
}
}
for _, kv := range rb.cookies {
req.AddCookie(&http.Cookie{
Expand Down
20 changes: 16 additions & 4 deletions core_url.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
)

type multimap struct {
key string
values []string
key string
values []string
optional bool
}

type kvpair struct {
Expand Down Expand Up @@ -41,7 +42,11 @@ func (ub *urlBuilder) Path(path string) {
}

func (ub *urlBuilder) Param(key string, values ...string) {
ub.params = append(ub.params, multimap{key, values})
ub.params = append(ub.params, multimap{key, values, false})
}

func (ub *urlBuilder) OptionalParam(key string, values ...string) {
ub.params = append(ub.params, multimap{key, values, true})
}

func (ub *urlBuilder) Clone() *urlBuilder {
Expand All @@ -68,7 +73,14 @@ func (ub *urlBuilder) URL() (u *url.URL, err error) {
if len(ub.params) > 0 {
q := u.Query()
for _, kv := range ub.params {
q[kv.key] = kv.values
if !kv.optional {
q[kv.key] = kv.values
}
}
for _, kv := range ub.params {
if kv.optional && minitrue.Or(q[kv.key]...) == "" {
q[kv.key] = kv.values
}
}
u.RawQuery = q.Encode()
}
Expand Down
2 changes: 1 addition & 1 deletion reqxml/body.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ func BodyConfig(v any) requests.Config {
return func(rb *requests.Builder) {
rb.
Body(Body(v)).
ContentType("application/xml")
OptionalHeader("Content-Type", "application/xml")
}
}

0 comments on commit d0a8e03

Please sign in to comment.