conn.go 5.3 KB

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