1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-27 01:45:23 +00:00
v2fly/transport/internet/headers/http/http.go

218 lines
4.5 KiB
Go
Raw Normal View History

2016-10-31 21:26:46 +00:00
package http
import (
"bytes"
2016-11-03 22:14:27 +00:00
"io"
2016-11-02 21:26:21 +00:00
"net"
2016-11-06 12:38:32 +00:00
"net/http"
2016-12-06 10:03:42 +00:00
"strings"
2016-11-06 12:38:32 +00:00
"time"
2016-10-31 21:26:46 +00:00
"v2ray.com/core/common/alloc"
2016-10-31 23:42:55 +00:00
"v2ray.com/core/common/loader"
2016-12-06 10:03:42 +00:00
"v2ray.com/core/common/serial"
2016-10-31 21:26:46 +00:00
"v2ray.com/core/transport/internet"
)
const (
CRLF = "\r\n"
ENDING = CRLF + CRLF
)
2016-12-06 10:03:42 +00:00
var (
writeCRLF = serial.WriteString(CRLF)
)
2016-11-05 00:50:51 +00:00
type Reader interface {
Read(io.Reader) (*alloc.Buffer, error)
}
type Writer interface {
Write(io.Writer) error
}
type NoOpReader struct{}
2016-11-27 20:39:09 +00:00
func (v *NoOpReader) Read(io.Reader) (*alloc.Buffer, error) {
2016-11-05 00:50:51 +00:00
return nil, nil
}
type NoOpWriter struct{}
2016-11-27 20:39:09 +00:00
func (v *NoOpWriter) Write(io.Writer) error {
2016-11-05 00:50:51 +00:00
return nil
}
2016-11-03 22:14:27 +00:00
type HeaderReader struct {
}
func (*HeaderReader) Read(reader io.Reader) (*alloc.Buffer, error) {
2016-12-06 10:03:42 +00:00
buffer := alloc.NewSmallBuffer()
2016-11-03 22:14:27 +00:00
for {
_, err := buffer.FillFrom(reader)
if err != nil {
return nil, err
}
2016-12-06 10:03:42 +00:00
if n := bytes.Index(buffer.Bytes(), []byte(ENDING)); n != -1 {
2016-11-03 22:14:27 +00:00
buffer.SliceFrom(n + len(ENDING))
break
}
if buffer.Len() >= len(ENDING) {
2016-12-06 10:03:42 +00:00
copy(buffer.Bytes(), buffer.BytesFrom(buffer.Len()-len(ENDING)))
2016-11-03 22:14:27 +00:00
buffer.Slice(0, len(ENDING))
}
}
2016-11-05 00:50:51 +00:00
if buffer.IsEmpty() {
buffer.Release()
return nil, nil
}
2016-11-03 22:14:27 +00:00
return buffer, nil
}
type HeaderWriter struct {
header *alloc.Buffer
}
2016-11-04 20:59:19 +00:00
func NewHeaderWriter(header *alloc.Buffer) *HeaderWriter {
return &HeaderWriter{
header: header,
}
}
2016-11-27 20:39:09 +00:00
func (v *HeaderWriter) Write(writer io.Writer) error {
if v.header == nil {
2016-11-03 22:14:27 +00:00
return nil
}
2016-12-06 10:03:42 +00:00
_, err := writer.Write(v.header.Bytes())
2016-11-27 20:39:09 +00:00
v.header.Release()
v.header = nil
2016-11-03 22:14:27 +00:00
return err
}
2016-11-02 21:26:21 +00:00
type HttpConn struct {
net.Conn
2016-11-03 22:14:27 +00:00
readBuffer *alloc.Buffer
2016-11-05 00:50:51 +00:00
oneTimeReader Reader
oneTimeWriter Writer
2016-10-31 21:26:46 +00:00
}
2016-11-05 00:50:51 +00:00
func NewHttpConn(conn net.Conn, reader Reader, writer Writer) *HttpConn {
2016-11-02 21:26:21 +00:00
return &HttpConn{
2016-11-03 22:14:27 +00:00
Conn: conn,
oneTimeReader: reader,
oneTimeWriter: writer,
2016-11-02 21:26:21 +00:00
}
}
2016-10-31 21:26:46 +00:00
2016-11-27 20:39:09 +00:00
func (v *HttpConn) Read(b []byte) (int, error) {
if v.oneTimeReader != nil {
buffer, err := v.oneTimeReader.Read(v.Conn)
2016-11-03 22:14:27 +00:00
if err != nil {
return 0, err
2016-11-02 21:26:21 +00:00
}
2016-11-27 20:39:09 +00:00
v.readBuffer = buffer
v.oneTimeReader = nil
2016-10-31 21:26:46 +00:00
}
2016-11-27 20:39:09 +00:00
if v.readBuffer.Len() > 0 {
nBytes, err := v.readBuffer.Read(b)
if nBytes == v.readBuffer.Len() {
v.readBuffer.Release()
v.readBuffer = nil
2016-11-02 21:26:21 +00:00
}
return nBytes, err
}
2016-10-31 21:26:46 +00:00
2016-11-27 20:39:09 +00:00
return v.Conn.Read(b)
2016-10-31 21:26:46 +00:00
}
2016-11-27 20:39:09 +00:00
func (v *HttpConn) Write(b []byte) (int, error) {
if v.oneTimeWriter != nil {
err := v.oneTimeWriter.Write(v.Conn)
v.oneTimeWriter = nil
2016-10-31 21:26:46 +00:00
if err != nil {
2016-11-02 21:26:21 +00:00
return 0, err
2016-10-31 21:26:46 +00:00
}
}
2016-11-27 20:39:09 +00:00
return v.Conn.Write(b)
2016-10-31 21:26:46 +00:00
}
2016-11-02 21:26:21 +00:00
type HttpAuthenticator struct {
config *Config
2016-10-31 21:26:46 +00:00
}
2016-11-27 20:39:09 +00:00
func (v HttpAuthenticator) GetClientWriter() *HeaderWriter {
2016-12-06 10:03:42 +00:00
header := alloc.NewSmallBuffer()
2016-11-27 20:39:09 +00:00
config := v.config.Request
2016-12-06 10:03:42 +00:00
header.AppendFunc(serial.WriteString(strings.Join([]string{config.Method.GetValue(), config.PickUri(), config.GetFullVersion()}, " ")))
header.AppendFunc(writeCRLF)
2016-10-31 21:26:46 +00:00
2016-11-02 21:26:21 +00:00
headers := config.PickHeaders()
for _, h := range headers {
2016-12-06 10:03:42 +00:00
header.AppendFunc(serial.WriteString(h))
header.AppendFunc(writeCRLF)
2016-10-31 21:26:46 +00:00
}
2016-12-06 10:03:42 +00:00
header.AppendFunc(writeCRLF)
2016-11-03 22:14:27 +00:00
return &HeaderWriter{
header: header,
}
2016-10-31 21:26:46 +00:00
}
2016-11-27 20:39:09 +00:00
func (v HttpAuthenticator) GetServerWriter() *HeaderWriter {
2016-12-06 10:03:42 +00:00
header := alloc.NewSmallBuffer()
2016-11-27 20:39:09 +00:00
config := v.config.Response
2016-12-06 10:03:42 +00:00
header.AppendFunc(serial.WriteString(strings.Join([]string{config.GetFullVersion(), config.Status.GetCode(), config.Status.GetReason()}, " ")))
header.AppendFunc(writeCRLF)
2016-10-31 21:26:46 +00:00
2016-11-02 21:26:21 +00:00
headers := config.PickHeaders()
2016-10-31 21:26:46 +00:00
for _, h := range headers {
2016-12-06 10:03:42 +00:00
header.AppendFunc(serial.WriteString(h))
header.AppendFunc(writeCRLF)
2016-11-06 12:38:32 +00:00
}
if !config.HasHeader("Date") {
2016-12-06 10:03:42 +00:00
header.AppendFunc(serial.WriteString("Date: "))
header.AppendFunc(serial.WriteString(time.Now().Format(http.TimeFormat)))
header.AppendFunc(writeCRLF)
2016-10-31 21:26:46 +00:00
}
2016-12-06 10:03:42 +00:00
header.AppendFunc(writeCRLF)
2016-11-03 22:14:27 +00:00
return &HeaderWriter{
header: header,
}
2016-11-02 21:26:21 +00:00
}
2016-10-31 21:26:46 +00:00
2016-11-27 20:39:09 +00:00
func (v HttpAuthenticator) Client(conn net.Conn) net.Conn {
if v.config.Request == nil && v.config.Response == nil {
2016-11-03 22:14:27 +00:00
return conn
}
2016-11-05 00:50:51 +00:00
var reader Reader = new(NoOpReader)
2016-11-27 20:39:09 +00:00
if v.config.Request != nil {
2016-11-05 00:50:51 +00:00
reader = new(HeaderReader)
}
var writer Writer = new(NoOpWriter)
2016-11-27 20:39:09 +00:00
if v.config.Response != nil {
writer = v.GetClientWriter()
2016-11-05 00:50:51 +00:00
}
return NewHttpConn(conn, reader, writer)
2016-10-31 21:26:46 +00:00
}
2016-11-27 20:39:09 +00:00
func (v HttpAuthenticator) Server(conn net.Conn) net.Conn {
if v.config.Request == nil && v.config.Response == nil {
2016-11-03 22:14:27 +00:00
return conn
}
2016-11-27 20:39:09 +00:00
return NewHttpConn(conn, new(HeaderReader), v.GetServerWriter())
2016-10-31 21:26:46 +00:00
}
2016-10-31 23:42:55 +00:00
2016-11-02 21:26:21 +00:00
type HttpAuthenticatorFactory struct{}
2016-10-31 23:42:55 +00:00
2016-11-02 21:26:21 +00:00
func (HttpAuthenticatorFactory) Create(config interface{}) internet.ConnectionAuthenticator {
return HttpAuthenticator{
config: config.(*Config),
2016-10-31 23:42:55 +00:00
}
}
func init() {
2016-11-02 21:26:21 +00:00
internet.RegisterConnectionAuthenticator(loader.GetType(new(Config)), HttpAuthenticatorFactory{})
2016-10-31 23:42:55 +00:00
}