Invalid AWN Request Fixer
All checks were successful
Build and Publish / release (push) Successful in 4m31s

This commit is contained in:
Ryan McGuire 2025-01-29 19:37:23 -05:00
parent cd04beeec6
commit ae53a1d5fd
2 changed files with 19 additions and 8 deletions

View File

@ -47,7 +47,7 @@ func main() {
HandlerFunc: aw.GetAWNHandlerFunc(ctx), HandlerFunc: aw.GetAWNHandlerFunc(ctx),
}, },
}, },
CustomListener: ambienthttp.NewLFStrippingListener(ctx, CustomListener: ambienthttp.NewAWNMutatingListener(ctx,
awConfig.HTTP.Listen), // Necessary to fix certain bad AWN firmware awConfig.HTTP.Listen), // Necessary to fix certain bad AWN firmware
HealthChecks: []srv.HealthCheckFunc{ HealthChecks: []srv.HealthCheckFunc{
// TODO: Implement // TODO: Implement

View File

@ -32,8 +32,9 @@ type LFStrippingListener struct {
} }
type LFStrippingConn struct { type LFStrippingConn struct {
net.Conn ctx context.Context
reader io.Reader reader io.Reader
net.Conn
} }
func (l *LFStrippingListener) WrapConn(conn net.Conn) net.Conn { func (l *LFStrippingListener) WrapConn(conn net.Conn) net.Conn {
@ -49,34 +50,47 @@ func (l *LFStrippingListener) WrapConn(conn net.Conn) net.Conn {
// Only restore newline if not a bad request // Only restore newline if not a bad request
if !badReqURI.Match(line) { if !badReqURI.Match(line) {
newData = append(newData, '\n') newData = append(newData, '\n')
} else {
zerolog.Ctx(l.ctx).Trace().Bytes("line", line).
Msg("malformed request found, stripped 0x0a")
}
if len(line) == 0 {
break
} }
} }
if scanner.Err() != nil { if scanner.Err() != nil {
zerolog.Ctx(l.ctx).Err(scanner.Err()).Send() zerolog.Ctx(l.ctx).Err(scanner.Err()).Send()
} }
zerolog.Ctx(l.ctx).Trace().
Int("numBytes", len(newData)).
Bytes("request", newData).
Msg("stripping conn complete")
// Use a multi-reader to prepend the modified request // Use a multi-reader to prepend the modified request
finalReader := io.MultiReader(bytes.NewReader(newData), conn) finalReader := io.MultiReader(bytes.NewReader(newData), conn)
return &LFStrippingConn{ return &LFStrippingConn{
Conn: conn, Conn: conn,
ctx: l.ctx,
reader: finalReader, reader: finalReader,
} }
} }
func NewLFStrippingListener(ctx context.Context, listen string) net.Listener { func NewAWNMutatingListener(ctx context.Context, listen string) net.Listener {
// Create the underlying TCP listener
rawListener, err := net.Listen("tcp", listen) rawListener, err := net.Listen("tcp", listen)
if err != nil { if err != nil {
panic(err) panic(err)
} }
// Encapsulate the raw listener with ours
return &LFStrippingListener{ return &LFStrippingListener{
Listener: rawListener, Listener: rawListener,
ctx: ctx, ctx: ctx,
} }
} }
// Accept waits for and returns the next connection to the listener.
func (l *LFStrippingListener) Accept() (net.Conn, error) { func (l *LFStrippingListener) Accept() (net.Conn, error) {
conn, err := l.Listener.Accept() conn, err := l.Listener.Accept()
if err != nil { if err != nil {
@ -85,13 +99,10 @@ func (l *LFStrippingListener) Accept() (net.Conn, error) {
return l.WrapConn(conn), nil return l.WrapConn(conn), nil
} }
// Close closes the listener.
// Any blocked Accept operations will be unblocked and return errors.
func (l *LFStrippingListener) Close() error { func (l *LFStrippingListener) Close() error {
return l.Listener.Close() return l.Listener.Close()
} }
// Addr returns the listener's network address.
func (l *LFStrippingListener) Addr() net.Addr { func (l *LFStrippingListener) Addr() net.Addr {
return l.Listener.Addr() return l.Listener.Addr()
} }