• 3min快速掌握Go语言正/反向代理的姿势


    先重温一下什么叫反向代理,正向代理。

    鹅厂二面,nginx回忆录

    所谓正向/反向代理取决于代理的是出站请求,还是入站请求

    正向代理: 代理的出站请求, 客户端能感知到代理程序,架构上距离客户端更近。
    反向代理: 代理的是入站请求,客户端认为代理程序就是服务器,客户端感知不到代理逻辑,架构上距离服务端更近。


    正向代理的实践

    正向代理的一个日常实践就是vpn/梯子。

    这几天刚好遇到了一个正向代理的case, 简单记录一下。

    name.com集群无法访问外界的机器, 于是在机房部署边缘代理,代理出站请求。

    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    	"net/http/httputil"
    )
    
    func ProxyHandler(w http.ResponseWriter, r *http.Request) {
    	fmt.Printf("receive a request from {0}  {1}: \n", r.RemoteAddr, r.RequestURI)
    	if r.Host != "localhost:8080" {
    		director := func(req *http.Request) {
    			req.URL.Scheme = "http"
    			req.URL.Host = r.Host
    			req.Host = r.Host
    		}
    		proxy := &httputil.ReverseProxy{Director: director}
    		proxy.ServeHTTP(w, r)
    	} else {
    		http.NotFound(w, r)
    	}
    }
    
    func main() {
    	if err := http.ListenAndServe(":8080", http.HandlerFunc(ProxyHandler)); err != nil {
    		log.Fatal(err)
    	}
    }
    

    其中要注意的就是,正向代理式要规避死循环代理。

    该代理程序靠近clients,client对于外部ip的请求,先发到代理程序。

    //针对httpclient设置proxy
    	transport := &http.Transport{
    		Proxy: http.ProxyURL(proxyURL),
    	}
    
    	//adding the Transport object to the http Client
    	client := &http.Client{
    		Transport: transport,
    	}
    

    下面使用curl指令演示(-x 后接代理地址)
    curl -x 127.0.0.1:8080 www.baidu.com


    反向代理的实践

    反向代理, 服务入站请求。
    前几天利用golang实现了反向代理程序,引出了[Host请求头在反代中的关键作用]{https://www.cnblogs.com/JulianHuang/p/16639016.html}:

    host 请求头用于在 (单负载主机支撑多域名)中区分服务域名,对应到 nginx --http context--- server context -- server_name 配置节。

    对于proxy.com的请求,都被透明无感代理到A.com

    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    	"net/http/httputil"
    )
    
    func ReverseProxyHandler(w http.ResponseWriter, r *http.Request) {
    	fmt.Printf("receive a request from %s,request header: %s: \n", r.RemoteAddr, r.Header)
    
    	target := "www.baidu.com"
    	director := func(req *http.Request) {
    		req.URL.Scheme = "https"
    		req.URL.Host = target
    		req.Host = target
    	}
    	proxy := &httputil.ReverseProxy{Director: director}
    	proxy.ServeHTTP(w, r)
            fmt.Printf("receive the destination website response header: %s\n", w.Header())
    }
    
    func main() {
    	fmt.Printf("Starting server at port 8080\n")
    	if err := http.ListenAndServe(":8080", http.HandlerFunc(ReverseProxyHandler)); err != nil {
    		log.Fatal(err)
    	}
    }
    
    

    以上代理服务器proxy.com部署在服务侧www.baidu.com;
    proxy.com接收clients的入站请求,反向转发到www.baidu.com。

    curl www.proxy.com返回baidu.com的内容。

    GO快闪#

    本文总结了go语言正/反向代理的姿势。

  • 相关阅读:
    【pen200-lab】10.11.1.146
    java字符串储存底层原理
    python基于Vue的web信息收集程序设计
    网卡和智能网卡
    [网上摘录]Gerber RS274X-CAM文件格式详解
    Vue3 复制 copy 功能实现(vue-clipboard3)
    闲话Python编程-始于计算
    计算机算法分析与设计(24)---分支限界章节复习
    【机器学习】梯度下降法与牛顿法【Ⅱ】牛顿法与修正牛顿法
    hashmap的一些坑
  • 原文地址:https://www.cnblogs.com/JulianHuang/p/16867844.html