package handler import ( "bytes" "compress/gzip" "crypto/tls" "encoding/json" "errors" "fmt" "github.com/gin-gonic/gin" "github.com/vulcand/oxy/forward" "github.com/vulcand/oxy/testutils" "gitlab.wodcloud.com/apaas/apaas-meshproxy/src/model" "gitlab.wodcloud.com/apaas/apaas-meshproxy/src/service" "gitlab.wodcloud.com/apaas/apaas-meshproxy/src/tools" "io/ioutil" "net/http" "strconv" "strings" "time" ) //var Resp *http.Response func Proxy(c *gin.Context) { appT := time.Now() fmt.Println(`开始:`, appT) applyId := c.Param("applyId") if applyId == "" { res := model.WebRes{} res.Data = "applyId不能为空" c.JSON(200, res) return } //获取服务相关信息 proxyData, err := service.GetRealPath(applyId) if err != nil { fmt.Println("err......", err.Error()) c.Error(err) return } if proxyData.Second_level != 1 { res := model.WebRes{} res.ErrMsg = `服务申请未通过审批,请联系组织管理员或超管审批` c.JSON(200, res) return } roundTripper := http.DefaultTransport.(*http.Transport) roundTripper.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} f, _ := forward.New(forward.PassHostHeader(true), forward.RoundTripper(roundTripper), forward.ResponseModifier(func(resp *http.Response) error { //Resp = resp //判断是否超过调用次数是否可以调用 callflag, sensitiveflag, err := service.QueryCallsCount(proxyData) if err != nil { fmt.Println("err......", err.Error()) return nil } if callflag == false { err = errors.New(`调用达到当日限定次数`) Return(nil, err, resp) return nil } bT := time.Now() fmt.Println(`开始获取数据:`, bT) respbody, _ := ioutil.ReadAll(resp.Body) var res interface{} res = respbody eT := time.Since(bT) fmt.Println("获取数据: ", eT) //是否需要过滤字段 if proxyData.ResFields != "" { bT := time.Now() fmt.Println(`过滤:`, bT) res = service.FiledFilter(proxyData, respbody) eT := time.Since(bT) fmt.Println("过滤: ", eT) } //是否需要屏蔽敏感字段 if sensitiveflag == false { res = service.SensitiveFilter(proxyData, res) } //计次 //bgn := time.Now() //fmt.Println(`开始携程:`, bgn) go service.CallCounts(proxyData) //end := time.Since(bgn) //fmt.Println("结束携程: ", end) //err = service.CallCounts(proxyData) //if err != nil { // Return(nil, err, resp) // return nil //} ////个人申请调用计次 //err = service.ApplyCallCounts(proxyData) //if err != nil { // Return(nil, err, resp) // return nil //} Return(res, nil, resp) //appeT := time.Since(appT) //fmt.Println("结束: ", appeT) return nil })) c.Request.URL = testutils.ParseURI(getProxyURL(proxyData, c.Request)) fmt.Println("c.Request.URL-------", c.Request.URL) c.Request.RequestURI = getRequestURI(c.Request) fmt.Println("c.Request-------", c.Request) c.Request.Host = getHost(proxyData.RealUrl) fmt.Println("proxyData.RealUrl-------", proxyData.RealUrl) f.ServeHTTP(c.Writer, c.Request) } func getProxyURL(proxyData model.ProxyData, req *http.Request) string { realPath := proxyData.RealUrl rawQuery := req.URL.RawQuery var result = "" if rawQuery == "" { if proxyData.Name == "时空服务" { result = realPath + "?f=json" } else { result = realPath } } else { result = realPath + "?" + rawQuery if proxyData.Name == "时空服务" && !strings.Contains(rawQuery, "f=json") { result = result + "&f=json" } } return result } func getRequestURI(req *http.Request) string { path := req.URL.Path rawQuery := req.URL.RawQuery var result = "" if rawQuery == "" { result = path } else { result = path + "?" + rawQuery } return result } func Return(res interface{}, err error, Resp *http.Response) { var b []byte if err == nil { switch res.(type) { case []byte: b = res.([]byte) case interface{}: b, _ = json.Marshal(res) } } else { Resp.Header.Set("Content-Encoding", "utf-8") b = []byte(err.Error()) } //if Resp.Header.Get("Content-Encoding") == "gzip" { //Resp.Header.Set("Content-Encoding","gzip") //b = gzipCompress(&b) //} Resp.Header.Set("X-Log-By", "Apaas") Resp.Header.Set("Content-Length", strconv.Itoa(len(b))) Resp.Body = ioutil.NopCloser(bytes.NewBuffer(b)) } func gzipCompress(content *[]byte) []byte { var compressData bytes.Buffer gzipWriter := gzip.NewWriter(&compressData) defer gzipWriter.Close() gzipWriter.Write(*content) gzipWriter.Flush() return compressData.Bytes() } // 获取域名 func getHost(url string) (path string) { if strings.Contains(url, "//") { path = strings.Split(url, "//")[1] if strings.Contains(path, "/") { path = strings.Split(path, "/")[0] } } return } func HealthCheck(c *gin.Context) { res := model.WebRes{} proxyData, err := service.GetReqPath() if err != nil { res.Data = err.Error() c.JSON(500, res) return } var requstMethod string //获取真实地址1GET 2POST 3 PUT 4 DELETE if proxyData.ReqType == 1 { requstMethod = "GET" } else if proxyData.ReqType == 2 { requstMethod = "POST" } else if proxyData.ReqType == 3 { requstMethod = "PUT" } else if proxyData.ReqType == 4 { requstMethod = "DELETE" } header := make(map[string]string, 0) resp, err := tools.ProxySendRes(c.Request, requstMethod, proxyData.ReqUrl, "", header) if err != nil { res.Data = err.Error() c.JSON(500, res) return } fmt.Println(resp) if resp.StatusCode < 400 { res.Data = "success" } else { res.Data = "fail" } res.Success = 1 //请求真实地址根据返回状态码判断是否服务可用 c.JSON(200, res) return }