1
1
package reverse_proxy
2
2
3
3
import (
4
- "fmt"
5
- "github.com/bots-garden/capsule/capsule-reverse-proxy/reverse-proxy/routes"
6
- "github.com/bots-garden/capsule/commons"
7
- "github.com/gin-gonic/gin"
8
- "gopkg.in/yaml.v3"
9
- "io/ioutil"
10
- "log"
11
- "net/http"
12
- "net/http/httputil"
13
- "net/url"
4
+ "fmt"
5
+ "github.com/bots-garden/capsule/capsule-reverse-proxy/reverse-proxy/routes"
6
+ "github.com/bots-garden/capsule/commons"
7
+ "github.com/gin-gonic/gin"
8
+ "net/http"
9
+ "net/http/httputil"
10
+ "net/url"
14
11
)
15
12
16
13
/*
@@ -25,165 +22,123 @@ func getEnv(key, fallback string) string {
25
22
var lastUrlIndex = 0
26
23
27
24
func redirect (functionUrls []string , c * gin.Context ) {
28
- //fmt.Println("🟢🖐", functionUrls)
29
- var functionUrl = ""
25
+ var functionUrl = ""
30
26
31
- if len (functionUrls ) == 1 {
32
- functionUrl = functionUrls [0 ]
33
- } else {
34
- //TODO better repartition (load balancing) handling
35
- lastUrlIndex += 1
36
- if lastUrlIndex == len (functionUrls ) {
37
- lastUrlIndex = 0
38
- }
27
+ if len (functionUrls ) == 1 {
28
+ functionUrl = functionUrls [0 ]
29
+ } else {
30
+ //TODO better repartition (load balancing) handling
31
+ lastUrlIndex += 1
32
+ if lastUrlIndex == len (functionUrls ) {
33
+ lastUrlIndex = 0
34
+ }
39
35
40
- functionUrl = functionUrls [lastUrlIndex ]
36
+ functionUrl = functionUrls [lastUrlIndex ]
41
37
42
- //fmt.Println("🛑 kind of load balancing", lastUrlIndex)
43
- //fmt.Println("🌍", functionUrl)
44
- }
38
+ }
45
39
46
- remote , err := url .Parse (functionUrl )
40
+ remote , err := url .Parse (functionUrl )
47
41
48
- if err != nil {
49
- panic (err )
50
- }
42
+ if err != nil {
43
+ panic (err )
44
+ }
51
45
52
- proxy := httputil .NewSingleHostReverseProxy (remote )
46
+ proxy := httputil .NewSingleHostReverseProxy (remote )
53
47
54
- proxy .Director = func (req * http.Request ) {
55
- req .Header = c .Request .Header
56
- req .Host = remote .Host
57
- req .URL .Scheme = remote .Scheme
58
- req .URL .Host = remote .Host
59
- req .URL .Path = c .Param ("proxyPath" )
48
+ proxy .Director = func (req * http.Request ) {
49
+ req .Header = c .Request .Header
50
+ req .Host = remote .Host
51
+ req .URL .Scheme = remote .Scheme
52
+ req .URL .Host = remote .Host
53
+ req .URL .Path = c .Param ("proxyPath" )
60
54
61
- //fmt.Println("🔴", c.Request.Header)
62
- }
55
+ }
63
56
64
- proxy .ServeHTTP (c .Writer , c .Request )
57
+ proxy .ServeHTTP (c .Writer , c .Request )
65
58
}
66
59
67
- // 👀 See https://github.com/bots-garden/procyon/blob/main/procyon-reverse-proxy/main.go
68
60
func proxy (c * gin.Context ) {
69
61
70
- functionName := c .Param ("function_name" )
71
- functionUrls := functions [functionName ]["default" ]
72
-
73
- //fmt.Println("👋functionName", functionName)
74
- //fmt.Println("👋functionUrls", functionUrls)
62
+ functionName := c .Param ("function_name" )
63
+ functionUrls := functions [functionName ]["default" ]
75
64
76
- if functionUrls != nil {
77
- /*
78
- 2022/08/09 14:11:44 http: panic serving 127.0.0.1:65399:
79
- interface conversion: interface {} is []string, not []interface {}
65
+ if functionUrls != nil {
66
+ //redirect(functionUrls.([]interface{}), c)
67
+ redirect (functionUrls .([]string ), c )
80
68
81
- */
82
-
83
- //redirect(functionUrls.([]interface{}), c)
84
- redirect (functionUrls .([]string ), c )
85
-
86
- } else {
87
- c .JSON (http .StatusInternalServerError , gin.H {"code" : "ERROR" , "message" : "😢 Houston? We have a problem 🥵" })
88
- }
69
+ } else {
70
+ c .JSON (http .StatusInternalServerError , gin.H {"code" : "ERROR" , "message" : "😢 Houston? We have a problem 🥵" })
71
+ }
89
72
90
73
}
91
74
92
75
func proxyRevision (c * gin.Context ) {
93
76
94
- functionName := c .Param ("function_name" )
95
- functionRevision := c .Param ("function_revision" )
96
- functionUrls := functions [functionName ][functionRevision ]
77
+ functionName := c .Param ("function_name" )
78
+ functionRevision := c .Param ("function_revision" )
79
+ functionUrls := functions [functionName ][functionRevision ]
97
80
98
- if functionUrls != nil {
99
- redirect (functionUrls .([]string ), c )
100
- } else {
101
- c .JSON (http .StatusInternalServerError , gin.H {"code" : "ERROR" , "message" : "😢 Houston? We have a problem 🥵" })
102
- }
81
+ if functionUrls != nil {
82
+ redirect (functionUrls .([]string ), c )
83
+ } else {
84
+ c .JSON (http .StatusInternalServerError , gin.H {"code" : "ERROR" , "message" : "😢 Houston? We have a problem 🥵" })
85
+ }
103
86
}
104
87
105
- var yamlConfig = make (map [interface {}]map [interface {}]map [interface {}]interface {})
88
+ // var yamlConfig = make(map[interface{}]map[interface{}]map[interface{}]interface{})
106
89
var functions = make (map [interface {}]map [interface {}]interface {})
107
- var filters = make (map [interface {}]map [interface {}]interface {})
90
+
91
+ //var filters = make(map[interface{}]map[interface{}]interface{})
108
92
109
93
func Serve (httpPort , config , backend , crt , key string ) {
110
94
111
- if config != "" {
112
- fmt .Println ("📝 config file:" , config )
113
- yamlFile , errFile := ioutil .ReadFile (config )
114
- if errFile != nil {
115
- log .Fatal (errFile )
116
- }
117
-
118
- errYaml := yaml .Unmarshal (yamlFile , & yamlConfig )
119
-
120
- if errYaml != nil {
121
- log .Fatal (errYaml )
122
- }
123
-
124
- functions = yamlConfig ["functions" ]
125
- filters = yamlConfig ["filters" ]
126
-
127
- // The code below is for testing
128
- /*
129
- functions["sandbox"] = map[interface{}]interface{}{"default": []string{"http://localhost:5050"}, "blue": []string{"http://localhost:5051"}}
130
-
131
- functions["sandbox"]["green"] = []string{"http://localhost:5052"}
132
-
133
- urlsList := functions["sandbox"]["green"].([]string)
134
- urlsList = append(urlsList, "http://localhost:5053")
135
-
136
- functions["sandbox"]["green"] = urlsList
137
- */
138
- }
139
-
140
- switch backend {
141
- case "yaml" :
142
- fmt .Println ("👋 routes are defined in" , config )
143
- case "memory" :
144
- // it's possible to mix memory and yaml for the functions
145
- fmt .Println ("👋 routes are defined in memory" )
146
- case "redis" :
147
- default :
148
- fmt .Println ("👋 routes are defined in a Redis backend" )
149
- //TODO check the environment variables
150
- fmt .Println ("👋 use environment variable for the Redis configuration " )
151
- }
152
-
153
- if commons .GetEnv ("DEBUG" , "false" ) == "false" {
154
- gin .SetMode (gin .ReleaseMode )
155
- } else {
156
- gin .SetMode (gin .DebugMode )
157
- }
158
- //router := gin.Default()
159
- router := gin .New ()
160
-
161
- router .NoRoute (func (c * gin.Context ) {
162
- c .JSON (404 , gin.H {"code" : "PAGE_NOT_FOUND" , "message" : "😢 Page not found 🥵" })
163
- })
164
-
165
- /*
166
- You need to use a header with this key: CAPSULE_REVERSE_PROXY_ADMIN_TOKEN
167
- */
168
- reverseProxyAdminToken := commons .GetEnv ("CAPSULE_REVERSE_PROXY_ADMIN_TOKEN" , "" )
169
-
170
- reverse_proxy_memory_routes .DefineFunctionsRoutes (router , functions , reverseProxyAdminToken )
171
- reverse_proxy_memory_routes .DefineRevisionsRoutes (router , functions , reverseProxyAdminToken )
172
- reverse_proxy_memory_routes .DefineUrlsRoutes (router , functions , reverseProxyAdminToken )
173
-
174
- // Call the functions
175
- router .Any ("/functions/:function_name" , proxy )
176
- router .Any ("/functions/:function_name/:function_revision" , proxyRevision )
177
-
178
- if crt != "" {
179
- // certs/procyon-registry.local.crt
180
- // certs/procyon-registry.local.key
181
- fmt .Println ("💊 Capsule (" , commons .CapsuleVersion (), ") Reverse-Proxy is listening on:" , httpPort , "🔐🌍" )
182
-
183
- router .RunTLS (":" + httpPort , crt , key )
184
- } else {
185
- fmt .Println ("💊 Capsule (" , commons .CapsuleVersion (), ") Reverse-Proxy is listening on:" , httpPort , "🌍" )
186
- router .Run (":" + httpPort )
187
- }
95
+ switch backend {
96
+ case "memory" :
97
+ // it's possible to mix memory and yaml for the functions
98
+ fmt .Println ("👋 routes are defined in memory" )
99
+ case "redis" :
100
+ fmt .Println ("👋 Redis backend (🚧 not implemented)" )
101
+ fmt .Println ("👋 routes are defined in a Redis backend" )
102
+ fmt .Println ("👋 use environment variable for the Redis configuration " )
103
+ default :
104
+ fmt .Println ("👋 routes are defined in a Redis backend" )
105
+ fmt .Println ("👋 use environment variable for the Redis configuration " )
106
+ }
107
+
108
+ if commons .GetEnv ("DEBUG" , "false" ) == "false" {
109
+ gin .SetMode (gin .ReleaseMode )
110
+ } else {
111
+ gin .SetMode (gin .DebugMode )
112
+ }
113
+ //router := gin.Default()
114
+ router := gin .New ()
115
+
116
+ router .NoRoute (func (c * gin.Context ) {
117
+ c .JSON (404 , gin.H {"code" : "PAGE_NOT_FOUND" , "message" : "😢 Page not found 🥵" })
118
+ })
119
+
120
+ /*
121
+ You need to use a header with this key: CAPSULE_REVERSE_PROXY_ADMIN_TOKEN
122
+ */
123
+ reverseProxyAdminToken := commons .GetEnv ("CAPSULE_REVERSE_PROXY_ADMIN_TOKEN" , "" )
124
+
125
+ reverse_proxy_memory_routes .DefineFunctionsRoutes (router , functions , reverseProxyAdminToken )
126
+ reverse_proxy_memory_routes .DefineRevisionsRoutes (router , functions , reverseProxyAdminToken )
127
+ reverse_proxy_memory_routes .DefineUrlsRoutes (router , functions , reverseProxyAdminToken )
128
+
129
+ // Call the functions
130
+ router .Any ("/functions/:function_name" , proxy )
131
+ router .Any ("/functions/:function_name/:function_revision" , proxyRevision )
132
+
133
+ if crt != "" {
134
+ // certs/procyon-registry.local.crt
135
+ // certs/procyon-registry.local.key
136
+ fmt .Println ("💊 Capsule (" , commons .CapsuleVersion (), ") Reverse-Proxy is listening on:" , httpPort , "🔐🌍" )
137
+
138
+ router .RunTLS (":" + httpPort , crt , key )
139
+ } else {
140
+ fmt .Println ("💊 Capsule (" , commons .CapsuleVersion (), ") Reverse-Proxy is listening on:" , httpPort , "🌍" )
141
+ router .Run (":" + httpPort )
142
+ }
188
143
189
144
}
0 commit comments