Linux,Golang

Golang正向代理

正向代理

一种客户端代理技术,用于帮助客户端访问无法直接访问的网络资源,并隐藏客户端IP,浏览器HTTP代理

实践

代理接收客户端发送的请求,复制该请求对象,根据实际需要修改请求参数。

构造新的请求,发送到服务器,并获取服务端响应

将接收到的内容返回给客户端

package main

import (
    "fmt"
    "io"
    "log"
    "net"
    "net/http"
    "strings"
)

type proxy struct{}

func (p *proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    //接收http请求
    fmt.Printf("接收到请求:方法 %s 域名 %s 地址 %s 长度 %d", r.Method, r.Host, r.RemoteAddr, r.ContentLength)
    //修改 构造新请求
    transport := http.DefaultTransport

    //copy源请求,避免影响源对象
    req := new(http.Request)
    //将源http请求给新new出的对象
    *req = *r

    //设置X-Forward-For请求头
    /*
        SplitHostPort 拆分“host:port”形式的网络地址,
        "host%zone:port"、"[host]:port" 或 "[host%zone]:port" 进入主机或
        主机%区域和端口。
    */
    clientIP, _, err := net.SplitHostPort(r.RemoteAddr)
    if err != nil {
        log.Println("SplitHostPort error", err)
    }

    //req.header是一个map
    if v, ok := req.Header["X-Forward-For"]; ok {
        clientIP = strings.Join(v, ", ") + ", " + clientIP
        fmt.Println("构造后的clientIP : ", clientIP)
    }
    req.Header.Set("X-Forward-For", clientIP)

    //构造新request请求
    response, err := transport.RoundTrip(req)
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }
    //获取数据并返回
    for k, v := range response.Header {
        for _, v1 := range v {
            w.Header().Add(k, v1)

        }
        w.WriteHeader(response.StatusCode)
        io.Copy(w, response.Body)
        response.Body.Close()

    }

}

func main() {
    server := &http.Server{
        Addr:    ":9090",
        Handler: &proxy{},
    }
    if err := server.ListenAndServe(); err != nil {
        log.Fatal("Http proxy server start failed.")
    }

}

curl -x 127.0.0.1:9090 http://www.baidu.com
经测试 http正常 https无法正常使用

回复

This is just a placeholder img.