Go实现简单的反向代理

在这里插入图片描述

真机侧

package main

type RealServer struct {
    
    
	Addr string
}

func NewRealServer(addr string) *RealServer {
    
    
	return &RealServer{
    
    Addr: addr}
}

func (r *RealServer) HelloHandler(w http.ResponseWriter, req *http.Request) {
    
    
	//127.0.0.1:8008/abc?sdsdsa=11
	//r.Addr=127.0.0.1:8008
	//req.URL.Path=/abc
	req.Header.Set("X-Forwarded-For", req.RemoteAddr)
	upath := fmt.Sprintf("http://%s%s\n", r.Addr, req.URL.Path)
	realIP := fmt.Sprintf("RemoteAddr=%s,X-Forwarded-For=%v,X-Real-Ip=%v\n", req.RemoteAddr, req.Header.Get("X-Forwarded-For"), req.Header.Get("X-Real-Ip"))
	header := fmt.Sprintf("headers =%v\n", req.Header)
	io.WriteString(w, upath)
	io.WriteString(w, realIP)
	io.WriteString(w, header)
}

func (r *RealServer) ErrorHandler(w http.ResponseWriter, req *http.Request) {
    
    
	upath := "error handler"
	w.WriteHeader(500)
	io.WriteString(w, upath)
}

func (r *RealServer) TimeoutHandler(w http.ResponseWriter, req *http.Request) {
    
    
	time.Sleep(6 * time.Second)
	upath := "timeout handler"
	w.WriteHeader(200)
	io.WriteString(w, upath)
}

func (r *RealServer) Run() {
    
    
	log.Println("Starting httpserver at " + r.Addr)
	mux := http.NewServeMux()
	mux.HandleFunc("/", r.HelloHandler)
	mux.HandleFunc("/base/error", r.ErrorHandler)
	mux.HandleFunc("/test_http_string/test_http_string/aaa", r.TimeoutHandler)
	server := &http.Server{
    
    
		Addr:         r.Addr,
		WriteTimeout: time.Second * 3,
		Handler:      mux,
	}
	go func() {
    
    
		log.Fatal(server.ListenAndServe())
	}()
}

func main() {
    
    
	rs1 := &RealServer{
    
    Addr: "127.0.0.1:2003"}
	rs1.Run()
	rs2 := &RealServer{
    
    Addr: "127.0.0.1:2004"}
	rs2.Run()

	//监听关闭信号
	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
}

代理侧

package main

import (
	"bufio"
	"log"
	"net/http"
	"net/url"
)

// + 反向代理
// - 客户端请求代理(以为代理就是真机)
// - 代理去真机拿数据(从定义的后端机器请求数据)
// - 代理返回数据给客户端(给w写入数据)
var (
	proxyAddr = "http://127.0.0.1:2003"
	port      = ":2002"
)

func handler(w http.ResponseWriter, r *http.Request) {
    
    
	//1. 解析代理地址,并更改请求体的协议和主机(真机)
	proxy, err := url.Parse(proxyAddr)
	if err != nil {
    
    
		w.WriteHeader(http.StatusBadGateway)
		log.Print(err)
		return
	}
	r.Header.Set("X-Real-Ip", proxy.Host)
	r.URL.Scheme = proxy.Scheme //http
	r.URL.Host = proxy.Host     //换成后端地址 127.0.0.1:2003

	//2. 请求Host主机
	transport := http.DefaultTransport
	resp, err := transport.RoundTrip(r)
	if err != nil {
    
    
		w.WriteHeader(http.StatusBadGateway)
		log.Print(err)
		return
	}
	// 3. 将内容拷给客户端
	for key, values := range resp.Header {
    
    
		for _, v := range values {
    
    
			w.Header().Add(key, v)
		}
	}
	// io.Copy(w, resp.Body)
	bufio.NewReader(resp.Body).WriteTo(w)
	resp.Body.Close()
}

func main() {
    
    
	http.HandleFunc("/", handler)
	log.Print("start server on ", port)
	if err := http.ListenAndServe(port, nil); err != nil {
    
    
		log.Fatal(err)
	}
}

猜你喜欢

转载自blog.csdn.net/qq_38900565/article/details/107576610
今日推荐