Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
9f29f019ad |
10
client.go
10
client.go
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/14 4:11 下午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
@ -29,13 +29,13 @@ type Client struct {
|
||||
|
||||
const (
|
||||
defaultUserAgent = "DobyteHttpClient"
|
||||
|
||||
|
||||
HeaderUserAgent = "User-Agent"
|
||||
HeaderContentType = "Content-Type"
|
||||
HeaderAuthorization = "Authorization"
|
||||
HeaderCookie = "Cookie"
|
||||
HeaderHost = "Host"
|
||||
|
||||
|
||||
ContentTypeJson = "application/json"
|
||||
ContentTypeXml = "application/xml"
|
||||
ContentTypeFormData = "form-data"
|
||||
@ -57,7 +57,7 @@ func NewClient() *Client {
|
||||
middlewares: make([]MiddlewareFunc, 0),
|
||||
}
|
||||
client.headers[HeaderUserAgent] = defaultUserAgent
|
||||
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/16 2:54 下午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
@ -10,8 +10,8 @@ package http_test
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/dobyte/http"
|
||||
|
||||
"git.echol.cn/loser/http"
|
||||
)
|
||||
|
||||
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlc2MiOjE2MjgwNDAzMjYxNTQ2MzIwMDAsImV4cCI6MTYyODIyMDMyNiwiaWF0IjoxNjI4MDQwMzI2LCJpZCI6MX0.KM19c6URIih-5SyycYIjNAdSiPKxMQEz3DoROm0N3nw"
|
||||
@ -23,13 +23,13 @@ func TestClient_Request(t *testing.T) {
|
||||
}).Use(func(r *http.Request) (*http.Response, error) {
|
||||
return nil, errors.New("Invalid params.")
|
||||
})
|
||||
|
||||
|
||||
resp, err := client.Request(http.MethodGet, "/common/regions")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
t.Log(resp.Response.Status)
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ func TestClient_Post(t *testing.T) {
|
||||
r.Request.Header.Set("Client-Type", "2")
|
||||
return r.Next()
|
||||
})
|
||||
|
||||
|
||||
type updateRegionArg struct {
|
||||
Id int `json:"id"`
|
||||
Pid int `json:"pid"`
|
||||
@ -50,7 +50,7 @@ func TestClient_Post(t *testing.T) {
|
||||
Name string `json:"name"`
|
||||
Sort int `json:"sort"`
|
||||
}
|
||||
|
||||
|
||||
data := updateRegionArg{
|
||||
Id: 1,
|
||||
Pid: 0,
|
||||
@ -58,7 +58,7 @@ func TestClient_Post(t *testing.T) {
|
||||
Name: "北京市",
|
||||
Sort: 0,
|
||||
}
|
||||
|
||||
|
||||
if resp, err := client.Put("/backend/region/update-region", data); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
@ -74,7 +74,7 @@ func TestClient_Post(t *testing.T) {
|
||||
|
||||
func TestClient_Download(t *testing.T) {
|
||||
url := "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"
|
||||
|
||||
|
||||
if path, err := http.NewClient().Download(url, "./"); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
|
21
download.go
21
download.go
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/26 1:59 下午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
@ -8,10 +8,9 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/http/internal"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/dobyte/http/internal"
|
||||
)
|
||||
|
||||
var contentTypeToFileSuffix = map[string]string{
|
||||
@ -55,33 +54,33 @@ func (d *Download) Download(url, dir string, filename ...string) (string, error)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
||||
var path string
|
||||
|
||||
|
||||
if len(filename) > 0 {
|
||||
path = strings.TrimRight(dir, string(os.PathSeparator)) + string(os.PathSeparator) + filename[0]
|
||||
} else {
|
||||
path = d.genFilePath(resp, dir)
|
||||
}
|
||||
|
||||
|
||||
if err = internal.SaveToFile(path, resp.ReadBytes()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
||||
return path, nil
|
||||
}
|
||||
|
||||
// genFilePath generate file path based on response content type
|
||||
func (d *Download) genFilePath(resp *Response, dir string) string {
|
||||
path := strings.TrimRight(dir, string(os.PathSeparator)) + string(os.PathSeparator) + internal.RandStr(16)
|
||||
|
||||
|
||||
if suffix := internal.GetFileType(resp.ReadBytes()); suffix != "" {
|
||||
path += "." + suffix
|
||||
}
|
||||
|
||||
|
||||
if internal.Exists(path) {
|
||||
return d.genFilePath(resp, dir)
|
||||
}
|
||||
|
||||
|
||||
return path
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/26 5:00 下午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
@ -68,20 +68,20 @@ func String(any interface{}) string {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
if i, ok := v.(stringInterface); ok {
|
||||
return i.String()
|
||||
}
|
||||
|
||||
|
||||
if i, ok := v.(errorInterface); ok {
|
||||
return i.Error()
|
||||
}
|
||||
|
||||
|
||||
var (
|
||||
rv = reflect.ValueOf(v)
|
||||
kind = rv.Kind()
|
||||
)
|
||||
|
||||
|
||||
switch kind {
|
||||
case reflect.Chan,
|
||||
reflect.Map,
|
||||
@ -96,11 +96,11 @@ func String(any interface{}) string {
|
||||
case reflect.String:
|
||||
return rv.String()
|
||||
}
|
||||
|
||||
|
||||
if kind == reflect.Ptr {
|
||||
return String(rv.Elem().Interface())
|
||||
}
|
||||
|
||||
|
||||
if b, e := json.Marshal(v); e != nil {
|
||||
return fmt.Sprint(v)
|
||||
} else {
|
||||
@ -211,16 +211,16 @@ func Scan(b []byte, any interface{}) error {
|
||||
rv = reflect.ValueOf(v)
|
||||
kind = rv.Kind()
|
||||
)
|
||||
|
||||
|
||||
if kind != reflect.Ptr {
|
||||
return fmt.Errorf("can't unmarshal %T", v)
|
||||
}
|
||||
|
||||
|
||||
switch kind = rv.Elem().Kind(); kind {
|
||||
case reflect.Array, reflect.Slice, reflect.Map, reflect.Struct:
|
||||
return json.Unmarshal(b, v)
|
||||
}
|
||||
|
||||
|
||||
return fmt.Errorf("can't unmarshal %T", v)
|
||||
}
|
||||
}
|
||||
@ -231,4 +231,4 @@ func UnsafeStringToBytes(s string) []byte {
|
||||
|
||||
func UnsafeBytesToString(b []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&b))
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/26 4:59 下午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
@ -29,19 +29,19 @@ func SaveToFile(path string, data []byte) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(0666))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
|
||||
if n, err := f.Write(data); err != nil {
|
||||
return err
|
||||
} else if n < len(data) {
|
||||
return io.ErrShortWrite
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/26 4:51 下午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
@ -17,12 +17,12 @@ var seedStr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
// RandStr generate a string of specified length.
|
||||
func RandStr(length int) (lastStr string) {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
|
||||
pos, seedLen := 0, len(seedStr)
|
||||
for i := 0; i < length; i++ {
|
||||
pos = rand.Intn(seedLen)
|
||||
lastStr += seedStr[pos : pos+1]
|
||||
}
|
||||
|
||||
|
||||
return lastStr
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/26 6:21 下午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
@ -81,21 +81,21 @@ func bytesToHexString(stream []byte) string {
|
||||
if stream == nil || len(stream) <= 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
var (
|
||||
hv string
|
||||
res = bytes.Buffer{}
|
||||
temp = make([]byte, 0)
|
||||
)
|
||||
|
||||
|
||||
for _, v := range stream {
|
||||
if hv = hex.EncodeToString(append(temp, v&0xFF)); len(hv) < 2 {
|
||||
res.WriteString(strconv.FormatInt(int64(0), 10))
|
||||
}
|
||||
|
||||
|
||||
res.WriteString(hv)
|
||||
}
|
||||
|
||||
|
||||
return res.String()
|
||||
}
|
||||
|
||||
@ -105,16 +105,16 @@ func GetFileType(stream []byte) string {
|
||||
fileType string
|
||||
fileCode = bytesToHexString(stream)
|
||||
)
|
||||
|
||||
|
||||
fileTypeMap.Range(func(key, value interface{}) bool {
|
||||
if strings.HasPrefix(fileCode, strings.ToLower(key.(string))) ||
|
||||
strings.HasPrefix(key.(string), strings.ToLower(fileCode)) {
|
||||
fileType = value.(string)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
|
||||
return fileType
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/16 3:47 下午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
@ -28,9 +28,9 @@ func BuildParams(params interface{}) string {
|
||||
params = nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m := make(map[string]interface{})
|
||||
|
||||
|
||||
if params != nil {
|
||||
if b, err := json.Marshal(params); err != nil {
|
||||
return String(params)
|
||||
@ -40,25 +40,25 @@ func BuildParams(params interface{}) string {
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
urlEncode := true
|
||||
|
||||
|
||||
if len(m) == 0 {
|
||||
return String(params)
|
||||
}
|
||||
|
||||
|
||||
for k, v := range m {
|
||||
if strings.Contains(k, fileUploadingKey) || strings.Contains(String(v), fileUploadingKey) {
|
||||
urlEncode = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var (
|
||||
s = ""
|
||||
str = ""
|
||||
)
|
||||
|
||||
|
||||
for k, v := range m {
|
||||
if len(str) > 0 {
|
||||
str += "&"
|
||||
@ -69,6 +69,6 @@ func BuildParams(params interface{}) string {
|
||||
}
|
||||
str += k + "=" + s
|
||||
}
|
||||
|
||||
|
||||
return str
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/16 9:47 上午
|
||||
* @Desc: request's middleware
|
||||
*/
|
||||
@ -27,6 +27,6 @@ func (m *middleware) Next() (*Response, error) {
|
||||
return m.resp, m.err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return m.resp, m.err
|
||||
}
|
||||
|
41
request.go
41
request.go
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/16 9:40 上午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.echol.cn/loser/http/internal"
|
||||
"io"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
@ -23,8 +24,6 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dobyte/http/internal"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -70,7 +69,7 @@ func (r *Request) request(method, url string, data ...interface{}) (resp *Respon
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
if count := len(r.client.middlewares); count > 0 {
|
||||
handlers := make([]MiddlewareFunc, 0, count+1)
|
||||
handlers = append(handlers, r.client.middlewares...)
|
||||
@ -86,7 +85,7 @@ func (r *Request) request(method, url string, data ...interface{}) (resp *Respon
|
||||
} else {
|
||||
resp, err = r.call()
|
||||
}
|
||||
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
@ -94,7 +93,7 @@ func (r *Request) request(method, url string, data ...interface{}) (resp *Respon
|
||||
func (r *Request) prepare(method, url string, data ...interface{}) (req *http.Request, err error) {
|
||||
method = strings.ToUpper(method)
|
||||
url = r.client.baseUrl + url
|
||||
|
||||
|
||||
var params string
|
||||
if len(data) > 0 {
|
||||
switch data[0].(type) {
|
||||
@ -121,10 +120,10 @@ func (r *Request) prepare(method, url string, data ...interface{}) (req *http.Re
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if method == MethodGet {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
|
||||
|
||||
if params != "" {
|
||||
switch r.client.headers[HeaderContentType] {
|
||||
case ContentTypeJson, ContentTypeXml:
|
||||
@ -137,7 +136,7 @@ func (r *Request) prepare(method, url string, data ...interface{}) (req *http.Re
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if req, err = http.NewRequest(method, url, buffer); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -147,7 +146,7 @@ func (r *Request) prepare(method, url string, data ...interface{}) (req *http.Re
|
||||
buffer = bytes.NewBuffer(nil)
|
||||
writer = multipart.NewWriter(buffer)
|
||||
)
|
||||
|
||||
|
||||
for _, item := range strings.Split(params, "&") {
|
||||
array := strings.Split(item, "=")
|
||||
if len(array[1]) > 6 && strings.Compare(array[1][0:6], fileUploadingKey) == 0 {
|
||||
@ -178,11 +177,11 @@ func (r *Request) prepare(method, url string, data ...interface{}) (req *http.Re
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if err = writer.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
if req, err = http.NewRequest(method, url, buffer); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
@ -205,13 +204,13 @@ func (r *Request) prepare(method, url string, data ...interface{}) (req *http.Re
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if r.client.ctx != nil {
|
||||
req = req.WithContext(r.client.ctx)
|
||||
} else {
|
||||
req = req.WithContext(context.Background())
|
||||
}
|
||||
|
||||
|
||||
if len(r.client.headers) > 0 {
|
||||
for key, value := range r.client.headers {
|
||||
if key != "" {
|
||||
@ -219,7 +218,7 @@ func (r *Request) prepare(method, url string, data ...interface{}) (req *http.Re
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if len(r.client.cookies) > 0 {
|
||||
var cookies = make([]string, 0)
|
||||
for key, value := range r.client.cookies {
|
||||
@ -229,18 +228,18 @@ func (r *Request) prepare(method, url string, data ...interface{}) (req *http.Re
|
||||
}
|
||||
req.Header.Set(HeaderCookie, strings.Join(cookies, ";"))
|
||||
}
|
||||
|
||||
|
||||
if host := req.Header.Get(HeaderHost); host != "" {
|
||||
req.Host = host
|
||||
}
|
||||
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// call nitiate an HTTP request and return the response data.
|
||||
func (r *Request) call() (resp *Response, err error) {
|
||||
resp = &Response{Request: r.Request}
|
||||
|
||||
|
||||
for {
|
||||
if resp.Response, err = r.client.Do(r.Request); err != nil {
|
||||
if resp.Response != nil {
|
||||
@ -248,7 +247,7 @@ func (r *Request) call() (resp *Response, err error) {
|
||||
log.Printf(`%+v`, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if r.retryCount > 0 {
|
||||
r.retryCount--
|
||||
time.Sleep(r.retryInterval)
|
||||
@ -259,6 +258,6 @@ func (r *Request) call() (resp *Response, err error) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
17
response.go
17
response.go
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @Author: fuxiao
|
||||
* @Email: 576101059@qq.com
|
||||
* @Author: Echo
|
||||
* @Email: 1711788888@qq.com
|
||||
* @Date: 2021/8/15 4:56 下午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
@ -8,11 +8,10 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/http/internal"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/dobyte/http/internal"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
@ -28,7 +27,7 @@ func (r *Response) ReadBytes() []byte {
|
||||
if r == nil || r.Response == nil {
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
|
||||
if r.body == nil {
|
||||
var err error
|
||||
r.mu.Lock()
|
||||
@ -37,7 +36,7 @@ func (r *Response) ReadBytes() []byte {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return r.body
|
||||
}
|
||||
|
||||
@ -67,7 +66,7 @@ func (r *Response) HasHeader(key string) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@ -86,7 +85,7 @@ func (r *Response) GetHeaders() map[string]interface{} {
|
||||
headers[k] = v[0]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return headers
|
||||
}
|
||||
|
||||
@ -96,7 +95,7 @@ func (r *Response) HasCookie(key string) bool {
|
||||
r.cookies = r.GetCookies()
|
||||
}
|
||||
_, ok := r.cookies[key]
|
||||
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user