touka

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: May 4, 2026 License: MPL-2.0 Imports: 48 Imported by: 24

README

Touka(灯花)框架

Touka(灯花) 是一个基于 Go 语言构建的多层次、高性能 Web 框架。其设计目标是为开发者提供更直接的控制、有效的扩展能力,以及针对特定场景的行为优化

文档

我们提供了详尽的文档来帮助您快速上手并深入了解 Touka:

快速上手
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"time"

	"github.com/fenthope/reco"
	"github.com/infinite-iroha/touka"
)

func main() {
	r := touka.Default() // 使用带 Recovery 中间件的默认引擎

	// 配置日志记录器 (可选)
	logConfig := reco.Config{
		Level:      reco.LevelDebug,
		Mode:       reco.ModeText,
		Output:     os.Stdout,
		Async:      true,
	}
	r.SetLoggerCfg(logConfig)

	// 配置统一错误处理器
	r.SetErrorHandler(func(c *touka.Context, code int, err error) {
		c.JSON(code, touka.H{"error_code": code, "message": http.StatusText(code)})
		c.GetLogger().Errorf("发生HTTP错误: %d, 路径: %s, 错误: %v", code, c.Request.URL.Path, err)
	})

	// 注册路由
	r.GET("/hello/:name", func(c *touka.Context) {
		name := c.Param("name")
		query := c.DefaultQuery("mood", "happy")
		c.String(http.StatusOK, "Hello, %s! You seem %s.", name, query)
	})

	// 启动服务器(通过 WithGracefulShutdown 启用优雅关闭)
	log.Println("Touka Server starting on :8080...")
	if err := r.Run(touka.WithAddr(":8080"), touka.WithGracefulShutdown(10*time.Second)); err != nil {
		log.Fatalf("Touka server failed to start: %v", err)
	}
}

中间件支持

内置
  • Recovery: r.Use(touka.Recovery()) (已包含在 touka.Default() 中)
第三方 (fenthope)

贡献

我们欢迎任何形式的贡献,无论是错误报告、功能建议还是代码提交。请遵循项目的贡献指南。

相关项目

  • gin: Touka 在路由和 API 设计上参考了 Gin。
  • reco: Touka 框架的默认日志库。
  • httpc: 一个现代化且易用的 HTTP Client,作为 Touka 框架 Context 携带的 HTTPC。

许可证

本项目基于 Mozilla Public License, v. 2.0 许可。

tree.go 部分代码源自 ginhttprouter,其原始许可为 BSD-style。

Documentation

Overview

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2026 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2026 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2026 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2025 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Copyright 2024 WJQSERVER. All rights reserved. All rights reserved by WJQSERVER, related rights can be exercised by the infinite-iroha organization.

Copyright 2013 Julien Schmidt. All rights reserved. Use of this source code is governed by a BSD-style license that can be found at https://github.com/julienschmidt/httprouter/blob/master/LICENSE This tree.go is gin's fork, you can see https://github.com/gin-gonic/gin/blob/master/tree.go

Index

Constants

View Source
const MaxSkippedNodesCap = 256

Variables

View Source
var (
	ErrInputFSisNil     = errors.New("input FS is nil")
	ErrMethodNotAllowed = errors.New("method not allowed")
)
View Source
var (
	MethodGet     = "GET"
	MethodHead    = "HEAD"
	MethodPost    = "POST"
	MethodPut     = "PUT"
	MethodPatch   = "PATCH"
	MethodDelete  = "DELETE"
	MethodConnect = "CONNECT"
	MethodOptions = "OPTIONS"
	MethodTrace   = "TRACE"
)

维护一个Methods列表

View Source
var ErrBodyTooLarge = fmt.Errorf("body too large")

ErrBodyTooLarge 是当读取的字节数超过 MaxBytesReader 设置的限制时返回的错误. 将其定义为可导出的变量, 方便调用方使用 errors.Is 进行判断.

View Source
var MethodsSet = map[string]struct{}{
	MethodGet:     {},
	MethodHead:    {},
	MethodPost:    {},
	MethodPut:     {},
	MethodPatch:   {},
	MethodDelete:  {},
	MethodConnect: {},
	MethodOptions: {},
	MethodTrace:   {},
}
View Source
var TempSkippedNodesPool = sync.Pool{
	New: func() any {

		s := make([]skippedNode, 0, MaxSkippedNodesCap)
		return &s
	},
}

TempSkippedNodesPool 存储 *[]skippedNode 以复用内存

Functions

func AcquireErrorCapturingResponseWriter

func AcquireErrorCapturingResponseWriter(c *Context) *errorCapturingResponseWriter

AcquireErrorCapturingResponseWriter 从对象池获取一个 errorCapturingResponseWriter 实例 必须在处理完成后调用 ReleaseErrorCapturingResponseWriter

func BytesToString

func BytesToString(b []byte) string

BytesToString 将字节切片转换为字符串, 不进行内存分配. 更多详情, 请参见 https://github.com/golang/go/issues/53003#issuecomment-1140276077. 注意: 此函数使用 unsafe 包, 应谨慎使用, 因为它可能导致内存不安全.

func CloseLogger

func CloseLogger(logger *reco.Logger)

func CreateTestContext

func CreateTestContext(w http.ResponseWriter) (c *Context, r *Engine)

CreateTestContext 为测试创建一个 *Context 和一个关联的 *Engine。 它使用 httptest.NewRecorder() (如果传入的 w 为 nil) 来捕获响应。 返回的 Context 已经过初始化,其 Writer 指向提供的 ResponseWriter (或新创建的 Recorder), 其 Request 是一个默认的 "GET /" 请求,并且其 engine 字段指向返回的 Engine 实例。

参数:

  • w (http.ResponseWriter): 可选的。如果为 nil,函数内部会创建一个 httptest.ResponseRecorder。 通常在测试中,你会传入一个 httptest.ResponseRecorder 来检查响应。

返回:

  • c (*Context): 一个初始化的 Touka Context。
  • r (*Engine): 一个新的 Touka Engine 实例,与 c 相关联。

func CreateTestContextWithRequest

func CreateTestContextWithRequest(w http.ResponseWriter, req *http.Request) (c *Context, r *Engine)

CreateTestContextWithRequest 功能与 CreateTestContext 类似,但允许传入自定义的 *http.Request。 这对于测试需要特定请求方法、URL、头部或Body的处理器非常有用。

参数:

  • w (http.ResponseWriter): 可选。如果为 nil,创建一个 httptest.ResponseRecorder。
  • req (*http.Request): 用户提供的 HTTP 请求。如果为 nil,则内部创建一个默认的 "GET /"。

返回:

  • c (*Context): 一个初始化的 Touka Context。
  • r (*Engine): 一个新的 Touka Engine 实例,与 c 相关联。

func FileServerHandleServe added in v0.3.0

func FileServerHandleServe(c *Context, fsHandle http.Handler)

func GetTempSkippedNodes added in v0.4.1

func GetTempSkippedNodes() *[]skippedNode

GetTempSkippedNodes 从 Pool 中获取一个 *[]skippedNode 指针

func MergeCtx added in v0.3.0

func MergeCtx(parents ...context.Context) (ctx context.Context, cancel context.CancelFunc)

MergeCtx 创建并返回一个新的 context.Context. 这个新的 context 会在任何一个传入的父 contexts 被取消时, 或者当返回的 CancelFunc 被调用时, 自动被取消 (逻辑或关系). 父 context 的取消原因 (cause) 会自动传播到返回的 context.

新的 context 会继承: - Deadline: 所有父 context 中最早的截止时间. - Value: 按传入顺序从第一个能找到值的父 context 中获取值.

func NewLogger

func NewLogger(logcfg reco.Config) *reco.Logger

func NewMaxBytesReader added in v0.3.0

func NewMaxBytesReader(r io.ReadCloser, n int64) io.ReadCloser

NewMaxBytesReader 创建并返回一个 io.ReadCloser, 它从 r 读取数据, 但在读取的字节数超过 n 后会返回 ErrBodyTooLarge 错误.

如果 r 为 nil, 会 panic. 如果 n 小于等于 0, 则读取不受限制, 直接返回原始的 r.

func PerformRequest

func PerformRequest(engine *Engine, method, path string, body io.Reader, headers http.Header) *httptest.ResponseRecorder

PerformRequest 在给定的 Engine 上执行一个模拟的 HTTP 请求,并返回响应记录器。 这是一个更高级别的测试辅助函数,封装了创建请求、Context 和执行引擎的 ServeHTTP 方法。

参数:

  • engine (*Engine): 要测试的 Touka 引擎实例。
  • method (string): HTTP 请求方法 (例如 "GET", "POST")。
  • path (string): 请求的路径 (例如 "/", "/users/123?name=test")。
  • body (io.Reader): 可选的请求体。对于 GET, HEAD 等通常为 nil。
  • headers (http.Header): 可选的请求头部。

返回:

  • *httptest.ResponseRecorder: 包含响应状态、头部和主体的记录器。

示例:

rr := touka.PerformRequest(myEngine, "GET", "/ping", nil, nil)
assert.Equal(t, http.StatusOK, rr.Code)
assert.Equal(t, "pong", rr.Body.String())

func PutTempSkippedNodes added in v0.4.1

func PutTempSkippedNodes(skippedNodes *[]skippedNode)

PutTempSkippedNodes 将用完的 *[]skippedNode 指针放回 Pool

func ReleaseErrorCapturingResponseWriter

func ReleaseErrorCapturingResponseWriter(ecw *errorCapturingResponseWriter)

ReleaseErrorCapturingResponseWriter 将一个 errorCapturingResponseWriter 实例返回到对象池

func StringToBytes

func StringToBytes(s string) []byte

StringToBytes 将字符串转换为字节切片, 不进行内存分配. 更多详情, 请参见 https://github.com/golang/go/issues/53003#issuecomment-1140276077. 注意: 此函数使用 unsafe 包, 应谨慎使用, 因为它可能导致内存不安全.

func UnwrapResponseWriter added in v0.5.1

func UnwrapResponseWriter(w ResponseWriter) http.ResponseWriter

UnwrapResponseWriter returns the underlying stdlib response writer when the provided writer is Touka's internal wrapper.

Types

type BufferPool added in v0.5.1

type BufferPool interface {
	Get() []byte
	Put([]byte)
}

BufferPool provides temporary buffers for response body copying.

type CloserLogger added in v1.0.0

type CloserLogger interface {
	Logger
	Close() error
}

CloserLogger 可选扩展接口,支持关闭操作 如果 Logger 实现了此接口,Engine 在关闭时会调用 Close()

type Context

type Context struct {
	Writer  ResponseWriter // 包装的 http.ResponseWriter
	Request *http.Request
	Params  Params // 从 httprouter 获取的路径参数

	Keys map[string]any // 用于在中间件之间传递数据

	Errors []error // 用于收集处理过程中的错误

	// HTTPClient 用于在此上下文中执行出站 HTTP 请求
	// 它由 Engine 提供
	HTTPClient *httpc.Client

	// 请求体Body大小限制
	MaxRequestBodySize int64

	// skippedNodes 用于记录跳过的节点信息,以便回溯
	// 通常在处理嵌套路由时使用
	SkippedNodes []skippedNode
	// contains filtered or unexported fields
}

Context 是每个请求的上下文,封装了请求和响应,并提供了很多便捷方法 它在中间件和最终处理函数之间传递

func (*Context) Abort

func (c *Context) Abort()

Abort 停止处理链的后续执行 通常在中间件中,当遇到错误或需要提前终止请求时调用

func (*Context) AbortWithStatus

func (c *Context) AbortWithStatus(code int)

AbortWithStatus 中止处理链并设置 HTTP 状态码

func (*Context) AddError

func (c *Context) AddError(err error)

AddError 添加一个错误到 Context 允许在处理请求过程中收集多个错误

func (*Context) AddHeader

func (c *Context) AddHeader(key, value string)

AddHeader 添加响应头部

func (*Context) Client deprecated

func (c *Context) Client() *httpc.Client

Client 返回当前请求的 HTTPClient 如果请求处理函数或中间件设置了自定义 HTTPClient,返回该实例; 否则返回 Engine 提供的默认实例

Deprecated: 使用 HTTPC() 替代,新方法会自动关联请求 Context

func (*Context) ClientIP

func (c *Context) ClientIP() string

ClientIP 返回客户端的 IP 地址 这是一个别名,与 RequestIP 功能相同

func (*Context) ContentType

func (c *Context) ContentType() string

ContentType 返回请求的 Content-Type 头部

func (*Context) Context

func (c *Context) Context() context.Context

Context() 返回请求的上下文,用于取消操作 这是 Go 标准库的 `context.Context`,用于请求的取消和超时管理

func (*Context) Debugf

func (c *Context) Debugf(format string, args ...any)

=== 日志记录 ===

func (*Context) DefaultPostForm

func (c *Context) DefaultPostForm(key, defaultValue string) string

DefaultPostForm 从 POST 请求体中获取表单值,如果不存在则返回默认值

func (*Context) DefaultQuery

func (c *Context) DefaultQuery(key, defaultValue string) string

DefaultQuery 从 URL 查询参数中获取值,如果不存在则返回默认值

func (*Context) DelHeader

func (c *Context) DelHeader(key string)

DelHeader 删除响应头部

func (*Context) DeleteCookie

func (c *Context) DeleteCookie(name string)

DeleteCookie 删除指定名称的 cookie 通过设置 MaxAge 为 -1 来删除 cookie

func (*Context) Done

func (c *Context) Done() <-chan struct{}

Done returns a channel that is closed when the request context is cancelled or times out. 继承自 `context.Context`

func (*Context) Err

func (c *Context) Err() error

Err returns the error, if any, that caused the context to be canceled or to time out. 继承自 `context.Context`

func (*Context) ErrorUseHandle

func (c *Context) ErrorUseHandle(code int, err error)

使用定义的errorHandle来处理error并结束当前handle

func (*Context) Errorf

func (c *Context) Errorf(format string, args ...any)

func (*Context) EventStream added in v0.3.7

func (c *Context) EventStream(streamer func(w io.Writer) bool)

EventStream 启动一个 SSE 事件流. 这是推荐的、更简单安全的方式, 采用阻塞和回调的设计, 框架负责管理连接生命周期.

详细用法:

r.GET("/sse/callback", func(c *touka.Context) {
    // streamer 回调函数会在一个循环中被调用.
    c.EventStream(func(w io.Writer) bool {
        event := touka.Event{
            Event: "time-tick",
            Data:  time.Now().Format(time.RFC1123),
        }

        if err := event.Render(w); err != nil {
            // 发生写入错误, 停止发送.
            return false // 返回 false 结束事件流.
        }

        time.Sleep(2 * time.Second)
        return true // 返回 true 继续事件流.
    })
    // 当事件流结束后(例如客户端关闭页面), 这行代码会被执行.
    fmt.Println("Client disconnected from /sse/callback")
})

func (*Context) EventStreamChan added in v0.3.7

func (c *Context) EventStreamChan(eventChan <-chan Event)

EventStreamChan 返回用于 SSE 事件流的 channel. 这是为高级并发场景设计的、更灵活的API.

与 EventStream 回调模式类似, 此方法是阻塞的: handler 会在此方法中停留, 直到事件 channel 被关闭 (close eventChan) 或客户端断开连接. 这保证了 Context 不会在 SSE 流期间被 pool 回收.

eventChan 必须在调用此方法之前创建, 以便调用者可以在独立的 goroutine 中发送事件. 调用者必须在完成后 close(eventChan) 来结束流. 生产者 goroutine 必须在 select 中监听 c.Request.Context().Done(), 否则在客户端断开时会产生 goroutine 泄漏.

详细用法:

r.GET("/sse/channel", func(c *touka.Context) {
    eventChan := make(chan touka.Event)

    // 在独立的 goroutine 中异步发送事件.
    go func() {
        defer close(eventChan) // 完成后关闭 channel 以结束事件流.

        for i := 1; i <= 5; i++ {
            select {
            case <-c.Request.Context().Done():
                return // 客户端已断开, 退出 goroutine.
            case eventChan <- touka.Event{
                Id:   fmt.Sprintf("%d", i),
                Data: "hello from channel",
            }:
            }
            time.Sleep(2 * time.Second)
        }
    }()

    // 阻塞直到事件流结束.
    c.EventStreamChan(eventChan)
})

func (*Context) Fatalf

func (c *Context) Fatalf(format string, args ...any)

func (*Context) File

func (c *Context) File(filepath string)

File 将指定路径的文件作为响应发送 它会设置 Content-Type 和 Content-Disposition 头部

func (*Context) FileText added in v0.4.0

func (c *Context) FileText(code int, filePath string)

FileText

func (*Context) GOB

func (c *Context) GOB(code int, obj any)

GOB 向响应写入GOB数据 设置 Content-Type 为 application/octet-stream

func (*Context) GOBBuf added in v1.0.0

func (c *Context) GOBBuf(code int, obj any)

GOBBuf 先将 GOB 编码到 buffer, 成功后再写入状态码和响应体.

func (*Context) Get

func (c *Context) Get(key string) (value any, exists bool)

Get 从 Context 中获取一个值 这是一个线程安全的操作

func (*Context) GetAllReqHeader

func (c *Context) GetAllReqHeader() http.Header

GetAllReqHeader 获取所有请求头部

func (*Context) GetAllRespHeader added in v0.2.5

func (c *Context) GetAllRespHeader() http.Header

获取所有resp Headers

func (*Context) GetBool added in v0.2.2

func (c *Context) GetBool(key string) (value bool, exists bool)

GetBool 从 Context 中获取一个 bool 值 这是一个线程安全的操作

func (*Context) GetCookie

func (c *Context) GetCookie(name string) (string, error)

GetCookie 获取指定名称的 cookie 值

func (*Context) GetDuration added in v0.2.2

func (c *Context) GetDuration(key string) (value time.Duration, exists bool)

GetDuration 从 Context 中获取一个 time.Duration 值 这是一个线程安全的操作

func (*Context) GetErrors

func (c *Context) GetErrors() []error

Errors 返回 Context 中收集的所有错误

func (*Context) GetFloat64 added in v0.2.2

func (c *Context) GetFloat64(key string) (value float64, exists bool)

GetFloat64 从 Context 中获取一个 float64 值 这是一个线程安全的操作

func (*Context) GetHTTPC

func (c *Context) GetHTTPC() *httpc.Client

GetHTTPC 返回底层的 httpc.Client 实例 Deprecated: 使用 HTTPC() 替代,新方法会自动关联请求 Context

func (*Context) GetInt added in v0.2.2

func (c *Context) GetInt(key string) (value int, exists bool)

GetInt 从 Context 中获取一个 int 值 这是一个线程安全的操作

func (*Context) GetLogger

func (c *Context) GetLogger() Logger

GetLogger 获取engine的Logger接口

func (*Context) GetLoggerReco added in v1.0.0

func (c *Context) GetLoggerReco() *reco.Logger

GetLoggerReco 返回底层的 reco.Logger 实例 用于需要访问 reco 特定功能的场景 如果当前 logger 不是 *reco.Logger 类型,返回 nil

func (*Context) GetProtocol

func (c *Context) GetProtocol() string

GetProtocol 获取当前连接版本

func (*Context) GetReqBody

func (c *Context) GetReqBody() io.ReadCloser

GetReqBody 以获取一个 io.ReadCloser 接口,用于读取请求体 注意:请求体只能读取一次

func (*Context) GetReqBodyBuffer added in v0.2.2

func (c *Context) GetReqBodyBuffer() (*bytes.Buffer, error)

类似 GetReqBodyFull, 返回 *bytes.Buffer

func (*Context) GetReqBodyFull

func (c *Context) GetReqBodyFull() ([]byte, error)

GetReqBodyFull 读取并返回请求体的所有内容 注意:请求体只能读取一次

func (*Context) GetReqHeader

func (c *Context) GetReqHeader(key string) string

GetReqHeader 获取请求头部的值

func (*Context) GetReqQueryString added in v0.2.2

func (c *Context) GetReqQueryString() string

GetReqQueryString GetReqQueryString 返回请求的原始查询字符串

func (*Context) GetRequestURI added in v0.2.2

func (c *Context) GetRequestURI() string

GetRequestURI 返回请求的原始 URI

func (*Context) GetRequestURIPath added in v0.2.2

func (c *Context) GetRequestURIPath() string

GetRequestURIPath 返回请求的原始 URI 的路径部分

func (*Context) GetString added in v0.2.2

func (c *Context) GetString(key string) (value string, exists bool)

GetString 从 Context 中获取一个字符串值 这是一个线程安全的操作

func (*Context) GetTime added in v0.2.2

func (c *Context) GetTime(key string) (value time.Time, exists bool)

GetTime 从 Context 中获取一个 time.Time 值 这是一个线程安全的操作

func (*Context) GetWriter

func (c *Context) GetWriter() io.Writer

GetWriter 获得一个 io.Writer 接口,可以直接向响应体写入数据 这对于需要自定义流式写入或与其他需要 io.Writer 的库集成非常有用

func (*Context) HTML

func (c *Context) HTML(code int, name string, obj any)

HTML 渲染 HTML 模板 如果 Engine 配置了 HTMLRender,则使用它进行渲染 否则,会进行简单的字符串输出 预留接口,可以扩展为支持多种模板引擎

func (*Context) HTMLBuf added in v1.0.0

func (c *Context) HTMLBuf(code int, name string, obj any)

HTMLBuf 先将 HTML 模板渲染到 buffer, 成功后再写入状态码和响应体. 如果模板渲染失败,则返回 500 错误且不写入任何内容.

func (*Context) HTTPC added in v1.0.0

func (c *Context) HTTPC() *contextHTTPClient

HTTPC 返回自动关联请求 Context 的 HTTP 客户端 当请求被取消时,通过此客户端发起的出站请求也会自动取消

func (*Context) Header

func (c *Context) Header(key, value string)

Header 作为SetHeader的别名

func (*Context) Infof

func (c *Context) Infof(format string, args ...any)

func (*Context) IsAborted

func (c *Context) IsAborted() bool

IsAborted 返回处理链是否已被中止

func (*Context) JSON

func (c *Context) JSON(code int, obj any)

JSON 向响应写入 JSON 数据 设置 Content-Type 为 application/json

func (*Context) JSONBuf added in v1.0.0

func (c *Context) JSONBuf(code int, obj any)

JSONBuf 先将 JSON 编码到 buffer, 成功后再写入状态码和响应体. 与 JSON 相比,编码失败时可以正确返回 500 状态码,代价是多一次内存分配.

func (*Context) MustGet

func (c *Context) MustGet(key string) any

MustGet 从 Context 中获取一个值,如果不存在则 panic 适用于确定值一定存在的场景

func (*Context) Next

func (c *Context) Next()

Next 在处理链中执行下一个处理函数 这是中间件模式的核心,允许请求依次经过多个处理函数

func (*Context) Panicf

func (c *Context) Panicf(format string, args ...any)

func (*Context) Param

func (c *Context) Param(key string) string

Param 从 URL 路径参数中获取值 例如,对于路由 /users/:id,c.Param("id") 可以获取 id 的值

func (*Context) PostForm

func (c *Context) PostForm(key string) string

PostForm 从 POST 请求体中获取表单值 懒加载解析表单数据,并进行缓存

func (*Context) Query

func (c *Context) Query(key string) string

Query 从 URL 查询参数中获取值 懒加载解析查询参数,并进行缓存

func (*Context) Raw

func (c *Context) Raw(code int, contentType string, data []byte)

Raw 向响应写入bytes

func (*Context) Redirect

func (c *Context) Redirect(code int, location string)

Redirect 执行 HTTP 重定向 code 应为 3xx 状态码 (如 http.StatusMovedPermanently, http.StatusFound)

func (*Context) RequestIP

func (c *Context) RequestIP() string

RequestIP 返回客户端的 IP 地址 它会根据 Engine 的配置 (ForwardByClientIP) 尝试从 X-Forwarded-For 或 X-Real-IP 等头部获取, 否则回退到 Request.RemoteAddr

func (*Context) Set

func (c *Context) Set(key string, value any)

Set 将一个键值对存储到 Context 中 这是一个线程安全的操作,用于在中间件之间传递数据

func (*Context) SetBodyStream added in v0.2.2

func (c *Context) SetBodyStream(reader io.Reader, contentSize int)

SetBodyStream 设置响应体为一个 io.Reader,并指定内容长度 如果 contentSize 为 -1,则表示内容长度未知,将使用 Transfer-Encoding: chunked

func (*Context) SetCookie

func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool, sameSite ...http.SameSite)

SetCookie 设置一个 HTTP cookie sameSite 参数是可选的,如果不提供则使用通过 SetSameSite 设置的值

func (*Context) SetCookieData

func (c *Context) SetCookieData(cookie *http.Cookie)

func (*Context) SetHeader

func (c *Context) SetHeader(key, value string)

SetHeader 设置响应头部

func (*Context) SetHeaders added in v0.2.4

func (c *Context) SetHeaders(headers map[string][]string)

SetHeaders 接受headers列表

func (*Context) SetMaxRequestBodySize added in v0.3.0

func (c *Context) SetMaxRequestBodySize(size int64)

SetMaxRequestBodySize

func (*Context) SetRespBodyFile added in v0.2.8

func (c *Context) SetRespBodyFile(code int, filePath string)

将文件内容作为响应body

func (*Context) SetSameSite

func (c *Context) SetSameSite(samesite http.SameSite)

SetSameSite 设置响应的 SameSite cookie 属性

func (*Context) ShouldBind

func (c *Context) ShouldBind(obj any) error

ShouldBind 尝试根据 Content-Type 将请求体绑定到结构体 支持的类型:application/json, application/x-www-form-urlencoded, multipart/form-data, application/wanf, application/vnd.wjqserver.wanf, application/gob

func (*Context) ShouldBindForm added in v0.5.0

func (c *Context) ShouldBindForm(obj any) error

ShouldBindForm 尝试将表单数据绑定到结构体 支持 application/x-www-form-urlencoded 和 multipart/form-data

func (*Context) ShouldBindGOB added in v0.5.0

func (c *Context) ShouldBindGOB(obj any) error

ShouldBindGOB 尝试将 GOB 格式的请求体绑定到对象

func (*Context) ShouldBindJSON

func (c *Context) ShouldBindJSON(obj any) error

ShouldBindJSON 尝试将请求体绑定到 JSON 对象

func (*Context) ShouldBindWANF added in v0.3.7

func (c *Context) ShouldBindWANF(obj any) error

ShouldBindWANF 尝试将 WANF 格式的请求体绑定到对象

func (*Context) Status

func (c *Context) Status(code int)

Status 设置响应状态码

func (*Context) String

func (c *Context) String(code int, format string, values ...any)

String 向响应写入格式化的字符串

func (*Context) Text added in v0.3.1

func (c *Context) Text(code int, text string)

Text 向响应写入无需格式化的string

func (*Context) UserAgent

func (c *Context) UserAgent() string

UserAgent 返回请求的 User-Agent 头部

func (*Context) Value

func (c *Context) Value(key any) any

Value returns the value associated with this context for key, or nil if no value is associated with key. 可以用于从 Context 中获取与特定键关联的值,包括 Go 原生 Context 的值和 Touka Context 的 Keys

func (*Context) WANF added in v0.3.7

func (c *Context) WANF(code int, obj any)

WANF向响应写入WANF数据 设置 application/vnd.wjqserver.wanf; charset=utf-8

func (*Context) WANFBuf added in v1.0.0

func (c *Context) WANFBuf(code int, obj any)

WANFBuf 先将 WANF 编码到 buffer, 成功后再写入状态码和响应体.

func (*Context) Warnf

func (c *Context) Warnf(format string, args ...any)

func (*Context) WriteStream

func (c *Context) WriteStream(reader io.Reader) (written int64, err error)

WriteStream 接受一个 io.Reader 并将其内容流式传输到响应体 返回写入的字节数和可能遇到的错误 该方法在开始写入之前,会确保设置 HTTP 状态码为 200 OK

type Engine

type Engine struct {

	// 可配置项,用于控制框架行为,参考 Gin
	RedirectTrailingSlash  bool     // 是否自动重定向带尾部斜杠的路径到不带尾部斜杠的路径 (e.g. /foo/ -> /foo)
	RedirectFixedPath      bool     // 是否自动修复路径中的大小写错误 (e.g. /Foo -> /foo)
	HandleMethodNotAllowed bool     // 是否启用 MethodNotAllowed 处理器
	ForwardByClientIP      bool     // 是否信任 X-Forwarded-For 等头部获取客户端 IP
	RemoteIPHeaders        []string // 用于获取客户端 IP 的头部列表,例如 {"X-Forwarded-For", "X-Real-IP"}

	HTTPClient *httpc.Client // 用于在此上下文中执行出站 HTTP 请求

	// LogReco 保留的 reco.Logger 字段
	// Deprecated: 使用 SetLogger/GetLogger 替代
	LogReco *reco.Logger

	HTMLRender any // 用于 HTML 模板渲染,可以设置为 *template.Template 或自定义渲染器接口

	UnMatchFSRoutes HandlersChain // UnMatch 处理器链, 用于扩展自由度, 在此局部链上, unMatchFS相关处理会在最后

	Protocols ProtocolsConfig //协议版本配置

	// ServerConfigurator 允许在服务器启动前对其进行自定义配置
	// 例如,设置 ReadTimeout, WriteTimeout 等
	ServerConfigurator func(*http.Server)

	// TLSServerConfigurator 允许在 HTTPS 服务器启动前进行自定义配置
	// 如果设置了此回调,它将优先于 ServerConfigurator 被用于 HTTPS 服务器
	// 如果未设置,HTTPS 服务器将回退使用 ServerConfigurator (如果已设置)
	TLSServerConfigurator func(*http.Server)

	// GlobalMaxRequestBodySize 全局请求体Body大小限制
	GlobalMaxRequestBodySize int64
	// contains filtered or unexported fields
}

Engine 是 Touka 框架的核心,负责路由注册、中间件管理和请求分发 它实现了 http.Handler 接口,可以直接用于 http.ListenAndServe

func Default

func Default() *Engine

生成一个携带默认中间件的Engine

func New

func New() *Engine

New 创建并返回一个 Engine 实例

func (*Engine) ANY

func (engine *Engine) ANY(relativePath string, handlers ...HandlerFunc)

ANY 注册所有常见 HTTP 方法的路由

func (*Engine) CloseLogger added in v0.2.2

func (engine *Engine) CloseLogger()

CloseLogger 关闭 Engine 的日志实现 如果 logger 实现了 CloserLogger 接口,会调用其 Close 方法

func (*Engine) Context added in v0.4.2

func (engine *Engine) Context() context.Context

Context 返回 Engine 的根上下文, 该上下文在服务器优雅关闭时会被取消. 它可以用于在长连接 (如 SSE) 中监听关闭信号.

func (*Engine) DELETE

func (engine *Engine) DELETE(relativePath string, handlers ...HandlerFunc)

DELETE 注册 DELETE 方法的路由

func (*Engine) GET

func (engine *Engine) GET(relativePath string, handlers ...HandlerFunc)

GET 注册 GET 方法的路由

func (*Engine) GetDefaultErrHandler

func (engine *Engine) GetDefaultErrHandler() ErrorHandler

获取一个默认错误处理handle

func (*Engine) GetLogReco added in v1.0.0

func (engine *Engine) GetLogReco() *reco.Logger

GetLogReco 返回底层的 reco.Logger 实例 用于需要访问 reco 特定功能的场景 如果当前 logger 不是 *reco.Logger 类型,返回 nil

func (*Engine) GetLogger added in v1.0.0

func (engine *Engine) GetLogger() Logger

GetLogger 返回 Logger 接口实例

func (*Engine) GetRouterInfo

func (engine *Engine) GetRouterInfo() []RouteInfo

GetRouterInfo 返回所有已注册的路由信息

func (*Engine) GetStaticDirHandle added in v0.3.0

func (engine *Engine) GetStaticDirHandle(rootPath string) HandlerFunc

GetStaticDirHandleFunc

func (*Engine) GetStaticFSHandle added in v0.3.0

func (engine *Engine) GetStaticFSHandle(fs http.FileSystem) HandlerFunc

GetStaticFSHandleFunc

func (*Engine) GetStaticFileHandle added in v0.3.0

func (engine *Engine) GetStaticFileHandle(filePath string) HandlerFunc

GetStaticFileHandleFunc

func (*Engine) Group

func (engine *Engine) Group(relativePath string, handlers ...HandlerFunc) Router

Group 创建一个新的路由组 路由组允许将具有相同前缀路径和/或共享中间件的路由组织在一起

func (*Engine) HEAD

func (engine *Engine) HEAD(relativePath string, handlers ...HandlerFunc)

HEAD 注册 HEAD 方法的路由

func (*Engine) Handle

func (engine *Engine) Handle(httpMethod, relativePath string, handlers ...HandlerFunc)

Handle 注册通用 HTTP 方法的路由 这是所有具体 HTTP 方法注册的基础方法

func (*Engine) HandleFunc added in v0.2.2

func (engine *Engine) HandleFunc(methods []string, relativePath string, handlers ...HandlerFunc)

HandleFunc 注册一个或多个 HTTP 方法的路由 methods 参数是一个字符串切片,包含要注册的 HTTP 方法(例如 []string{"GET", "POST"}) relativePath 是相对于当前组或 Engine 的路径 handlers 是处理函数链

func (*Engine) NoRoute

func (Engine *Engine) NoRoute(handler HandlerFunc)

传入并设置NoRoute (这不是最后一个处理, 你仍可以next到默认的404处理)

func (*Engine) NoRoutes

func (Engine *Engine) NoRoutes(handlerFuncs ...HandlerFunc)

传入并设置NoRoutes (这不是最后一个处理, 你仍可以next到默认的404处理)

func (*Engine) OPTIONS

func (engine *Engine) OPTIONS(relativePath string, handlers ...HandlerFunc)

OPTIONS 注册 OPTIONS 方法的路由

func (*Engine) PATCH

func (engine *Engine) PATCH(relativePath string, handlers ...HandlerFunc)

PATCH 注册 PATCH 方法的路由

func (*Engine) POST

func (engine *Engine) POST(relativePath string, handlers ...HandlerFunc)

POST 注册 POST 方法的路由

func (*Engine) PUT

func (engine *Engine) PUT(relativePath string, handlers ...HandlerFunc)

PUT 注册 PUT 方法的路由

func (*Engine) Run

func (engine *Engine) Run(opts ...RunOption) error

Run starts the engine with the provided startup options.

Default behavior with no options:

  • HTTP only
  • listens on :8080
  • no graceful shutdown orchestration

Add WithGracefulShutdown(...) or WithGracefulShutdownDefault() to enable signal-aware graceful shutdown and request-context cancellation semantics. Add WithTLS(...) to run HTTPS; this is independent from graceful shutdown.

func (*Engine) ServeHTTP

func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP 实现了 http.Handler 接口,是 Engine 处理所有 HTTP 请求的入口 每个传入的 HTTP 请求都会调用此方法

func (*Engine) SetDefaultProtocols

func (engine *Engine) SetDefaultProtocols()

设置默认Protocols

func (*Engine) SetErrorHandler

func (engine *Engine) SetErrorHandler(handler ErrorHandler)

设置自定义错误处理

func (*Engine) SetForwardByClientIP

func (engine *Engine) SetForwardByClientIP(enable bool)

SetForwardByClientIP 设置是否信任 X-Forwarded-For 等头部获取客户端 IP

func (*Engine) SetGlobalMaxRequestBodySize added in v0.3.0

func (engine *Engine) SetGlobalMaxRequestBodySize(size int64)

配置全局Req Body大小限制

func (*Engine) SetHTTPClient

func (engine *Engine) SetHTTPClient(client *httpc.Client)

SetHTTPClient 设置 Engine 使用的 httpc.Client

func (*Engine) SetHandleMethodNotAllowed added in v0.2.7

func (engine *Engine) SetHandleMethodNotAllowed(enable bool)

是否开启MethodNotAllowed

func (*Engine) SetLogReco added in v1.0.0

func (engine *Engine) SetLogReco(l *reco.Logger)

SetLogReco 设置 reco.Logger 实例 用于向后兼容,等价于 SetLogger(l)

func (*Engine) SetLogger

func (engine *Engine) SetLogger(logger Logger)

SetLogger 传入 Logger 接口实例

func (*Engine) SetLoggerCfg added in v0.2.2

func (engine *Engine) SetLoggerCfg(logcfg reco.Config)

SetLoggerCfg 使用 reco.Config 配置日志

func (*Engine) SetProtocols

func (engine *Engine) SetProtocols(config *ProtocolsConfig)

设置Protocol

func (*Engine) SetRedirectFixedPath added in v0.2.7

func (engine *Engine) SetRedirectFixedPath(enable bool)

是否开启固定路径重定向

func (*Engine) SetRedirectTrailingSlash added in v0.2.7

func (engine *Engine) SetRedirectTrailingSlash(enable bool)

是否开启末尾slash重定向

func (*Engine) SetRemoteIPHeaders

func (engine *Engine) SetRemoteIPHeaders(headers []string)

配置Req IP来源 Headers

func (*Engine) SetServerConfigurator added in v0.2.3

func (engine *Engine) SetServerConfigurator(fn func(*http.Server))

SetServerConfigurator 设置一个函数,该函数将在任何 HTTP 或 HTTPS 服务器 (通过 RunShutdown, RunTLS, RunTLSRedir) 启动前被调用, 允许用户对底层的 *http.Server 实例进行自定义配置

func (*Engine) SetTLSServerConfigurator added in v0.2.3

func (engine *Engine) SetTLSServerConfigurator(fn func(*http.Server))

SetTLSServerConfigurator 设置一个函数,该函数将专门用于配置 HTTPS 服务器 如果设置了此函数,它将覆盖通用的 ServerConfigurator

func (*Engine) SetUnMatchFS

func (engine *Engine) SetUnMatchFS(fs http.FileSystem, handlers ...HandlerFunc)

func (*Engine) SetUnMatchFSChain added in v0.3.0

func (engine *Engine) SetUnMatchFSChain(fs http.FileSystem, handlers ...HandlerFunc)

func (*Engine) StaticDir added in v0.2.2

func (engine *Engine) StaticDir(relativePath, rootPath string)

StaticDir 传入一个文件夹路径, 使用FileServer进行处理 r.StaticDir("/test/*filepath", "/var/www/test")

func (*Engine) StaticFS added in v0.2.7

func (engine *Engine) StaticFS(relativePath string, fs http.FileSystem)

StaticFS

func (*Engine) StaticFile

func (engine *Engine) StaticFile(relativePath, filePath string)

Static File 传入一个文件路径, 使用FileServer进行处理

func (*Engine) Use

func (engine *Engine) Use(middleware ...HandlerFunc) Router

Use 将全局中间件添加到 Engine 这些中间件将应用于所有注册的路由

func (*Engine) UseChainIf added in v0.2.5

func (engine *Engine) UseChainIf(condition bool, factories ...MiddlewareXFunc) HandlerFunc

UseChainIf 是一个条件中间件包装器,用于一组中间件 如果 `condition` 为 true,它将按顺序创建并执行提供的 `factories` 生成的中间件链 否则,它会直接跳过整个链

func (*Engine) UseIf added in v0.2.5

func (engine *Engine) UseIf(condition bool, middlewareX MiddlewareXFunc) HandlerFunc

UseIf 是一个条件中间件包装器

type ErrorHandle

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

type ErrorHandler

type ErrorHandler func(c *Context, code int, err error)

type Event added in v0.3.7

type Event struct {
	// Event 是事件的名称.
	Event string
	// Data 是事件的内容, 可以是多行文本.
	Data string
	// Id 是事件的唯一标识符.
	Id string
	// Retry 是指定客户端在连接丢失后应等待多少毫秒后尝试重新连接.
	Retry string
}

Event 代表一个服务器发送事件(SSE).

func (*Event) Render added in v0.3.7

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

Render 将事件格式化并写入给定的 writer. 通过逐行处理数据, 此方法可防止因数据中包含换行符而导致的CRLF注入问题. 为了性能, 它使用 bytes.Buffer 并通过 WriteTo 直接写入, 以避免不必要的内存分配.

type ForwardedHeadersPolicy added in v0.5.1

type ForwardedHeadersPolicy int

ForwardedHeadersPolicy controls how forwarding headers are generated. The zero value uses both X-Forwarded-* and RFC 7239 Forwarded headers.

const (
	ForwardedBoth ForwardedHeadersPolicy = iota
	ForwardedNone
	ForwardedXForwardedOnly
	ForwardedRFC7239Only
)

type H

type H map[string]any // map简写, 类似gin.H

type HTTPRedirectOption added in v1.0.0

type HTTPRedirectOption interface {
	// contains filtered or unexported methods
}

func WithRedirectHost added in v1.0.0

func WithRedirectHost(host string) HTTPRedirectOption

func WithRedirectHostHeaders added in v1.0.0

func WithRedirectHostHeaders(headers []string) HTTPRedirectOption

func WithUseHeaderHost added in v1.0.0

func WithUseHeaderHost(enabled bool) HTTPRedirectOption

type Handle

type Handle func(http.ResponseWriter, *http.Request, Params)

type HandlerFunc

type HandlerFunc func(*Context)

HandlerFunc 定义框架处理函数的类型,包括中间件和最终的路由处理函数。

func AdapterStdFunc

func AdapterStdFunc(f http.HandlerFunc) HandlerFunc

AdapterStdFunc 将一个标准的 http.HandlerFunc (func(http.ResponseWriter, *http.Request)) 适配成一个 Touka 框架的 HandlerFunc (func(*Context)) 这使得标准的 HTTP 处理器可以轻松地在 Touka 路由中使用

示例:

stdHandlerFunc := func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello from a standard handler function!"))
}
r.GET("/std-func", touka.AdapterStdFunc(stdHandlerFunc))

注意: 被适配的处理器执行完毕后,Touka 的处理链会被中止 (c.Abort()), 因为我们假设标准处理器已经完成了对请求的响应

func AdapterStdHandle

func AdapterStdHandle(h http.Handler) HandlerFunc

AdapterStdHandle 将一个实现了 http.Handler 接口的对象 适配成一个 Touka 框架的 HandlerFunc (func(*Context)) 这使得像 http.FileServer, http.StripPrefix 或其他第三方库的 Handler 可以直接在 Touka 路由中使用

示例:

// 创建一个 http.FileServer
fileServer := http.FileServer(http.Dir("./static"))
// 将 FileServer 适配后用于 Touka 路由
r.GET("/static/*filepath", touka.AdapterStdHandle(http.StripPrefix("/static", fileServer)))

注意: 被适配的处理器执行完毕后,Touka 的处理链会被中止 (c.Abort())

func FileServer added in v0.2.2

func FileServer(fs http.FileSystem) HandlerFunc

FileServer方式, 返回一个HandleFunc, 统一化处理

func GetStaticDirHandleFunc added in v0.3.0

func GetStaticDirHandleFunc(fsHandle http.Handler) HandlerFunc

GetStaticDirHandle

func GetStaticFSHandleFunc added in v0.3.0

func GetStaticFSHandleFunc(fsHandle http.Handler) HandlerFunc

GetStaticFSHandleFunc

func GetStaticFileHandleFunc added in v0.3.0

func GetStaticFileHandleFunc(fsHandle http.Handler, fileName string) HandlerFunc

GetStaticFileHandleFunc

func MethodNotAllowed

func MethodNotAllowed() HandlerFunc

405中间件

func NotFound

func NotFound() HandlerFunc

404最后处理

func Recovery

func Recovery() HandlerFunc

Recovery 返回一个使用默认配置的 panic 恢复中间件 它是 RecoveryWithOptions(nil) 的一个便捷包装

func RecoveryWithOptions

func RecoveryWithOptions(handler PanicHandlerFunc) HandlerFunc

RecoveryWithOptions 返回一个可配置的 panic 恢复中间件

参数:

  • handler (PanicHandlerFunc): 一个可选的回调函数 如果提供了,当 panic 发生时, 它将被调用,允许用户进行自定义的日志记录、错误上报或响应 如果为 nil,将使用默认的 panic 处理逻辑

func ReverseProxy added in v0.5.1

func ReverseProxy(config ReverseProxyConfig) HandlerFunc

ReverseProxy returns a handler that proxies requests to the configured backend.

type HandlersChain

type HandlersChain []HandlerFunc

HandlersChain 定义处理函数链(中间件栈)的类型。

func (HandlersChain) Last

func (c HandlersChain) Last() HandlerFunc

Last 返回链中的最后一个处理函数 如果链为空,则返回 nil

type HeaderOps added in v1.0.0

type HeaderOps struct {
	Add     map[string][]string
	Set     map[string][]string
	Delete  []string
	Replace map[string][]Replacement
}

func (*HeaderOps) Provision added in v1.0.0

func (ops *HeaderOps) Provision() error

type Logger added in v1.0.0

type Logger interface {
	Debugf(format string, args ...any)
	Infof(format string, args ...any)
	Warnf(format string, args ...any)
	Errorf(format string, args ...any)
	Fatalf(format string, args ...any)
	Panicf(format string, args ...any)
}

Logger 是日志接口,支持多种日志库实现(reco、zap、logrus 等) 用户可以通过实现此接口来替换默认的日志实现

type MiddlewareXFunc added in v0.2.6

type MiddlewareXFunc func() HandlerFunc

type PanicHandlerFunc

type PanicHandlerFunc func(c *Context, panicInfo any)

PanicHandlerFunc 定义了用户自定义的 panic 处理函数类型 它接收当前的 Context 和 panic 的值

type Param

type Param struct {
	Key   string // 参数的键名
	Value string // 参数的值
}

Param 是单个 URL 参数, 由键和值组成.

type Params

type Params []Param

Params 是 Param 类型的切片, 由路由器返回. 该切片是有序的, 第一个 URL 参数也是切片中的第一个值. 因此, 按索引读取值是安全的.

func (Params) ByName

func (ps Params) ByName(name string) (va string)

ByName 返回键名与给定名称匹配的第一个 Param 的值. 如果未找到匹配的 Param, 则返回空字符串.

func (Params) Get

func (ps Params) Get(name string) (string, bool)

Get 返回键名与给定名称匹配的第一个 Param 的值, 并返回一个布尔值 true. 如果未找到匹配的 Param, 则返回空字符串和布尔值 false.

type ProtocolsConfig

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

ProtocolsConfig 协议版本配置结构体

func GetDefaultProtocolsConfig

func GetDefaultProtocolsConfig() *ProtocolsConfig

获取默认Protocol配置

type Replacement added in v1.0.0

type Replacement struct {
	Search       string
	Replace      string
	SearchRegexp string
	// contains filtered or unexported fields
}

type RespHeaderOps added in v1.0.0

type RespHeaderOps struct {
	*HeaderOps
	Deferred bool
}

type ResponseWriter

type ResponseWriter interface {
	http.ResponseWriter
	http.Hijacker // 支持 WebSocket 等
	http.Flusher  // 支持流式响应

	Status() int   // 返回写入的 HTTP 状态码,如果未写入则为 0
	Size() int     // 返回已写入响应体的字节数
	Written() bool // 返回 WriteHeader 是否已被调用
	IsHijacked() bool
}

ResponseWriter 接口扩展了 http.ResponseWriter 以提供对响应状态和大小的访问

type ReverseProxyConfig added in v0.5.1

type ReverseProxyConfig struct {
	Target  *url.URL
	Targets []string

	LoadBalancing ReverseProxyLoadBalancingConfig
	PassiveHealth ReverseProxyPassiveHealthConfig

	Transport        http.RoundTripper
	FlushInterval    time.Duration
	BufferPool       BufferPool
	AllowH2CUpstream bool

	ModifyRequest  func(*http.Request)
	ModifyResponse func(*http.Response) error
	ErrorHandler   func(http.ResponseWriter, *http.Request, error)

	ForwardedHeaders ForwardedHeadersPolicy
	ForwardedBy      string
	Via              string
	PreserveHost     bool

	RequestHeaders  *HeaderOps
	ResponseHeaders *RespHeaderOps
}

ReverseProxyConfig configures the reverse proxy handler.

type ReverseProxyLBPolicy added in v1.0.0

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

ReverseProxyLBPolicy selects an upstream from the configured target pool. Use the helper constructors such as LBRandom or LBHeader to build a policy.

func LBClientIPHash added in v1.0.0

func LBClientIPHash() ReverseProxyLBPolicy

func LBFirst added in v1.0.0

func LBFirst() ReverseProxyLBPolicy

func LBHeader added in v1.0.0

func LBHeader(field string, fallback ReverseProxyLBPolicy) ReverseProxyLBPolicy

func LBIPHash added in v1.0.0

func LBIPHash() ReverseProxyLBPolicy

func LBLeastConn added in v1.0.0

func LBLeastConn() ReverseProxyLBPolicy

func LBQuery added in v1.0.0

func LBQuery(key string, fallback ReverseProxyLBPolicy) ReverseProxyLBPolicy

func LBRandom added in v1.0.0

func LBRandom() ReverseProxyLBPolicy

func LBRoundRobin added in v1.0.0

func LBRoundRobin() ReverseProxyLBPolicy

func LBURIHash added in v1.0.0

func LBURIHash() ReverseProxyLBPolicy

type ReverseProxyLoadBalancingConfig added in v1.0.0

type ReverseProxyLoadBalancingConfig struct {
	Policy      ReverseProxyLBPolicy
	Retries     int
	TryDuration time.Duration
	TryInterval time.Duration
}

ReverseProxyLoadBalancingConfig configures upstream selection and retries.

type ReverseProxyPassiveHealthConfig added in v1.0.0

type ReverseProxyPassiveHealthConfig struct {
	FailDuration    time.Duration
	MaxFails        int
	UnhealthyStatus []int
}

ReverseProxyPassiveHealthConfig configures inline passive health tracking.

type RouteInfo

type RouteInfo struct {
	Method  string // HTTP 方法 (GET, POST, PUT, DELETE 等)
	Path    string // 路由路径
	Handler string // 处理函数名称
	Group   string // 路由分组
}

RouteInfo 包含一个已注册路由的详细信息。 由 Router.GetRouters() 方法返回。

type Router added in v1.0.0

type Router interface {
	Group(relativePath string, handlers ...HandlerFunc) Router // 创建路由分组
	Use(middleware ...HandlerFunc) Router                      // 应用中间件到当前组或子组

	Handle(httpMethod, relativePath string, handlers ...HandlerFunc) // 注册通用HTTP方法
	GET(relativePath string, handlers ...HandlerFunc)
	POST(relativePath string, handlers ...HandlerFunc)
	PUT(relativePath string, handlers ...HandlerFunc)
	DELETE(relativePath string, handlers ...HandlerFunc)
	PATCH(relativePath string, handlers ...HandlerFunc)
	HEAD(relativePath string, handlers ...HandlerFunc)
	OPTIONS(relativePath string, handlers ...HandlerFunc)
	ANY(relativePath string, handlers ...HandlerFunc) // 注册所有HTTP方法
}

Router 定义了路由注册的接口,提供路由分组和HTTP方法注册的能力。

type RouterGroup

type RouterGroup struct {
	Handlers HandlersChain // 组中间件,仅应用于当前组及其子组的路由
	// contains filtered or unexported fields
}

RouterGroup 表示一个路由分组,可以添加组特定的中间件和路由 它也实现了 Router 接口,允许嵌套分组

func (*RouterGroup) ANY

func (group *RouterGroup) ANY(relativePath string, handlers ...HandlerFunc)

func (*RouterGroup) DELETE

func (group *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc)

func (*RouterGroup) GET

func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc)

GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, ANY 方法与 Engine 类似,只是通过 Group 的 Handle 方法注册

func (*RouterGroup) GetStaticDirHandle added in v0.3.0

func (group *RouterGroup) GetStaticDirHandle(rootPath string) HandlerFunc

GetStaticDirHandleFunc

func (*RouterGroup) GetStaticFSHandle added in v0.3.0

func (group *RouterGroup) GetStaticFSHandle(fs http.FileSystem) HandlerFunc

GetStaticFSHandleFunc

func (*RouterGroup) GetStaticFileHandle added in v0.3.0

func (group *RouterGroup) GetStaticFileHandle(filePath string) HandlerFunc

GetStaticFileHandleFunc

func (*RouterGroup) Group

func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) Router

Group 为当前组创建一个新的子组

func (*RouterGroup) HEAD

func (group *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc)

func (*RouterGroup) Handle

func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers ...HandlerFunc)

Handle 注册通用 HTTP 方法的路由到当前组 路径是相对于当前组的 basePath

func (*RouterGroup) HandleFunc added in v0.2.2

func (group *RouterGroup) HandleFunc(methods []string, relativePath string, handlers ...HandlerFunc)

HandleFunc 注册一个或多个 HTTP 方法的路由 methods 参数是一个字符串切片,包含要注册的 HTTP 方法(例如 []string{"GET", "POST"}) relativePath 是相对于当前组或 Engine 的路径 handlers 是处理函数链

func (*RouterGroup) OPTIONS

func (group *RouterGroup) OPTIONS(relativePath string, handlers ...HandlerFunc)

func (*RouterGroup) PATCH

func (group *RouterGroup) PATCH(relativePath string, handlers ...HandlerFunc)

func (*RouterGroup) POST

func (group *RouterGroup) POST(relativePath string, handlers ...HandlerFunc)

func (*RouterGroup) PUT

func (group *RouterGroup) PUT(relativePath string, handlers ...HandlerFunc)

func (*RouterGroup) StaticDir added in v0.2.2

func (group *RouterGroup) StaticDir(relativePath, rootPath string)

Group的StaticDir方式

func (*RouterGroup) StaticFS added in v0.2.7

func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem)

Group的StaticFS

func (*RouterGroup) StaticFile

func (group *RouterGroup) StaticFile(relativePath, filePath string)

Group的StaticFile

func (*RouterGroup) Use

func (group *RouterGroup) Use(middleware ...HandlerFunc) Router

Use 将中间件应用于当前路由组 这些中间件将应用于当前组及其子组的所有路由

type RunOption added in v1.0.0

type RunOption interface {
	// contains filtered or unexported methods
}

func WithAddr added in v1.0.0

func WithAddr(addr string) RunOption

func WithGracefulShutdown added in v1.0.0

func WithGracefulShutdown(timeout time.Duration) RunOption

func WithGracefulShutdownDefault added in v1.0.0

func WithGracefulShutdownDefault() RunOption

func WithHTTPRedirect added in v1.0.0

func WithHTTPRedirect(addr string, opts ...HTTPRedirectOption) RunOption

func WithShutdownContext added in v1.0.0

func WithShutdownContext(ctx context.Context) RunOption

func WithTLS added in v1.0.0

func WithTLS(tlsConfig *tls.Config) RunOption

type UnMatchFS

type UnMatchFS struct {
	FSForUnmatched     http.FileSystem
	ServeUnmatchedAsFS bool
}

Directories

Path Synopsis
examples
httpc command
logger_slog command

Jump to

Keyboard shortcuts

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