1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-27 22:36:12 -04:00
v2fly/transport/internet/authenticators/http/http.go

169 lines
3.7 KiB
Go
Raw Normal View History

2016-10-31 17:26:46 -04:00
package http
import (
"bytes"
2016-11-03 18:14:27 -04:00
"io"
2016-11-02 17:26:21 -04:00
"net"
2016-10-31 17:26:46 -04:00
"v2ray.com/core/common/alloc"
2016-10-31 19:42:55 -04:00
"v2ray.com/core/common/loader"
2016-10-31 17:26:46 -04:00
"v2ray.com/core/transport/internet"
)
const (
CRLF = "\r\n"
ENDING = CRLF + CRLF
)
2016-11-03 18:14:27 -04:00
type HeaderReader struct {
}
func (*HeaderReader) Read(reader io.Reader) (*alloc.Buffer, error) {
buffer := alloc.NewLocalBuffer(2048)
for {
_, err := buffer.FillFrom(reader)
if err != nil {
return nil, err
}
if n := bytes.Index(buffer.Value, []byte(ENDING)); n != -1 {
buffer.SliceFrom(n + len(ENDING))
break
}
if buffer.Len() >= len(ENDING) {
copy(buffer.Value, buffer.Value[buffer.Len()-len(ENDING):])
buffer.Slice(0, len(ENDING))
}
}
return buffer, nil
}
type HeaderWriter struct {
header *alloc.Buffer
}
2016-11-04 16:59:19 -04:00
func NewHeaderWriter(header *alloc.Buffer) *HeaderWriter {
return &HeaderWriter{
header: header,
}
}
2016-11-03 18:14:27 -04:00
func (this *HeaderWriter) Write(writer io.Writer) error {
if this.header == nil {
return nil
}
_, err := writer.Write(this.header.Value)
this.header.Release()
this.header = nil
return err
}
2016-11-02 17:26:21 -04:00
type HttpConn struct {
net.Conn
2016-11-03 18:14:27 -04:00
readBuffer *alloc.Buffer
oneTimeReader *HeaderReader
oneTimeWriter *HeaderWriter
2016-10-31 17:26:46 -04:00
}
2016-11-03 18:14:27 -04:00
func NewHttpConn(conn net.Conn, reader *HeaderReader, writer *HeaderWriter) *HttpConn {
2016-11-02 17:26:21 -04:00
return &HttpConn{
2016-11-03 18:14:27 -04:00
Conn: conn,
oneTimeReader: reader,
oneTimeWriter: writer,
2016-11-02 17:26:21 -04:00
}
}
2016-10-31 17:26:46 -04:00
2016-11-02 17:26:21 -04:00
func (this *HttpConn) Read(b []byte) (int, error) {
2016-11-03 18:14:27 -04:00
if this.oneTimeReader != nil {
buffer, err := this.oneTimeReader.Read(this.Conn)
if err != nil {
return 0, err
2016-11-02 17:26:21 -04:00
}
2016-11-03 18:14:27 -04:00
this.readBuffer = buffer
this.oneTimeReader = nil
2016-10-31 17:26:46 -04:00
}
2016-11-03 18:14:27 -04:00
if this.readBuffer.Len() > 0 {
nBytes, err := this.readBuffer.Read(b)
if nBytes == this.readBuffer.Len() {
this.readBuffer.Release()
this.readBuffer = nil
2016-11-02 17:26:21 -04:00
}
return nBytes, err
}
2016-10-31 17:26:46 -04:00
2016-11-02 17:26:21 -04:00
return this.Conn.Read(b)
2016-10-31 17:26:46 -04:00
}
2016-11-02 17:26:21 -04:00
func (this *HttpConn) Write(b []byte) (int, error) {
2016-11-03 18:14:27 -04:00
if this.oneTimeWriter != nil {
err := this.oneTimeWriter.Write(this.Conn)
this.oneTimeWriter = nil
2016-10-31 17:26:46 -04:00
if err != nil {
2016-11-02 17:26:21 -04:00
return 0, err
2016-10-31 17:26:46 -04:00
}
}
2016-11-02 17:26:21 -04:00
return this.Conn.Write(b)
2016-10-31 17:26:46 -04:00
}
2016-11-02 17:26:21 -04:00
type HttpAuthenticator struct {
config *Config
2016-10-31 17:26:46 -04:00
}
2016-11-03 18:14:27 -04:00
func (this HttpAuthenticator) GetClientWriter() *HeaderWriter {
2016-11-02 17:26:21 -04:00
header := alloc.NewLocalBuffer(2048)
config := this.config.Request
header.AppendString(config.Method.GetValue()).AppendString(" ").AppendString(config.PickUri()).AppendString(" ").AppendString(config.GetFullVersion()).AppendString(CRLF)
2016-10-31 17:26:46 -04:00
2016-11-02 17:26:21 -04:00
headers := config.PickHeaders()
for _, h := range headers {
header.AppendString(h).AppendString(CRLF)
2016-10-31 17:26:46 -04:00
}
2016-11-02 17:26:21 -04:00
header.AppendString(CRLF)
2016-11-03 18:14:27 -04:00
return &HeaderWriter{
header: header,
}
2016-10-31 17:26:46 -04:00
}
2016-11-03 18:14:27 -04:00
func (this HttpAuthenticator) GetServerWriter() *HeaderWriter {
2016-10-31 17:26:46 -04:00
header := alloc.NewLocalBuffer(2048)
2016-11-02 17:26:21 -04:00
config := this.config.Response
header.AppendString(config.GetFullVersion()).AppendString(" ").AppendString(config.Status.GetCode()).AppendString(" ").AppendString(config.Status.GetReason()).AppendString(CRLF)
2016-10-31 17:26:46 -04:00
2016-11-02 17:26:21 -04:00
headers := config.PickHeaders()
2016-10-31 17:26:46 -04:00
for _, h := range headers {
header.AppendString(h).AppendString(CRLF)
}
header.AppendString(CRLF)
2016-11-03 18:14:27 -04:00
return &HeaderWriter{
header: header,
}
2016-11-02 17:26:21 -04:00
}
2016-10-31 17:26:46 -04:00
2016-11-02 17:26:21 -04:00
func (this HttpAuthenticator) Client(conn net.Conn) net.Conn {
2016-11-03 18:14:27 -04:00
if this.config.Request == nil && this.config.Response == nil {
return conn
}
return NewHttpConn(conn, new(HeaderReader), this.GetClientWriter())
2016-10-31 17:26:46 -04:00
}
2016-11-02 17:26:21 -04:00
func (this HttpAuthenticator) Server(conn net.Conn) net.Conn {
2016-11-03 18:14:27 -04:00
if this.config.Request == nil && this.config.Response == nil {
return conn
}
return NewHttpConn(conn, new(HeaderReader), this.GetServerWriter())
2016-10-31 17:26:46 -04:00
}
2016-10-31 19:42:55 -04:00
2016-11-02 17:26:21 -04:00
type HttpAuthenticatorFactory struct{}
2016-10-31 19:42:55 -04:00
2016-11-02 17:26:21 -04:00
func (HttpAuthenticatorFactory) Create(config interface{}) internet.ConnectionAuthenticator {
return HttpAuthenticator{
config: config.(*Config),
2016-10-31 19:42:55 -04:00
}
}
func init() {
2016-11-02 17:26:21 -04:00
internet.RegisterConnectionAuthenticator(loader.GetType(new(Config)), HttpAuthenticatorFactory{})
2016-10-31 19:42:55 -04:00
}