traefik/pkg/middlewares/pipelining/pipelining.go

71 lines
1.7 KiB
Go
Raw Normal View History

package pipelining
import (
"bufio"
2019-03-18 10:30:07 +00:00
"context"
"net"
"net/http"
2019-03-18 10:30:07 +00:00
"github.com/traefik/traefik/v2/pkg/log"
"github.com/traefik/traefik/v2/pkg/middlewares"
2019-03-18 10:30:07 +00:00
)
const (
typeName = "Pipelining"
)
2020-05-11 10:06:07 +00:00
// pipelining returns a middleware.
2019-03-18 10:30:07 +00:00
type pipelining struct {
next http.Handler
}
2020-05-11 10:06:07 +00:00
// New returns a new pipelining instance.
2019-03-18 10:30:07 +00:00
func New(ctx context.Context, next http.Handler, name string) http.Handler {
2019-09-13 17:28:04 +00:00
log.FromContext(middlewares.GetLoggerCtx(ctx, name, typeName)).Debug("Creating middleware")
2019-03-18 10:30:07 +00:00
return &pipelining{
next: next,
}
}
2019-03-18 10:30:07 +00:00
func (p *pipelining) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
// 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 10:06:07 +00:00
// writerWithoutCloseNotify helps to disable closeNotify.
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 10:06:07 +00:00
// WriteHeader sends an HTTP response header with the provided status code.
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()
}