forked from 0xch4z/dockerhub-go
-
Notifications
You must be signed in to change notification settings - Fork 1
/
dockerhub.go
130 lines (109 loc) · 2.82 KB
/
dockerhub.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
package dockerhub
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
)
const (
defaultUserAgent = "dockerhub-go/v1"
defaultAPIBaseURL = "https://hub.docker.com"
defaultAPIBaseEndpoint = "/v2"
)
// A Client manages communication with the Dockerhub API.
type Client struct {
httpClient *http.Client
BaseURL *url.URL
UserAgent string
authToken string
common service
Auth *AuthService
Repositories *RepositoriesService
User *UserService
Webhook *WebhookService
Organization *OrganizationService
Tag *TagService
}
// NewClient returns a new Dockerhub client. If an httpClient is not
// provided, a new http.Client will be used.
func NewClient(httpClient *http.Client) *Client {
if httpClient == nil {
httpClient = &http.Client{}
}
baseURL, _ := url.Parse(defaultAPIBaseURL)
c := &Client{
httpClient: httpClient,
UserAgent: defaultUserAgent,
BaseURL: baseURL,
}
c.common.client = c
c.Auth = (*AuthService)(&c.common)
c.Repositories = (*RepositoriesService)(&c.common)
c.User = (*UserService)(&c.common)
c.Webhook = (*WebhookService)(&c.common)
c.Organization = (*OrganizationService)(&c.common)
c.Tag = (*TagService)(&c.common)
return c
}
type service struct {
client *Client
}
// SetAuthToken sets the Authorization token on the client to be sent with
// API requests.
func (c *Client) SetAuthToken(token string) {
c.authToken = token
}
// Do sends an API request and returns the API response. The API response is JSON
// decoded and stored in the value pointed to by v.
func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*http.Response, error) {
req = req.WithContext(ctx)
resp, err := c.httpClient.Do(req)
if err != nil {
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
}
return nil, err
}
defer resp.Body.Close()
if err := checkResponse(resp); err != nil {
return nil, err
}
if err := json.NewDecoder(resp.Body).Decode(v); err != nil && err != io.EOF {
return nil, err
}
return resp, nil
}
// NewRequest creates an API request. The given URL is relative to the Client's
// BaseURL.
func (c *Client) NewRequest(method, url string, body interface{}) (*http.Request, error) {
u, err := c.BaseURL.Parse(defaultAPIBaseEndpoint + url)
if err != nil {
return nil, err
}
var buf io.ReadWriter
if body != nil {
buf = new(bytes.Buffer)
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
if err := enc.Encode(body); err != nil {
return nil, err
}
}
req, err := http.NewRequest(method, u.String(), buf)
if err != nil {
return nil, err
}
if len(c.authToken) != 0 {
req.Header.Set("Authorization", fmt.Sprintf("JWT %s", c.authToken))
}
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
req.Header.Set("User-Agent", c.UserAgent)
return req, nil
}