caddyhttp: Use LimitedReader for HTTPRedirectListener

This commit is contained in:
Matthew Holt 2023-09-26 07:32:46 -06:00
parent a306c5f769
commit 58ab3a01a0
No known key found for this signature in database
GPG key ID: 2A349DD577D586A5

View file

@ -17,6 +17,7 @@ package caddyhttp
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"io"
"net" "net"
"net/http" "net/http"
"sync" "sync"
@ -42,7 +43,11 @@ func init() {
// //
// This listener wrapper must be placed BEFORE the "tls" listener // This listener wrapper must be placed BEFORE the "tls" listener
// wrapper, for it to work properly. // wrapper, for it to work properly.
type HTTPRedirectListenerWrapper struct{} type HTTPRedirectListenerWrapper struct {
// MaxHeaderBytes is the maximum size to parse from a client's
// HTTP request headers. Default: 1 MB
MaxHeaderBytes int64 `json:"max_header_bytes,omitempty"`
}
func (HTTPRedirectListenerWrapper) CaddyModule() caddy.ModuleInfo { func (HTTPRedirectListenerWrapper) CaddyModule() caddy.ModuleInfo {
return caddy.ModuleInfo{ return caddy.ModuleInfo{
@ -56,7 +61,7 @@ func (h *HTTPRedirectListenerWrapper) UnmarshalCaddyfile(d *caddyfile.Dispenser)
} }
func (h *HTTPRedirectListenerWrapper) WrapListener(l net.Listener) net.Listener { func (h *HTTPRedirectListenerWrapper) WrapListener(l net.Listener) net.Listener {
return &httpRedirectListener{l} return &httpRedirectListener{l, h.MaxHeaderBytes}
} }
// httpRedirectListener is listener that checks the first few bytes // httpRedirectListener is listener that checks the first few bytes
@ -64,6 +69,7 @@ func (h *HTTPRedirectListenerWrapper) WrapListener(l net.Listener) net.Listener
// to respond to an HTTP request with a redirect. // to respond to an HTTP request with a redirect.
type httpRedirectListener struct { type httpRedirectListener struct {
net.Listener net.Listener
maxHeaderBytes int64
} }
// Accept waits for and returns the next connection to the listener, // Accept waits for and returns the next connection to the listener,
@ -74,9 +80,14 @@ func (l *httpRedirectListener) Accept() (net.Conn, error) {
return nil, err return nil, err
} }
maxHeaderBytes := l.maxHeaderBytes
if maxHeaderBytes == 0 {
maxHeaderBytes = 1024 * 1024
}
return &httpRedirectConn{ return &httpRedirectConn{
Conn: c, Conn: c,
r: bufio.NewReader(c), r: bufio.NewReader(io.LimitReader(c, maxHeaderBytes)),
}, nil }, nil
} }