真机侧
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)
}
}