-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontroller.go
102 lines (83 loc) · 2.69 KB
/
controller.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
package gateway
import (
"fmt"
"io"
"net/http"
"strings"
contractshttp "github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/foundation/json"
"github.com/spf13/cast"
)
func Get(ctx contractshttp.Context) contractshttp.Response {
return request(ctx, http.MethodGet)
}
func Post(ctx contractshttp.Context) contractshttp.Response {
return request(ctx, http.MethodPost)
}
func Put(ctx contractshttp.Context) contractshttp.Response {
return request(ctx, http.MethodPut)
}
func Delete(ctx contractshttp.Context) contractshttp.Response {
return request(ctx, http.MethodDelete)
}
func Patch(ctx contractshttp.Context) contractshttp.Response {
return request(ctx, http.MethodPatch)
}
func request(ctx contractshttp.Context, method string) contractshttp.Response {
// Inject Value into Query
if injectValue, exist := ctx.Value(InjectKey).(map[string]any); exist {
query := ctx.Request().Origin().URL.Query()
for key, value := range injectValue {
query.Add(key, cast.ToString(value))
}
ctx.Request().Origin().URL.RawQuery = query.Encode()
}
fallback := FacadesConfig.Get("gateway.fallback").(func(ctx contractshttp.Context, err error) contractshttp.Response)
var body io.Reader
if method != http.MethodGet && method != http.MethodDelete {
// Put Query into Body, because Gateway only accept Body
data, err := io.ReadAll(ctx.Request().Origin().Body)
if err != nil {
return fallback(ctx, err)
}
jsonDriver := json.NewJson()
var dataJson map[string]any
if err := jsonDriver.Unmarshal(data, &dataJson); err != nil {
return fallback(ctx, err)
}
for key, value := range ctx.Request().Queries() {
dataJson[key] = value
}
newData, err := jsonDriver.Marshal(dataJson)
if err != nil {
return fallback(ctx, err)
}
body = strings.NewReader(string(newData))
}
url := fmt.Sprintf("http://%s:%s%s", FacadesConfig.GetString("gateway.host"), FacadesConfig.GetString("gateway.port"), ctx.Request().Path())
gatewayReq, err := http.NewRequest(method, url, body)
if err != nil {
return fallback(ctx, err)
}
query := ctx.Request().Origin().URL.Query()
gatewayReq.URL.RawQuery = query.Encode()
for key, header := range ctx.Request().Headers() {
gatewayReq.Header.Set(key, header[0])
}
gatewayResp, err := http.DefaultClient.Do(gatewayReq)
if err != nil {
return fallback(ctx, err)
}
defer gatewayResp.Body.Close()
data, err := io.ReadAll(gatewayResp.Body)
if err != nil {
return fallback(ctx, err)
}
resp := ctx.Response()
for key, value := range gatewayResp.Header {
if len(value) > 0 && key != "Content-Length" {
resp = resp.Header(key, value[0])
}
}
return resp.Data(200, ctx.Request().Header("Content-Type", "application/json"), data)
}