1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-27 17:55:23 +00:00

allow single side auth

This commit is contained in:
Darien Raymond 2016-11-03 23:14:27 +01:00
parent 0747203132
commit 010f34c76c
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
2 changed files with 77 additions and 42 deletions

View File

@ -53,6 +53,9 @@ message ResponseConfig {
} }
message Config { message Config {
// Settings for authenticating requests. If not set, client side will not send authenication header, and server side will bypass authentication.
RequestConfig request = 1; RequestConfig request = 1;
// Settings for authenticating responses. If not set, client side will bypass authentication, and server side will not send authentication header.
ResponseConfig response = 2; ResponseConfig response = 2;
} }

View File

@ -2,6 +2,7 @@ package http
import ( import (
"bytes" "bytes"
"io"
"net" "net"
"v2ray.com/core/common/alloc" "v2ray.com/core/common/alloc"
@ -14,51 +15,73 @@ const (
ENDING = CRLF + CRLF ENDING = CRLF + CRLF
) )
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
}
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
}
type HttpConn struct { type HttpConn struct {
net.Conn net.Conn
buffer *alloc.Buffer readBuffer *alloc.Buffer
readHeader bool oneTimeReader *HeaderReader
oneTimeWriter *HeaderWriter
writeHeaderContent *alloc.Buffer
writeHeader bool
} }
func NewHttpConn(conn net.Conn, writeHeaderContent *alloc.Buffer) *HttpConn { func NewHttpConn(conn net.Conn, reader *HeaderReader, writer *HeaderWriter) *HttpConn {
return &HttpConn{ return &HttpConn{
Conn: conn, Conn: conn,
readHeader: true, oneTimeReader: reader,
writeHeader: true, oneTimeWriter: writer,
writeHeaderContent: writeHeaderContent,
} }
} }
func (this *HttpConn) Read(b []byte) (int, error) { func (this *HttpConn) Read(b []byte) (int, error) {
if this.readHeader { if this.oneTimeReader != nil {
buffer := alloc.NewLocalBuffer(2048) buffer, err := this.oneTimeReader.Read(this.Conn)
for { if err != nil {
_, err := buffer.FillFrom(this.Conn) return 0, err
if err != nil {
return 0, 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))
}
} }
this.buffer = buffer this.readBuffer = buffer
this.readHeader = false this.oneTimeReader = nil
} }
if this.buffer.Len() > 0 { if this.readBuffer.Len() > 0 {
nBytes, err := this.buffer.Read(b) nBytes, err := this.readBuffer.Read(b)
if nBytes == this.buffer.Len() { if nBytes == this.readBuffer.Len() {
this.buffer.Release() this.readBuffer.Release()
this.buffer = nil this.readBuffer = nil
} }
return nBytes, err return nBytes, err
} }
@ -67,13 +90,12 @@ func (this *HttpConn) Read(b []byte) (int, error) {
} }
func (this *HttpConn) Write(b []byte) (int, error) { func (this *HttpConn) Write(b []byte) (int, error) {
if this.writeHeader { if this.oneTimeWriter != nil {
_, err := this.Conn.Write(this.writeHeaderContent.Value) err := this.oneTimeWriter.Write(this.Conn)
this.writeHeaderContent.Release() this.oneTimeWriter = nil
if err != nil { if err != nil {
return 0, err return 0, err
} }
this.writeHeader = false
} }
return this.Conn.Write(b) return this.Conn.Write(b)
@ -83,7 +105,7 @@ type HttpAuthenticator struct {
config *Config config *Config
} }
func (this HttpAuthenticator) GetClientWriteHeader() *alloc.Buffer { func (this HttpAuthenticator) GetClientWriter() *HeaderWriter {
header := alloc.NewLocalBuffer(2048) header := alloc.NewLocalBuffer(2048)
config := this.config.Request config := this.config.Request
header.AppendString(config.Method.GetValue()).AppendString(" ").AppendString(config.PickUri()).AppendString(" ").AppendString(config.GetFullVersion()).AppendString(CRLF) header.AppendString(config.Method.GetValue()).AppendString(" ").AppendString(config.PickUri()).AppendString(" ").AppendString(config.GetFullVersion()).AppendString(CRLF)
@ -93,10 +115,12 @@ func (this HttpAuthenticator) GetClientWriteHeader() *alloc.Buffer {
header.AppendString(h).AppendString(CRLF) header.AppendString(h).AppendString(CRLF)
} }
header.AppendString(CRLF) header.AppendString(CRLF)
return header return &HeaderWriter{
header: header,
}
} }
func (this HttpAuthenticator) GetServerWriteHeader() *alloc.Buffer { func (this HttpAuthenticator) GetServerWriter() *HeaderWriter {
header := alloc.NewLocalBuffer(2048) header := alloc.NewLocalBuffer(2048)
config := this.config.Response config := this.config.Response
header.AppendString(config.GetFullVersion()).AppendString(" ").AppendString(config.Status.GetCode()).AppendString(" ").AppendString(config.Status.GetReason()).AppendString(CRLF) header.AppendString(config.GetFullVersion()).AppendString(" ").AppendString(config.Status.GetCode()).AppendString(" ").AppendString(config.Status.GetReason()).AppendString(CRLF)
@ -106,15 +130,23 @@ func (this HttpAuthenticator) GetServerWriteHeader() *alloc.Buffer {
header.AppendString(h).AppendString(CRLF) header.AppendString(h).AppendString(CRLF)
} }
header.AppendString(CRLF) header.AppendString(CRLF)
return header return &HeaderWriter{
header: header,
}
} }
func (this HttpAuthenticator) Client(conn net.Conn) net.Conn { func (this HttpAuthenticator) Client(conn net.Conn) net.Conn {
return NewHttpConn(conn, this.GetClientWriteHeader()) if this.config.Request == nil && this.config.Response == nil {
return conn
}
return NewHttpConn(conn, new(HeaderReader), this.GetClientWriter())
} }
func (this HttpAuthenticator) Server(conn net.Conn) net.Conn { func (this HttpAuthenticator) Server(conn net.Conn) net.Conn {
return NewHttpConn(conn, this.GetServerWriteHeader()) if this.config.Request == nil && this.config.Response == nil {
return conn
}
return NewHttpConn(conn, new(HeaderReader), this.GetServerWriter())
} }
type HttpAuthenticatorFactory struct{} type HttpAuthenticatorFactory struct{}