-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttp.go
More file actions
113 lines (95 loc) · 2.78 KB
/
http.go
File metadata and controls
113 lines (95 loc) · 2.78 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
// Copyright 2017-2026 Allow2 Pty Ltd. All rights reserved.
// Use of this source code is governed by the Allow2 API and SDK Licence.
package allow2service
import (
"bytes"
"encoding/json"
"io"
"net/http"
"sync"
"time"
)
// HttpResponse is a simple value object representing an HTTP response.
type HttpResponse struct {
StatusCode int
Body string
decoded map[string]interface{}
decodeOnce sync.Once
}
// JSON decodes the response body as JSON.
// Returns nil if the body is not valid JSON.
func (r *HttpResponse) JSON() map[string]interface{} {
r.decodeOnce.Do(func() {
var result map[string]interface{}
if err := json.Unmarshal([]byte(r.Body), &result); err == nil {
r.decoded = result
}
})
return r.decoded
}
// IsSuccess returns true if the HTTP status code is 2xx.
func (r *HttpResponse) IsSuccess() bool {
return r.StatusCode >= 200 && r.StatusCode < 300
}
// IsUnauthorized returns true if the HTTP status code is 401 or 403.
func (r *HttpResponse) IsUnauthorized() bool {
return r.StatusCode == 401 || r.StatusCode == 403
}
// defaultHTTPClient is the default HTTP client implementation using net/http.
type defaultHTTPClient struct {
client *http.Client
}
const (
defaultTimeout = 15 * time.Second
userAgentValue = "Allow2-Go-SDK/2.0"
)
// newDefaultHTTPClient creates a new default HTTP client with a 15-second timeout.
func newDefaultHTTPClient() *defaultHTTPClient {
return &defaultHTTPClient{
client: &http.Client{
Timeout: defaultTimeout,
},
}
}
// Post sends a POST request with JSON-encoded body data.
func (c *defaultHTTPClient) Post(url string, data map[string]interface{}, headers map[string]string) (*HttpResponse, error) {
return c.request("POST", url, data, headers)
}
// Get sends a GET request.
func (c *defaultHTTPClient) Get(url string, headers map[string]string) (*HttpResponse, error) {
return c.request("GET", url, nil, headers)
}
// request executes an HTTP request.
func (c *defaultHTTPClient) request(method, url string, data map[string]interface{}, headers map[string]string) (*HttpResponse, error) {
var bodyReader io.Reader
if data != nil && method == "POST" {
jsonData, err := json.Marshal(data)
if err != nil {
return nil, err
}
bodyReader = bytes.NewReader(jsonData)
}
req, err := http.NewRequest(method, url, bodyReader)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
req.Header.Set("User-Agent", userAgentValue)
for k, v := range headers {
req.Header.Set(k, v)
}
resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return &HttpResponse{
StatusCode: resp.StatusCode,
Body: string(bodyBytes),
}, nil
}