1
0
Fork 0

Add forwardAuth.addAuthCookiesToResponse

This commit is contained in:
Thomas Gunsch 2024-01-15 16:14:05 +01:00 committed by GitHub
parent 980dac4572
commit 81ce45271d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 155 additions and 19 deletions

View file

@ -8,6 +8,7 @@ import (
"strings"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/vulcand/oxy/v2/forward"
)
@ -58,7 +59,7 @@ func (s *Header) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
// If there is a next, call it.
if s.next != nil {
s.next.ServeHTTP(newResponseModifier(rw, req, s.PostRequestModifyResponseHeaders), req)
s.next.ServeHTTP(middlewares.NewResponseModifier(rw, req, s.PostRequestModifyResponseHeaders), req)
}
}

View file

@ -1,103 +0,0 @@
package headers
import (
"bufio"
"fmt"
"net"
"net/http"
"github.com/rs/zerolog/log"
)
type responseModifier struct {
req *http.Request
rw http.ResponseWriter
headersSent bool // whether headers have already been sent
code int // status code, must default to 200
modifier func(*http.Response) error // can be nil
modified bool // whether modifier has already been called for the current request
modifierErr error // returned by modifier call
}
// modifier can be nil.
func newResponseModifier(w http.ResponseWriter, r *http.Request, modifier func(*http.Response) error) http.ResponseWriter {
return &responseModifier{
req: r,
rw: w,
modifier: modifier,
code: http.StatusOK,
}
}
// WriteHeader is, in the specific case of 1xx status codes, a direct call to the wrapped ResponseWriter, without marking headers as sent,
// allowing so further calls.
func (r *responseModifier) WriteHeader(code int) {
if r.headersSent {
return
}
// Handling informational headers.
if code >= 100 && code <= 199 {
r.rw.WriteHeader(code)
return
}
defer func() {
r.code = code
r.headersSent = true
}()
if r.modifier == nil || r.modified {
r.rw.WriteHeader(code)
return
}
resp := http.Response{
Header: r.rw.Header(),
Request: r.req,
}
if err := r.modifier(&resp); err != nil {
r.modifierErr = err
// we are propagating when we are called in Write, but we're logging anyway,
// because we could be called from another place which does not take care of
// checking w.modifierErr.
log.Error().Err(err).Msg("Error when applying response modifier")
r.rw.WriteHeader(http.StatusInternalServerError)
return
}
r.modified = true
r.rw.WriteHeader(code)
}
func (r *responseModifier) Header() http.Header {
return r.rw.Header()
}
func (r *responseModifier) Write(b []byte) (int, error) {
r.WriteHeader(r.code)
if r.modifierErr != nil {
return 0, r.modifierErr
}
return r.rw.Write(b)
}
// Hijack hijacks the connection.
func (r *responseModifier) Hijack() (net.Conn, *bufio.ReadWriter, error) {
if h, ok := r.rw.(http.Hijacker); ok {
return h.Hijack()
}
return nil, nil, fmt.Errorf("not a hijacker: %T", r.rw)
}
// Flush sends any buffered data to the client.
func (r *responseModifier) Flush() {
if flusher, ok := r.rw.(http.Flusher); ok {
flusher.Flush()
}
}

View file

@ -4,6 +4,7 @@ import (
"net/http"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/unrolled/secure"
)
@ -45,6 +46,6 @@ func newSecure(next http.Handler, cfg dynamic.Headers, contextKey string) *secur
func (s secureHeader) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
s.secure.HandlerFuncWithNextForRequestOnly(rw, req, func(writer http.ResponseWriter, request *http.Request) {
s.next.ServeHTTP(newResponseModifier(writer, request, s.secure.ModifyResponseHeaders), request)
s.next.ServeHTTP(middlewares.NewResponseModifier(writer, request, s.secure.ModifyResponseHeaders), request)
})
}