-
Notifications
You must be signed in to change notification settings - Fork 2
/
client.go
64 lines (55 loc) · 1.51 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
package goHttpDigestClient
import (
"io"
"io/ioutil"
"net/http"
)
// if option is set, get challenge at construct time
// if option not set, ever digest auth will send 2 request
type Client struct {
is_init bool
option ClientOption
http.Client
}
type ClientOption struct {
username string
password string
}
// create new Client instance
func NewClient(username, password string) *Client {
opt := &ClientOption{username: username, password: password}
// here need more attention
return &Client{option: *opt, is_init: false}
}
func GetChallengeFromHeader(h *http.Header) Challenge {
return NewChallenge(h.Get(KEY_WWW_Authenticate))
}
func (c *Client) Do(req *http.Request, opt *ClientOption) (*http.Response, error) {
res, err := c.Client.Do(req)
if res.StatusCode == http.StatusUnauthorized {
challenge := GetChallengeFromHeader(&res.Header)
challenge.ComputeResponse(req.Method, req.URL.RequestURI(), getStrFromIO(req.Body), opt.username, opt.password)
authorization := challenge.ToAuthorizationStr()
req.Header.Set(KEY_AUTHORIZATION, authorization)
return c.Client.Do(req)
} else {
return res, err
}
}
// From ReadCloser to string
func getStrFromIO(r io.ReadCloser) string {
if r == nil {
return ""
}
if b, err := ioutil.ReadAll(r); err == nil {
return string(b)
} else {
return ""
}
}
// static Defualt Client
var DefaultClient = &Client{is_init: true}
// Default Client Do Request
func Do(req *http.Request, opt *ClientOption) (*http.Response, error) {
return DefaultClient.Do(req, opt)
}