http.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. package http
  2. //go:generate errorgen
  3. import (
  4. "bytes"
  5. "context"
  6. "io"
  7. "net"
  8. "net/http"
  9. "strings"
  10. "time"
  11. "v2ray.com/core/common"
  12. "v2ray.com/core/common/buf"
  13. "v2ray.com/core/common/serial"
  14. )
  15. const (
  16. // CRLF is the line ending in HTTP header
  17. CRLF = "\r\n"
  18. // ENDING is the double line ending between HTTP header and body.
  19. ENDING = CRLF + CRLF
  20. // max length of HTTP header. Safety precaution for DDoS attack.
  21. maxHeaderLength = 8192
  22. )
  23. var (
  24. ErrHeaderToLong = newError("Header too long.")
  25. writeCRLF = serial.WriteString(CRLF)
  26. )
  27. type Reader interface {
  28. Read(io.Reader) (*buf.Buffer, error)
  29. }
  30. type Writer interface {
  31. Write(io.Writer) error
  32. }
  33. type NoOpReader struct{}
  34. func (NoOpReader) Read(io.Reader) (*buf.Buffer, error) {
  35. return nil, nil
  36. }
  37. type NoOpWriter struct{}
  38. func (NoOpWriter) Write(io.Writer) error {
  39. return nil
  40. }
  41. type HeaderReader struct {
  42. }
  43. func (*HeaderReader) Read(reader io.Reader) (*buf.Buffer, error) {
  44. buffer := buf.New()
  45. totalBytes := int32(0)
  46. endingDetected := false
  47. for totalBytes < maxHeaderLength {
  48. err := buffer.AppendSupplier(buf.ReadFrom(reader))
  49. if err != nil {
  50. buffer.Release()
  51. return nil, err
  52. }
  53. if n := bytes.Index(buffer.Bytes(), []byte(ENDING)); n != -1 {
  54. buffer.Advance(int32(n + len(ENDING)))
  55. endingDetected = true
  56. break
  57. }
  58. if buffer.Len() >= int32(len(ENDING)) {
  59. totalBytes += buffer.Len() - int32(len(ENDING))
  60. leftover := buffer.BytesFrom(-int32(len(ENDING)))
  61. buffer.Reset(func(b []byte) (int, error) {
  62. return copy(b, leftover), nil
  63. })
  64. }
  65. }
  66. if buffer.IsEmpty() {
  67. buffer.Release()
  68. return nil, nil
  69. }
  70. if !endingDetected {
  71. buffer.Release()
  72. return nil, ErrHeaderToLong
  73. }
  74. return buffer, nil
  75. }
  76. type HeaderWriter struct {
  77. header *buf.Buffer
  78. }
  79. func NewHeaderWriter(header *buf.Buffer) *HeaderWriter {
  80. return &HeaderWriter{
  81. header: header,
  82. }
  83. }
  84. func (w *HeaderWriter) Write(writer io.Writer) error {
  85. if w.header == nil {
  86. return nil
  87. }
  88. err := buf.WriteAllBytes(writer, w.header.Bytes())
  89. w.header.Release()
  90. w.header = nil
  91. return err
  92. }
  93. type HttpConn struct {
  94. net.Conn
  95. readBuffer *buf.Buffer
  96. oneTimeReader Reader
  97. oneTimeWriter Writer
  98. errorWriter Writer
  99. }
  100. func NewHttpConn(conn net.Conn, reader Reader, writer Writer, errorWriter Writer) *HttpConn {
  101. return &HttpConn{
  102. Conn: conn,
  103. oneTimeReader: reader,
  104. oneTimeWriter: writer,
  105. errorWriter: errorWriter,
  106. }
  107. }
  108. func (c *HttpConn) Read(b []byte) (int, error) {
  109. if c.oneTimeReader != nil {
  110. buffer, err := c.oneTimeReader.Read(c.Conn)
  111. if err != nil {
  112. return 0, err
  113. }
  114. c.readBuffer = buffer
  115. c.oneTimeReader = nil
  116. }
  117. if !c.readBuffer.IsEmpty() {
  118. nBytes, _ := c.readBuffer.Read(b)
  119. if c.readBuffer.IsEmpty() {
  120. c.readBuffer.Release()
  121. c.readBuffer = nil
  122. }
  123. return nBytes, nil
  124. }
  125. return c.Conn.Read(b)
  126. }
  127. // Write implements io.Writer.
  128. func (c *HttpConn) Write(b []byte) (int, error) {
  129. if c.oneTimeWriter != nil {
  130. err := c.oneTimeWriter.Write(c.Conn)
  131. c.oneTimeWriter = nil
  132. if err != nil {
  133. return 0, err
  134. }
  135. }
  136. return c.Conn.Write(b)
  137. }
  138. // Close implements net.Conn.Close().
  139. func (c *HttpConn) Close() error {
  140. if c.oneTimeWriter != nil && c.errorWriter != nil {
  141. // Connection is being closed but header wasn't sent. This means the client request
  142. // is probably not valid. Sending back a server error header in this case.
  143. c.errorWriter.Write(c.Conn)
  144. }
  145. return c.Conn.Close()
  146. }
  147. func formResponseHeader(config *ResponseConfig) *HeaderWriter {
  148. header := buf.New()
  149. header.AppendSupplier(serial.WriteString(strings.Join([]string{config.GetFullVersion(), config.GetStatusValue().Code, config.GetStatusValue().Reason}, " ")))
  150. header.AppendSupplier(writeCRLF)
  151. headers := config.PickHeaders()
  152. for _, h := range headers {
  153. header.AppendSupplier(serial.WriteString(h))
  154. header.AppendSupplier(writeCRLF)
  155. }
  156. if !config.HasHeader("Date") {
  157. header.AppendSupplier(serial.WriteString("Date: "))
  158. header.AppendSupplier(serial.WriteString(time.Now().Format(http.TimeFormat)))
  159. header.AppendSupplier(writeCRLF)
  160. }
  161. header.AppendSupplier(writeCRLF)
  162. return &HeaderWriter{
  163. header: header,
  164. }
  165. }
  166. type HttpAuthenticator struct {
  167. config *Config
  168. }
  169. func (a HttpAuthenticator) GetClientWriter() *HeaderWriter {
  170. header := buf.New()
  171. config := a.config.Request
  172. header.AppendSupplier(serial.WriteString(strings.Join([]string{config.GetMethodValue(), config.PickUri(), config.GetFullVersion()}, " ")))
  173. header.AppendSupplier(writeCRLF)
  174. headers := config.PickHeaders()
  175. for _, h := range headers {
  176. header.AppendSupplier(serial.WriteString(h))
  177. header.AppendSupplier(writeCRLF)
  178. }
  179. header.AppendSupplier(writeCRLF)
  180. return &HeaderWriter{
  181. header: header,
  182. }
  183. }
  184. func (a HttpAuthenticator) GetServerWriter() *HeaderWriter {
  185. return formResponseHeader(a.config.Response)
  186. }
  187. func (a HttpAuthenticator) Client(conn net.Conn) net.Conn {
  188. if a.config.Request == nil && a.config.Response == nil {
  189. return conn
  190. }
  191. var reader Reader = NoOpReader{}
  192. if a.config.Request != nil {
  193. reader = new(HeaderReader)
  194. }
  195. var writer Writer = NoOpWriter{}
  196. if a.config.Response != nil {
  197. writer = a.GetClientWriter()
  198. }
  199. return NewHttpConn(conn, reader, writer, NoOpWriter{})
  200. }
  201. func (a HttpAuthenticator) Server(conn net.Conn) net.Conn {
  202. if a.config.Request == nil && a.config.Response == nil {
  203. return conn
  204. }
  205. return NewHttpConn(conn, new(HeaderReader), a.GetServerWriter(), formResponseHeader(&ResponseConfig{
  206. Version: &Version{
  207. Value: "1.1",
  208. },
  209. Status: &Status{
  210. Code: "500",
  211. Reason: "Internal Server Error",
  212. },
  213. Header: []*Header{
  214. {
  215. Name: "Connection",
  216. Value: []string{"close"},
  217. },
  218. {
  219. Name: "Cache-Control",
  220. Value: []string{"private"},
  221. },
  222. {
  223. Name: "Content-Length",
  224. Value: []string{"0"},
  225. },
  226. },
  227. }))
  228. }
  229. func NewHttpAuthenticator(ctx context.Context, config *Config) (HttpAuthenticator, error) {
  230. return HttpAuthenticator{
  231. config: config,
  232. }, nil
  233. }
  234. func init() {
  235. common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
  236. return NewHttpAuthenticator(ctx, config.(*Config))
  237. }))
  238. }