Documentation
¶
Index ¶
- func HTTPMiddleware(handler http.Handler, limit int64) http.Handler
- func IsBodyTooLargeError(e error) bool
- func IsNilReaderError(e error) bool
- func IsNotAReaderInstanceError(e error) bool
- func IsReaderNotFoundError(e error) bool
- type BodyTooLargeError
- type DoppelgangerFactory
- type NilReaderError
- type NotAReaderInstanceError
- type ReaderNotFoundError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HTTPMiddleware ¶
HTTPMiddleware adds a doppelganger factory for the body to the request. At the same time it replaces the original body with a doppelganger reader. You can specify a size limit for the reader (0 disables the limit) The factory can be fetched by using HTTPBodyFactory()
A body that exceeds the limit is reported as BodyTooLargeError on the next Read rather than being silently truncated, so a handler cannot mistake a truncated body for a complete one. Use IsBodyTooLargeError to detect it.
func IsBodyTooLargeError ¶
IsBodyTooLargeError returns true if the specified error is a BodyTooLargeError.
func IsNilReaderError ¶
IsNilReaderError returns true if the specified error is a NilReaderError.
func IsNotAReaderInstanceError ¶
IsNotAReaderInstanceError returns true if the specified error is a NotAReaderInstanceError.
func IsReaderNotFoundError ¶
IsReaderNotFoundError returns true if the specified error is a ReaderNotFoundError.
Types ¶
type BodyTooLargeError ¶
type BodyTooLargeError struct {
// Limit is the configured maximum, in bytes.
Limit int64
}
BodyTooLargeError is reported when the request body exceeds the limit given to HTTPMiddleware.
func (BodyTooLargeError) Error ¶
func (e BodyTooLargeError) Error() string
Error returns the error message.
func (BodyTooLargeError) Is ¶
func (BodyTooLargeError) Is(target error) bool
Is reports whether target is a BodyTooLargeError, so errors.Is works on wrapped errors.
Limit is deliberately not compared: without this method errors.Is falls back to struct equality, so the natural check errors.Is(err, BodyTooLargeError{}) would be false for any non-zero limit. Use errors.As when the limit itself is needed.
type DoppelgangerFactory ¶
type DoppelgangerFactory interface {
NewDoppelganger() io.ReadCloser
RemoveDoppelganger(r io.ReadCloser) error
Close() error
}
DoppelgangerFactory is a reader that mimics the behavior of an other reader it can be used to read readers multiple times.
Example (HttpErrorHandler) ¶
package main
import (
"net/http"
"time"
"io"
"log"
"github.com/Eun/go-doppelgangerreader"
)
type errorHandler struct {
NextHandler http.Handler
}
func (e errorHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
factory := doppelgangerreader.NewFactory(request.Body)
request.Body = factory.NewDoppelganger()
defer func() {
err := recover()
body, _ := io.ReadAll(io.LimitReader(factory.NewDoppelganger(), 128))
log.Printf("handler panic: %#v, body was %v", err, body)
factory.Close()
}()
e.NextHandler.ServeHTTP(writer, request)
}
func main() {
handler := http.NewServeMux()
handler.HandleFunc("/", func(_ http.ResponseWriter, request *http.Request) {
_, _ = io.ReadAll(request.Body)
panic("some random error")
})
srv := &http.Server{
Addr: ":8000",
Handler: errorHandler{handler},
ReadHeaderTimeout: 10 * time.Second,
}
_ = srv.ListenAndServe()
}
Output:
func GetFactory ¶
func GetFactory(reader io.Reader) DoppelgangerFactory
GetFactory returns the DoppelgangerFactory if the reader is a Doppelganger.
func HTTPBodyFactory ¶
func HTTPBodyFactory(r *http.Request) DoppelgangerFactory
HTTPBodyFactory returns a http body factory for a request. Notice that you have to use the HTTPMiddleware function.
func NewFactory ¶
func NewFactory(readerToMimic io.Reader) DoppelgangerFactory
NewFactory creates a new DoppelgangerFactory with the original reader specified if the reader is already a Doppelganger it will return the original factory.
type NilReaderError ¶
type NilReaderError struct{}
NilReaderError will be reported if the provided reader is nil.
func (NilReaderError) Is ¶
func (NilReaderError) Is(target error) bool
Is reports whether target is a NilReaderError, so errors.Is works on wrapped errors.
type NotAReaderInstanceError ¶
type NotAReaderInstanceError struct{}
NotAReaderInstanceError will be reported if the reader was not created by a DoppelgangerFactory.
func (NotAReaderInstanceError) Error ¶
func (NotAReaderInstanceError) Error() string
Error returns the error message.
func (NotAReaderInstanceError) Is ¶
func (NotAReaderInstanceError) Is(target error) bool
Is reports whether target is a NotAReaderInstanceError, so errors.Is works on wrapped errors.
type ReaderNotFoundError ¶
type ReaderNotFoundError struct{}
ReaderNotFoundError will be reported if the reader is not (or no longer) registered with the factory. A reader that has been closed, removed, or whose factory has already closed is no longer registered, so this is not necessarily a caller error.
func (ReaderNotFoundError) Error ¶
func (ReaderNotFoundError) Error() string
Error returns the error message.
func (ReaderNotFoundError) Is ¶
func (ReaderNotFoundError) Is(target error) bool
Is reports whether target is a ReaderNotFoundError, so errors.Is works on wrapped errors.