gojs/modules/http/http.go
Star 205c4f20dc add file.readBytes
change http result to r.bytes(), r.string(), r.object()
2024-10-03 12:24:08 +08:00

177 lines
4.9 KiB
Go

package http
import (
"apigo.cc/apigo/gojs"
"apigo.cc/apigo/gojs/dop251/goja"
_ "embed"
"github.com/ssgo/httpclient"
"github.com/ssgo/u"
"reflect"
)
//go:embed http.ts
var httpTS string
type Http struct {
client *httpclient.ClientPool
}
var defaultHttp = &Http{
client: httpclient.GetClient(0),
}
var h2cHttp = &Http{
client: httpclient.GetClientH2C(0),
}
func init() {
obj := map[string]any{
"get": defaultHttp.Get,
"get2C": h2cHttp.Get,
"head": defaultHttp.Head,
"head2C": h2cHttp.Head,
"post": defaultHttp.Post,
"post2C": h2cHttp.Post,
"put": defaultHttp.Put,
"put2C": h2cHttp.Put,
"delete": defaultHttp.Delete,
"delete2C": h2cHttp.Delete,
"do": defaultHttp.Do,
"do2C": h2cHttp.Do,
"upload": defaultHttp.Upload,
"upload2C": h2cHttp.Upload,
"download": defaultHttp.Download,
"download2C": h2cHttp.Download,
}
gojs.Register("http", gojs.Module{
Object: obj,
TsCode: httpTS,
Desc: "",
Example: "",
})
}
func makeResult(r *httpclient.Result, vm *goja.Runtime) goja.Value {
if r.Error != nil {
panic(vm.NewGoError(r.Error))
}
headers := map[string]string{}
for k, v := range r.Response.Header {
headers[k] = v[0]
}
return vm.ToValue(map[string]any{
"status": r.Response.Status,
"statusCode": r.Response.StatusCode,
"headers": headers,
"_data": r.Bytes(),
"bytes": toBytes,
"string": toString,
"object": toObject,
})
}
func toBytes(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
dataValue := argsIn.This.ToObject(vm).Get("_data")
if _, ok := dataValue.Export().([]byte); ok {
return dataValue
}
return nil
}
func toString(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
dataValue := argsIn.This.ToObject(vm).Get("_data")
if data, ok := dataValue.Export().([]byte); ok {
return vm.ToValue(string(data))
}
return nil
}
func toObject(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
dataValue := argsIn.This.ToObject(vm).Get("_data")
if data, ok := dataValue.Export().([]byte); ok {
obj := u.UnJsonBytes(data, nil)
v := u.FinalValue(reflect.ValueOf(obj))
return vm.ToValue(v.Interface())
}
return nil
}
func (hc *Http) Get(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
return makeResult(hc.client.Get(args.Str(0), args.Map2StrArr(1)...), vm)
}
func (hc *Http) Head(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
return makeResult(hc.client.Head(args.Str(0), args.Map2StrArr(1)...), vm)
}
func (hc *Http) Post(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(2)
return makeResult(hc.client.Post(args.Str(0), args.Any(1), args.Map2StrArr(2)...), vm)
}
func (hc *Http) Put(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(2)
return makeResult(hc.client.Put(args.Str(0), args.Any(1), args.Map2StrArr(2)...), vm)
}
func (hc *Http) Delete(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(2)
return makeResult(hc.client.Delete(args.Str(0), args.Any(1), args.Map2StrArr(2)...), vm)
}
func (hc *Http) Do(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(3)
if len(argsIn.Arguments) == 3 {
argsIn.Arguments = append(argsIn.Arguments, vm.ToValue(nil))
}
var r *httpclient.Result
if cb, ok := goja.AssertFunction(argsIn.Arguments[3]); ok {
r = hc.client.ManualDo(args.Str(0), args.Str(1), args.Any(2), args.Map2StrArr(4)...)
buf := make([]byte, 1024)
for {
n, err := r.Response.Body.Read(buf)
if err != nil {
break
}
_, _ = cb(argsIn.This, vm.ToValue(u.String(buf[0:n])))
}
} else {
r = hc.client.Do(args.Str(0), args.Str(1), args.Any(2), args.Map2StrArr(4)...)
}
return makeResult(r, vm)
}
func (hc *Http) Upload(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(2)
postData := map[string]string{}
postFiles := map[string]any{}
u.Convert(args.Any(1), &postData)
if len(argsIn.Arguments) > 2 {
u.Convert(args.Any(2), &postFiles)
}
r, _ := hc.client.MPost(args.Str(0), postData, postFiles, args.Map2StrArr(3)...)
return makeResult(r, vm)
}
func (hc *Http) Download(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(2)
var r *httpclient.Result
var callback goja.Callable
if len(argsIn.Arguments) > 2 {
if cb, ok := goja.AssertFunction(argsIn.Arguments[2]); ok {
callback = cb
}
}
if callback != nil {
r, _ = hc.client.Download(args.Str(0), args.Str(1), func(start, end int64, ok bool, finished, total int64) {
_, _ = callback(argsIn.This, vm.ToValue(finished), vm.ToValue(total))
}, args.Map2StrArr(3)...)
} else {
r, _ = hc.client.Download(args.Str(0), args.Str(1), nil, args.Map2StrArr(3)...)
}
return makeResult(r, vm)
}