diff --git a/pkg/stdlib/io/net/http/delete.go b/pkg/stdlib/io/net/http/delete.go index aa238293..6d5489de 100644 --- a/pkg/stdlib/io/net/http/delete.go +++ b/pkg/stdlib/io/net/http/delete.go @@ -7,7 +7,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" ) -// DELETE makes a HTTP DELETE request. +// DELETE makes a DELETE request. // @param {Object} params - Request parameters. // @param {String} params.url - Target url // @param {Binary} params.body - Request data diff --git a/pkg/stdlib/io/net/http/get.go b/pkg/stdlib/io/net/http/get.go index cf0ef57a..f2e051cc 100644 --- a/pkg/stdlib/io/net/http/get.go +++ b/pkg/stdlib/io/net/http/get.go @@ -9,7 +9,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/values/types" ) -// GET makes a HTTP GET request. +// GET makes a GET request. // @param {Object | String} urlOrParam - Target url or parameters. // @param {String} [param.url] - Target url or parameters. // @param {Object} [param.headers] - HTTP headers diff --git a/pkg/stdlib/io/net/http/post.go b/pkg/stdlib/io/net/http/post.go index 9b4f0a6b..3fa02ef2 100644 --- a/pkg/stdlib/io/net/http/post.go +++ b/pkg/stdlib/io/net/http/post.go @@ -10,7 +10,7 @@ import ( // POST makes a POST request. // @param {Object} params - Request parameters. // @param {String} params.url - Target url -// @param {Binary} params.body - Request data +// @param {Any} params.body - Request data // @param {Object} [params.headers] - HTTP headers // @return {Binary} - Response in binary format func POST(ctx context.Context, args ...core.Value) (core.Value, error) { diff --git a/pkg/stdlib/io/net/http/post_test.go b/pkg/stdlib/io/net/http/post_test.go index 99c2be61..1de06bcf 100644 --- a/pkg/stdlib/io/net/http/post_test.go +++ b/pkg/stdlib/io/net/http/post_test.go @@ -16,7 +16,7 @@ import ( ) func TestPOST(t *testing.T) { - SkipConvey("Should successfully make request", t, func() { + Convey("Should successfully make request", t, func() { type User struct { FirstName string `json:"first_name"` LastName string `json:"last_name"` @@ -98,4 +98,85 @@ func TestPOST(t *testing.T) { So(out.Type().ID(), ShouldEqual, types.Binary.ID()) So(out.String(), ShouldEqual, "OK") }) + + Convey("Should successfully make request with auto-marshalling to JSON", t, func() { + type User struct { + FirstName string `json:"first_name"` + LastName string `json:"last_name"` + } + + port := randPort() + + server := &h.Server{ + Addr: port, + Handler: h.HandlerFunc(func(w h.ResponseWriter, r *h.Request) { + var err error + + defer func() { + if err != nil { + w.Write([]byte(err.Error())) + } else { + w.Write([]byte("OK")) + } + }() + + if r.Method != "POST" { + err = errors.Errorf("Expected method to be POST, but got %s", r.Method) + + return + } + + data, err := ioutil.ReadAll(r.Body) + + if err != nil { + return + } + + user := User{} + + err = json.Unmarshal(data, &user) + + if err != nil { + return + } + + if user.FirstName != "Rob" { + err = errors.Errorf("Expected FirstName to be Rob, but got %s", user.FirstName) + + return + } + + if user.LastName != "Pike" { + err = errors.Errorf("Expected LastName to be Pike, but got %s", user.LastName) + + return + } + }), + } + + ctx, cancel := context.WithCancel(context.Background()) + + go func() { + server.ListenAndServe() + }() + + defer func() { + cancel() + server.Shutdown(ctx) + }() + + j := values.NewObjectWith( + values.NewObjectProperty("first_name", values.NewString("Rob")), + values.NewObjectProperty("last_name", values.NewString("Pike")), + ) + + out, err := http.POST(ctx, values.NewObjectWith( + values.NewObjectProperty("url", values.NewString("http://127.0.0.1"+port)), + values.NewObjectProperty("body", j), + )) + + So(err, ShouldBeNil) + So(out.Type().ID(), ShouldEqual, types.Binary.ID()) + So(out.String(), ShouldEqual, "OK") + }) } diff --git a/pkg/stdlib/io/net/http/put.go b/pkg/stdlib/io/net/http/put.go index 224cd567..e8a398a6 100644 --- a/pkg/stdlib/io/net/http/put.go +++ b/pkg/stdlib/io/net/http/put.go @@ -10,7 +10,7 @@ import ( // PUT makes a PUT HTTP request. // @param {Object} params - Request parameters. // @param {String} params.url - Target url -// @param {Binary} params.body - Request data +// @param {Any} params.body - Request data // @param {Object} [params.headers] - HTTP headers // @return {Binary} - Response in binary format func PUT(ctx context.Context, args ...core.Value) (core.Value, error) { diff --git a/pkg/stdlib/io/net/http/request.go b/pkg/stdlib/io/net/http/request.go index 7abd0026..fd184aa9 100644 --- a/pkg/stdlib/io/net/http/request.go +++ b/pkg/stdlib/io/net/http/request.go @@ -118,11 +118,23 @@ func newParamsFrom(obj *values.Object) (Params, error) { body, exists := obj.Get("body") if exists { - if err := core.ValidateType(body, types.Binary); err != nil { - return Params{}, core.Error(err, ".body") - } + if core.IsTypeOf(body, types.Binary) { + p.Body = body.(values.Binary) + } else { + j, err := body.MarshalJSON() + + if err != nil { + return Params{}, core.Error(err, ".body") + } + + p.Body = values.NewBinary(j) - p.Body = body.(values.Binary) + if p.Headers == nil { + p.Headers = values.NewObject() + } + + p.Headers.Set("Content-Type", values.NewString("application/json")) + } } return p, nil