2018-06-20 09:12:03 +02:00
package pipelining
import (
"bufio"
2019-03-18 11:30:07 +01:00
"context"
2018-06-20 09:12:03 +02:00
"net"
"net/http"
2019-03-18 11:30:07 +01:00
2020-09-16 15:46:04 +02:00
"github.com/traefik/traefik/v2/pkg/log"
"github.com/traefik/traefik/v2/pkg/middlewares"
2019-03-18 11:30:07 +01:00
)
const (
typeName = "Pipelining"
2018-06-20 09:12:03 +02:00
)
2020-05-11 12:06:07 +02:00
// pipelining returns a middleware.
2019-03-18 11:30:07 +01:00
type pipelining struct {
2018-06-20 09:12:03 +02:00
next http . Handler
}
2020-05-11 12:06:07 +02:00
// New returns a new pipelining instance.
2019-03-18 11:30:07 +01:00
func New ( ctx context . Context , next http . Handler , name string ) http . Handler {
2019-09-13 19:28:04 +02:00
log . FromContext ( middlewares . GetLoggerCtx ( ctx , name , typeName ) ) . Debug ( "Creating middleware" )
2019-03-18 11:30:07 +01:00
return & pipelining {
2018-06-20 09:12:03 +02:00
next : next ,
}
}
2019-03-18 11:30:07 +01:00
func ( p * pipelining ) ServeHTTP ( rw http . ResponseWriter , r * http . Request ) {
2018-06-20 09:12:03 +02:00
// https://github.com/golang/go/blob/3d59583836630cf13ec4bfbed977d27b1b7adbdc/src/net/http/server.go#L201-L218
if r . Method == http . MethodPut || r . Method == http . MethodPost {
p . next . ServeHTTP ( rw , r )
} else {
p . next . ServeHTTP ( & writerWithoutCloseNotify { rw } , r )
}
}
2020-05-11 12:06:07 +02:00
// writerWithoutCloseNotify helps to disable closeNotify.
2018-06-20 09:12:03 +02:00
type writerWithoutCloseNotify struct {
W http . ResponseWriter
}
// Header returns the response headers.
func ( w * writerWithoutCloseNotify ) Header ( ) http . Header {
return w . W . Header ( )
}
// Write writes the data to the connection as part of an HTTP reply.
func ( w * writerWithoutCloseNotify ) Write ( buf [ ] byte ) ( int , error ) {
return w . W . Write ( buf )
}
2020-05-11 12:06:07 +02:00
// WriteHeader sends an HTTP response header with the provided status code.
2018-06-20 09:12:03 +02:00
func ( w * writerWithoutCloseNotify ) WriteHeader ( code int ) {
w . W . WriteHeader ( code )
}
// Flush sends any buffered data to the client.
func ( w * writerWithoutCloseNotify ) Flush ( ) {
if f , ok := w . W . ( http . Flusher ) ; ok {
f . Flush ( )
}
}
// Hijack hijacks the connection.
func ( w * writerWithoutCloseNotify ) Hijack ( ) ( net . Conn , * bufio . ReadWriter , error ) {
return w . W . ( http . Hijacker ) . Hijack ( )
}