Das Go-Gin-Framework führt eine Anforderungsweiterleitung durch (Proxy-Proxy).

Hintergrund

Ich habe derzeit zwei Dienste, kurz genannt Aund B. AEs handelt sich um einen nach außen offenen Dienst, der Bdie für den Zugriff notwendigen Parameter speichert. Kunden müssen AAnfragen über weiterleiten B.

Umsetzungsideen

Tatsächlich geht es darum, die Anforderung gemäß den angegebenen Regeln abzufangen und die angeforderte Adresse zu ersetzen. Während dieser Zeit können Sie die Anforderung und die zurückgegebenen Ergebnisse selbst abfangen und einige Vorgänge wie das Ändern von Werten ausführen.

  1. serverDer Dienst fungiert als Middleware und fängt ab. (Ich fange anhand des Inhalts im Anforderungsheader ab, um festzustellen, ob der Wert headerdarin ist .)directlab
  2. Ersetzen Sie angefordert Scheme(z. B.: http) und Host(z. B.: www.baidu.com)
  3. Stellen Sie sicher, dass die Anfrageparameter der ursprünglichen Anfrage unverändert bleiben
  4. Ergebnis der Rückgabeanforderung

Code

  1. goDas offizielle Lager httputilkapselt verwandte MethodenReverseProxy
  2. Durch die obige Logik können Sie die Anfrage einfach selbst kapseln und entsprechend Ihren Anforderungen entsprechende Änderungen vornehmen.

Laden Sie den Code direkt hoch

httputil.ReverseProxy

func Proxy(c *gin.Context) {
    
    
	if c.GetHeader("direct") != "lab" {
    
    
		return
	}
	var proxyUrl = new(url.URL)
	proxyUrl.Scheme = "http"
	proxyUrl.Host = "172.16.60.161"
	//u.Path = "base" // 这边若是赋值了,做转发的时候,会带上path前缀,例: /hello -> /base/hello

	proxyUrl.RawQuery = url.QueryEscape("token=" + "VjouhpQHa6wgWvtkPQeDZbQd") // 和如下方式等价
	//var query url.Values
	//query.Add("token", "VjouhpQHa6wgWvtkPQeDZbQd")
	//u.RawQuery = query.Encode()

	proxy := httputil.NewSingleHostReverseProxy(proxyUrl)

	//proxy := httputil.ReverseProxy{}
	//proxy.Director = func(req *http.Request) {
    
    
	//	fmt.Println(req.URL.String())
	//	req.URL.Scheme = "http"
	//	req.URL.Host = "172.16.60.161"
	//	rawQ := req.URL.Query()
	//	rawQ.Add("token", "VjouhpQHa6wgWvtkPQeDZbQd")
	//	req.URL.RawQuery = rawQ.Encode()
	//}

	// proxy.ErrorHandler // 可以添加错误回调
	// proxy.Transport // 若有需要可以自定义 http.Transport


	proxy.ServeHTTP(c.Writer, c.Request)

	c.Abort()
}

Einfache Umsetzung selbst

/ 也就是做简单的转发操作
func Proxy(c *gin.Context) {
    
    
	if c.GetHeader("direct") != "lab" {
    
    
		return
	}

	err := setTokenToUrl(c.Request.URL)
	if err != nil {
    
    
		c.String(http.StatusInternalServerError, fmt.Sprintf("填写的地址有误: %s", err.Error()))
		c.Abort()
		return
	}

	req, err := http.NewRequestWithContext(c, c.Request.Method, c.Request.URL.String(), c.Request.Body)
	if err != nil {
    
    
		c.String(http.StatusInternalServerError, err.Error())
		c.Abort()
		return
	}
	defer req.Body.Close()
	req.Header = c.Request.Header

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
    
    
		c.String(http.StatusInternalServerError, err.Error())
		c.Abort()
		return
	}
	// header 也带过来
	for k :=  range resp.Header {
    
    
		for j := range resp.Header[k] {
    
    
			c.Header(k, resp.Header[k][j])
		}
	}
	extraHeaders := make(map[string]string)
	extraHeaders["direct"] = "lab"
	c.DataFromReader(resp.StatusCode, resp.ContentLength, resp.Header.Get("Content-Type"), resp.Body, extraHeaders)
	c.Abort()
}

func setTokenToUrl(rawUrl *url.URL) (error) {
    
    
	// 这边是从设置里拿代理值
	//equipment, err := proxy.GetEquipment()
	//if err != nil {
    
    
	//	return err
	//}
	proxyUrl := "http://172.16.60.161"
	token := "VjouhpQHa6wgWvtkPQeDZbQd"
	u, err := url.Parse(proxyUrl)
	if err != nil {
    
    
		return err
	}

	rawUrl.Scheme = u.Scheme
	rawUrl.Host = u.Host
	ruq := rawUrl.Query()
	ruq.Add("token", token)
	rawUrl.RawQuery = ruq.Encode()
	return nil
}

Supongo que te gusta

Origin blog.csdn.net/DisMisPres/article/details/119041567
Recomendado
Clasificación