This commit is contained in:
loser 2022-10-31 17:22:49 +08:00
parent 63c8b46474
commit 9f29f019ad
11 changed files with 96 additions and 99 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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))
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}