-
-
Notifications
You must be signed in to change notification settings - Fork 124
/
client.go
138 lines (106 loc) · 3.65 KB
/
client.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
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
138
// Copyright (c) 2021 - 2024, Ludvig Lundgren and the autobrr contributors.
// SPDX-License-Identifier: GPL-2.0-or-later
package sonarr
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"net/url"
"path"
"github.com/autobrr/autobrr/pkg/errors"
)
func (c *client) get(ctx context.Context, endpoint string) (int, []byte, error) {
u, err := url.Parse(c.config.Hostname)
u.Path = path.Join(u.Path, "/api/v3/", endpoint)
reqUrl := u.String()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqUrl, http.NoBody)
if err != nil {
return 0, nil, errors.Wrap(err, "could not build request")
}
if c.config.BasicAuth {
req.SetBasicAuth(c.config.Username, c.config.Password)
}
c.setHeaders(req)
resp, err := c.http.Do(req)
if err != nil {
return 0, nil, errors.Wrap(err, "sonarr.http.Do(req): %+v", req)
}
defer resp.Body.Close()
var buf bytes.Buffer
if _, err = io.Copy(&buf, resp.Body); err != nil {
return resp.StatusCode, nil, errors.Wrap(err, "sonarr.io.Copy")
}
return resp.StatusCode, buf.Bytes(), nil
}
func (c *client) post(ctx context.Context, endpoint string, data interface{}) (*http.Response, error) {
u, err := url.Parse(c.config.Hostname)
u.Path = path.Join(u.Path, "/api/v3/", endpoint)
reqUrl := u.String()
jsonData, err := json.Marshal(data)
if err != nil {
return nil, errors.Wrap(err, "could not marshal data: %+v", data)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, reqUrl, bytes.NewBuffer(jsonData))
if err != nil {
return nil, errors.Wrap(err, "could not build request")
}
if c.config.BasicAuth {
req.SetBasicAuth(c.config.Username, c.config.Password)
}
req.Header.Add("X-Api-Key", c.config.APIKey)
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
req.Header.Set("User-Agent", "autobrr")
res, err := c.http.Do(req)
if err != nil {
return res, errors.Wrap(err, "could not make request: %+v", req)
}
// validate response
if res.StatusCode == http.StatusUnauthorized {
return res, errors.New("unauthorized: bad credentials")
} else if res.StatusCode != http.StatusOK {
return res, errors.New("sonarr: bad request")
}
// return raw response and let the caller handle json unmarshal of body
return res, nil
}
func (c *client) postBody(ctx context.Context, endpoint string, data interface{}) (int, []byte, error) {
u, err := url.Parse(c.config.Hostname)
u.Path = path.Join(u.Path, "/api/v3/", endpoint)
reqUrl := u.String()
jsonData, err := json.Marshal(data)
if err != nil {
return 0, nil, errors.Wrap(err, "could not marshal data: %+v", data)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, reqUrl, bytes.NewBuffer(jsonData))
if err != nil {
return 0, nil, errors.Wrap(err, "could not build request")
}
if c.config.BasicAuth {
req.SetBasicAuth(c.config.Username, c.config.Password)
}
c.setHeaders(req)
resp, err := c.http.Do(req)
if err != nil {
return 0, nil, errors.Wrap(err, "sonarr.http.Do(req): %+v", req)
}
defer resp.Body.Close()
var buf bytes.Buffer
if _, err = io.Copy(&buf, resp.Body); err != nil {
return resp.StatusCode, nil, errors.Wrap(err, "sonarr.io.Copy")
}
if resp.StatusCode == http.StatusBadRequest {
return resp.StatusCode, buf.Bytes(), nil
} else if resp.StatusCode < 200 || resp.StatusCode > 401 {
return resp.StatusCode, buf.Bytes(), errors.New("sonarr: bad request: %v (status: %s): %s", resp.Request.RequestURI, resp.Status, buf.String())
}
return resp.StatusCode, buf.Bytes(), nil
}
func (c *client) setHeaders(req *http.Request) {
if req.Body != nil {
req.Header.Set("Content-Type", "application/json")
}
req.Header.Set("User-Agent", "autobrr")
req.Header.Set("X-Api-Key", c.config.APIKey)
}