-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
110 lines (88 loc) · 2.08 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package traefik_response_header_forward_plugin
import (
"bufio"
"bytes"
"context"
"fmt"
"io"
"net"
"net/http"
)
var (
_ interface {
http.ResponseWriter
http.Hijacker
} = &wrappedResponseWriter{}
)
type wrappedResponseWriter struct {
rw http.ResponseWriter
buf *bytes.Buffer
code int
}
func (w *wrappedResponseWriter) Header() http.Header {
return w.rw.Header()
}
func (w *wrappedResponseWriter) Write(b []byte) (int, error) {
return w.buf.Write(b)
}
func (w *wrappedResponseWriter) WriteHeader(code int) {
w.code = code
}
func (w *wrappedResponseWriter) Flush() {
w.rw.WriteHeader(w.code)
io.Copy(w.rw, w.buf)
}
func (w *wrappedResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
hijacker, ok := w.rw.(http.Hijacker)
if !ok {
return nil, nil, fmt.Errorf("%T is not an http.Hijacker", w.rw)
}
return hijacker.Hijack()
}
// ========================================
type RequestHeader struct {
Name string `json:"name,omitempty"`
}
type Config struct {
RequestHeaders []RequestHeader `json:"requestHeaders,omitempty"`
}
func CreateConfig() *Config {
return &Config{
RequestHeaders: make([]RequestHeader, 0),
}
}
type ResponseHeaderForward struct {
next http.Handler
name string
config *Config
}
func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error) {
if len(config.RequestHeaders) == 0 {
return nil, fmt.Errorf("RequestHeaders cannot be empty")
}
for _, headerName := range config.RequestHeaders {
if headerName.Name == "" {
return nil, fmt.Errorf("RequestHeaders.Name cannot be empty")
}
}
return &ResponseHeaderForward{
next: next,
name: name,
config: config,
}, nil
}
func (a *ResponseHeaderForward) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
resp := &wrappedResponseWriter{
rw: rw,
buf: &bytes.Buffer{},
}
defer resp.Flush()
a.next.ServeHTTP(resp, req)
for _, requestHeader := range a.config.RequestHeaders {
headerValue := req.Header.Get(requestHeader.Name)
if headerValue == "" {
continue
}
resp.Header().Set(requestHeader.Name, headerValue)
}
}