美文网首页
golang http(s)请求转发

golang http(s)请求转发

作者: 杜子龙 | 来源:发表于2019-02-14 21:24 被阅读0次
    func main(){
        router := gin.Default()//创建一个router
        router.Use(MiddleWare())//中间件,起拦截器的作用
        router.Any("/*action", Forward)//所有请求都会经过Forward函数转发
        router.Run(":8000")
    }
    func Forward(c *gin.Context) {
        targetHost := &httputils.TargetHost{
            Host:    "www.baidu.com",
            IsHttps: false,
            CAPath:  "****/*****.crt",
        }
        HostReverseProxy(c.Writer, c.Request, targetHost)
    }
    func HostReverseProxy(w http.ResponseWriter, req *http.Request, targetHost *TargetHost) {
        host := ""
        if targetHost.IsHttps {
            host = host + "https://"
        } else {
            host = host + "http://"
        }
        remote, err := url.Parse(host + targetHost.Host)
        if err != nil {
            log.Errorf("err:%s", err)
            w.WriteHeader(http.StatusInternalServerError)
            return
        }
        proxy := httputil.NewSingleHostReverseProxy(remote)
        if targetHost.IsHttps {
            tls, err := GetVerTLSConfig(targetHost.CAPath)
            if err != nil {
                log.Errorf("https crt error: %s", err)
                w.WriteHeader(http.StatusInternalServerError)
                return
            }
            var pTransport http.RoundTripper = &http.Transport{
                Dial: func(netw, addr string) (net.Conn, error) {
                    c, err := net.DialTimeout(netw, addr, time.Second*time.Duration(DialTimeout))
                    if err != nil {
                        return nil, err
                    }
                    return c, nil
                },
                ResponseHeaderTimeout: time.Second * time.Duration(ResponseHeaderTimeout),
                TLSClientConfig:       tls,
            }
            proxy.Transport = pTransport
        }
        proxy.ServeHTTP(w, req)
    }
    type TargetHost struct {
        Host    string
        IsHttps bool
        CAPath  string
    }
    var TlsConfig *tls.Config
    func GetVerTLSConfig(CAPath string) (*tls.Config, error) {
        caData, err := ioutil.ReadFile(CAPath)
        if err != nil {
            log.Errorf("read wechat ca fail", err)
            return nil, err
        }
        pool := x509.NewCertPool()
        pool.AppendCertsFromPEM(caData)
    
        TlsConfig = &tls.Config{
            RootCAs: pool,
        }
        return TlsConfig, nil
    }
    func MiddleWare() gin.HandlerFunc {
        return func(c *gin.Context) {
            account := c.Request.Header.Get("ename")//从请求头中获取ename字段
        if account == "" {
            c.JSON(http.StatusOK, httputils.Response{
                Code:    400002,
                Message: "用户未登录",
            })
            c.Abort()
            return
        }
            fmt.Println("before middleware")
            c.Set("request", "clinet_request")
            c.Next()
            fmt.Println("before middleware")
        }
    }

    相关文章

      网友评论

          本文标题:golang http(s)请求转发

          本文链接:https://www.haomeiwen.com/subject/imwyeqtx.html