1
0

proxy.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package proxy
  2. import (
  3. "fmt"
  4. "io"
  5. "net"
  6. "net/http"
  7. "os"
  8. "time"
  9. "github.com/fatedier/frp/models/plugin"
  10. "github.com/fatedier/frp/utils/log"
  11. wrap "github.com/fatedier/frp/utils/net"
  12. )
  13. var (
  14. HTTP_200 = []byte("HTTP/1.1 200 Connection Established\r\n\r\n")
  15. ProxyName = "default-proxy"
  16. cnfg Config
  17. )
  18. func init() {
  19. // 加载配置文件
  20. err := cnfg.GetConfig("../config/config.json")
  21. if err != nil {
  22. log.Error("can not load config file:%v\n", err)
  23. os.Exit(-1)
  24. }
  25. plugin.Register(ProxyName, NewProxyPlugin)
  26. }
  27. type ProxyServer struct {
  28. Tr *http.Transport
  29. }
  30. type Proxy struct {
  31. Server *http.Server
  32. Ln net.Listener
  33. }
  34. func NewProxyPlugin(params map[string]string) (p plugin.Plugin, err error) {
  35. listen, err := net.Listen("tcp", cnfg.Port)
  36. if err != nil {
  37. log.Error("can not listen %v port", cnfg.Port)
  38. return
  39. }
  40. proxy := &Proxy{
  41. Server: NewProxyServer(),
  42. Ln: listen,
  43. }
  44. go proxy.Server.Serve(proxy.Ln)
  45. return proxy, nil
  46. }
  47. func (proxy *Proxy) Name() string {
  48. return ProxyName
  49. }
  50. // right??
  51. func (proxy *Proxy) Handle(conn io.ReadWriteCloser) {
  52. wrapConn := wrap.WrapReadWriteCloserToConn(conn)
  53. remote, err := net.Dial("tcp", cnfg.Port)
  54. if err != nil {
  55. log.Error("dial tcp error:%v", err)
  56. return
  57. }
  58. // or tcp.Join(remote,wrapConn)
  59. _, err = io.Copy(remote, wrapConn)
  60. if err != nil && err != io.EOF {
  61. log.Error("io copy data error:%v", err)
  62. return
  63. }
  64. return
  65. }
  66. func (proxy *Proxy) Close() error {
  67. return proxy.Server.Close()
  68. }
  69. func NewProxyServer() *http.Server {
  70. return &http.Server{
  71. Addr: cnfg.Port,
  72. Handler: &ProxyServer{Tr: http.DefaultTransport.(*http.Transport)},
  73. ReadTimeout: 10 * time.Second,
  74. WriteTimeout: 10 * time.Second,
  75. MaxHeaderBytes: 1 << 20,
  76. }
  77. }
  78. func (proxy *ProxyServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
  79. defer func() {
  80. if err := recover(); err != nil {
  81. rw.WriteHeader(http.StatusInternalServerError)
  82. log.Error("Panic: %v", err)
  83. fmt.Fprintf(rw, fmt.Sprintln(err))
  84. }
  85. }()
  86. if req.Method == "CONNECT" { // 是connect连接
  87. proxy.HttpsHandler(rw, req)
  88. } else {
  89. proxy.HttpHandler(rw, req)
  90. }
  91. }
  92. // 处理普通的http请求
  93. func (proxy *ProxyServer) HttpHandler(rw http.ResponseWriter, req *http.Request) {
  94. log.Info("is sending request %v %v ", req.Method, req.URL.Host)
  95. removeProxyHeaders(req) // 去除不必要的头
  96. resp, err := proxy.Tr.RoundTrip(req)
  97. if err != nil {
  98. log.Error("transport RoundTrip error: %v", err)
  99. http.Error(rw, err.Error(), http.StatusInternalServerError)
  100. return
  101. }
  102. defer resp.Body.Close()
  103. clearHeaders(rw.Header()) // 得到一个空的Header
  104. copyHeaders(rw.Header(), resp.Header)
  105. rw.WriteHeader(resp.StatusCode)
  106. nr, err := io.Copy(rw, resp.Body)
  107. if err != nil && err != io.EOF {
  108. log.Error("got an error when copy remote response to client.%v", err)
  109. return
  110. }
  111. log.Info("copied %v bytes from remote host %v.", nr, req.URL.Host)
  112. }
  113. // 处理https连接,主要用于CONNECT方法
  114. func (proxy *ProxyServer) HttpsHandler(rw http.ResponseWriter, req *http.Request) {
  115. log.Info("[CONNECT] tried to connect to remote host %v", req.URL.Host)
  116. hj, _ := rw.(http.Hijacker)
  117. client, _, err := hj.Hijack() //获取客户端与代理服务器的tcp连接
  118. if err != nil {
  119. log.Error("failed to get Tcp connection of", req.RequestURI)
  120. http.Error(rw, "Failed", http.StatusBadRequest)
  121. return
  122. }
  123. remote, err := net.Dial("tcp", req.URL.Host) //建立服务端和代理服务器的tcp连接
  124. if err != nil {
  125. log.Error("failed to connect %v", req.RequestURI)
  126. http.Error(rw, "Failed", http.StatusBadRequest)
  127. client.Close()
  128. return
  129. }
  130. client.Write(HTTP_200)
  131. go copyRemoteToClient(remote, client)
  132. go copyRemoteToClient(client, remote)
  133. }
  134. // data copy between two socket
  135. func copyRemoteToClient(remote, client net.Conn) {
  136. defer func() {
  137. remote.Close()
  138. client.Close()
  139. }()
  140. nr, err := io.Copy(remote, client)
  141. if err != nil && err != io.EOF {
  142. log.Error("got an error when handles CONNECT %v", err)
  143. return
  144. }
  145. log.Info("[CONNECT] transported %v bytes betwwen %v and %v", nr, remote.RemoteAddr(), client.RemoteAddr())
  146. }
  147. func copyHeaders(dst, src http.Header) {
  148. for key, values := range src {
  149. for _, value := range values {
  150. dst.Add(key, value)
  151. }
  152. }
  153. }
  154. func clearHeaders(headers http.Header) {
  155. for key, _ := range headers {
  156. headers.Del(key)
  157. }
  158. }
  159. func removeProxyHeaders(req *http.Request) {
  160. req.RequestURI = ""
  161. req.Header.Del("Proxy-Connection")
  162. req.Header.Del("Connection")
  163. req.Header.Del("Keep-Alive")
  164. req.Header.Del("Proxy-Authenticate")
  165. req.Header.Del("Proxy-Authorization")
  166. req.Header.Del("TE")
  167. req.Header.Del("Trailers")
  168. req.Header.Del("Transfer-Encoding")
  169. req.Header.Del("Upgrade")
  170. }