From d6a6e0aaf8eb366e1158e3684e78b52ae74bbaba Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Wed, 14 Dec 2016 12:25:22 +0100 Subject: [PATCH] send back http response on error --- tools/conf/transport_authenticators.go | 4 ++ transport/internet/headers/http/http.go | 71 +++++++++++++++++++------ 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/tools/conf/transport_authenticators.go b/tools/conf/transport_authenticators.go index 895ce22a..768292d4 100644 --- a/tools/conf/transport_authenticators.go +++ b/tools/conf/transport_authenticators.go @@ -124,6 +124,10 @@ func (v *HTTPAuthenticatorResponse) Build() (*http.ResponseConfig, error) { Name: "Pragma", Value: []string{"no-cache"}, }, + { + Name: "Cache-Control", + Value: []string{"private", "no-cache"}, + }, }, } diff --git a/transport/internet/headers/http/http.go b/transport/internet/headers/http/http.go index d0ce52ad..8b85d23e 100644 --- a/transport/internet/headers/http/http.go +++ b/transport/internet/headers/http/http.go @@ -97,13 +97,15 @@ type HttpConn struct { readBuffer *buf.Buffer oneTimeReader Reader 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{ Conn: conn, oneTimeReader: reader, oneTimeWriter: writer, + isServer: isServer, } } @@ -141,14 +143,43 @@ func (v *HttpConn) Write(b []byte) (int, error) { return v.Conn.Write(b) } -type HttpAuthenticator struct { - config *Config +// Close implements net.Conn.Close(). +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) + } + + return v.Conn.Close() } -func (v HttpAuthenticator) GetClientWriter() *HeaderWriter { +func formResponseHeader(config *ResponseConfig) *HeaderWriter { header := buf.NewSmall() - config := v.config.Request - header.AppendSupplier(serial.WriteString(strings.Join([]string{config.Method.GetValue(), config.PickUri(), config.GetFullVersion()}, " "))) + header.AppendSupplier(serial.WriteString(strings.Join([]string{config.GetFullVersion(), config.Status.GetCode(), config.Status.GetReason()}, " "))) header.AppendSupplier(writeCRLF) headers := config.PickHeaders() @@ -156,16 +187,25 @@ func (v HttpAuthenticator) GetClientWriter() *HeaderWriter { header.AppendSupplier(serial.WriteString(h)) 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) return &HeaderWriter{ header: header, } } -func (v HttpAuthenticator) GetServerWriter() *HeaderWriter { +type HttpAuthenticator struct { + config *Config +} + +func (v HttpAuthenticator) GetClientWriter() *HeaderWriter { header := buf.NewSmall() - config := v.config.Response - header.AppendSupplier(serial.WriteString(strings.Join([]string{config.GetFullVersion(), config.Status.GetCode(), config.Status.GetReason()}, " "))) + config := v.config.Request + header.AppendSupplier(serial.WriteString(strings.Join([]string{config.Method.GetValue(), config.PickUri(), config.GetFullVersion()}, " "))) header.AppendSupplier(writeCRLF) headers := config.PickHeaders() @@ -173,17 +213,16 @@ func (v HttpAuthenticator) GetServerWriter() *HeaderWriter { header.AppendSupplier(serial.WriteString(h)) 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) return &HeaderWriter{ header: header, } } +func (v HttpAuthenticator) GetServerWriter() *HeaderWriter { + return formResponseHeader(v.config.Response) +} + func (v HttpAuthenticator) Client(conn net.Conn) net.Conn { if v.config.Request == nil && v.config.Response == nil { return conn @@ -197,14 +236,14 @@ func (v HttpAuthenticator) Client(conn net.Conn) net.Conn { if v.config.Response != nil { writer = v.GetClientWriter() } - return NewHttpConn(conn, reader, writer) + return NewHttpConn(conn, reader, writer, false) } func (v HttpAuthenticator) Server(conn net.Conn) net.Conn { if v.config.Request == nil && v.config.Response == nil { return conn } - return NewHttpConn(conn, new(HeaderReader), v.GetServerWriter()) + return NewHttpConn(conn, new(HeaderReader), v.GetServerWriter(), true) } type HttpAuthenticatorFactory struct{}