199 lines
4.8 KiB
Go
199 lines
4.8 KiB
Go
package core
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"net/http"
|
|
u "net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/cdle/sillyplus/utils"
|
|
"github.com/dop251/goja"
|
|
"github.com/goccy/go-json"
|
|
)
|
|
|
|
func fetch(vm *goja.Runtime, resolve func(result interface{}), reject func(reason interface{}), wts ...interface{}) interface{} {
|
|
var block = resolve == nil
|
|
var method = "get"
|
|
var url = ""
|
|
var req *http.Request
|
|
|
|
var headers map[string]interface{}
|
|
var transport *http.Transport
|
|
var formData map[string]interface{}
|
|
// var isJson bool
|
|
var isJsonBody bool
|
|
var body string
|
|
var allow_redirects bool = true
|
|
var responseType = ""
|
|
// var err error
|
|
// var useproxy bool
|
|
var timeout time.Duration = 0
|
|
var login = false
|
|
for _, wt := range wts {
|
|
switch wt := wt.(type) {
|
|
case string:
|
|
url = wt
|
|
case map[string]interface{}:
|
|
props := wt
|
|
for i := range props {
|
|
switch strings.ToLower(i) {
|
|
case "timeout":
|
|
timeout = time.Duration(utils.Int64(props[i])) * time.Millisecond
|
|
case "headers":
|
|
headers = props[i].(map[string]interface{})
|
|
case "method":
|
|
method = strings.ToLower(props[i].(string))
|
|
case "url":
|
|
if f, ok := props[i].(func(i goja.FunctionCall) goja.Value); ok {
|
|
url = f(goja.FunctionCall{}).ToString().String()
|
|
} else {
|
|
url = props[i].(string)
|
|
}
|
|
case "json":
|
|
if props[i].(bool) {
|
|
responseType = "json"
|
|
}
|
|
case "responsetype":
|
|
responseType = props[i].(string)
|
|
case "datatype":
|
|
responseType = props[i].(string)
|
|
case "allowredirects":
|
|
allow_redirects = props[i].(bool)
|
|
case "body":
|
|
if v, ok := props[i].(string); !ok {
|
|
d, _ := json.Marshal(props[i])
|
|
body = string(d)
|
|
isJsonBody = true
|
|
} else {
|
|
body = v
|
|
}
|
|
case "login":
|
|
login = true
|
|
case "formdata":
|
|
formData = props[i].(map[string]interface{})
|
|
case "form":
|
|
formData = props[i].(map[string]interface{})
|
|
case "proxy":
|
|
var url, user, password string
|
|
for k, v := range props[i].(map[string]interface{}) {
|
|
if k == "url" {
|
|
url = fmt.Sprint(v)
|
|
}
|
|
if k == "user" {
|
|
user = fmt.Sprint(v)
|
|
}
|
|
if k == "password" {
|
|
password = fmt.Sprint(v)
|
|
}
|
|
}
|
|
if url != "" {
|
|
var err error
|
|
transport, err = GetTransport(url, user, password)
|
|
if err != nil {
|
|
info := "proxy config error " + err.Error()
|
|
console.Error()
|
|
if block {
|
|
panic(Error(vm, info))
|
|
} else {
|
|
reject(Error(vm, info))
|
|
// return nil
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
method = strings.ToUpper(method)
|
|
|
|
if len(formData) > 0 {
|
|
data := u.Values{}
|
|
for key, value := range formData {
|
|
switch v := value.(type) {
|
|
case string:
|
|
data.Set(key, v)
|
|
case bool:
|
|
data.Set(key, strconv.FormatBool(v))
|
|
case int:
|
|
data.Set(key, strconv.Itoa(v))
|
|
// 可以根据需要添加其他类型的处理
|
|
default:
|
|
data.Set(key, fmt.Sprintf("%v", v))
|
|
}
|
|
}
|
|
|
|
req, _ = http.NewRequest(method, url, strings.NewReader(data.Encode()))
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
} else {
|
|
req, _ = http.NewRequest(method, url, bytes.NewBuffer([]byte(body)))
|
|
if isJsonBody {
|
|
req.Header.Set("Content-Type", "application/json")
|
|
}
|
|
}
|
|
if login {
|
|
req.Header.Set("Cookie", "uuid=40e67d5e-f6f3-11ed-8bc2-dca9049272e5; token="+getTempAuth())
|
|
}
|
|
for i := range headers {
|
|
req.Header.Set(i, fmt.Sprint(headers[i]))
|
|
}
|
|
}
|
|
|
|
var rspObj goja.Proxy
|
|
var rsp *http.Response
|
|
var err error
|
|
|
|
var client = &http.Client{
|
|
Timeout: timeout,
|
|
}
|
|
if transport != nil {
|
|
client.Transport = transport
|
|
}
|
|
|
|
if !allow_redirects {
|
|
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
|
return http.ErrUseLastResponse
|
|
}
|
|
}
|
|
rsp, err = client.Do(req)
|
|
if err == nil {
|
|
defer rsp.Body.Close()
|
|
rspObj = vm.NewProxy(MakeResponseObject(vm, reject, rsp, responseType), &goja.ProxyTrapConfig{
|
|
Get: func(target *goja.Object, property string, receiver goja.Value) (value goja.Value) {
|
|
obj := target.Get(property)
|
|
if obj != nil {
|
|
return obj
|
|
}
|
|
switch property {
|
|
case "statusText", "statusMessage":
|
|
return vm.ToValue("")
|
|
case "statusCode":
|
|
return target.Get("status")
|
|
// case "body":
|
|
// return vm.ToValue(target.Get("getBody").Export().(func() interface{})())
|
|
case "then":
|
|
return goja.Undefined()
|
|
}
|
|
console.Error("response has no property " + property)
|
|
return goja.Undefined()
|
|
},
|
|
})
|
|
if block {
|
|
return rspObj
|
|
} else {
|
|
resolve(rspObj)
|
|
|
|
}
|
|
} else {
|
|
if block {
|
|
return rspObj
|
|
} else {
|
|
reject(Error(vm, err))
|
|
|
|
}
|
|
}
|
|
return nil
|
|
}
|