321 lines
7.9 KiB
Go
321 lines
7.9 KiB
Go
package core
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
u "net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/cdle/sillyplus/utils"
|
|
"github.com/dop251/goja"
|
|
"github.com/goccy/go-json"
|
|
)
|
|
|
|
func request(wt interface{}, handles ...func(error, map[string]interface{}, interface{}) interface{}) interface{} {
|
|
var method = "get"
|
|
var url = ""
|
|
var req *http.Request
|
|
|
|
var headers map[string]interface{}
|
|
// var formData map[string]interface{}
|
|
var isJson bool
|
|
var isJsonBody bool
|
|
var body string
|
|
var allow_redirects bool = true
|
|
// var useproxy bool
|
|
// var timeout time.Duration = 0
|
|
var goroutine = false
|
|
var uuid = ""
|
|
switch wt := wt.(type) {
|
|
case string:
|
|
url = wt
|
|
default:
|
|
props := wt.(map[string]interface{})
|
|
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":
|
|
isJson = props[i].(bool)
|
|
case "uuid":
|
|
uuid = props[i].(string)
|
|
case "goroutine":
|
|
goroutine = true
|
|
case "datatype":
|
|
switch props[i].(type) {
|
|
case string:
|
|
switch strings.ToLower(props[i].(string)) {
|
|
case "json":
|
|
isJson = true
|
|
}
|
|
}
|
|
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 "formdata":
|
|
// formData = props[i].(map[string]interface{})
|
|
// case "useproxy":
|
|
// useproxy = props[i].(bool)
|
|
}
|
|
}
|
|
}
|
|
method = strings.ToUpper(method)
|
|
req, _ = http.NewRequest(method, url, bytes.NewBuffer([]byte(body)))
|
|
// if timeout != 0 {
|
|
// req.SetTimeout(timeout, timeout)
|
|
// }
|
|
|
|
if isJsonBody {
|
|
req.Header.Set("Content-Type", "application/json")
|
|
}
|
|
for i := range headers {
|
|
req.Header.Set(i, fmt.Sprint(headers[i]))
|
|
}
|
|
// for i := range formData {
|
|
// req.Param(i, fmt.Sprint(formData[i]))
|
|
// }
|
|
|
|
// if useproxy && Transport != nil {
|
|
// req.SetTransport(Transport)
|
|
// }
|
|
|
|
rspObj := map[string]interface{}{}
|
|
var rsp *http.Response
|
|
var err error
|
|
// if !allow_redirects {
|
|
// req.SetCheckRedirect(func(req *http.Request, via []*http.Request) error {
|
|
// return http.ErrUseLastResponse
|
|
// })
|
|
// }
|
|
var dddd = func() interface{} {
|
|
client := &http.Client{}
|
|
if !allow_redirects {
|
|
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
|
return http.ErrUseLastResponse
|
|
}
|
|
}
|
|
rsp, err = client.Do(req)
|
|
var bd interface{}
|
|
if err == nil {
|
|
defer rsp.Body.Close()
|
|
rspObj["status"] = rsp.StatusCode
|
|
rspObj["statusCode"] = rsp.StatusCode
|
|
data, _ := ioutil.ReadAll(rsp.Body)
|
|
if isJson {
|
|
var v interface{}
|
|
json.Unmarshal(data, &v)
|
|
bd = v
|
|
} else {
|
|
bd = string(data)
|
|
}
|
|
rspObj["body"] = bd
|
|
h := make(map[string][]string)
|
|
for k := range rsp.Header {
|
|
h[k] = rsp.Header[k]
|
|
}
|
|
rspObj["headers"] = h
|
|
} else {
|
|
rspObj["error"] = err.Error()
|
|
}
|
|
if uuid != "" {
|
|
rspObj["uuid"] = uuid
|
|
}
|
|
if len(handles) > 0 {
|
|
return handles[0](err, rspObj, bd)
|
|
} else {
|
|
return rspObj
|
|
}
|
|
}
|
|
if goroutine {
|
|
go dddd()
|
|
} else {
|
|
return dddd()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func fetch(vm *goja.Runtime, resolve func(result interface{}), reject func(reason interface{}), wts ...interface{}) {
|
|
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 {
|
|
reject(Error(vm, "proxy config error "+err.Error()))
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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()
|
|
},
|
|
})
|
|
resolve(rspObj)
|
|
} else {
|
|
reject(Error(vm, err))
|
|
}
|
|
}
|