-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient.go
More file actions
135 lines (107 loc) · 2.9 KB
/
client.go
File metadata and controls
135 lines (107 loc) · 2.9 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
package cptec
import (
"errors"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
"time"
)
const (
defaultBaseURL = "http://sinda.crn.inpe.br"
userAgent = "go-cptec"
// Headers
// headerAccept header Accept
headerAccept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
// headerContentTypePost header content type when post data
headerContentTypePost = "application/x-www-form-urlencoded"
)
// These are the errors that can be returned
var (
ErrStatusCode = errors.New("Http invalid status code")
)
// CPTEC manages communication with the CPTEC.
type CPTEC struct {
Client *http.Client // HTTP client used to communicate with the API.
// Base URL for CPTEC requests. BaseURL should always be specified with a
// trailing slash.
BaseURL *url.URL
// User agent used when communicating with the CPTEC.
UserAgent string
// Services used for talking to different parts of the CPTEC.
Station *StationService
Forecast *ForecastService
}
// New returns a new CPTEC client. If a nil httpClient is
// provided, http.DefaultClient will be used.
func New(httpClient *http.Client) *CPTEC {
if httpClient == nil {
cookieJar, _ := cookiejar.New(nil)
httpClient = http.DefaultClient
httpClient.Jar = cookieJar
httpClient.Timeout = time.Duration(10 * time.Second)
}
baseURL, _ := url.Parse(defaultBaseURL)
c := &CPTEC{
Client: httpClient,
BaseURL: baseURL,
UserAgent: userAgent,
}
c.Station = &StationService{client: c}
c.Forecast = &ForecastService{client: c}
return c
}
// NewRequest ...
func (c *CPTEC) NewRequest(method, path string, data interface{}, header interface{}) (req *http.Request, err error) {
rel := &url.URL{Path: path}
u := c.BaseURL.ResolveReference(rel)
if method == "POST" && data != nil {
formData, ok := data.(map[string]string)
if !ok {
return nil, errors.New("Invalid format type data")
}
form := url.Values{}
for k, v := range formData {
form.Add(k, v)
}
req, err = http.NewRequest(method, u.String(), strings.NewReader(form.Encode()))
if err != nil {
return nil, err
}
// req.PostForm = form
req.Header.Add("Content-Type", headerContentTypePost)
} else {
req, err = http.NewRequest(method, u.String(), nil)
if err != nil {
return nil, err
}
}
if header != nil {
headerData, ok := header.(map[string]string)
if !ok {
return nil, errors.New("Invalid header")
}
for k, v := range headerData {
req.Header.Add(k, v)
}
}
req.Header.Set("Accept", headerAccept)
req.Header.Set("User-Agent", c.UserAgent)
return req, nil
}
func (c *CPTEC) do(req *http.Request) ([]byte, error) {
resp, err := c.Client.Do(req)
if err != nil {
return []byte(""), err
}
if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte(""), err
}
defer resp.Body.Close()
return body, nil
}
return []byte(""), ErrStatusCode
}