1
0
mirror of https://github.com/MontFerret/ferret.git synced 2024-12-29 01:44:23 +02:00
ferret/pkg/stdlib/io/net/http/request.go
Tim Voronov 67dc8703c7
Added HTTP methods (#452)
* Added HTTP methods

* Added unit tests

* Fixed linting issue

* Replaced localhost with 127.0.0.1

* Added random port generator

* Disabled http tests

* Disabled HTTP GET test
2020-02-21 11:06:45 -05:00

123 lines
2.3 KiB
Go

package http
import (
"bytes"
"context"
"io/ioutil"
h "net/http"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
)
type Params struct {
Method values.String
URL values.String
Headers *values.Object
Body values.Binary
}
func REQUEST(ctx context.Context, args ...core.Value) (core.Value, error) {
return execMethod(ctx, "", args)
}
func execMethod(ctx context.Context, method values.String, args []core.Value) (core.Value, error) {
if err := core.ValidateArgs(args, 1, 1); err != nil {
return values.None, err
}
arg := args[0]
if err := core.ValidateType(arg, types.Object); err != nil {
return values.None, err
}
p, err := newParamsFrom(arg.(*values.Object))
if err != nil {
return values.None, err
}
if method != "" {
p.Method = method
}
return makeRequest(ctx, p)
}
func makeRequest(ctx context.Context, params Params) (core.Value, error) {
client := h.Client{}
req, err := h.NewRequest(params.Method.String(), params.URL.String(), bytes.NewBuffer(params.Body))
if err != nil {
return values.None, err
}
req.Header = h.Header{}
if params.Headers != nil {
params.Headers.ForEach(func(value core.Value, key string) bool {
req.Header.Set(key, value.String())
return true
})
}
resp, err := client.Do(req.WithContext(ctx))
if err != nil {
return values.None, err
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return values.None, err
}
defer resp.Body.Close()
return values.NewBinary(data), nil
}
func newParamsFrom(obj *values.Object) (Params, error) {
p := Params{}
method, exists := obj.Get("method")
if exists {
p.Method = values.ToString(method)
}
url, exists := obj.Get("url")
if !exists {
return Params{}, core.Error(core.ErrMissedArgument, ".url")
}
p.URL = values.NewString(url.String())
headers, exists := obj.Get("headers")
if exists {
if err := core.ValidateType(headers, types.Object); err != nil {
return Params{}, core.Error(err, ".headers")
}
p.Headers = headers.(*values.Object)
}
body, exists := obj.Get("body")
if exists {
if err := core.ValidateType(body, types.Binary); err != nil {
return Params{}, core.Error(err, ".body")
}
p.Body = body.(values.Binary)
}
return p, nil
}