diff --git a/API.md b/API.md index c855ada2a1f..34e0f3da0c9 100644 --- a/API.md +++ b/API.md @@ -1288,7 +1288,9 @@ View API token in Settings - About, request header: `Authorization: T "Cookie": "" } ], - "payload": {} + "payload": {}, + "payloadEncoding": "text", + "responseEncoding": "text" } ``` @@ -1298,6 +1300,22 @@ View API token in Settings - About, request header: `Authorization: T * `contentType`: Content-Type, default is `application/json` * `headers`: HTTP headers * `payload`: HTTP payload, object or string + * `payloadEncoding`: The encoding scheme used by `pyaload`, default is `text`, optional values are as follows + + * `text` + * `base64` | `base64-std` + * `base64-url` + * `base32` | `base32-std` + * `base32-hex` + * `hex` + * `responseEncoding`: The encoding scheme used by `body` in response data, default is `text`, optional values are as follows + + * `text` + * `base64` | `base64-std` + * `base64-url` + * `base32` | `base32-std` + * `base32-hex` + * `hex` * Return value ```json @@ -1306,6 +1324,7 @@ View API token in Settings - About, request header: `Authorization: T "msg": "", "data": { "body": "", + "bodyEncoding": "text", "contentType": "text/html", "elapsed": 1976, "headers": { @@ -1316,6 +1335,15 @@ View API token in Settings - About, request header: `Authorization: T } ``` + * `bodyEncoding`:The encoding scheme used by `body`, is consistent with field `responseEncoding` in request, default is `text`, optional values are as follows + + * `text` + * `base64` | `base64-std` + * `base64-url` + * `base32` | `base32-std` + * `base32-hex` + * `hex` + ## System ### Get boot progress diff --git a/API_zh_CN.md b/API_zh_CN.md index 51d826b0ced..2377b1a399d 100644 --- a/API_zh_CN.md +++ b/API_zh_CN.md @@ -1278,7 +1278,9 @@ "Cookie": "" } ], - "payload": {} + "payload": {}, + "payloadEncoding": "text", + "responseEncoding": "text" } ``` @@ -1288,6 +1290,22 @@ * `contentType`:HTTP Content-Type,默认为 `application/json` * `headers`:HTTP 请求标头 * `payload`:HTTP 请求体,对象或者是字符串 + * `payloadEncoding`:`pyaload` 所使用的编码方案,默认为 `text`,可选值如下所示 + + * `text` + * `base64` | `base64-std` + * `base64-url` + * `base32` | `base32-std` + * `base32-hex` + * `hex` + * `responseEncoding`:响应数据中 `body` 字段所使用的编码方案,默认为 `text`,可选值如下所示 + + * `text` + * `base64` | `base64-std` + * `base64-url` + * `base32` | `base32-std` + * `base32-hex` + * `hex` * 返回值 ```json @@ -1296,6 +1314,7 @@ "msg": "", "data": { "body": "", + "bodyEncoding": "text", "contentType": "text/html", "elapsed": 1976, "headers": { @@ -1306,6 +1325,15 @@ } ``` + * `bodyEncoding`:`body` 所使用的编码方案,与请求中 `responseEncoding` 字段一致,默认为 `text`,可能的值如下所示 + + * `text` + * `base64` | `base64-std` + * `base64-url` + * `base32` | `base32-std` + * `base32-hex` + * `hex` + ## 系统 ### 获取启动进度 diff --git a/kernel/api/network.go b/kernel/api/network.go index eadfd528d7b..ff00fe5f416 100644 --- a/kernel/api/network.go +++ b/kernel/api/network.go @@ -17,6 +17,9 @@ package api import ( + "encoding/base32" + "encoding/base64" + "encoding/hex" "fmt" "io" "net/http" @@ -74,7 +77,60 @@ func forwardProxy(c *gin.Context) { } request.SetHeader("Content-Type", contentType) - request.SetBody(arg["payload"]) + payloadEncoding := "json" + if payloadEncodingArg := arg["payloadEncoding"]; nil != payloadEncodingArg { + payloadEncoding = payloadEncodingArg.(string) + } + + switch payloadEncoding { + case "base64": + fallthrough + case "base64-std": + if payload, err := base64.StdEncoding.DecodeString(arg["payload"].(string)); nil != err { + ret.Code = -2 + ret.Msg = "decode base64-std payload failed: " + err.Error() + return + } else { + request.SetBody(payload) + } + case "base64-url": + if payload, err := base64.URLEncoding.DecodeString(arg["payload"].(string)); nil != err { + ret.Code = -2 + ret.Msg = "decode base64-url payload failed: " + err.Error() + return + } else { + request.SetBody(payload) + } + case "base32": + fallthrough + case "base32-std": + if payload, err := base32.StdEncoding.DecodeString(arg["payload"].(string)); nil != err { + ret.Code = -2 + ret.Msg = "decode base32-std payload failed: " + err.Error() + return + } else { + request.SetBody(payload) + } + case "base32-hex": + if payload, err := base32.HexEncoding.DecodeString(arg["payload"].(string)); nil != err { + ret.Code = -2 + ret.Msg = "decode base32-hex payload failed: " + err.Error() + return + } else { + request.SetBody(payload) + } + case "hex": + if payload, err := hex.DecodeString(arg["payload"].(string)); nil != err { + ret.Code = -2 + ret.Msg = "decode hex payload failed: " + err.Error() + return + } else { + request.SetBody(payload) + } + case "text": + default: + request.SetBody(arg["payload"]) + } started := time.Now() resp, err := request.Send(method, destURL) @@ -90,16 +146,45 @@ func forwardProxy(c *gin.Context) { ret.Msg = "read response body failed: " + err.Error() return } - body := string(bodyData) + elapsed := time.Now().Sub(started) + responseEncoding := "text" + if responseEncodingArg := arg["responseEncoding"]; nil != responseEncodingArg { + responseEncoding = responseEncodingArg.(string) + } + + body := "" + switch responseEncoding { + case "base64": + fallthrough + case "base64-std": + body = base64.StdEncoding.EncodeToString(bodyData) + case "base64-url": + body = base64.URLEncoding.EncodeToString(bodyData) + case "base32": + fallthrough + case "base32-std": + body = base32.StdEncoding.EncodeToString(bodyData) + case "base32-hex": + body = base32.HexEncoding.EncodeToString(bodyData) + case "hex": + body = hex.EncodeToString(bodyData) + case "text": + fallthrough + default: + responseEncoding = "text" + body = string(bodyData) + } + data := map[string]interface{}{ - "url": destURL, - "status": resp.StatusCode, - "contentType": resp.GetHeader("content-type"), - "body": body, - "headers": resp.Header, - "elapsed": elapsed.Milliseconds(), + "url": destURL, + "status": resp.StatusCode, + "contentType": resp.GetHeader("content-type"), + "body": body, + "bodyEncoding": responseEncoding, + "headers": resp.Header, + "elapsed": elapsed.Milliseconds(), } ret.Data = data