forked from harness/gitness
-
Notifications
You must be signed in to change notification settings - Fork 0
/
http.go
186 lines (154 loc) · 4.21 KB
/
http.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package bitbucket
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"net/url"
"github.com/drone/go-bitbucket/oauth1"
)
var (
// Returned if the specified resource does not exist.
ErrNotFound = errors.New("Not Found")
// Returned if the caller attempts to make a call or modify a resource
// for which the caller is not authorized.
//
// The request was a valid request, the caller's authentication credentials
// succeeded but those credentials do not grant the caller permission to
// access the resource.
ErrForbidden = errors.New("Forbidden")
// Returned if the call requires authentication and either the credentials
// provided failed or no credentials were provided.
ErrNotAuthorized = errors.New("Unauthorized")
// Returned if the caller submits a badly formed request. For example,
// the caller can receive this return if you forget a required parameter.
ErrBadRequest = errors.New("Bad Request")
)
// DefaultClient uses DefaultTransport, and is used internall to execute
// all http.Requests. This may be overriden for unit testing purposes.
//
// IMPORTANT: this is not thread safe and should not be touched with
// the exception overriding for mock unit testing.
var DefaultClient = http.DefaultClient
func (c *Client) do(method string, path string, params url.Values, values url.Values, v interface{}) error {
// if this is the guest client then we don't need
// to sign the request ... we will execute just
// a simple http request.
if c == Guest {
return c.guest(method, path, params, values, v)
}
// create the client
var client = oauth1.Consumer{
ConsumerKey: c.ConsumerKey,
ConsumerSecret: c.ConsumerSecret,
}
// create the URI
uri, err := url.Parse("https://api.bitbucket.org/1.0" + path)
if err != nil {
return err
}
if params != nil && len(params) > 0 {
uri.RawQuery = params.Encode()
}
// create the access token
token := oauth1.NewAccessToken(c.AccessToken, c.TokenSecret, nil)
// create the request
req := &http.Request{
URL: uri,
Method: method,
ProtoMajor: 1,
ProtoMinor: 1,
Close: true,
}
if values != nil && len(values) > 0 {
body := []byte(values.Encode())
buf := bytes.NewBuffer(body)
req.Body = ioutil.NopCloser(buf)
}
// add the Form data to the request
// (we'll need this in order to sign the request)
req.Form = values
// sign the request
if err := client.Sign(req, token); err != nil {
return err
}
// make the request using the default http client
resp, err := DefaultClient.Do(req)
if err != nil {
return err
}
// Read the bytes from the body (make sure we defer close the body)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
// Check for an http error status (ie not 200 StatusOK)
switch resp.StatusCode {
case 404:
return ErrNotFound
case 403:
return ErrForbidden
case 401:
return ErrNotAuthorized
case 400:
return ErrBadRequest
}
// Unmarshall the JSON response
if v != nil {
return json.Unmarshal(body, v)
}
return nil
}
func (c *Client) guest(method string, path string, params url.Values, values url.Values, v interface{}) error {
// create the URI
uri, err := url.Parse("https://api.bitbucket.org/1.0" + path)
if err != nil {
return err
}
if params != nil && len(params) > 0 {
uri.RawQuery = params.Encode()
}
// create the request
req := &http.Request{
URL: uri,
Method: method,
ProtoMajor: 1,
ProtoMinor: 1,
Close: true,
}
// add the Form values to the body
if values != nil && len(values) > 0 {
body := []byte(values.Encode())
buf := bytes.NewBuffer(body)
req.Body = ioutil.NopCloser(buf)
}
// make the request using the default http client
resp, err := DefaultClient.Do(req)
if err != nil {
return err
}
// Read the bytes from the body (make sure we defer close the body)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
// Check for an http error status (ie not 200 StatusOK)
switch resp.StatusCode {
case 404:
return ErrNotFound
case 403:
return ErrForbidden
case 401:
return ErrNotAuthorized
case 400:
return ErrBadRequest
}
// Unmarshall the JSON response
if v != nil {
return json.Unmarshal(body, v)
}
return nil
}