12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 |
- package isapi
- import (
- "bytes"
- "io/ioutil"
- "net/http"
- )
- // AuthTransport 实现接口http.RoundTripper,自定义RoundTripper处理认证
- type AuthTransport struct {
- Username string
- Password string
- Transport http.RoundTripper
- }
- func NewAuthTransport(username, password string) *AuthTransport {
- t := &AuthTransport{
- Username: username,
- Password: password,
- }
- t.Transport = http.DefaultTransport
- return t
- }
- func (t *AuthTransport) RoundTrip(req *http.Request) (*http.Response, error) {
- req2 := new(http.Request)
- *req2 = *req
- //复制header
- req2.Header = make(http.Header)
- for k, s := range req.Header {
- req2.Header[k] = s
- }
- // 复制body
- if req.Body != nil {
- buf, _ := ioutil.ReadAll(req.Body)
- req.Body = ioutil.NopCloser(bytes.NewBuffer(buf))
- req2.Body = ioutil.NopCloser(bytes.NewBuffer(buf))
- }
- //
- resp, err := t.Transport.RoundTrip(req)
- if err != nil || resp.StatusCode != 401 {
- return resp, err
- }
- //↓未认证逻辑-----------
- authChal := resp.Header.Get("WWW-Authenticate")
- c := NewChallenge(authChal)
- authResp := c.Authorize(t.Username, t.Password, req.Method, req.URL.Path)
- resp.Body.Close()
- //todo nonce并未重用,可以优化
- req2.Header.Set("Authorization", authResp.String())
- return t.Transport.RoundTrip(req2)
- }
|