2023-06-06 10:59:13 +08:00
|
|
|
package request
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/http/cookiejar"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
|
|
|
BeforeRequest func(req *http.Request) (err error)
|
|
|
|
AfterRequest func(req *http.Request, res *http.Response) (err error)
|
|
|
|
|
|
|
|
Client struct {
|
|
|
|
baseUrl string
|
|
|
|
Authorization Authorization
|
|
|
|
client *http.Client
|
|
|
|
cookieJar *cookiejar.Jar
|
|
|
|
interceptorRequest []BeforeRequest
|
|
|
|
interceptorResponse []AfterRequest
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
func (client *Client) stashUri(urlPath string) string {
|
|
|
|
var (
|
|
|
|
pos int
|
|
|
|
)
|
|
|
|
if len(urlPath) == 0 {
|
|
|
|
return client.baseUrl
|
|
|
|
}
|
|
|
|
if pos = strings.Index(urlPath, "//"); pos == -1 {
|
|
|
|
if client.baseUrl != "" {
|
|
|
|
if urlPath[0] != '/' {
|
|
|
|
urlPath = "/" + urlPath
|
|
|
|
}
|
|
|
|
return client.baseUrl + urlPath
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return urlPath
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) BeforeRequest(cb BeforeRequest) *Client {
|
|
|
|
client.interceptorRequest = append(client.interceptorRequest, cb)
|
|
|
|
return client
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) AfterRequest(cb AfterRequest) *Client {
|
|
|
|
client.interceptorResponse = append(client.interceptorResponse, cb)
|
|
|
|
return client
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) SetBaseUrl(s string) *Client {
|
|
|
|
client.baseUrl = strings.TrimSuffix(s, "/")
|
|
|
|
return client
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) SetCookieJar(cookieJar *cookiejar.Jar) *Client {
|
|
|
|
client.client.Jar = cookieJar
|
|
|
|
return client
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) SetClient(httpClient *http.Client) *Client {
|
|
|
|
client.client = httpClient
|
|
|
|
if client.cookieJar != nil {
|
|
|
|
client.client.Jar = client.cookieJar
|
|
|
|
}
|
|
|
|
return client
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) SetTransport(transport http.RoundTripper) *Client {
|
|
|
|
client.client.Transport = transport
|
|
|
|
return client
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) Get(urlPath string) *Request {
|
|
|
|
return newRequest(http.MethodGet, client.stashUri(urlPath), client)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) Put(urlPath string) *Request {
|
|
|
|
return newRequest(http.MethodPut, client.stashUri(urlPath), client)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) Post(urlPath string) *Request {
|
|
|
|
return newRequest(http.MethodPost, client.stashUri(urlPath), client)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) Delete(urlPath string) *Request {
|
|
|
|
return newRequest(http.MethodDelete, client.stashUri(urlPath), client)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *Client) execute(r *Request) (res *http.Response, err error) {
|
|
|
|
var (
|
|
|
|
n int
|
|
|
|
reader io.Reader
|
|
|
|
)
|
|
|
|
if r.contentType == "" && r.body != nil {
|
|
|
|
r.contentType = r.detectContentType(r.body)
|
|
|
|
}
|
|
|
|
if r.body != nil {
|
2023-06-06 18:14:00 +08:00
|
|
|
if reader, err = r.readRequestBody(r.contentType, r.body); err != nil {
|
2023-06-06 10:59:13 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if r.rawRequest, err = http.NewRequest(r.method, r.uri, reader); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for k, vs := range r.header {
|
|
|
|
for _, v := range vs {
|
|
|
|
r.rawRequest.Header.Add(k, v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if r.contentType != "" {
|
|
|
|
r.rawRequest.Header.Set("Content-Type", r.contentType)
|
|
|
|
}
|
|
|
|
if client.Authorization != nil {
|
|
|
|
r.rawRequest.Header.Set("Authorization", client.Authorization.Token())
|
|
|
|
}
|
|
|
|
if r.context != nil {
|
|
|
|
r.rawRequest = r.rawRequest.WithContext(r.context)
|
|
|
|
}
|
|
|
|
n = len(client.interceptorRequest)
|
|
|
|
for i := n - 1; i >= 0; i-- {
|
|
|
|
if err = client.interceptorRequest[i](r.rawRequest); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if r.rawResponse, err = client.client.Do(r.rawRequest); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
n = len(client.interceptorResponse)
|
|
|
|
for i := n - 1; i >= 0; i-- {
|
|
|
|
if err = client.interceptorResponse[i](r.rawRequest, r.rawResponse); err != nil {
|
|
|
|
_ = r.rawResponse.Body.Close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return r.rawResponse, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func New() *Client {
|
|
|
|
client := &Client{
|
|
|
|
client: http.DefaultClient,
|
|
|
|
interceptorRequest: make([]BeforeRequest, 0, 10),
|
|
|
|
interceptorResponse: make([]AfterRequest, 0, 10),
|
|
|
|
}
|
|
|
|
client.cookieJar, _ = cookiejar.New(nil)
|
|
|
|
client.client.Jar = client.cookieJar
|
|
|
|
return client
|
|
|
|
}
|