requests

package module
v0.0.0-...-bfda6a9 Latest Latest
Warning

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

Go to latest
Published: Apr 6, 2025 License: Apache-2.0 Imports: 22 Imported by: 4

README

requests

Requests is a simple, yet elegant, Go HTTP client and server library for Humans™ ✨🍰✨
Go Reference Apache V2 License Build status go report requests on Sourcegraph

Overview

Requests is inspired by Python's famous requests library, bringing a more elegant, intuitive approach to HTTP in Go. This library simplifies common HTTP tasks while remaining fully compatible with Go's standard library.

API Reference and User Guide available on Read the Docs
Supported Features & Best–Practices
  • Safe Close resp.Body
  • Only depends on standard library
  • Streaming Downloads
  • Chunked HTTP Requests
  • Keep-Alive & Connection Pooling
  • Sessions with Cookie Persistence
  • Basic & Digest Authentication
  • Implement http.RoundTripper fully compatible with net/http
  • Offer File System to upload or download files easily

Installation

go get github.com/golang-io/requests

Quick Start

Get Started
cat github.com/golang-io/examples/example_1/main.go
package main

import (
	"context"
	"github.com/golang-io/requests"
)

func main() {
	sess := requests.New(requests.URL("https://httpbin.org/uuid"), requests.TraceLv(4))
	_, _ = sess.DoRequest(context.TODO())
}

$ go run github.com/golang-io/examples/example_1/main.go
* Connect: httpbin.org:80
* Got Conn: <nil> -> <nil>
* Connect: httpbin.org:443
* Resolved Host: httpbin.org
* Resolved DNS: [50.16.63.240 107.21.176.221 3.220.97.10 18.208.241.22], Coalesced: false, err=<nil>
* Trying ConnectStart tcp 50.16.63.240:443...
* Completed connection: tcp 50.16.63.240:443, err=<nil>
* SSL HandshakeComplete: true
* Got Conn: 192.168.255.10:64170 -> 50.16.63.240:443
> GET /uuid HTTP/1.1
> Host: httpbin.org
> User-Agent: Go-http-client/1.1
> Accept-Encoding: gzip
> 
> 

< HTTP/1.1 200 OK
< Content-Length: 53
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Origin: *
< Connection: keep-alive
< Content-Type: application/json
< Date: Fri, 22 Mar 2024 12:16:04 GMT
< Server: gunicorn/19.9.0
< 
< {
<   "uuid": "ba0a69b3-25d0-415e-b998-030120052f4d"
< }
< 

* 

  • use requests.New() method to create a global session for http client.
  • use requests.URL() method to define a sever address to request.
  • use requests.Trace() method to open http trace mode.
  • use DoRequest() method to send a request from local to remote server.

Also, you can using simple method like requests.Get(), requests.Post() etc. to send a request, and return *http.Response, error. This is fully compatible with net/http method.

Simple Get
package main

import (
	"bytes"
	"github.com/golang-io/requests"
	"log"
)

func main() {
	resp, err := requests.Get("https://httpbin.org/get")
	if err != nil {
		log.Fatalln(err)
	}
	defer resp.Body.Close()
	var buf bytes.Buffer
	if _, err := buf.ReadFrom(resp.Body); err != nil {
		log.Fatalln(err)
	}
	log.Println(buf.String())
}
% go run github.com/golang-io/examples/example_2/main.go
2024/03/22 20:31:12 {
  "args": {}, 
  "headers": {
    "Host": "httpbin.org", 
    "User-Agent": "Go-http-client/1.1", 
    "X-Amzn-Trace-Id": "Root=1-65fd7a10-781981cc111ac4662510a87e"
  }, 
  "origin": "43.132.141.21", 
  "url": "https://httpbin.org/get"
}

Auto handle response.Body

There are many negative cases, network connections not released or memory cannot be released, because the response.Body is not closed correctly. To solve this problem, requests offers type *requests.Response. The response body sample read from response.Content. There is no need to declare a bunch of variables and duplicate code just for reading the response.Body. Additionally, the body will be safely closed, regardless of whether you need to read it or not.

For example:

package main

import (
	"context"
	"github.com/golang-io/requests"
	"log"
)

func main() {
	sess := requests.New(requests.URL("http://httpbin.org/post"))
	resp, err := sess.DoRequest(context.TODO(), requests.MethodPost, requests.Body("Hello world"))
	log.Printf("resp=%s, err=%v", resp.Content, err)
}

% go run github.com/golang-io/examples/example_3/main.go
2024/03/22 20:43:25 resp={
  "args": {}, 
  "data": "Hello world", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Content-Length": "11", 
    "Host": "httpbin.org", 
    "User-Agent": "Go-http-client/1.1", 
    "X-Amzn-Trace-Id": "Root=1-65fd7ced-718974b7528527911b977e1e"
  }, 
  "json": null, 
  "origin": "127.0.0.1", 
  "url": "http://httpbin.org/post"
}
, err=<nil>

Usage
Common Rules

All parameters can be set at two levels: session and request.

Session parameters are persistent and apply to all requests made with that session:

// Create a session with persistent parameters
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.Header("User-Agent", "My Custom Agent"),
    requests.Timeout(10),
)

// All requests from this session will inherit these parameters
resp1, _ := sess.DoRequest(context.TODO(), requests.Path("/users"))
resp2, _ := sess.DoRequest(context.TODO(), requests.Path("/posts"))

Request parameters are provisional and only apply to the specific request:

sess := requests.New(requests.URL("https://api.example.com"))

// This parameter only applies to this specific request
resp, _ := sess.DoRequest(context.TODO(), 
    requests.Path("/users"),
    requests.Query("limit", "10"),
)
Debugging - Log/Trace

Requests provides multiple trace levels to help with debugging:

package main

import (
	"context"
	"github.com/golang-io/requests"
)

func main() {
	sess := requests.New(
		requests.URL("https://httpbin.org/get"),
		requests.Trace(),  // Most detailed tracing
	)
	
	// The trace output will show detailed connection info
	resp, _ := sess.DoRequest(context.TODO())
}

You can also use custom loggers:

sess := requests.New(
    requests.URL("https://httpbin.org/get"),
    requests.Logger(myCustomLogger),
)
Set Body

Requests supports multiple body formats:

// String body
resp, _ := sess.DoRequest(context.TODO(), 
    requests.MethodPost,
    requests.Body("Hello World"),
)

// JSON body (automatically serialized)
resp, _ := sess.DoRequest(context.TODO(), 
    requests.MethodPost,
    requests.JSON(map[string]interface{}{
        "name": "John",
        "age": 30,
    }),
)

// Form data
resp, _ := sess.DoRequest(context.TODO(), 
    requests.MethodPost,
    requests.Form(map[string]string{
        "username": "johndoe",
        "password": "secret",
    }),
)

// File upload
resp, _ := sess.DoRequest(context.TODO(), 
    requests.MethodPost,
    requests.FileUpload("file", "/path/to/file.pdf", "application/pdf"),
)
Set Header

Headers can be set at both session and request levels:

// Session-level headers
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.Header("Authorization", "Bearer token123"),
    requests.Header("Accept", "application/json"),
)

// Request-level headers (will override session headers if same key)
resp, _ := sess.DoRequest(context.TODO(),
    requests.Header("X-Custom-Header", "value"),
    requests.Headers(map[string]string{
        "Content-Type": "application/json",
        "X-Request-ID": "abc123",
    }),
)
Authentication

Requests supports various authentication methods:

// Basic authentication
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.BasicAuth("username", "password"),
)

// Bearer token
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.BearerAuth("your-token-here"),
)

// Custom auth scheme
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.Auth("CustomScheme", "credentials"),
)
Gzip Compression

Requests handles gzip compression automatically:

// Automatic handling of gzip responses
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.AutoDecompress(true),  // Default is true
)

// Send compressed request
resp, _ := sess.DoRequest(context.TODO(),
    requests.MethodPost,
    requests.Gzip("large content here"),
)
Request and Response Middleware

Add middleware to process requests or responses:

// Request middleware
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.RequestMiddleware(func(req *http.Request) error {
        req.Header.Add("X-Request-Time", time.Now().String())
        return nil
    }),
)

// Response middleware
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.ResponseMiddleware(func(resp *http.Response) error {
        log.Printf("Response received with status: %d", resp.StatusCode)
        return nil
    }),
)
Client and Transport Middleware

Customize the underlying HTTP client behavior:

// Custom transport
transport := &http.Transport{
    MaxIdleConns:        100,
    MaxIdleConnsPerHost: 10,
    IdleConnTimeout:     30 * time.Second,
}

sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.Transport(transport),
)

// Transport middleware
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.TransportMiddleware(func(rt http.RoundTripper) http.RoundTripper {
        return requests.RoundTripFunc(func(req *http.Request) (*http.Response, error) {
            startTime := time.Now()
            resp, err := rt.RoundTrip(req)
            duration := time.Since(startTime)
            log.Printf("Request took %v", duration)
            return resp, err
        })
    }),
)
Proxy

Configure proxies for your requests:

// HTTP proxy
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.Proxy("http://proxy.example.com:8080"),
)

// SOCKS5 proxy
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.Proxy("socks5://proxy.example.com:1080"),
)

// Per-request proxy
resp, _ := sess.DoRequest(context.TODO(),
    requests.Proxy("http://special-proxy.example.com:8080"),
)
Retry

Automatic retry functionality for failed requests:

sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.Retry(3, 500*time.Millisecond),  // 3 retries with 500ms delay
    // Custom retry condition
    requests.RetryCondition(func(resp *http.Response, err error) bool {
        return err != nil || resp.StatusCode >= 500
    }),
)
Sessions with Cookies

Maintain a persistent session with cookies:

// Create a session that automatically handles cookies
sess := requests.New(
    requests.URL("https://api.example.com"),
    requests.CookieJar(true),  // Enable cookie jar
)

// Login to establish session
_, _ = sess.DoRequest(context.TODO(),
    requests.MethodPost,
    requests.Path("/login"),
    requests.Form(map[string]string{
        "username": "johndoe",
        "password": "secret",
    }),
)

// Subsequent requests will include session cookies automatically
resp, _ := sess.DoRequest(context.TODO(),
    requests.Path("/profile"),
)
Streaming Downloads

Handle large file downloads efficiently:

package main

import (
	"context"
	"github.com/golang-io/requests"
	"io"
	"os"
)

func main() {
	file, _ := os.Create("large-file.zip")
	defer file.Close()
	
	sess := requests.New(requests.URL("https://example.com/large-file.zip"))
	
	// Stream the download directly to file
	resp, _ := sess.DoRequest(context.TODO(), requests.Stream(true))
	
	_, _ = io.Copy(file, resp.Body)
	resp.Body.Close()
}

Advanced Examples

REST API Client
package main

import (
	"context"
	"fmt"
	"github.com/golang-io/requests"
	"log"
)

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

func main() {
	apiClient := requests.New(
		requests.URL("https://jsonplaceholder.typicode.com"),
		requests.Header("Accept", "application/json"),
		requests.Timeout(10),
	)
	
	// GET users
	resp, err := apiClient.DoRequest(context.TODO(),
		requests.Path("/users"),
	)
	if err != nil {
		log.Fatalf("Error: %v", err)
	}
	
	var users []User
	if err := resp.JSON(&users); err != nil {
		log.Fatalf("Parse error: %v", err)
	}
	
	fmt.Printf("Found %d users\n", len(users))
	
	// POST a new user
	newUser := User{Name: "John Doe", Email: "john@example.com"}
	resp, err = apiClient.DoRequest(context.TODO(),
		requests.MethodPost,
		requests.Path("/users"),
		requests.JSON(newUser),
	)
	if err != nil {
		log.Fatalf("Error: %v", err)
	}
	
	var createdUser User
	if err := resp.JSON(&createdUser); err != nil {
		log.Fatalf("Parse error: %v", err)
	}
	
	fmt.Printf("Created user with ID: %d\n", createdUser.ID)
}

Server

package main

import (
	"context"
	"fmt"
	"github.com/go-chi/chi/v5/middleware"
	"github.com/golang-io/requests"
	"github.com/gorilla/websocket"
	"io"
	"log"
	"net/http"
)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func ws(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer conn.Close()
	for {
		messageType, message, err := conn.ReadMessage()
		if err != nil {
			log.Printf("Failed to read message: %v", err)
			break
		}

		log.Printf("Received message: %s", message)

		err = conn.WriteMessage(messageType, message)
		if err != nil {
			log.Printf("Failed to write message: %v", err)
			break
		}
	}
}

func main() {
	r := requests.NewServeMux(
		requests.URL("0.0.0.0:1234"),
		requests.Use(middleware.Recoverer, middleware.Logger),
		requests.Use(func(next http.Handler) http.Handler {
			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				next.ServeHTTP(w, r)
			})
		}),
	)
	r.Route("/panic", func(w http.ResponseWriter, r *http.Request) {
		panic("panic test")
	})
	r.Route("/echo", func(w http.ResponseWriter, r *http.Request) {
		_, _ = io.Copy(w, r.Body)
	})
	r.Route("/ping", func(w http.ResponseWriter, r *http.Request) {
		_, _ = fmt.Fprintf(w, "pong\n")
	}, requests.Use(func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			next.ServeHTTP(w, r)
		})
	}))
	r.Route("/ws", ws)
	err := requests.ListenAndServe(context.Background(), r)
	fmt.Println(err)
}

Then, do some requests...

% curl http://127.0.0.1:1234/echo
% curl http://127.0.0.1:1234/ping
pong

And, there are some logs from server.

% go run github.com/golang-io/examples/server/example_1/main.go
2024-03-27 02:47:47 http serve 0.0.0.0:1234
2024/03/27 02:47:59 "GET http://127.0.0.1:1234/echo HTTP/1.1" from 127.0.0.1:60922 - 000 0B in 9.208µs
path use {}
2024/03/27 02:48:06 "GET http://127.0.0.1:1234/ping HTTP/1.1" from 127.0.0.1:60927 - 200 5B in 5.125µs

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Acknowledgments

Documentation

Index

Constants

View Source
const RequestId = "Request-Id"

Variables

View Source
var (
	MethodGet  = Method("GET")
	MethodPost = Method("POST")
)

Method http method

View Source
var ErrHandler = func(err string, code int) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, err, code)
	})
}

ErrHandler handler err

Functions

func CORS

func CORS() func(next http.Handler) http.Handler

func CopyBody

func CopyBody(b io.ReadCloser) (*bytes.Buffer, io.ReadCloser, error)

CopyBody reads all of b to memory and then returns two equivalent ReadClosers yielding the same bytes.

It returns an error if the initial slurp of all bytes fails. It does not attempt to make the returned ReadClosers have identical error-matching behavior.

func Delete

func Delete(url, contentType string, body io.Reader) (*http.Response, error)

Delete send delete request

func GenId

func GenId(id ...string) string

GenId gen random id.

func Get

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

Get send get request

func Head(url string) (resp *http.Response, err error)

Head send post request

func ListenAndServe

func ListenAndServe(ctx context.Context, h http.Handler, opts ...Option) error

ListenAndServe listens on the TCP network address addr and then calls [Serve] with handler to handle requests on incoming connections. Accepted connections are configured to enable TCP keep-alives.

The handler is typically nil, in which case [DefaultServeMux] is used.

ListenAndServe always returns a non-nil error.

func Log

func Log(format string, v ...any)

Log print

func LogS

func LogS(ctx context.Context, stat *Stat)

LogS supply default handle Stat, print to stdout.

func NewRequestWithContext

func NewRequestWithContext(ctx context.Context, options Options) (*http.Request, error)

NewRequestWithContext creates a new HTTP request with the given context and options. It handles: - Converting the request body to an appropriate io.Reader - Setting the request method and URL - Appending path segments - Setting query parameters - Setting headers and cookies

Returns the constructed http.Request and any error encountered during creation.

func PUT

func PUT(url, contentType string, body io.Reader) (*http.Response, error)

PUT send put request

func ParseBody

func ParseBody(r io.ReadCloser) (*bytes.Buffer, error)

ParseBody parse body from `Request.Body`.

func Post

func Post(url string, contentType string, body io.Reader) (*http.Response, error)

Post send post request

func PostForm

func PostForm(url string, data url.Values) (*http.Response, error)

PostForm send post request, content-type = application/x-www-form-urlencoded

func SSE

func SSE() func(next http.Handler) http.Handler

SSE returns a middleware function that enables Server-Sent Events support. The middleware:

  • Sets appropriate SSE headers (Content-Type, Cache-Control, etc.)
  • Creates a ServerSentEvents wrapper for the response writer
  • Ensures proper stream termination via deferred End() call
  • Enables CORS support for cross-origin requests

func Socket

func Socket(ctx context.Context, opts ...Option) (net.Conn, error)

func WarpHandler

func WarpHandler(next http.Handler) func(http.Handler) http.Handler

WarpHandler warp `http.Handler`.

func WarpRoundTripper

func WarpRoundTripper(next http.RoundTripper) func(http.RoundTripper) http.RoundTripper

WarpRoundTripper wraps an http.RoundTripper instance. This function returns a new decorator function that adds additional functionality to an existing RoundTripper.

Types

type Node

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

Node trie node

func NewNode

func NewNode(path string, h http.Handler, opts ...Option) *Node

NewNode new

func (*Node) Add

func (node *Node) Add(path string, h http.HandlerFunc, opts ...Option)

Add node

func (*Node) Find

func (node *Node) Find(path string) *Node

Find 按照最长的匹配原则,/a/b/c/会优先返回/a/b/c/,其次返回/a/b/c,再返回/a/b,再返回/a,再返回/

func (*Node) Print

func (node *Node) Print()

Print print trie tree struct

type Option

type Option func(*Options)

Option func

func BasicAuth

func BasicAuth(username, password string) Option

BasicAuth base auth

func Body

func Body(body any) Option

Body request body

func CertKey

func CertKey(cert, key string) Option

CertKey is cert and key file.

func Cookie(cookie http.Cookie) Option

Cookie cookie

func Cookies

func Cookies(cookies ...http.Cookie) Option

Cookies cookies

func Form

func Form(form url.Values) Option

Form set form, content-type is

func Gzip

func Gzip(body any) Option

Gzip request gzip compressed

func Header(k, v string) Option

Header header

func Headers

func Headers(kv map[string]string) Option

Headers headers

func Host

func Host(host string) Option

Host set net/http.Request.Host. 在客户端,请求的Host字段(可选地)用来重写请求的Host头。 如过该字段为"",Request.Write方法会使用URL字段的Host。

func LocalAddr

func LocalAddr(addr net.Addr) Option

LocalAddr local ip for tcp: &net.TCPAddr{IP: ip} for unix: &net.UnixAddr{Net: "unix", Name: "xxx")}

func Logf

func Logf(f func(context.Context, *Stat)) Option

Logf xxx

func MaxConns

func MaxConns(conn int) Option

MaxConns set max connections

func Method

func Method(method string) Option

Method set method

func OnShutdown

func OnShutdown(f func(*http.Server)) Option

func OnStart

func OnStart(f func(*http.Server)) Option

func Param

func Param(k string, v ...string) Option

Param params

func Params

func Params(query map[string]string) Option

Params add query args

func Path

func Path(path string) Option

Path set path

func Proxy

func Proxy(addr string) Option

Proxy set proxy addr os.Setenv("HTTP_PROXY", "http://127.0.0.1:9743") os.Setenv("HTTPS_PROXY", "https://127.0.0.1:9743") https://stackoverflow.com/questions/14661511/setting-up-proxy-for-http-client

func RoundTripper

func RoundTripper(tr http.RoundTripper) Option

RoundTripper set default `*http.Transport` by customer define.

func Setup

func Setup(fn ...func(tripper http.RoundTripper) http.RoundTripper) Option

Setup is used for client middleware

func Stream

func Stream(stream func(int64, []byte) error) Option

Stream handle func

func Timeout

func Timeout(timeout time.Duration) Option

Timeout client timeout duration

func Trace

func Trace(mLimit ...int) Option

Trace trace print

func URL

func URL(url string) Option

URL set client to dial connection use http transport or unix socket. IF using socket connection. you must set unix in session, and set http in request. For example, sess := requests.New(requests.URL("unix:///tmp/requests.sock")) sess.DoRequest(context.Background(), requests.URL("http://path?k=v"), requests.Body("12345")) https://old.lubui.com/2021/07/26/golang-socket-file/

func Use

func Use(fn ...func(http.Handler) http.Handler) Option

Use is used for server middleware

func Verify

func Verify(verify bool) Option

Verify verify

type Options

type Options struct {
	Method   string
	URL      string
	Path     []string
	RawQuery url.Values

	Header   http.Header
	Cookies  []http.Cookie
	Timeout  time.Duration
	MaxConns int
	Verify   bool

	Transport        http.RoundTripper
	HttpRoundTripper []func(http.RoundTripper) http.RoundTripper

	Handler     http.Handler
	HttpHandler []func(http.Handler) http.Handler
	OnStart     func(*http.Server)
	OnShutdown  func(*http.Server)

	// client session used
	LocalAddr net.Addr
	Proxy     func(*http.Request) (*url.URL, error)
	// contains filtered or unexported fields
}

Options request

type Response

type Response struct {
	*http.Request                // 原始 HTTP 请求
	*http.Response               // 原始 HTTP 响应
	StartAt        time.Time     // 请求开始时间
	Cost           time.Duration // 请求耗时
	Content        *bytes.Buffer // 响应内容缓存
	Err            error         // 请求过程中的错误
}

Response 包装了 http.Response 结构体,提供了额外的功能: 1. 记录请求开始时间和耗时 2. 缓存响应内容 3. 错误处理 4. 统计信息收集

func (*Response) Error

func (resp *Response) Error() string

Error 实现 error 接口 返回请求过程中的错误信息

func (*Response) Stat

func (resp *Response) Stat() *Stat

Stat 返回请求的统计信息 包括请求/响应的详细信息、耗时等

func (*Response) String

func (resp *Response) String() string

String 实现 fmt.Stringer 接口 返回响应内容的字符串形式

type ResponseWriter

type ResponseWriter struct {
	http.ResponseWriter

	StatusCode int           // HTTP 响应状态码
	Content    *bytes.Buffer // 响应内容的缓存
	// contains filtered or unexported fields
}

ResponseWriter 包装了 http.ResponseWriter 接口,提供了额外的功能: 1. 记录响应状态码 2. 缓存响应内容 3. 支持并发安全的读写操作

func (*ResponseWriter) Flush

func (w *ResponseWriter) Flush()

Flush 实现 http.Flusher 接口 将缓冲的数据立即发送到客户端

func (*ResponseWriter) Hijack

func (w *ResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)

Hijack 实现 http.Hijacker 接口 允许接管 HTTP 连接

func (*ResponseWriter) Push

func (w *ResponseWriter) Push(target string, opts *http.PushOptions) error

Push 实现 http.Pusher 接口 支持 HTTP/2 服务器推送功能

func (*ResponseWriter) Read

func (w *ResponseWriter) Read(b []byte) (int, error)

Read 实现 io.Reader 接口 从内容缓存中读取数据

func (*ResponseWriter) Write

func (w *ResponseWriter) Write(b []byte) (int, error)

Write 实现 io.Writer 接口 将数据同时写入原始 ResponseWriter 和内容缓存

func (*ResponseWriter) WriteHeader

func (w *ResponseWriter) WriteHeader(statusCode int)

WriteHeader 设置 HTTP 响应状态码 该方法确保状态码只被设置一次

type RoundTripperFunc

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

RoundTripperFunc is a functional implementation of the http.RoundTripper interface. It allows converting regular functions to the RoundTripper interface, facilitating functional extensions.

func (RoundTripperFunc) RoundTrip

func (fn RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip implements the http.RoundTripper interface. It directly calls the underlying function to complete the request sending and response receiving.

type ServeMux

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

ServeMux implement ServeHTTP interface.

func NewServeMux

func NewServeMux(opts ...Option) *ServeMux

NewServeMux new router.

func (*ServeMux) Handle

func (mux *ServeMux) Handle(path string, h http.Handler, opts ...Option)

Handle set handler pattern path to handler

func (*ServeMux) HandleFunc

func (mux *ServeMux) HandleFunc(path string, f func(http.ResponseWriter, *http.Request), opts ...Option)

HandleFunc set func pattern path to handle path cannot override, so if your path not work, maybe it is already exists!

func (*ServeMux) Pprof

func (mux *ServeMux) Pprof()

Pprof debug, 必须使用这个路径访问:/debug/pprof/

func (*ServeMux) Print

func (mux *ServeMux) Print()

Print print trie tree struct.

func (*ServeMux) Redirect

func (mux *ServeMux) Redirect(source, target string)

Redirect set redirect path to handle

func (*ServeMux) Route

func (mux *ServeMux) Route(path string, v any, opts ...Option)

Route set any pattern path to handle

func (*ServeMux) ServeHTTP

func (mux *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implement http.Handler interface 首先对路由进行校验,不满足的话直接404 其次执行RequestEach对`http.Request`进行处理,如果处理失败的话,直接返回400 最后处理中间件`func(next http.Handler) http.Handler`

func (*ServeMux) Use

func (mux *ServeMux) Use(fn ...func(http.Handler) http.Handler)

Use can set middleware which compatible with net/http.ServeMux.

type Server

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

Server server

func NewServer

func NewServer(ctx context.Context, h http.Handler, opts ...Option) *Server

NewServer new server, opts is not add to ServeMux

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() (err error)

ListenAndServe listens on the TCP network address srv.Addr and then calls [Serve] or [ServeTLS] to handle requests on incoming (TLS) connections. Accepted connections are configured to enable TCP keep-alives.

If srv.Addr is blank, ":http" is used.

Filenames containing a certificate and matching private key for the server must be provided if neither the Server's TLSConfig.Certificates nor TLSConfig.GetCertificate are populated. If the certificate is signed by a certificate authority, the certFile should be the concatenation of the server's certificate, any intermediates, and the CA's certificate.

ListenAndServe(TLS) always returns a non-nil error. After Server.Shutdown or [Server.Close], the returned error is [ErrServerClosed].

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the server without interrupting any active connections.

type ServerSentEvents

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

ServerSentEvents implements http.Handler interface for Server-Sent Events (SSE) streaming. It wraps a http.ResponseWriter to provide SSE-specific functionality.

func (*ServerSentEvents) End

func (s *ServerSentEvents) End()

End terminates the SSE stream by writing two newlines. This should be called when the stream is complete.

func (*ServerSentEvents) Header

func (s *ServerSentEvents) Header() http.Header

Header implements http.ResponseWriter interface. It returns the header map that will be sent by WriteHeader.

func (*ServerSentEvents) Read

func (s *ServerSentEvents) Read(b []byte) ([]byte, error)

Read parses an SSE message from the given byte slice. It handles different types of SSE events (empty, event, data). Returns:

  • For data events: returns the event value
  • For empty or event lines: returns nil, nil
  • For unknown events: returns nil and an error

func (*ServerSentEvents) Send

func (s *ServerSentEvents) Send(name string, b []byte) (int, error)

Send writes a named SSE event with formatted data to the stream. It automatically flushes the response after writing. Parameters:

  • name: The event name (e.g., "data", "event", etc.)
  • b: The byte slice containing the event data

func (*ServerSentEvents) Write

func (s *ServerSentEvents) Write(b []byte) (int, error)

Write implements http.ResponseWriter interface. It writes the byte slice as a data event to the SSE stream.

func (*ServerSentEvents) WriteHeader

func (s *ServerSentEvents) WriteHeader(statusCode int)

WriteHeader implements http.ResponseWriter interface. It writes the HTTP status code to the response.

type Session

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

Session httpclient session Clients and Transports are safe for concurrent use by multiple goroutines for efficiency should only be created once and re-used. so, session is also safe for concurrent use by multiple goroutines.

func New

func New(opts ...Option) *Session

New session

func (*Session) Do

func (s *Session) Do(ctx context.Context, opts ...Option) (*http.Response, error)

Do send a request and return `http.Response`. DO NOT forget close `resp.Body`. transport【http.Transport】-> http.client.Do -> transport.RoundTrip

func (*Session) DoRequest

func (s *Session) DoRequest(ctx context.Context, opts ...Option) (*Response, error)

DoRequest send a request and return a response, and is safely close `resp.Body`.

func (*Session) HTTPClient

func (s *Session) HTTPClient() *http.Client

HTTPClient returns the http.Client that is configured to be used for HTTP requests.

func (*Session) RoundTrip

func (s *Session) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip implements the RoundTripper interface. Like the `http.RoundTripper` interface, the error types returned by RoundTrip are unspecified.

func (*Session) RoundTripper

func (s *Session) RoundTripper(opts ...Option) http.RoundTripper

RoundTripper returns a configured http.RoundTripper. It applies all registered middleware in reverse order.

func (*Session) Transport

func (s *Session) Transport() *http.Transport

Transport returns *http.Transport.

type Stat

type Stat struct {
	RequestId string `json:"RequestId"`
	StartAt   string `json:"StartAt"`
	Cost      int64  `json:"Cost"`

	Request struct {
		// RemoteAddr is remote addr in server side,
		// For client requests, it is unused.
		RemoteAddr string `json:"RemoteAddr"`

		// URL is Request.URL
		// For client requests, is request addr. contains schema://ip:port/path/xx
		// For server requests, is only path. eg: /api/v1/xxx
		URL    string            `json:"URL"`
		Method string            `json:"Method"`
		Header map[string]string `json:"Header"`
		Body   any               `json:"Body"`
	} `json:"Request"`
	Response struct {

		// URL is server addr(http://127.0.0.1:8080).
		// For client requests, it is unused.
		URL           string            `json:"URL"`
		Header        map[string]string `json:"Header"`
		Body          any               `json:"Body"`
		StatusCode    int               `json:"StatusCode"`
		ContentLength int64             `json:"ContentLength"`
	} `json:"Response"`
	Err string `json:"Err"`
}

Stat stats

func (*Stat) Print

func (stat *Stat) Print() string

Print is used for server side

func (*Stat) String

func (stat *Stat) String() string

String implement fmt.Stringer interface.

Jump to

Keyboard shortcuts

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