git.iko.soy/typeable/oauth2-proxy
on ea261ca help sign in
115 lines 3.4 kB history raw
1package middleware
3import (
4 "fmt"
5 "net/http"
6 "strings"
8 "github.com/justinas/alice"
9 middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
10 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
11 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/header"
14func NewRequestHeaderInjector(headers []options.Header) (alice.Constructor, error) {
15 headerInjector, err := newRequestHeaderInjector(headers)
16 if err != nil {
17 return nil, fmt.Errorf("error building request header injector: %v", err)
18 }
20 strip := newStripHeaders(headers)
21 if strip != nil {
22 return alice.New(strip, headerInjector).Then, nil
23 }
24 return headerInjector, nil
27func newStripHeaders(headers []options.Header) alice.Constructor {
28 headersToStrip := []string{}
29 for _, header := range headers {
30 if !header.PreserveRequestValue {
31 headersToStrip = append(headersToStrip, header.Name)
32 }
33 }
35 if len(headersToStrip) == 0 {
36 return nil
37 }
39 return func(next http.Handler) http.Handler {
40 return stripHeaders(headersToStrip, next)
41 }
44func flattenHeaders(headers http.Header) {
45 for name, values := range headers {
46 // Set-Cookie should not be flattened, ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
47 if len(values) > 1 && name != "Set-Cookie" {
48 headers.Set(name, strings.Join(values, ","))
49 }
50 }
53func stripHeaders(headers []string, next http.Handler) http.Handler {
54 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
55 for _, header := range headers {
56 req.Header.Del(header)
57 }
58 next.ServeHTTP(rw, req)
59 })
62func newRequestHeaderInjector(headers []options.Header) (alice.Constructor, error) {
63 injector, err := header.NewInjector(headers)
64 if err != nil {
65 return nil, fmt.Errorf("error building request injector: %v", err)
66 }
68 return func(next http.Handler) http.Handler {
69 return injectRequestHeaders(injector, next)
70 }, nil
73func injectRequestHeaders(injector header.Injector, next http.Handler) http.Handler {
74 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
75 scope := middlewareapi.GetRequestScope(req)
77 // If scope is nil, this will panic.
78 // A scope should always be injected before this handler is called.
79 injector.Inject(req.Header, scope.Session)
80 flattenHeaders(req.Header)
81 next.ServeHTTP(rw, req)
82 })
85func NewResponseHeaderInjector(headers []options.Header) (alice.Constructor, error) {
86 headerInjector, err := newResponseHeaderInjector(headers)
87 if err != nil {
88 return nil, fmt.Errorf("error building response header injector: %v", err)
89 }
91 return headerInjector, nil
94func newResponseHeaderInjector(headers []options.Header) (alice.Constructor, error) {
95 injector, err := header.NewInjector(headers)
96 if err != nil {
97 return nil, fmt.Errorf("error building response injector: %v", err)
98 }
100 return func(next http.Handler) http.Handler {
101 return injectResponseHeaders(injector, next)
102 }, nil
105func injectResponseHeaders(injector header.Injector, next http.Handler) http.Handler {
106 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
107 scope := middlewareapi.GetRequestScope(req)
109 // If scope is nil, this will panic.
110 // A scope should always be injected before this handler is called.
111 injector.Inject(rw.Header(), scope.Session)
112 flattenHeaders(rw.Header())
113 next.ServeHTTP(rw, req)
114 })