http.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package http
  2. import (
  3. "bytes"
  4. "io"
  5. "net"
  6. "v2ray.com/core/common/alloc"
  7. "v2ray.com/core/common/loader"
  8. "v2ray.com/core/transport/internet"
  9. )
  10. const (
  11. CRLF = "\r\n"
  12. ENDING = CRLF + CRLF
  13. )
  14. type Reader interface {
  15. Read(io.Reader) (*alloc.Buffer, error)
  16. }
  17. type Writer interface {
  18. Write(io.Writer) error
  19. }
  20. type NoOpReader struct{}
  21. func (this *NoOpReader) Read(io.Reader) (*alloc.Buffer, error) {
  22. return nil, nil
  23. }
  24. type NoOpWriter struct{}
  25. func (this *NoOpWriter) Write(io.Writer) error {
  26. return nil
  27. }
  28. type HeaderReader struct {
  29. }
  30. func (*HeaderReader) Read(reader io.Reader) (*alloc.Buffer, error) {
  31. buffer := alloc.NewLocalBuffer(2048)
  32. for {
  33. _, err := buffer.FillFrom(reader)
  34. if err != nil {
  35. return nil, err
  36. }
  37. if n := bytes.Index(buffer.Value, []byte(ENDING)); n != -1 {
  38. buffer.SliceFrom(n + len(ENDING))
  39. break
  40. }
  41. if buffer.Len() >= len(ENDING) {
  42. copy(buffer.Value, buffer.Value[buffer.Len()-len(ENDING):])
  43. buffer.Slice(0, len(ENDING))
  44. }
  45. }
  46. if buffer.IsEmpty() {
  47. buffer.Release()
  48. return nil, nil
  49. }
  50. return buffer, nil
  51. }
  52. type HeaderWriter struct {
  53. header *alloc.Buffer
  54. }
  55. func NewHeaderWriter(header *alloc.Buffer) *HeaderWriter {
  56. return &HeaderWriter{
  57. header: header,
  58. }
  59. }
  60. func (this *HeaderWriter) Write(writer io.Writer) error {
  61. if this.header == nil {
  62. return nil
  63. }
  64. _, err := writer.Write(this.header.Value)
  65. this.header.Release()
  66. this.header = nil
  67. return err
  68. }
  69. type HttpConn struct {
  70. net.Conn
  71. readBuffer *alloc.Buffer
  72. oneTimeReader Reader
  73. oneTimeWriter Writer
  74. }
  75. func NewHttpConn(conn net.Conn, reader Reader, writer Writer) *HttpConn {
  76. return &HttpConn{
  77. Conn: conn,
  78. oneTimeReader: reader,
  79. oneTimeWriter: writer,
  80. }
  81. }
  82. func (this *HttpConn) Read(b []byte) (int, error) {
  83. if this.oneTimeReader != nil {
  84. buffer, err := this.oneTimeReader.Read(this.Conn)
  85. if err != nil {
  86. return 0, err
  87. }
  88. this.readBuffer = buffer
  89. this.oneTimeReader = nil
  90. }
  91. if this.readBuffer.Len() > 0 {
  92. nBytes, err := this.readBuffer.Read(b)
  93. if nBytes == this.readBuffer.Len() {
  94. this.readBuffer.Release()
  95. this.readBuffer = nil
  96. }
  97. return nBytes, err
  98. }
  99. return this.Conn.Read(b)
  100. }
  101. func (this *HttpConn) Write(b []byte) (int, error) {
  102. if this.oneTimeWriter != nil {
  103. err := this.oneTimeWriter.Write(this.Conn)
  104. this.oneTimeWriter = nil
  105. if err != nil {
  106. return 0, err
  107. }
  108. }
  109. return this.Conn.Write(b)
  110. }
  111. type HttpAuthenticator struct {
  112. config *Config
  113. }
  114. func (this HttpAuthenticator) GetClientWriter() *HeaderWriter {
  115. header := alloc.NewLocalBuffer(2048)
  116. config := this.config.Request
  117. header.AppendString(config.Method.GetValue()).AppendString(" ").AppendString(config.PickUri()).AppendString(" ").AppendString(config.GetFullVersion()).AppendString(CRLF)
  118. headers := config.PickHeaders()
  119. for _, h := range headers {
  120. header.AppendString(h).AppendString(CRLF)
  121. }
  122. header.AppendString(CRLF)
  123. return &HeaderWriter{
  124. header: header,
  125. }
  126. }
  127. func (this HttpAuthenticator) GetServerWriter() *HeaderWriter {
  128. header := alloc.NewLocalBuffer(2048)
  129. config := this.config.Response
  130. header.AppendString(config.GetFullVersion()).AppendString(" ").AppendString(config.Status.GetCode()).AppendString(" ").AppendString(config.Status.GetReason()).AppendString(CRLF)
  131. headers := config.PickHeaders()
  132. for _, h := range headers {
  133. header.AppendString(h).AppendString(CRLF)
  134. }
  135. header.AppendString(CRLF)
  136. return &HeaderWriter{
  137. header: header,
  138. }
  139. }
  140. func (this HttpAuthenticator) Client(conn net.Conn) net.Conn {
  141. if this.config.Request == nil && this.config.Response == nil {
  142. return conn
  143. }
  144. var reader Reader = new(NoOpReader)
  145. if this.config.Request != nil {
  146. reader = new(HeaderReader)
  147. }
  148. var writer Writer = new(NoOpWriter)
  149. if this.config.Response != nil {
  150. writer = this.GetClientWriter()
  151. }
  152. return NewHttpConn(conn, reader, writer)
  153. }
  154. func (this HttpAuthenticator) Server(conn net.Conn) net.Conn {
  155. if this.config.Request == nil && this.config.Response == nil {
  156. return conn
  157. }
  158. return NewHttpConn(conn, new(HeaderReader), this.GetServerWriter())
  159. }
  160. type HttpAuthenticatorFactory struct{}
  161. func (HttpAuthenticatorFactory) Create(config interface{}) internet.ConnectionAuthenticator {
  162. return HttpAuthenticator{
  163. config: config.(*Config),
  164. }
  165. }
  166. func init() {
  167. internet.RegisterConnectionAuthenticator(loader.GetType(new(Config)), HttpAuthenticatorFactory{})
  168. }