Skip to content

Commit

Permalink
fix: add hash to http builder
Browse files Browse the repository at this point in the history
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
  • Loading branch information
CarstenLeue committed Feb 8, 2024
1 parent 9f6b6d4 commit 6f91e91
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 1 deletion.
4 changes: 4 additions & 0 deletions bytes/bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@

package bytes

func Empty() []byte {
return Monoid.Empty()
}

func ToString(a []byte) string {
return string(a)
}
Expand Down
2 changes: 1 addition & 1 deletion context/readerioeither/http/builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
func TestBuilderWithQuery(t *testing.T) {
// add some query
withLimit := R.WithQueryArg("limit")("10")
withURL := R.WithUrl("http://www.example.org?a=b")
withURL := R.WithURL("http://www.example.org?a=b")

b := F.Pipe2(
R.Default,
Expand Down
43 changes: 43 additions & 0 deletions http/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@
package builder

import (
"bytes"
"crypto/sha256"
"fmt"
"net/http"
"net/url"

A "github.com/IBM/fp-go/array"
B "github.com/IBM/fp-go/bytes"
E "github.com/IBM/fp-go/either"
ENDO "github.com/IBM/fp-go/endomorphism"
F "github.com/IBM/fp-go/function"
Expand All @@ -29,6 +34,7 @@ import (
LZ "github.com/IBM/fp-go/lazy"
L "github.com/IBM/fp-go/optics/lens"
O "github.com/IBM/fp-go/option"
R "github.com/IBM/fp-go/record"
S "github.com/IBM/fp-go/string"
T "github.com/IBM/fp-go/tuple"
)
Expand Down Expand Up @@ -138,6 +144,9 @@ var (
WithBytes,
ENDO.Chain(WithContentType(C.FormEncoded)),
)

// bodyAsBytes returns a []byte with a fallback to the empty array
bodyAsBytes = O.Fold(B.Empty, E.Fold(F.Ignore1of1[error](B.Empty), F.Identity[[]byte]))
)

func setRawQuery(u *url.URL, raw string) *url.URL {
Expand Down Expand Up @@ -272,6 +281,11 @@ func (builder *Builder) GetHeaderValues(name string) []string {
return builder.headers.Values(name)
}

// GetHash returns a hash value for the builder that can be used as a cache key
func (builder *Builder) GetHash() string {
return MakeHash(builder)
}

// Header returns a [L.Lens] for a single header
func Header(name string) L.Lens[*Builder, O.Option[string]] {
get := getHeader(name)
Expand Down Expand Up @@ -342,3 +356,32 @@ func WithQueryArg(name string) func(value string) Endomorphism {
func WithoutQueryArg(name string) Endomorphism {
return QueryArg(name).Set(noQueryArg)
}

func hashWriteValue(buf *bytes.Buffer, value string) *bytes.Buffer {
buf.WriteString(value)
return buf
}

func hashWriteQuery(name string, buf *bytes.Buffer, values []string) *bytes.Buffer {
buf.WriteString(name)
return A.Reduce(hashWriteValue, buf)(values)
}

func makeBytes(b *Builder) []byte {
var buf bytes.Buffer

buf.WriteString(b.GetMethod())
buf.WriteString(b.GetURL())
b.GetHeaders().Write(&buf) // #nosec: G104

R.ReduceOrdWithIndex[[]string, *bytes.Buffer](S.Ord)(hashWriteQuery, &buf)(b.GetQuery())

buf.Write(bodyAsBytes(b.GetBody()))

return buf.Bytes()
}

// MakeHash converts a [Builder] into a hash string, convenient to use as a cache key
func MakeHash(b *Builder) string {
return fmt.Sprintf("%x", sha256.Sum256(makeBytes(b)))
}
25 changes: 25 additions & 0 deletions http/builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package builder

import (
"fmt"
"testing"

F "github.com/IBM/fp-go/function"
Expand Down Expand Up @@ -66,3 +67,27 @@ func TestWithFormData(t *testing.T) {

assert.Equal(t, C.FormEncoded, Headers.Get(res).Get(H.ContentType))
}

func TestHash(t *testing.T) {

b1 := F.Pipe4(
Default,
WithContentType(C.JSON),
WithHeader(H.Accept)(C.JSON),
WithURL("http://www.example.com"),
WithJSON(map[string]string{"a": "b"}),
)

b2 := F.Pipe4(
Default,
WithURL("http://www.example.com"),
WithHeader(H.Accept)(C.JSON),
WithContentType(C.JSON),
WithJSON(map[string]string{"a": "b"}),
)

assert.Equal(t, MakeHash(b1), MakeHash(b2))
assert.NotEqual(t, MakeHash(Default), MakeHash(b2))

fmt.Println(MakeHash(b1))
}

0 comments on commit 6f91e91

Please sign in to comment.