|
|
@ -97,13 +97,15 @@ type HttpConn struct {
|
|
|
|
readBuffer *buf.Buffer
|
|
|
|
readBuffer *buf.Buffer
|
|
|
|
oneTimeReader Reader
|
|
|
|
oneTimeReader Reader
|
|
|
|
oneTimeWriter Writer
|
|
|
|
oneTimeWriter Writer
|
|
|
|
|
|
|
|
isServer bool
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func NewHttpConn(conn net.Conn, reader Reader, writer Writer) *HttpConn {
|
|
|
|
func NewHttpConn(conn net.Conn, reader Reader, writer Writer, isServer bool) *HttpConn {
|
|
|
|
return &HttpConn{
|
|
|
|
return &HttpConn{
|
|
|
|
Conn: conn,
|
|
|
|
Conn: conn,
|
|
|
|
oneTimeReader: reader,
|
|
|
|
oneTimeReader: reader,
|
|
|
|
oneTimeWriter: writer,
|
|
|
|
oneTimeWriter: writer,
|
|
|
|
|
|
|
|
isServer: isServer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -141,14 +143,43 @@ func (v *HttpConn) Write(b []byte) (int, error) {
|
|
|
|
return v.Conn.Write(b)
|
|
|
|
return v.Conn.Write(b)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type HttpAuthenticator struct {
|
|
|
|
// Close implements net.Conn.Close().
|
|
|
|
config *Config
|
|
|
|
func (v *HttpConn) Close() error {
|
|
|
|
|
|
|
|
if v.isServer && v.oneTimeWriter != nil {
|
|
|
|
|
|
|
|
// Connection is being closed but header wasn't sent. This means the client request
|
|
|
|
|
|
|
|
// is probably not valid. Sending back a server error header in this case.
|
|
|
|
|
|
|
|
writer := formResponseHeader(&ResponseConfig{
|
|
|
|
|
|
|
|
Version: &Version{
|
|
|
|
|
|
|
|
Value: "1.1",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Status: &Status{
|
|
|
|
|
|
|
|
Code: "500",
|
|
|
|
|
|
|
|
Reason: "Internal Server Error",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Header: []*Header{
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Name: "Connection",
|
|
|
|
|
|
|
|
Value: []string{"close"},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Name: "Cache-Control",
|
|
|
|
|
|
|
|
Value: []string{"private"},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Name: "Content-Length",
|
|
|
|
|
|
|
|
Value: []string{"0"},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
writer.Write(v.Conn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (v HttpAuthenticator) GetClientWriter() *HeaderWriter {
|
|
|
|
return v.Conn.Close()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func formResponseHeader(config *ResponseConfig) *HeaderWriter {
|
|
|
|
header := buf.NewSmall()
|
|
|
|
header := buf.NewSmall()
|
|
|
|
config := v.config.Request
|
|
|
|
header.AppendSupplier(serial.WriteString(strings.Join([]string{config.GetFullVersion(), config.Status.GetCode(), config.Status.GetReason()}, " ")))
|
|
|
|
header.AppendSupplier(serial.WriteString(strings.Join([]string{config.Method.GetValue(), config.PickUri(), config.GetFullVersion()}, " ")))
|
|
|
|
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
|
|
|
|
|
|
|
|
headers := config.PickHeaders()
|
|
|
|
headers := config.PickHeaders()
|
|
|
@ -156,16 +187,25 @@ func (v HttpAuthenticator) GetClientWriter() *HeaderWriter {
|
|
|
|
header.AppendSupplier(serial.WriteString(h))
|
|
|
|
header.AppendSupplier(serial.WriteString(h))
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !config.HasHeader("Date") {
|
|
|
|
|
|
|
|
header.AppendSupplier(serial.WriteString("Date: "))
|
|
|
|
|
|
|
|
header.AppendSupplier(serial.WriteString(time.Now().Format(http.TimeFormat)))
|
|
|
|
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
|
|
|
|
}
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
return &HeaderWriter{
|
|
|
|
return &HeaderWriter{
|
|
|
|
header: header,
|
|
|
|
header: header,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (v HttpAuthenticator) GetServerWriter() *HeaderWriter {
|
|
|
|
type HttpAuthenticator struct {
|
|
|
|
|
|
|
|
config *Config
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (v HttpAuthenticator) GetClientWriter() *HeaderWriter {
|
|
|
|
header := buf.NewSmall()
|
|
|
|
header := buf.NewSmall()
|
|
|
|
config := v.config.Response
|
|
|
|
config := v.config.Request
|
|
|
|
header.AppendSupplier(serial.WriteString(strings.Join([]string{config.GetFullVersion(), config.Status.GetCode(), config.Status.GetReason()}, " ")))
|
|
|
|
header.AppendSupplier(serial.WriteString(strings.Join([]string{config.Method.GetValue(), config.PickUri(), config.GetFullVersion()}, " ")))
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
|
|
|
|
|
|
|
|
headers := config.PickHeaders()
|
|
|
|
headers := config.PickHeaders()
|
|
|
@ -173,17 +213,16 @@ func (v HttpAuthenticator) GetServerWriter() *HeaderWriter {
|
|
|
|
header.AppendSupplier(serial.WriteString(h))
|
|
|
|
header.AppendSupplier(serial.WriteString(h))
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !config.HasHeader("Date") {
|
|
|
|
|
|
|
|
header.AppendSupplier(serial.WriteString("Date: "))
|
|
|
|
|
|
|
|
header.AppendSupplier(serial.WriteString(time.Now().Format(http.TimeFormat)))
|
|
|
|
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
header.AppendSupplier(writeCRLF)
|
|
|
|
return &HeaderWriter{
|
|
|
|
return &HeaderWriter{
|
|
|
|
header: header,
|
|
|
|
header: header,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (v HttpAuthenticator) GetServerWriter() *HeaderWriter {
|
|
|
|
|
|
|
|
return formResponseHeader(v.config.Response)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (v HttpAuthenticator) Client(conn net.Conn) net.Conn {
|
|
|
|
func (v HttpAuthenticator) Client(conn net.Conn) net.Conn {
|
|
|
|
if v.config.Request == nil && v.config.Response == nil {
|
|
|
|
if v.config.Request == nil && v.config.Response == nil {
|
|
|
|
return conn
|
|
|
|
return conn
|
|
|
@ -197,14 +236,14 @@ func (v HttpAuthenticator) Client(conn net.Conn) net.Conn {
|
|
|
|
if v.config.Response != nil {
|
|
|
|
if v.config.Response != nil {
|
|
|
|
writer = v.GetClientWriter()
|
|
|
|
writer = v.GetClientWriter()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NewHttpConn(conn, reader, writer)
|
|
|
|
return NewHttpConn(conn, reader, writer, false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (v HttpAuthenticator) Server(conn net.Conn) net.Conn {
|
|
|
|
func (v HttpAuthenticator) Server(conn net.Conn) net.Conn {
|
|
|
|
if v.config.Request == nil && v.config.Response == nil {
|
|
|
|
if v.config.Request == nil && v.config.Response == nil {
|
|
|
|
return conn
|
|
|
|
return conn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NewHttpConn(conn, new(HeaderReader), v.GetServerWriter())
|
|
|
|
return NewHttpConn(conn, new(HeaderReader), v.GetServerWriter(), true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type HttpAuthenticatorFactory struct{}
|
|
|
|
type HttpAuthenticatorFactory struct{}
|
|
|
|