http.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. "log"
  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. http = s.NewServer(s.httpPort)
  48. go func() {
  49. log.Println("启动http监听,端口为", s.httpPort)
  50. err := http.ListenAndServe()
  51. if err != nil {
  52. log.Fatalln(err)
  53. }
  54. }()
  55. }
  56. if s.httpsPort > 0 {
  57. https = s.NewServer(s.httpsPort)
  58. go func() {
  59. log.Println("启动https监听,端口为", s.httpsPort)
  60. err := https.ListenAndServeTLS(s.pemPath, s.keyPath)
  61. if err != nil {
  62. log.Fatalln(err)
  63. }
  64. }()
  65. }
  66. select {
  67. case <-s.stop:
  68. if http != nil {
  69. http.Close()
  70. }
  71. if https != nil {
  72. https.Close()
  73. }
  74. }
  75. return nil
  76. }
  77. func (s *httpServer) Close() {
  78. s.stop <- true
  79. }
  80. func (s *httpServer) handleTunneling(w http.ResponseWriter, r *http.Request) {
  81. hijacker, ok := w.(http.Hijacker)
  82. if !ok {
  83. http.Error(w, "Hijacking not supported", http.StatusInternalServerError)
  84. return
  85. }
  86. conn, _, err := hijacker.Hijack()
  87. if err != nil {
  88. http.Error(w, err.Error(), http.StatusServiceUnavailable)
  89. }
  90. s.process(utils.NewConn(conn), r)
  91. }
  92. func (s *httpServer) process(c *utils.Conn, r *http.Request) {
  93. //多客户端域名代理
  94. var (
  95. isConn = true
  96. link *utils.Link
  97. host *utils.Host
  98. tunnel *utils.Conn
  99. err error
  100. )
  101. for {
  102. //首次获取conn
  103. if isConn {
  104. if host, err = GetInfoByHost(r.Host); err != nil {
  105. log.Printf("the host %s is not found !", r.Host)
  106. break
  107. }
  108. //流量限制
  109. if host.Client.Flow.FlowLimit > 0 && (host.Client.Flow.FlowLimit<<20) < (host.Client.Flow.ExportFlow+host.Client.Flow.InletFlow) {
  110. break
  111. }
  112. host.Client.Cnf.CompressDecode, host.Client.Cnf.CompressEncode = utils.GetCompressType(host.Client.Cnf.Compress)
  113. //权限控制
  114. if err = s.auth(r, c, host.Client.Cnf.U, host.Client.Cnf.P); err != nil {
  115. break
  116. }
  117. link = utils.NewLink(host.Client.GetId(), utils.CONN_TCP, host.Target, host.Client.Cnf.CompressEncode, host.Client.Cnf.CompressDecode, host.Client.Cnf.Crypt, c, host.Flow, nil, host.Client.Rate, nil)
  118. if tunnel, err = s.bridge.SendLinkInfo(host.Client.Id, link); err != nil {
  119. break
  120. }
  121. isConn = false
  122. } else {
  123. r, err = http.ReadRequest(bufio.NewReader(c))
  124. if err != nil {
  125. log.Println(err)
  126. break
  127. }
  128. }
  129. //根据设定,修改header和host
  130. utils.ChangeHostAndHeader(r, host.HostChange, host.HeaderChange, c.Conn.RemoteAddr().String())
  131. b, err := httputil.DumpRequest(r, true)
  132. if err != nil {
  133. break
  134. }
  135. host.Flow.Add(len(b), 0)
  136. if _, err := tunnel.SendMsg(b, link); err != nil {
  137. c.Close()
  138. break
  139. }
  140. }
  141. if isConn {
  142. s.writeConnFail(c.Conn)
  143. } else {
  144. tunnel.SendMsg([]byte(utils.IO_EOF), link)
  145. }
  146. c.Close()
  147. }
  148. func (s *httpServer) NewServer(port int) *http.Server {
  149. return &http.Server{
  150. Addr: ":" + strconv.Itoa(port),
  151. Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  152. s.handleTunneling(w, r)
  153. }),
  154. // Disable HTTP/2.
  155. TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)),
  156. }
  157. }