http

package
v1.4.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 30, 2020 License: MIT Imports: 19 Imported by: 0

README

HTTP 客户端

封装http 客户端

使用

import (
  "fmt"
  "github.com/go-eyas/toolkit/http/v2"
)

func main() {
  h := http.
    TransformRequest(func(client *http.Client, req *nethttp.Request) *http.Client {
        fmt.Printf("HTTP SEND %s %s header=%v\n", req.Method, req.URL, req.Header)
        return client
    }).
    TransformResponse(func (c *http.Client, req *nethttp.Request, resp *http.Response) *http.Response {
        fmt.Printf("HTTP RECV %s %s %d\n", req.Method, req.URL, resp.StatusCode())
        if resp.StatusCode() >= 400 {
            resp.SetBody([]byte("error! error!"))	
        }   
        return resp
    }).
    Type("json").
    Use(http.AccessLogger(logger))
    Header("Authorization", "Bearer xxxxxxxxxxxxxxx").
    Header("x-test", func() string { return "in func string" })
    Header("x-test2", func(cli *http.Client) string { return "in func string2" })
    UserAgent("your custom user-agent").
    Cookie("sid", "sgf2fdas").
    BaseURL("https://api.github.com").
  	Config(&http.Config{
  	    BaseURL: "/api", // 叠加	
    })

  res, err := h.Get("/repos/eyasliu/blog/issues", map[string]string{
    "per_page": 1,
  })

  // 获取字符串
  fmt.Printf("print string: %s\n", res.String())
  // 获取字节
  fmt.Printf("print bytes: %v", res.Byte())

  // 绑定结构体
  s := []struct {
		URL   string `json:"url"`
		Title string `json:"title"`
  }{}
  res.JSON(&s)
  fmt.Printf("print Struct: %v", s)

  // 使用代理
  res, err := http.Proxy("http://127.0.0.1:1080").Get("https://www.google.com", map[string]string{
		"hl": "zh-Hans",
  })
  fmt.Printf("google html: %s", res.String())
}

使用指南

请求示例
// get url, 第二个参数可忽略
http.Get("https://api.github.com")

// 带查询参数
http.Get("https://www.google.com", "hl=zh-Hans") // 查询参数可以是字符串
http.Get("https://www.google.com", map[string]string{
	"hl": "zh-Hans",
}) // 可以是map
http.Get("https://www.google.com", struct{
  HL string `json:"hl"`
}{"zh-Hans"}) // 可以是结构体,使用json key作为查询参数的key

// post 请求,第二个参数可忽略
http.Post("https://api.github.com")

// post 带json body参数
http.Post("https://api.github.com", `{"hello": "world"}`) // 可以是字符串
http.Post("https://api.github.com", map[string]interface{}{"hello": "world"}) // 可以是map
http.Post("https://api.github.com", struct{
  Hello string `json:"hello"`
}{"world"}) // 可以是结构体,使用json 序列化字符串

// post 带 查询参数,带json body 参数
http.Query("hl=zh-Hans").Post("https://api.github.com", `{"hello": "world"}`)

// post form表单
http.Type("multipart").Post("https://api.github.com", map[string]interface{}{"hello": "world"})
// post 上传文件,会以表单提交
http.Post("https://api.github.com", "name=@file:./example_file.txt&name=@file:./example_file.txt")

// post 上传多文件,使用file文件流
http.Post("https://api.github.com", "name=@file:./example_file.txt&name=@file:./example_file.txt")

// put, 和post完全一致
http.Put("https://api.github.com")

// delete, 和post完全一致
http.Del("https://api.github.com")

// patch, 和post完全一致
http.Patch("https://api.github.com")

// head, 和get完全一致
http.Head("https://api.github.com")

// options, 和get完全一致
http.Options("https://api.github.com")
响应示例
res, err := http.Options("https://api.github.com", nil)

// 错误信息
if err != nil {
  err.Error() // 错误信息
}
res.Error() // 与上面等价

// 响应数据
// 将响应数据转为字符串
var str string = res.String() 

// 将响应数据转为字节
var bt []byte = res.Byte()

// 获取响应状态码
var statusCode = res.Status()

// 获取响应的 header
var headers http.Header = res.Header()

// 获取响应的 cookies
var cookies []*http.Cookie = res.Cookies()

// 与 json 结构体绑定
type ResTest struct {
  Hello string `json:"hello"`
}
rt := &ResTest{}
res.JSON(rt)

// 与 xml 结构体绑定
type ResTest struct {
Hello string `xml:"hello"`
}
rt := &ResTest{}
res.XML(rt)

注意:

  • http的响应状态码 >= 400 时会被视为错误,err 值是 fmt.Errorf("http status code %d", statusCode)
链式安全调用

默认是链式安全的,即在链式调用的时候,返回的 *http.Client 是个新的实例,不会影响之前链式阶段的配置,如

cli := http.BaseURL("http://xxx.com")
cli2 := cli.BaseURL("/api") // 需要重新给 cli 赋值才会让其生效

cli.Get("/users") // GET http://xxx.com/users
cli2.Get("/users") // GET http://xxx.com/api/users

如果不希望链式安全调用,可以关闭

cli := http.Safe(false) // 关闭后要赋值一次

// 下面的赋值都将生效,链式安全关闭后,赋值和不赋值没有区别
cli.BaseURL("http://xxx.com")
cli = cli.BaseURL("/api") // 可赋值,可也不赋值,没有区别

cli.Get("/users") // GET http://xxx.com/api/users

// 可以后面再进行开启
cli = cli.Safe(true)
cli = cli.BaseURL("/v1") // 开启后如果不赋值将不会生效

提前设置通用项
h := http.Header("Authorization", "Bearer xxxxxxxxxxxxxxx"). // 设置header
    UserAgent("your custom user-agent"). // 设置 useragent
    Timeout(10 * time.Second). // 设置请求超时时间
    Query("lang=zh_ch"). // 设置查询参数
    Proxy("http://127.0.0.1:1080") // 设置代理
    

h.Get("xxxx", nil)
中间件支持

可以增加请求中间件和响应中间件,用于在请求或响应中改变内部操作

http.TransformRequest(func(client *http.Client, req *nethttp.Request) *http.Client {
  fmt.Printf("HTTP SEND %s %s header=%v\n", req.Method, req.URL, req.Header)
  return client
}).
TransformResponse(func (c *http.Client, req *nethttp.Request, resp *http.Response) *http.Response {
  fmt.Printf("HTTP RECV %s %s %d\n", req.Method, req.URL, resp.StatusCode())
  if resp.StatusCode() >= 400 {
    resp.SetBody([]byte("error! error!"))
  }
  return resp
})
代理设置

默认会获取环境变量 http_proxy 的值使用代理,但是可以手动指定

http.Proxy("http://127.0.0.1:1080").Get("https://www.google.com", map[string]string{
	"hl": "zh-Hans",
})

// 临时取消代理
http.Proxy("").Get("https://www.google.com", map[string]string{
	"hl": "zh-Hans",
})
提交方式

也就是 Type(t string) 函数支持的值

"text/html" uses "html"
"application/json" uses "json"
"application/xml" uses "xml"
"text/plain" uses "text"
"application/x-www-form-urlencoded" uses "urlencoded", "form" or "form-data"

如果是文件上传,会自动设置为 multipart,无需手动指定

godoc

API 文档

Tranks

部分 api 和代码借鉴了以下库

  • GoFrame 部分api,思路借鉴自 GoFrame
  • axios 中间件思路来源于 axios

Documentation

Index

Constants

View Source
const (
	TypeJSON       = "json"
	TypeXML        = "xml"
	TypeUrlencoded = "urlencoded"
	TypeForm       = "form"
	TypeFormData   = "form-data"
	TypeHTML       = "html"
	TypeText       = "text"
	TypeMultipart  = "multipart"
)

Types we support.

Variables

View Source
var Logger = AccessLogger(consoleLogger{})
View Source
var Types = map[string]string{
	TypeJSON:       "application/json",
	TypeXML:        "application/xml",
	TypeForm:       "application/x-www-form-urlencoded",
	TypeFormData:   "application/x-www-form-urlencoded",
	TypeUrlencoded: "application/x-www-form-urlencoded",
	TypeHTML:       "text/html",
	TypeText:       "text/plain",
	TypeMultipart:  "multipart/form-data",
}

Functions

This section is empty.

Types

type Client

type Client struct {
	http.Client
	// contains filtered or unexported fields
}

func BaseURL

func BaseURL(url string) *Client

BaseURL 设置url前缀

func Cookie(k string, v string) *Client

Cookie 设置请求 Cookie

func Header(key, val string) *Client

Header 设置请求 Header

func New

func New() *Client

创建 HTTP Client 实例

func Proxy

func Proxy(url string) *Client

Proxy 设置请求代理

func Query

func Query(query interface{}) *Client

Query 设置请求代理

func Retry

func Retry(n int) *Client

BaseURL 设置url前缀

func Timeout

func Timeout(timeout time.Duration) *Client

Timeout 设置请求代理

func Type

func Type(name string) *Client

Type 请求提交方式,默认json

func Use

func Use(mdl ClientMiddleware) *Client

UseRequest 增加请求中间件

func UseResponse

func UseResponse(mdl responseMiddlewareHandler) *Client

UseResponse 增加响应中间件

func UserAgent

func UserAgent(name string) *Client

UserAgent 设置请求 user-agent

func (*Client) BaseURL

func (c *Client) BaseURL(url string) *Client

BaseURL 设置url前缀

func (*Client) Clone

func (c *Client) Clone() *Client

func (*Client) Config added in v1.4.4

func (c *Client) Config(conf *ClientConfig) *Client

Config 批量设置 HTTP Client 的配置项

func (*Client) Cookie

func (c *Client) Cookie(k string, v string) *Client

Cookie 设置请求 Cookie

func (*Client) Del

func (c *Client) Del(url string, args ...interface{}) (*Response, error)

Del 发起 del 请求

func (*Client) DoRequest

func (c *Client) DoRequest(method, u string, data ...interface{}) (resp *Response, err error)

DoRequest 发起请求, data 参数在 GET, HEAD 请求时被解析为查询参数,在其他方法请求时根据 Content-Type 解析为其他数据类型,如 json, url-form-encoding, xml 等等

func (*Client) Get

func (c *Client) Get(url string, args ...interface{}) (*Response, error)

Get 发起 get 请求

func (*Client) Head

func (c *Client) Head(url string, data ...interface{}) (*Response, error)

Head 发起 head 请求

func (*Client) Header

func (c *Client) Header(k string, v interface{}) *Client

Header 设置请求 Header

func (*Client) Options

func (c *Client) Options(url string, args ...interface{}) (*Response, error)

Options 发起 get 请求

func (*Client) Patch

func (c *Client) Patch(url string, args ...interface{}) (*Response, error)

Patch 发起 patch 请求

func (*Client) Post

func (c *Client) Post(url string, args ...interface{}) (*Response, error)

Post 发起 post 请求

func (*Client) Proxy

func (c *Client) Proxy(url string) *Client

Proxy 设置请求代理

func (*Client) Put

func (c *Client) Put(url string, args ...interface{}) (*Response, error)

Put 发起 put 请求

func (*Client) Query

func (c *Client) Query(query interface{}) *Client

Query 增加查询参数, 如果设置过多次,将会叠加拼接

func (*Client) Retry

func (c *Client) Retry(n int) *Client

BaseURL 设置url前缀

func (*Client) Safe

func (c *Client) Safe(s ...bool) *Client

Safe 链式安全模式,启用后,链式调用时对所有配置的修改都是逐个叠加,并且不会影响链式前配置,默认开启

func (*Client) SetClient added in v1.4.4

func (c *Client) SetClient(rawClient http.Client) *Client

func (*Client) Timeout

func (c *Client) Timeout(timeout time.Duration) *Client

Timeout 请求超时时间

func (*Client) TransformRequest

func (c *Client) TransformRequest(h requestMiddlewareHandler) *Client

TransformRequest 增加请求中间件,可以在请求发起前对整个请求做前置处理,比如修改 body, header, proxy, url, 配置项等等,也可以获取请求的各种数据,如自定义日志,类似于 axios 的 transformRequest

func (*Client) TransformResponse

func (c *Client) TransformResponse(h responseMiddlewareHandler) *Client

TransformResponse 增加响应中间件,可以在收到请求后第一时间对请求做处理,如验证 status code,验证 body 数据,甚至重置 body 数据,更改响应等等任何操作,类似于 axios 的 transformResponse

func (*Client) Type

func (c *Client) Type(ty string) *Client

Type 请求提交方式,默认json

func (*Client) Use

func (c *Client) Use(mdl ClientMiddleware) *Client

Use 应用中间件,实现了 TransformRequest 和 TransformResponse 接口的中间件,如 http.Use(http.AccessLogger()),通常用于成对的请求响应处理

func (*Client) UserAgent

func (c *Client) UserAgent(name string) *Client

UserAgent 设置请求 user-agent

type ClientConfig added in v1.4.4

type ClientConfig struct {
	TransformRequest  requestMiddlewareHandler  // 请求中间件
	TransformResponse responseMiddlewareHandler // 响应中间件
	Headers           map[string]string         // 预设 Header
	Cookies           map[string]string         // 预设请求 Cookie
	Type              string                    // 预设请求数据类型, 该配置为空时忽略
	UserAgent         string                    // 预设 User-Agent, 该配置为空时忽略
	Proxy             string                    // 预设请求代理,该配置为空时忽略
	BaseURL           string                    // 预设 url 前缀,叠加
	Query             interface{}               // 预设请求查询参数
	Timeout           time.Duration             // 请求超时时间,该配置为 0 时忽略
	Retry             int                       // 重试次数,该配置为 0 时忽略
}

批量设置 HTTP Client 的配置项

type ClientMiddleware

type ClientMiddleware interface {
	TransformRequest(*Client, *http.Request) *Client
	TransformResponse(*Client, *http.Request, *Response) *Response
}

type HttpLogger

type HttpLogger struct {
	Logger           printLogger
	MaxLoggerBodyLen int64
}

打印 HTTP 请求响应日志

func AccessLogger

func AccessLogger(logger printLogger, bodyLimit ...int64) *HttpLogger

func (*HttpLogger) TransformRequest

func (l *HttpLogger) TransformRequest(c *Client, req *http.Request) *Client

打印 HTTP 请求日志

func (*HttpLogger) TransformResponse

func (l *HttpLogger) TransformResponse(c *Client, req *http.Request, resp *Response) *Response

打印 HTTP 响应日志 warning: 会先读取一遍 Response.Body,如果该中间件导致了 http 下载异常问题,请关闭该中间件

type Response

type Response struct {
	Client   *Client
	Request  *http.Request
	Response *http.Response

	Err    *ResponseError
	IsRead bool
	// contains filtered or unexported fields
}

func Del

func Del(url string, data ...interface{}) (*Response, error)

Del 发起 delete 请求,body 是请求带的参数,可使用json字符串或者结构体

func Get

func Get(url string, data ...interface{}) (*Response, error)

Get 发起 get 请求, query 查询参数

func Head(url string, data ...interface{}) (*Response, error)

Head 发起 head 请求

func Options

func Options(url string, data ...interface{}) (*Response, error)

Options 发起 options 请求,query 查询参数

func Patch

func Patch(url string, data ...interface{}) (*Response, error)

Patch 发起 patch 请求,body 是请求带的参数,可使用json字符串或者结构体

func Post

func Post(url string, data ...interface{}) (*Response, error)

Post 发起 post 请求,body 是请求带的参数,可使用json字符串或者结构体

func Put

func Put(url string, data ...interface{}) (*Response, error)

Put 发起 put 请求,body 是请求带的参数,可使用json字符串或者结构体

func (*Response) AddError

func (rp *Response) AddError(err error)

AddError 手动增加错误

func (*Response) Body

func (rp *Response) Body() (bt []byte)

Body 获取响应的原始数据

func (*Response) Byte added in v1.4.4

func (rp *Response) Byte() (bt []byte)

Byte 同 Body()

func (*Response) Cookie added in v1.4.4

func (rp *Response) Cookie() []*http.Cookie

func (*Response) Error

func (rp *Response) Error() string

Error 实现 error interface

func (*Response) GetError

func (rp *Response) GetError() error

GetError 获取错误

func (*Response) Header added in v1.4.4

func (rp *Response) Header() http.Header

func (*Response) JSON

func (rp *Response) JSON(v interface{}) error

JSON 使用 JSON 解析响应 Body 数据

func (*Response) ReadAllBody

func (rp *Response) ReadAllBody() (bt []byte, err error)

ReadAllBody 读取响应的 Body 流

func (*Response) SetBody added in v1.4.1

func (rp *Response) SetBody(bt []byte)

SetBody 重置响应的 Body

func (*Response) Status

func (rp *Response) Status() int

Status StatusCode 别名

func (*Response) StatusCode

func (rp *Response) StatusCode() int

StatusCode 获取 HTTP 响应状态码

func (*Response) String

func (rp *Response) String() string

String 将响应的 Body 数据转成字符串

func (*Response) XML added in v1.4.4

func (rp *Response) XML(v interface{}) error

XML 使用 XML 解析响应 Body 数据

type ResponseError

type ResponseError struct {
	// contains filtered or unexported fields
}

func (*ResponseError) Add

func (e *ResponseError) Add(err error)

func (*ResponseError) Error

func (e *ResponseError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL