Ver código fonte

feat(api): improve `/api/network/forwardProxy` (#9110)

Yingyi / 颖逸 1 ano atrás
pai
commit
d99ac84092
3 arquivos alterados com 151 adições e 10 exclusões
  1. 29 1
      API.md
  2. 29 1
      API_zh_CN.md
  3. 93 8
      kernel/api/network.go

+ 29 - 1
API.md

@@ -1288,7 +1288,9 @@ View API token in <kbd>Settings - About</kbd>, request header: `Authorization: T
             "Cookie": ""
         }
     ],
-    "payload": {}
+    "payload": {},
+    "payloadEncoding": "text",
+    "responseEncoding": "text"
   }
   ```
 
@@ -1298,6 +1300,22 @@ View API token in <kbd>Settings - About</kbd>, 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 <kbd>Settings - About</kbd>, request header: `Authorization: T
     "msg": "",
     "data": {
       "body": "",
+      "bodyEncoding": "text",
       "contentType": "text/html",
       "elapsed": 1976,
       "headers": {
@@ -1316,6 +1335,15 @@ View API token in <kbd>Settings - About</kbd>, 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

+ 29 - 1
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`
+
 ## 系统
 
 ### 获取启动进度

+ 93 - 8
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