-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrequest.go
More file actions
137 lines (130 loc) · 4.76 KB
/
request.go
File metadata and controls
137 lines (130 loc) · 4.76 KB
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
131
132
133
134
135
136
137
package keycloak
import (
"fmt"
"github.com/getevo/evo/v2/lib/curl"
"github.com/tidwall/gjson"
)
// adminError inspects a Keycloak admin-API response and, when the HTTP status
// is non-2xx, returns an error carrying the message Keycloak itself reported
// (`error_description` / `errorMessage` / `error` envelopes) instead of letting
// callers blindly unmarshal the error body into the success type and fail with
// a confusing JSON-shape error.
func adminError(resp *curl.Resp) error {
if resp == nil || resp.Response() == nil {
return nil
}
status := resp.Response().StatusCode
if status >= 200 && status < 300 {
return nil
}
body := resp.String()
parsed := gjson.Parse(body)
for _, key := range []string{"error_description", "errorMessage", "error"} {
if msg := parsed.Get(key).String(); msg != "" {
return fmt.Errorf("keycloak admin %d: %s", status, msg)
}
}
if body == "" {
return fmt.Errorf("keycloak admin %d (empty response)", status)
}
return fmt.Errorf("keycloak admin %d: %s", status, body)
}
// Put sends a PUT request to the specified endpoint with the provided query strings and data. It returns a curl.Resp and an error.
// Parameters:
// - endpoint: The endpoint path to send the request to.
// - query: The query string to be appended to the endpoint URL.
// - data: Optional data to be included in the request body.
// Returns:
// - *curl.Resp: The response from the PUT request.
// - error: Any error that occurred during the request.
func (connection *Connection) Put(endpoint string, query string, data ...interface{}) (*curl.Resp, error) {
data = connection.PrepareRequest(data)
var url = join(connection.Settings.Server, connection.Settings.BasePath, endpoint, "realms", connection.Settings.Realm, query)
resp, err := curl.Put(url, data...)
if err != nil {
return nil, err
}
if connection.Settings.Debug {
fmt.Println(resp.Dump())
}
resp, err = handleRedirect(resp)
if err != nil {
return nil, err
}
if resp.Response().StatusCode == 204 {
return resp, nil
}
return resp, nil
}
func (connection *Connection) Delete(endpoint string, query string, data ...interface{}) (*curl.Resp, error) {
data = connection.PrepareRequest(data)
var url = join(connection.Settings.Server, connection.Settings.BasePath, endpoint, "realms", connection.Settings.Realm, query)
resp, err := curl.Delete(url, data...)
if err != nil {
return nil, err
}
if connection.Settings.Debug {
fmt.Println(resp.Dump())
}
resp, err = handleRedirect(resp)
if err != nil {
return nil, err
}
if resp.Response().StatusCode == 204 {
return resp, nil
}
return resp, nil
}
// Post sends a POST request to the specified endpoint with optional query parameters and data. It returns the response and an error if any.
func (connection *Connection) Post(endpoint string, query string, data ...interface{}) (*curl.Resp, error) {
data = connection.PrepareRequest(data)
var url = join(connection.Settings.Server, connection.Settings.BasePath, endpoint, "realms", connection.Settings.Realm, query)
resp, err := curl.Post(url, data...)
if err != nil {
return nil, err
}
if connection.Settings.Debug {
fmt.Println(resp.Dump())
}
/*resp, err = handleRedirect(resp)
if resp.Response().StatusCode == 204 {
return resp, nil
}*/
return resp, nil
}
// Get method sends a GET request to the specified endpoint with optional query parameters and data.
//
// Parameters:
// - endpoint: the endpoint URL string to send the request to.
// - query: the query string to include in the request URL.
// - data: optional variadic parameter to include data in the request body.
//
// Returns:
// - *curl.Resp: the response object containing the HTTP response information.
// - error: any error that occurred during the request.
func (connection *Connection) Get(endpoint string, query string, data ...interface{}) (*curl.Resp, error) {
data = connection.PrepareRequest(data)
var url = join(connection.Settings.Server, connection.Settings.BasePath, endpoint, "realms", connection.Settings.Realm, query)
resp, err := curl.Get(url, data...)
if err != nil {
return nil, err
}
if connection.Settings.Debug {
fmt.Println(resp.Dump())
}
resp, err = handleRedirect(resp)
return resp, nil
}
// handleRedirect redirects the response to the location specified in the "location" header, if present.
// It uses the curl.Get function to make a new request to the location. If there is an error during the request, it returns nil and the error.
// If there is no "location" header or there is no error, it returns the original response and nil error.
func handleRedirect(resp *curl.Resp) (*curl.Resp, error) {
var err error
if resp.Response().Header.Get("location") != "" {
resp, err = curl.Get(resp.Response().Header.Get("location"), resp.Request().Header)
if err != nil {
return nil, err
}
}
return resp, nil
}