httpc

package module
v0.9.3 Latest Latest
Warning

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

Go to latest
Published: May 2, 2026 License: MPL-2.0 Imports: 23 Imported by: 3

README

httpc

Go Report Card GoDoc License

httpc 是一个基于 Go 标准库 net/http 构建的高级 HTTP 客户端库。它提供了链式调用、自动重试、中间件支持、响应自动解码以及详细的日志记录等功能,旨在简化日常开发中的 HTTP 请求处理。

特性

  • 流式 API:支持链式调用,轻松构建复杂的请求。
  • 自动重试:内置指数退避 (Exponential Backoff) 和抖动 (Jitter) 策略。
  • 响应解码:支持 JSON、XML、GOB、字符串及字节流的自动解码。
  • 中间件支持:允许在请求生命周期内注入自定义逻辑。
  • 性能优化:通过 sync.Pool 复用字节缓冲区,降低内存分配开销。
  • 深度可调:支持对底层 TransportDialer 的精细配置。
  • HTTP/2 & H2C:完整支持 HTTP/1.1、HTTP/2 以及非加密的 H2C 协议。

安装

go get github.com/WJQSERVER-STUDIO/httpc

快速开始

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/WJQSERVER-STUDIO/httpc"
)

type User struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

func main() {
	// 创建并配置客户端
	client := httpc.New(
		httpc.WithTimeout(15 * time.Second),
		httpc.WithDumpLog(), // 启用请求日志
	)

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	var user User
	// 链式调用发送 GET 请求并解码 JSON
	err := client.GET("https://api.example.com/users/1").
		WithContext(ctx).
		SetHeader("Accept", "application/json").
		AddQueryParam("details", "true").
		DecodeJSON(&user)

	if err != nil {
		if httpErr, ok := err.(*httpc.HTTPError); ok {
			log.Printf("HTTP Error: %d, Body: %s", httpErr.StatusCode, string(httpErr.Body))
		} else {
			log.Fatal(err)
		}
		return
	}

	fmt.Printf("User: %+v\n", user)
}

文档

更多详细指南请参阅以下文档:

核心功能

1. 请求构建器 (RequestBuilder)

RequestBuilder 提供了丰富的接口来设置请求参数:

rb := client.POST("https://api.example.com/data").
    SetHeaders(map[string]string{"Authorization": "Bearer token"}).
    SetQueryParams(map[string]string{"page": "1", "limit": "20"}).
    SetJSONBody(map[string]interface{}{"foo": "bar"})

// 执行请求并获取原始响应
resp, err := rb.Execute()
if err == nil {
    defer resp.Body.Close()
}
2. 自动重试策略

默认启用 2 次重试(共执行 3 次),支持针对特定状态码进行指数退避。

client := httpc.New(
    httpc.WithRetryOptions(httpc.RetryOptions{
        MaxAttempts:   3,
        BaseDelay:     200 * time.Millisecond,
        MaxDelay:      2 * time.Second,
        RetryStatuses: []int{429, 500, 503},
        Jitter:        true,
    }),
)
3. 中间件

中间件签名遵循 func(next http.Handler) http.Handler,方便与标准库生态集成。

func LoggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        next.ServeHTTP(w, r)
        log.Printf("%s %s took %v", r.Method, r.URL.Path, time.Since(start))
    })
}

client := httpc.New(httpc.WithMiddleware(LoggingMiddleware))
4. 详细日志记录

通过 WithDumpLog 可以输出结构化的请求调试日志,包括请求头、协议版本及底层 Transport 配置。

详细配置

选项 说明
WithTimeout 设置全局请求超时
WithUserAgent 自定义 User-Agent
WithTransport 替换或扩展底层 http.Transport
WithProtocols 配置支持的 HTTP 协议 (HTTP1/2/H2C)
WithMiddleware 注册全局中间件

错误处理

httpc 会在状态码 >= 400 时返回 *httpc.HTTPError。你可以通过它获取响应头、状态码以及响应体的前几位预览,方便调试。

许可证

本项目采用 MPL-2.0WJQserver Studio License 2.0 双重授权。您可以任选其一使用。所有权利由 satomitouka 保留,WJQserver Studio 代行相关权利。

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrRequestTimeout     = errors.New("httpc: request timeout")
	ErrMaxRetriesExceeded = errors.New("httpc: max retries exceeded")
	ErrDecodeResponse     = errors.New("httpc: failed to decode response body")
	ErrInvalidURL         = errors.New("httpc: invalid URL")
	ErrInvalidSSEStream   = errors.New("httpc: invalid SSE stream")
	ErrNoResponse         = errors.New("httpc: no response")
	ErrUseLastResponse    = errors.New("httpc: use last response")
)

错误定义

View Source
var EOF = io.EOF
View Source
var ErrShortWrite = errors.New("short write")

Functions

This section is empty.

Types

type BufferPool

type BufferPool interface {
	Get() *bytes.Buffer
	Put(*bytes.Buffer)
}

BufferPool 缓冲池接口

type Client

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

Client 主客户端结构

func New

func New(opts ...Option) *Client

New 创建客户端实例

func (*Client) DELETE

func (c *Client) DELETE(urlStr string) *RequestBuilder

func (*Client) Delete

func (c *Client) Delete(ctx context.Context, url string) (*http.Response, error)

Delete 发送 DELETE 请求

func (*Client) Do

func (c *Client) Do(req *http.Request) (*http.Response, error)

func (*Client) GET

func (c *Client) GET(urlStr string) *RequestBuilder

GET, POST, PUT, DELETE 等快捷方法

func (*Client) Get

func (c *Client) Get(url string) (*http.Response, error)

Get 发送 GET 请求

func (*Client) GetContext

func (c *Client) GetContext(ctx context.Context, url string) (*http.Response, error)

GetContext 发送带 Context 的 GET 请求

func (*Client) GetSSE added in v0.9.0

func (c *Client) GetSSE(ctx context.Context, url string) (*SSEStream, error)

GetSSE 使用 GET 请求建立一个 SSE 流.

func (*Client) HEAD

func (c *Client) HEAD(urlStr string) *RequestBuilder

func (*Client) NewRequest

func (c *Client) NewRequest(method, urlStr string, body io.Reader) (*http.Request, error)

NewRequest 创建请求,支持与 http.NewRequest 兼容

func (*Client) NewRequestBuilder

func (c *Client) NewRequestBuilder(method, urlStr string) *RequestBuilder

NewRequestBuilder 创建 RequestBuilder 实例

func (*Client) OPTIONS

func (c *Client) OPTIONS(urlStr string) *RequestBuilder

func (*Client) PATCH

func (c *Client) PATCH(urlStr string) *RequestBuilder

func (*Client) POST

func (c *Client) POST(urlStr string) *RequestBuilder

func (*Client) PUT

func (c *Client) PUT(urlStr string) *RequestBuilder

func (*Client) Post

func (c *Client) Post(ctx context.Context, url string, body io.Reader) (*http.Response, error)

Post 发送 POST 请求

func (*Client) PostGOB

func (c *Client) PostGOB(ctx context.Context, url string, body any) (*http.Response, error)

PostGOB 发送 GOB POST 请求

func (*Client) PostJSON

func (c *Client) PostJSON(ctx context.Context, url string, body any) (*http.Response, error)

PostJSON 发送 JSON POST 请求

func (*Client) PostXML

func (c *Client) PostXML(ctx context.Context, url string, body any) (*http.Response, error)

PostXML 发送 XML POST 请求

func (*Client) Put

func (c *Client) Put(ctx context.Context, url string, body io.Reader) (*http.Response, error)

Put 发送 PUT 请求

func (*Client) PutGOB

func (c *Client) PutGOB(ctx context.Context, url string, body any) (*http.Response, error)

PutGOB 发送 GOB PUT 请求

func (*Client) PutJSON

func (c *Client) PutJSON(ctx context.Context, url string, body any) (*http.Response, error)

PutJSON 发送 JSON PUT 请求

func (*Client) PutXML

func (c *Client) PutXML(ctx context.Context, url string, body any) (*http.Response, error)

PutXML 发送 XML PUT 请求

func (*Client) SetDumpLogFunc

func (c *Client) SetDumpLogFunc(dumpLog DumpLogFunc)

SetDumpLogFunc 动态设置日志记录函数

func (*Client) SetRetryOptions

func (c *Client) SetRetryOptions(opts RetryOptions)

SetRetryOptions 动态设置重试选项

func (*Client) SetTimeout

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

SetTimeout 动态设置客户端超时

type DumpLogFunc

type DumpLogFunc func(ctx context.Context, log string)

DumpLogFunc 定义日志记录函数

type HTTPError

type HTTPError struct {
	StatusCode int         // HTTP 状态码
	Status     string      // HTTP 状态文本 (e.g., "Not Found")
	Header     http.Header // 响应头 (副本)
	Body       []byte      // 响应体的前缀 (用于预览)
}

HTTPError 表示一个 HTTP 错误响应 (状态码 >= 400). 它实现了 error 接口.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type MiddlewareFunc

type MiddlewareFunc func(next http.RoundTripper) http.RoundTripper

MiddlewareFunc 是客户端中间件的类型 它接收一个 http.RoundTripper (代表下一个处理器) 并返回一个新的 http.RoundTripper

type Option

type Option func(*Client)

Option 配置选项类型

func WithBufferPool

func WithBufferPool(pool BufferPool) Option

WithBufferPool 自定义缓冲池

func WithBufferSize

func WithBufferSize(bufferSize int) Option

WithBufferSize 自定义缓冲池 Buffer 大小

func WithCheckRedirect added in v0.9.3

func WithCheckRedirect(fn func(req *http.Request, via []*http.Request) error) Option

WithCheckRedirect 设置自定义重定向检查函数。 设置后将完全接管重定向策略,WithMaxRedirects 的默认限制失效。 用户需在函数内自行实现重定向次数限制等逻辑。 返回 ErrUseLastResponse 可阻止跟随并直接返回当前 3xx 响应。 返回其他 error 将中止请求并返回该错误(响应 Body 已关闭)。 返回 nil 则允许继续重定向。

func WithDNSResolver added in v0.7.1

func WithDNSResolver(servers []string, timeout time.Duration) Option

WithDNSResolver 设置自定义DNS解析器 servers: 一个或多个DNS服务器地址, 格式为 "ip:port" (例如, "8.8.8.8:53") timeout: DNS查询的超时时间如果为0, 将使用默认超时 (5秒) 此选项会覆盖系统默认的DNS解析行为

func WithDialTimeout

func WithDialTimeout(dialTimeout time.Duration) Option

WithDialTimeout 设置 DialContext 的超时时间

func WithDumpLog

func WithDumpLog() Option

WithDumpLog 启用默认日志记录功能

func WithDumpLogFunc

func WithDumpLogFunc(dumpLog DumpLogFunc) Option

WithDumpLogFunc 自定义日志记录功能

func WithExpectContinueTimeout

func WithExpectContinueTimeout(expectContinueTimeout time.Duration) Option

WithExpectContinueTimeout 设置 ExpectContinue 超时时间

func WithFollowRedirects added in v0.9.3

func WithFollowRedirects(follow bool) Option

WithFollowRedirects 设置是否自动跟随重定向

func WithHTTPProxy added in v0.8.1

func WithHTTPProxy(proxyURL string) Option

WithHTTPProxy 设置 HTTP/HTTPS 代理 proxyURL: HTTP/HTTPS 代理地址, 例如 "http://user:password@host:port"

func WithIdleConnTimeout

func WithIdleConnTimeout(idleConnTimeout time.Duration) Option

WithIdleConnTimeout 设置空闲连接超时时间

func WithKeepAliveTimeout

func WithKeepAliveTimeout(keepAliveTimeout time.Duration) Option

WithKeepAliveTimeout 设置 KeepAlive 超时时间

func WithMaxBufferPoolSize

func WithMaxBufferPoolSize(maxBufferPool int) Option

WithMaxBufferPoolSize 自定义最大缓冲池数量

func WithMaxIdleConns

func WithMaxIdleConns(maxIdleConns int) Option

WithMaxIdleConns 设置最大空闲连接数

func WithMaxRedirects added in v0.9.3

func WithMaxRedirects(maxRedirects int) Option

WithMaxRedirects 设置最大重定向次数。 0 表示禁止跟随重定向(直接返回 3xx 响应),负值等同于 0。 默认值为 10,与 Go 标准库一致。 若同时设置了 WithCheckRedirect,自定义函数将完全接管重定向策略,此设置失效。

func WithMiddleware

func WithMiddleware(middleware ...MiddlewareFunc) Option

WithMiddleware 添加中间件

func WithProtocols

func WithProtocols(config ProtocolsConfig) Option

WithProtocols 配置客户端支持的 HTTP 协议版本

func WithRetryOptions

func WithRetryOptions(opts RetryOptions) Option

WithRetryOptions 自定义重试策略

func WithSocks5Proxy added in v0.8.1

func WithSocks5Proxy(proxyURL string) Option

WithSocks5Proxy 设置 SOCKS5 代理 proxyURL: SOCKS5 代理地址, 例如 "socks5://user:password@host:port" 如果代理不需要认证, 可以省略 user:password, 例如 "socks5://host:port"

func WithTLSHandshakeTimeout

func WithTLSHandshakeTimeout(tlsHandshakeTimeout time.Duration) Option

WithTLSHandshakeTimeout 设置 TLS 握手超时时间

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout 设置默认请求超时时间

func WithTransport

func WithTransport(t *http.Transport) Option

WithTransport 自定义 Transport,将非零字段合并到默认 Transport 中

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent 设置自定义 User-Agent

type ProtocolsConfig

type ProtocolsConfig struct {
	Http1           bool // 是否启用 HTTP/1.1
	Http2           bool // 是否启用 HTTP/2
	Http2_Cleartext bool // 是否启用 H2C
	ForceH2C        bool // 是否强制启用 H2C
}

ProtocolsConfig 协议版本配置结构体

type RequestBuilder

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

RequestBuilder 用于构建请求的结构体

func (*RequestBuilder) AddHeader

func (rb *RequestBuilder) AddHeader(key, value string) *RequestBuilder

AddHeader 添加 Header

func (*RequestBuilder) AddQueryParam

func (rb *RequestBuilder) AddQueryParam(key, value string) *RequestBuilder

AddQueryParam 添加 Query 参数

func (*RequestBuilder) Build

func (rb *RequestBuilder) Build() (*http.Request, error)

Build 构建 http.Request

func (*RequestBuilder) Bytes

func (rb *RequestBuilder) Bytes() ([]byte, error)

Bytes 获取 Bytes 响应

func (*RequestBuilder) DecodeGOB

func (rb *RequestBuilder) DecodeGOB(v any) error

DecodeGOB 解析 GOB 响应

func (*RequestBuilder) DecodeJSON

func (rb *RequestBuilder) DecodeJSON(v any) error

DecodeJSON 解析 JSON 响应

func (*RequestBuilder) DecodeXML

func (rb *RequestBuilder) DecodeXML(v any) error

DecodeXML 解析 XML 响应

func (*RequestBuilder) Execute

func (rb *RequestBuilder) Execute() (*http.Response, error)

Execute 执行请求并返回 http.Response

func (*RequestBuilder) NoDefaultHeaders

func (rb *RequestBuilder) NoDefaultHeaders() *RequestBuilder

NoDefaultHeaders 设置请求不添加默认 Header

func (*RequestBuilder) SSE added in v0.9.0

func (rb *RequestBuilder) SSE() (*SSEStream, error)

SSE 建立一个 SSE 流,并返回流式解析器.

func (*RequestBuilder) SetBody

func (rb *RequestBuilder) SetBody(body io.Reader) *RequestBuilder

SetBody 设置 Body (io.Reader)

func (*RequestBuilder) SetGOBBody

func (rb *RequestBuilder) SetGOBBody(body any) (*RequestBuilder, error)

SetGOBBody 设置GOB Body

func (*RequestBuilder) SetHeader

func (rb *RequestBuilder) SetHeader(key, value string) *RequestBuilder

SetHeader 设置 Header

func (*RequestBuilder) SetHeaders

func (rb *RequestBuilder) SetHeaders(headers map[string]string) *RequestBuilder

SetHeaders 批量设置 Headers

func (*RequestBuilder) SetJSONBody

func (rb *RequestBuilder) SetJSONBody(body any) (*RequestBuilder, error)

SetJSONBody 设置 JSON Body

func (*RequestBuilder) SetQueryParam

func (rb *RequestBuilder) SetQueryParam(key, value string) *RequestBuilder

SetQueryParam 设置 Query 参数

func (*RequestBuilder) SetQueryParams

func (rb *RequestBuilder) SetQueryParams(params map[string]string) *RequestBuilder

SetQueryParams 批量设置 Query 参数

func (*RequestBuilder) SetRawBody added in v0.8.1

func (rb *RequestBuilder) SetRawBody(body []byte) *RequestBuilder

SetRawBody 设置 Body ([]byte)

func (*RequestBuilder) SetXMLBody

func (rb *RequestBuilder) SetXMLBody(body any) (*RequestBuilder, error)

SetXMLBody 设置 XML Body

func (*RequestBuilder) Text

func (rb *RequestBuilder) Text() (string, error)

Text 获取 Text 响应

func (*RequestBuilder) WithContext

func (rb *RequestBuilder) WithContext(ctx context.Context) *RequestBuilder

WithContext 设置 Context

type RetryOptions

type RetryOptions struct {
	MaxAttempts   int
	BaseDelay     time.Duration
	MaxDelay      time.Duration
	RetryStatuses []int
	Jitter        bool // 是否启用 Jitter 抖动
}

RetryOptions 重试配置

type RoundTripperFunc

type RoundTripperFunc func(req *http.Request) (*http.Response, error)

RoundTripperFunc 是一个适配器,允许使用普通函数作为 HTTP RoundTripper

func (RoundTripperFunc) RoundTrip

func (f RoundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip 实现了 http.RoundTripper 接口

type SSEEvent added in v0.9.0

type SSEEvent struct {
	Event string
	Data  string
	Id    string
	Retry string
}

SSEEvent 表示一个服务器发送事件. 字段设计与 touka 的 SSE 事件结构保持兼容.

func (*SSEEvent) Render added in v0.9.0

func (e *SSEEvent) Render(w io.Writer) error

Render 将事件按 SSE 线格式写入指定 writer.

type SSEStream added in v0.9.0

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

SSEStream 表示一个已经建立的 SSE 流连接.

func (*SSEStream) Close added in v0.9.0

func (s *SSEStream) Close() error

Close 关闭底层 SSE 响应体.

func (*SSEStream) Next added in v0.9.0

func (s *SSEStream) Next() (*SSEEvent, error)

Next 读取下一个完整的 SSE 事件帧. 它按 SSE 协议逐行解析,并忽略注释行与空的 keepalive 块.

func (*SSEStream) Response added in v0.9.0

func (s *SSEStream) Response() *http.Response

Response 返回建立流时的原始 HTTP 响应.

Jump to

Keyboard shortcuts

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