http.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package server
  2. import (
  3. "bufio"
  4. "crypto/tls"
  5. "github.com/astaxie/beego"
  6. "github.com/cnlh/easyProxy/bridge"
  7. "github.com/cnlh/easyProxy/utils"
  8. "net"
  9. "net/http"
  10. "net/http/httputil"
  11. "strconv"
  12. "sync"
  13. )
  14. type httpServer struct {
  15. server
  16. httpPort int //http端口
  17. httpsPort int //https监听端口
  18. pemPath string
  19. keyPath string
  20. stop chan bool
  21. }
  22. func NewHttp(bridge *bridge.Bridge, c *utils.Tunnel) *httpServer {
  23. httpPort, _ := beego.AppConfig.Int("httpProxyPort")
  24. httpsPort, _ := beego.AppConfig.Int("httpsProxyPort")
  25. pemPath := beego.AppConfig.String("pemPath")
  26. keyPath := beego.AppConfig.String("keyPath")
  27. return &httpServer{
  28. server: server{
  29. task: c,
  30. bridge: bridge,
  31. Mutex: sync.Mutex{},
  32. },
  33. httpPort: httpPort,
  34. httpsPort: httpsPort,
  35. pemPath: pemPath,
  36. keyPath: keyPath,
  37. stop: make(chan bool),
  38. }
  39. }
  40. func (s *httpServer) Start() error {
  41. var err error
  42. var http, https *http.Server
  43. if s.errorContent, err = utils.ReadAllFromFile(beego.AppPath + "/web/static/page/error.html"); err != nil {
  44. s.errorContent = []byte("easyProxy 404")
  45. }
  46. if s.httpPort > 0 {
  47. if !s.TestTcpPort(s.httpPort) {
  48. utils.Fatalln("http端口", s.httpPort, "被占用!")
  49. }
  50. http = s.NewServer(s.httpPort)
  51. go func() {
  52. utils.Println("启动http监听,端口为", s.httpPort)
  53. err := http.ListenAndServe()
  54. if err != nil {
  55. utils.Fatalln(err)
  56. }
  57. }()
  58. }
  59. if s.httpsPort > 0 {
  60. if !s.TestTcpPort(s.httpsPort) {
  61. utils.Fatalln("https端口", s.httpsPort, "被占用!")
  62. }
  63. if !utils.FileExists(s.pemPath) {
  64. utils.Fatalf("ssl certFile文件%s不存在", s.pemPath)
  65. }
  66. if !utils.FileExists(s.keyPath) {
  67. utils.Fatalf("ssl keyFile文件%s不存在", s.keyPath)
  68. }
  69. https = s.NewServer(s.httpsPort)
  70. go func() {
  71. utils.Println("启动https监听,端口为", s.httpsPort)
  72. err := https.ListenAndServeTLS(s.pemPath, s.keyPath)
  73. if err != nil {
  74. utils.Fatalln(err)
  75. }
  76. }()
  77. }
  78. startFinish <- true
  79. select {
  80. case <-s.stop:
  81. if http != nil {
  82. http.Close()
  83. }
  84. if https != nil {
  85. https.Close()
  86. }
  87. }
  88. return nil
  89. }
  90. func (s *httpServer) Close() {
  91. s.stop <- true
  92. }
  93. func (s *httpServer) handleTunneling(w http.ResponseWriter, r *http.Request) {
  94. hijacker, ok := w.(http.Hijacker)
  95. if !ok {
  96. http.Error(w, "Hijacking not supported", http.StatusInternalServerError)
  97. return
  98. }
  99. conn, _, err := hijacker.Hijack()
  100. if err != nil {
  101. http.Error(w, err.Error(), http.StatusServiceUnavailable)
  102. }
  103. s.process(utils.NewConn(conn), r)
  104. }
  105. func (s *httpServer) process(c *utils.Conn, r *http.Request) {
  106. //多客户端域名代理
  107. var (
  108. isConn = true
  109. link *utils.Link
  110. host *utils.Host
  111. tunnel *utils.Conn
  112. err error
  113. )
  114. for {
  115. //首次获取conn
  116. if isConn {
  117. if host, err = GetInfoByHost(r.Host); err != nil {
  118. utils.Printf("the host %s is not found !", r.Host)
  119. break
  120. }
  121. //流量限制
  122. if host.Client.Flow.FlowLimit > 0 && (host.Client.Flow.FlowLimit<<20) < (host.Client.Flow.ExportFlow+host.Client.Flow.InletFlow) {
  123. break
  124. }
  125. host.Client.Cnf.CompressDecode, host.Client.Cnf.CompressEncode = utils.GetCompressType(host.Client.Cnf.Compress)
  126. //权限控制
  127. if err = s.auth(r, c, host.Client.Cnf.U, host.Client.Cnf.P); err != nil {
  128. break
  129. }
  130. link = utils.NewLink(host.Client.GetId(), utils.CONN_TCP, host.GetRandomTarget(), host.Client.Cnf.CompressEncode, host.Client.Cnf.CompressDecode, host.Client.Cnf.Crypt, c, host.Flow, nil, host.Client.Rate, nil)
  131. if tunnel, err = s.bridge.SendLinkInfo(host.Client.Id, link); err != nil {
  132. break
  133. }
  134. isConn = false
  135. } else {
  136. r, err = http.ReadRequest(bufio.NewReader(c))
  137. if err != nil {
  138. break
  139. }
  140. }
  141. //根据设定,修改header和host
  142. utils.ChangeHostAndHeader(r, host.HostChange, host.HeaderChange, c.Conn.RemoteAddr().String())
  143. b, err := httputil.DumpRequest(r, true)
  144. if err != nil {
  145. break
  146. }
  147. host.Flow.Add(len(b), 0)
  148. if _, err := tunnel.SendMsg(b, link); err != nil {
  149. c.Close()
  150. break
  151. }
  152. }
  153. if isConn {
  154. s.writeConnFail(c.Conn)
  155. } else {
  156. tunnel.SendMsg([]byte(utils.IO_EOF), link)
  157. }
  158. c.Close()
  159. }
  160. func (s *httpServer) NewServer(port int) *http.Server {
  161. return &http.Server{
  162. Addr: ":" + strconv.Itoa(port),
  163. Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  164. s.handleTunneling(w, r)
  165. }),
  166. // Disable HTTP/2.
  167. TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)),
  168. }
  169. }
  170. func (s *httpServer) TestTcpPort(port int) bool {
  171. l, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), port, ""})
  172. defer l.Close()
  173. if err != nil {
  174. return false
  175. }
  176. return true
  177. }