proxy.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. p = &Proxy{
  41. Server: NewProxyServer(),
  42. Ln: listen,
  43. }
  44. return
  45. }
  46. func (proxy *Proxy) Name() string {
  47. return ProxyName
  48. }
  49. // right??
  50. func (proxy *Proxy) Handle(conn io.ReadWriteCloser) {
  51. wrapConn := wrap.WrapReadWriteCloserToConn(conn)
  52. remote, err := net.Dial("tcp", cnfg.Port)
  53. if err != nil {
  54. log.Error("dial tcp error:%v", err)
  55. return
  56. }
  57. // or tcp.Join(remote,wrapConn)
  58. _, err = io.Copy(remote, wrapConn)
  59. if err != nil && err != io.EOF {
  60. log.Error("io copy data error:%v", err)
  61. return
  62. }
  63. return
  64. }
  65. func (proxy *Proxy) Close() error {
  66. return proxy.Server.Close()
  67. }
  68. func NewProxyServer() *http.Server {
  69. return &http.Server{
  70. Addr: cnfg.Port,
  71. Handler: &ProxyServer{Tr: http.DefaultTransport.(*http.Transport)},
  72. ReadTimeout: 10 * time.Second,
  73. WriteTimeout: 10 * time.Second,
  74. MaxHeaderBytes: 1 << 20,
  75. }
  76. }
  77. func (proxy *ProxyServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
  78. defer func() {
  79. if err := recover(); err != nil {
  80. rw.WriteHeader(http.StatusInternalServerError)
  81. log.Error("Panic: %v", err)
  82. fmt.Fprintf(rw, fmt.Sprintln(err))
  83. }
  84. }()
  85. if req.Method == "CONNECT" { // 是connect连接
  86. proxy.HttpsHandler(rw, req)
  87. } else {
  88. proxy.HttpHandler(rw, req)
  89. }
  90. }
  91. // 处理普通的http请求
  92. func (proxy *ProxyServer) HttpHandler(rw http.ResponseWriter, req *http.Request) {
  93. log.Info("is sending request %v %v ", req.Method, req.URL.Host)
  94. removeProxyHeaders(req) // 去除不必要的头
  95. resp, err := proxy.Tr.RoundTrip(req)
  96. if err != nil {
  97. log.Error("transport RoundTrip error: %v", err)
  98. http.Error(rw, err.Error(), http.StatusInternalServerError)
  99. return
  100. }
  101. defer resp.Body.Close()
  102. clearHeaders(rw.Header()) // 得到一个空的Header
  103. copyHeaders(rw.Header(), resp.Header)
  104. rw.WriteHeader(resp.StatusCode)
  105. nr, err := io.Copy(rw, resp.Body)
  106. if err != nil && err != io.EOF {
  107. log.Error("got an error when copy remote response to client.%v", err)
  108. return
  109. }
  110. log.Info("copied %v bytes from remote host %v.", nr, req.URL.Host)
  111. }
  112. // 处理https连接,主要用于CONNECT方法
  113. func (proxy *ProxyServer) HttpsHandler(rw http.ResponseWriter, req *http.Request) {
  114. log.Info("[CONNECT] tried to connect to remote host %v", req.URL.Host)
  115. hj, _ := rw.(http.Hijacker)
  116. client, _, err := hj.Hijack() //获取客户端与代理服务器的tcp连接
  117. if err != nil {
  118. log.Error("failed to get Tcp connection of", req.RequestURI)
  119. http.Error(rw, "Failed", http.StatusBadRequest)
  120. return
  121. }
  122. remote, err := net.Dial("tcp", req.URL.Host) //建立服务端和代理服务器的tcp连接
  123. if err != nil {
  124. log.Error("failed to connect %v", req.RequestURI)
  125. http.Error(rw, "Failed", http.StatusBadRequest)
  126. client.Close()
  127. return
  128. }
  129. client.Write(HTTP_200)
  130. go copyRemoteToClient(remote, client)
  131. go copyRemoteToClient(client, remote)
  132. }
  133. // data copy between two socket
  134. func copyRemoteToClient(remote, client net.Conn) {
  135. defer func() {
  136. remote.Close()
  137. client.Close()
  138. }()
  139. nr, err := io.Copy(remote, client)
  140. if err != nil && err != io.EOF {
  141. log.Error("got an error when handles CONNECT %v", err)
  142. return
  143. }
  144. log.Info("[CONNECT] transported %v bytes betwwen %v and %v", nr, remote.RemoteAddr(), client.RemoteAddr())
  145. }
  146. func copyHeaders(dst, src http.Header) {
  147. for key, values := range src {
  148. for _, value := range values {
  149. dst.Add(key, value)
  150. }
  151. }
  152. }
  153. func clearHeaders(headers http.Header) {
  154. for key, _ := range headers {
  155. headers.Del(key)
  156. }
  157. }
  158. func removeProxyHeaders(req *http.Request) {
  159. req.RequestURI = ""
  160. req.Header.Del("Proxy-Connection")
  161. req.Header.Del("Connection")
  162. req.Header.Del("Keep-Alive")
  163. req.Header.Del("Proxy-Authenticate")
  164. req.Header.Del("Proxy-Authorization")
  165. req.Header.Del("TE")
  166. req.Header.Del("Trailers")
  167. req.Header.Del("Transfer-Encoding")
  168. req.Header.Del("Upgrade")
  169. }