-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathproxy.go
130 lines (106 loc) · 2.88 KB
/
proxy.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package proxy
import (
"crypto/tls"
"fmt"
"net/url"
"strings"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/utils"
"github.com/valyala/fasthttp"
)
// New is deprecated
func New(config Config) fiber.Handler {
fmt.Println("proxy.New is deprecated, please use proxy.Balancer instead")
return Balancer(config)
}
// Balancer creates a load balancer among multiple upstream servers
func Balancer(config Config) fiber.Handler {
// Set default config
cfg := configDefault(config)
// Load balanced client
var lbc fasthttp.LBClient
// Set timeout
lbc.Timeout = cfg.Timeout
// Scheme must be provided, falls back to http
// TODO add https support
for _, server := range cfg.Servers {
if !strings.HasPrefix(server, "http") {
server = "http://" + server
}
u, err := url.Parse(server)
if err != nil {
panic(err)
}
client := &fasthttp.HostClient{
NoDefaultUserAgentHeader: true,
DisablePathNormalizing: true,
Addr: u.Host,
ReadBufferSize: config.ReadBufferSize,
WriteBufferSize: config.WriteBufferSize,
TLSConfig: config.TlsConfig,
}
lbc.Clients = append(lbc.Clients, client)
}
// Return new handler
return func(c *fiber.Ctx) (err error) {
// Don't execute middleware if Next returns true
if cfg.Next != nil && cfg.Next(c) {
return c.Next()
}
// Set request and response
req := c.Request()
res := c.Response()
// Don't proxy "Connection" header
req.Header.Del(fiber.HeaderConnection)
// Modify request
if cfg.ModifyRequest != nil {
if err = cfg.ModifyRequest(c); err != nil {
return err
}
}
req.SetRequestURI(utils.UnsafeString(req.RequestURI()))
// Forward request
if err = lbc.Do(req, res); err != nil {
return err
}
// Don't proxy "Connection" header
res.Header.Del(fiber.HeaderConnection)
// Modify response
if cfg.ModifyResponse != nil {
if err = cfg.ModifyResponse(c); err != nil {
return err
}
}
// Return nil to end proxying if no error
return nil
}
}
var client = fasthttp.Client{
NoDefaultUserAgentHeader: true,
DisablePathNormalizing: true,
}
// WithTlsConfig update http client with a user specified tls.config
// This function should be called before Do and Forward.
func WithTlsConfig(tlsConfig *tls.Config) {
client.TLSConfig = tlsConfig
}
// Forward performs the given http request and fills the given http response.
// This method will return an fiber.Handler
func Forward(addr string) fiber.Handler {
return func(c *fiber.Ctx) error {
return Do(c, addr)
}
}
// Do performs the given http request and fills the given http response.
// This method can be used within a fiber.Handler
func Do(c *fiber.Ctx, addr string) error {
req := c.Request()
res := c.Response()
req.SetRequestURI(addr)
req.Header.Del(fiber.HeaderConnection)
if err := client.Do(req, res); err != nil {
return err
}
res.Header.Del(fiber.HeaderConnection)
return nil
}