conn.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. package v2rayhttp
  2. import (
  3. std_bufio "bufio"
  4. "io"
  5. "net"
  6. "net/http"
  7. "os"
  8. "strings"
  9. "sync"
  10. "time"
  11. "github.com/sagernet/sing/common"
  12. "github.com/sagernet/sing/common/baderror"
  13. "github.com/sagernet/sing/common/buf"
  14. "github.com/sagernet/sing/common/bufio"
  15. E "github.com/sagernet/sing/common/exceptions"
  16. F "github.com/sagernet/sing/common/format"
  17. M "github.com/sagernet/sing/common/metadata"
  18. N "github.com/sagernet/sing/common/network"
  19. )
  20. type HTTPConn struct {
  21. net.Conn
  22. request *http.Request
  23. requestWritten bool
  24. responseRead bool
  25. responseCache *buf.Buffer
  26. }
  27. func NewHTTP1Conn(conn net.Conn, request *http.Request) *HTTPConn {
  28. return &HTTPConn{
  29. Conn: conn,
  30. request: request,
  31. }
  32. }
  33. func (c *HTTPConn) Read(b []byte) (n int, err error) {
  34. if !c.responseRead {
  35. reader := std_bufio.NewReader(c.Conn)
  36. response, err := http.ReadResponse(reader, c.request)
  37. if err != nil {
  38. return 0, E.Cause(err, "read response")
  39. }
  40. if response.StatusCode != 200 {
  41. return 0, E.New("v2ray-http: unexpected status: ", response.Status)
  42. }
  43. if cacheLen := reader.Buffered(); cacheLen > 0 {
  44. c.responseCache = buf.NewSize(cacheLen)
  45. _, err = c.responseCache.ReadFullFrom(reader, cacheLen)
  46. if err != nil {
  47. c.responseCache.Release()
  48. return 0, E.Cause(err, "read cache")
  49. }
  50. }
  51. c.responseRead = true
  52. }
  53. if c.responseCache != nil {
  54. n, err = c.responseCache.Read(b)
  55. if err == io.EOF {
  56. c.responseCache.Release()
  57. c.responseCache = nil
  58. }
  59. if n > 0 {
  60. return n, nil
  61. }
  62. }
  63. return c.Conn.Read(b)
  64. }
  65. func (c *HTTPConn) Write(b []byte) (int, error) {
  66. if !c.requestWritten {
  67. err := c.writeRequest(b)
  68. if err != nil {
  69. return 0, E.Cause(err, "write request")
  70. }
  71. c.requestWritten = true
  72. return len(b), nil
  73. }
  74. return c.Conn.Write(b)
  75. }
  76. func (c *HTTPConn) writeRequest(payload []byte) error {
  77. writer := bufio.NewBufferedWriter(c.Conn, buf.New())
  78. const CRLF = "\r\n"
  79. _, err := writer.Write([]byte(F.ToString(c.request.Method, " ", c.request.URL.RequestURI(), " HTTP/1.1", CRLF)))
  80. if err != nil {
  81. return err
  82. }
  83. if c.request.Header.Get("Host") == "" {
  84. c.request.Header.Set("Host", c.request.Host)
  85. }
  86. for key, value := range c.request.Header {
  87. _, err = writer.Write([]byte(F.ToString(key, ": ", strings.Join(value, ", "), CRLF)))
  88. if err != nil {
  89. return err
  90. }
  91. }
  92. _, err = writer.Write([]byte(CRLF))
  93. if err != nil {
  94. return err
  95. }
  96. _, err = writer.Write(payload)
  97. if err != nil {
  98. return err
  99. }
  100. err = writer.Fallthrough()
  101. if err != nil {
  102. return err
  103. }
  104. return nil
  105. }
  106. func (c *HTTPConn) ReaderReplaceable() bool {
  107. return c.responseRead
  108. }
  109. func (c *HTTPConn) WriterReplaceable() bool {
  110. return c.requestWritten
  111. }
  112. func (c *HTTPConn) NeedHandshake() bool {
  113. return !c.requestWritten
  114. }
  115. func (c *HTTPConn) Upstream() any {
  116. return c.Conn
  117. }
  118. type HTTP2Conn struct {
  119. reader io.Reader
  120. writer io.Writer
  121. create chan struct{}
  122. err error
  123. }
  124. func NewHTTPConn(reader io.Reader, writer io.Writer) HTTP2Conn {
  125. return HTTP2Conn{
  126. reader: reader,
  127. writer: writer,
  128. }
  129. }
  130. func NewLateHTTPConn(writer io.Writer) *HTTP2Conn {
  131. return &HTTP2Conn{
  132. create: make(chan struct{}),
  133. writer: writer,
  134. }
  135. }
  136. func (c *HTTP2Conn) Setup(reader io.Reader, err error) {
  137. c.reader = reader
  138. c.err = err
  139. close(c.create)
  140. }
  141. func (c *HTTP2Conn) Read(b []byte) (n int, err error) {
  142. if c.reader == nil {
  143. <-c.create
  144. if c.err != nil {
  145. return 0, c.err
  146. }
  147. }
  148. n, err = c.reader.Read(b)
  149. return n, baderror.WrapH2(err)
  150. }
  151. func (c *HTTP2Conn) Write(b []byte) (n int, err error) {
  152. n, err = c.writer.Write(b)
  153. return n, baderror.WrapH2(err)
  154. }
  155. func (c *HTTP2Conn) Close() error {
  156. return common.Close(c.reader, c.writer)
  157. }
  158. func (c *HTTP2Conn) LocalAddr() net.Addr {
  159. return M.Socksaddr{}
  160. }
  161. func (c *HTTP2Conn) RemoteAddr() net.Addr {
  162. return M.Socksaddr{}
  163. }
  164. func (c *HTTP2Conn) SetDeadline(t time.Time) error {
  165. return os.ErrInvalid
  166. }
  167. func (c *HTTP2Conn) SetReadDeadline(t time.Time) error {
  168. return os.ErrInvalid
  169. }
  170. func (c *HTTP2Conn) SetWriteDeadline(t time.Time) error {
  171. return os.ErrInvalid
  172. }
  173. func (c *HTTP2Conn) NeedAdditionalReadDeadline() bool {
  174. return true
  175. }
  176. type ServerHTTPConn struct {
  177. HTTP2Conn
  178. Flusher http.Flusher
  179. }
  180. func (c *ServerHTTPConn) Write(b []byte) (n int, err error) {
  181. n, err = c.writer.Write(b)
  182. if err == nil {
  183. c.Flusher.Flush()
  184. }
  185. return
  186. }
  187. type HTTP2ConnWrapper struct {
  188. N.ExtendedConn
  189. access sync.Mutex
  190. closed bool
  191. }
  192. func NewHTTP2Wrapper(conn net.Conn) *HTTP2ConnWrapper {
  193. return &HTTP2ConnWrapper{
  194. ExtendedConn: bufio.NewExtendedConn(conn),
  195. }
  196. }
  197. func (w *HTTP2ConnWrapper) Write(p []byte) (n int, err error) {
  198. w.access.Lock()
  199. defer w.access.Unlock()
  200. if w.closed {
  201. return 0, net.ErrClosed
  202. }
  203. return w.ExtendedConn.Write(p)
  204. }
  205. func (w *HTTP2ConnWrapper) WriteBuffer(buffer *buf.Buffer) error {
  206. w.access.Lock()
  207. defer w.access.Unlock()
  208. if w.closed {
  209. return net.ErrClosed
  210. }
  211. return w.ExtendedConn.WriteBuffer(buffer)
  212. }
  213. func (w *HTTP2ConnWrapper) CloseWrapper() {
  214. w.access.Lock()
  215. defer w.access.Unlock()
  216. w.closed = true
  217. }
  218. func (w *HTTP2ConnWrapper) Close() error {
  219. w.CloseWrapper()
  220. return w.ExtendedConn.Close()
  221. }
  222. func (w *HTTP2ConnWrapper) Upstream() any {
  223. return w.ExtendedConn
  224. }