瀏覽代碼

Merge remote-tracking branch 'origin/dev' into dev

Vanessa 2 年之前
父節點
當前提交
c78cbe067d
共有 2 個文件被更改,包括 116 次插入0 次删除
  1. 114 0
      kernel/api/network.go
  2. 2 0
      kernel/api/router.go

+ 114 - 0
kernel/api/network.go

@@ -0,0 +1,114 @@
+// SiYuan - Refactor your thinking
+// Copyright (c) 2020-present, b3log.org
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+package api
+
+import (
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
+	"time"
+
+	"github.com/88250/gulu"
+	"github.com/gin-gonic/gin"
+	"github.com/imroc/req/v3"
+	"github.com/siyuan-note/siyuan/kernel/util"
+)
+
+func forwardProxy(c *gin.Context) {
+	ret := gulu.Ret.NewResult()
+	defer c.JSON(http.StatusOK, ret)
+
+	arg, ok := util.JsonArg(c, ret)
+	if !ok {
+		return
+	}
+
+	destURL := arg["url"].(string)
+	if _, e := url.ParseRequestURI(destURL); nil != e {
+		ret.Code = -1
+		ret.Msg = "invalid [url]"
+		return
+	}
+
+	method := strings.ToUpper(arg["method"].(string))
+	timeoutArg := arg["timeout"]
+	timeout := 7 * 1000
+	if nil != timeoutArg {
+		timeout = int(timeoutArg.(float64))
+		if 1 > timeout {
+			timeout = 7 * 1000
+		}
+	}
+
+	client := req.C()
+	client.SetTimeout(time.Duration(timeout) * time.Millisecond)
+	request := client.R()
+	headers := arg["headers"].([]interface{})
+	for _, pair := range headers {
+		for k, v := range pair.(map[string]interface{}) {
+			request.SetHeader(k, fmt.Sprintf("%s", v))
+		}
+	}
+
+	contentType := arg["contentType"]
+	if nil != contentType && "" != contentType {
+		request.SetHeader("Content-Type", contentType.(string))
+	}
+
+	if "POST" == method {
+		request.SetBody(arg["payload"])
+	}
+
+	started := time.Now()
+	resp, err := request.Send(method, destURL)
+	if nil != err {
+		ret.Code = -1
+		ret.Msg = "forward request failed: " + err.Error()
+		return
+	}
+
+	bodyData, err := io.ReadAll(resp.Body)
+	if nil != err {
+		ret.Code = -1
+		ret.Msg = "read response body failed: " + err.Error()
+		return
+	}
+	body := string(bodyData)
+	elapsed := time.Now().Sub(started)
+
+	data := map[string]interface{}{
+		"url":         destURL,
+		"status":      resp.StatusCode,
+		"contentType": resp.GetHeader("content-type"),
+		"body":        body,
+		"headers":     resp.Header,
+		"elapsed":     elapsed.Milliseconds(),
+	}
+	ret.Data = data
+
+	//shortBody := ""
+	//if 64 > len(body) {
+	//	shortBody = body
+	//} else {
+	//	shortBody = body[:64]
+	//}
+	//
+	//logging.LogInfof("elapsed [%.1fs], length [%d], request [url=%s, headers=%s, content-type=%s, body=%s], status [%d], body [%s]",
+	//	elapsed.Seconds(), len(bodyData), data["url"], headers, contentType, arg["payload"], data["status"], shortBody)
+}

+ 2 - 0
kernel/api/router.go

@@ -364,4 +364,6 @@ func ServeAPI(ginServer *gin.Engine) {
 
 	ginServer.Handle("POST", "/api/petal/loadPetals", model.CheckAuth, model.CheckReadonly, loadPetals)
 	ginServer.Handle("POST", "/api/petal/setPetalEnabled", model.CheckAuth, model.CheckReadonly, setPetalEnabled)
+
+	ginServer.Handle("POST", "/api/network/forwardProxy", model.CheckAuth, model.CheckReadonly, forwardProxy)
 }