Help us shape the future of Go! Take the 2026 Go Developer Survey

handler

package
v0.14.9 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: Apache-2.0 Imports: 38 Imported by: 0

README

transport/http/handler/ - HTTP 请求处理器

此目录存放复杂业务场景的 HTTP 请求处理器实现。

与 gen/http/handler 的区别

目录 用途 修改
gen/http/handler/ Hz 生成的骨架代码 可编辑调用逻辑
transport/http/handler/ 复杂 handler 实现 完全手写

使用场景

  • 需要复杂参数处理的接口
  • 需要聚合多个服务的接口
  • 自定义响应格式的接口
  • WebSocket 等特殊协议处理

示例

package handler

import (
    "context"
    
    "github.com/cloudwego/hertz/pkg/app"
    "github.com/pigeonbox/core/app/user"
    "github.com/pigeonbox/core/pkg/resp"
)

type UserHandler struct {
    userSvc *user.Service
}

func NewUserHandler() *UserHandler {
    return &UserHandler{
        userSvc: user.NewService(),
    }
}

func (h *UserHandler) GetUserProfile(ctx context.Context, c *app.RequestContext) {
    userID := c.Param("id")
    
    // 聚合多个服务数据
    userInfo, _ := h.userSvc.GetByID(ctx, userID)
    // orderInfo, _ := h.orderSvc.GetByUserID(ctx, userID)
    
    resp.Success(c, map[string]interface{}{
        "user": userInfo,
        // "orders": orderInfo,
    })
}

注册路由

在 gen/http/router/ 中注册自定义 handler:

// 在路由中间件或自定义路由文件中
userHandler := handler.NewUserHandler()
r.GET("/api/v1/user/:id/profile", userHandler.GetUserProfile)

依赖规则

  • 可以依赖:app/、pkg/
  • 不应直接依赖:repo/(通过 app 层访问)

Documentation

Overview

Package handler 提供定制 HTTP handlers(不走 thrift IDL 生成)。 admin_manage.go 管理端增强:用户 CRUD / 文件管理 / 富统计 Dashboard。 均注册在 /admin 组(AdminMiddleware 保护),操作经审计落 admin_operation_logs。

P2P 联邦解析代理(GET /api/v1/federation/resolve,手写路由)。 前端在录码本站未命中时经此查询联邦,命中则直跳源节点取件页预填口令; 本端点只做"发现",不代理文件流量(下载始终直连源节点、源节点本地校验)。 未启用联邦时统一 available:false,不区分"未启用/不存在"(降探测面); registry 侧对 resolve 限流最严,本端点不再叠加限流(M4 视压测调参)。

寄件码/反向收件 HTTP 端点(P2,手写路由)。

helpers.go handler 包内样板收口:登录守卫 / 密码守卫 / 路径 ID 解析 / multipart 上传落盘循环。此前同一模式散落 share_multi / localimport / localfiles / file_request / share_user / notify_user / admin_manage 各写一份, 策略调整需逐处同步——统一到本文件单一实现(响应文案/状态码与原各处一致)。

管理端本地文件管理端点(对标上游 2.7.0 data/local 管理;AdminMiddleware 组内)。 路径以「root 索引 + 相对路径」表达,服务端配置为唯一真相源,杜绝穿越。

NAS 本地文件免上传导入端点(P3,手写路由)。

OIDC SSO HTTP 端点(P2,手写路由)。

运行时 OpenAPI 规范生成。

背景:openapi.json 曾依赖手工维护的快照文件(拆分后与路由漂移、容器内恒 404, 前端 /api-docs Swagger 页拉不到 spec)。这里改为在路由注册完成后从 hertz 运行时路由表生成「契约级骨架规范」——与实际注册路由零漂移,覆盖端点/方法/ 认证方式/路径参数。

边界(有意为之):骨架不内联请求/响应 schema,字段级真相源在 contracts 仓 thrift IDL;本规范用于端点发现、认证方式说明与 Swagger UI 可用性。

管理端设置测试端点:SMTP 测试发信 / OIDC discovery 验证(AdminMiddleware 组内)。 读取的是叠加后的全局 conf(管理端保存的在线设置已热应用),测的就是"当前生效值"。

取件元数据端点(GET /share/metadata/:code,手写路由)。 查询不扣次数、不要求密码;限流走 download 桶(2026-10-08 起未归桶路径另有全局默认桶兜底), 存在性探测面由 6 位随机码空间 + 统一 404 语义约束。

多文件分享创建端点(P0 多文件,手写路由不走 IDL):

POST /api/v1/share/multi-direct  multipart 多文件直传(小文件)
POST /api/v1/share/multi-bind    绑定已上传的 chunk 会话/presign 对象为一个多文件分享

Package handler 提供定制 HTTP handlers(不走 thrift IDL 生成)。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AdminBatchDeleteFiles

func AdminBatchDeleteFiles(ctx context.Context, c *app.RequestContext)

AdminBatchDeleteFiles 批量删除文件 POST /admin/files/batch-delete {ids:[]}

func AdminBatchExtendFiles

func AdminBatchExtendFiles(ctx context.Context, c *app.RequestContext)

AdminBatchExtendFiles 批量延期 POST /admin/files/batch-extend {ids:[], expire_value, expire_style}

func AdminBatchSetFilesStatus

func AdminBatchSetFilesStatus(ctx context.Context, c *app.RequestContext)

AdminBatchSetFilesStatus 批量设置分享管控状态(滥用处置主路径:定位 IP 后批量禁用) POST /admin/files/batch-status {ids: [..], status: normal|blocked|pending_review}

func AdminCreateUser

func AdminCreateUser(ctx context.Context, c *app.RequestContext)

AdminCreateUser 创建用户 POST /admin/users {username,email,password,nickname,role,max_storage_quota}

func AdminDeleteLocalFile

func AdminDeleteLocalFile(ctx context.Context, c *app.RequestContext)

AdminDeleteLocalFile DELETE /admin/local-files?root=0&path=a/b.txt

func AdminDeleteUser

func AdminDeleteUser(ctx context.Context, c *app.RequestContext)

AdminDeleteUser 删除用户(级联软删分享,带审计) DELETE /admin/users/:id

func AdminDownloadFile

func AdminDownloadFile(ctx context.Context, c *app.RequestContext)

AdminDownloadFile 管理端下载:302 到公开下载端点(附服务端签发的下载令牌) GET /admin/files/:id/download

func AdminEnhancedStats

func AdminEnhancedStats(ctx context.Context, c *app.RequestContext)

AdminEnhancedStats 富指标(昨日对比 / 下载总量 / top 后缀 / 类型分布 / 存储用量与配额) GET /admin/stats/enhanced

func AdminFileDetail

func AdminFileDetail(ctx context.Context, c *app.RequestContext)

AdminFileDetail 文件详情 GET /admin/files/:id

func AdminGetUserSettings

func AdminGetUserSettings(ctx context.Context, c *app.RequestContext)

AdminGetUserSettings 获取"用户配置"段(生效值:持久化优先,回退 yaml)。 GET /admin/config/user

func AdminImportLocalFile

func AdminImportLocalFile(ctx context.Context, c *app.RequestContext)

AdminImportLocalFile POST /admin/local-files/import 请求体:{root, path, expire_value, expire_style, require_auth, password, custom_code} 管理员把白名单目录内的文件直接生成提取码(服务端拷贝入存储,配额/审核同链路)。

func AdminListFilesFiltered

func AdminListFilesFiltered(ctx context.Context, c *app.RequestContext)

AdminListFilesFiltered 管理端文件列表组合过滤。 GET /admin/files/filter?keyword=&user_id=&upload_type=&owner_ip=&status=&

min_size=&max_size=&created_after=&created_before=&expired=&page=&page_size=

相比 IDL /admin/files(仅 keyword)补充滥用定位维度,返回项含 owner_ip/status/ upload_type/user_id(owner_ip 仅管理端可见)。

func AdminListLocalFiles

func AdminListLocalFiles(ctx context.Context, c *app.RequestContext)

AdminListLocalFiles GET /admin/local-files?root=0&dir=sub/dir 返回 {roots: [...], entries: [...]}(roots 供前端切换根目录)

func AdminListUsersFiltered

func AdminListUsersFiltered(ctx context.Context, c *app.RequestContext)

AdminListUsersFiltered 带筛选的用户列表(keyword/status/role) GET /admin/users/filter?keyword=&status=&role=&page=&page_size=

func AdminPurgeFiles

func AdminPurgeFiles(ctx context.Context, c *app.RequestContext)

AdminPurgeFiles 彻底删除(DB 硬删 + 存储对象删除,不可恢复) POST /admin/files/purge {ids:[]}

func AdminResetUserPassword

func AdminResetUserPassword(ctx context.Context, c *app.RequestContext)

AdminResetUserPassword 管理员重置用户密码 POST /admin/users/:id/reset-password {password}

func AdminRestoreFiles

func AdminRestoreFiles(ctx context.Context, c *app.RequestContext)

AdminRestoreFiles 从回收站恢复(软删 → 存活) POST /admin/files/restore {ids:[]}

func AdminSetFileStatus

func AdminSetFileStatus(ctx context.Context, c *app.RequestContext)

AdminSetFileStatus 设置单个分享管控状态(禁用/恢复/待审) PUT /admin/files/:id/status {status: normal|blocked|pending_review}

func AdminStatsTrend

func AdminStatsTrend(ctx context.Context, c *app.RequestContext)

AdminStatsTrend 趋势序列(连续 N 天,缺失日补 0): uploads 来自 file_codes 按天创建数,downloads 来自 transfer_logs(pkg/transfer 写入)。 GET /admin/stats/trend?days=7

func AdminTestOIDC

func AdminTestOIDC(ctx context.Context, c *app.RequestContext)

AdminTestOIDC POST /admin/oidc/test 验证当前生效 OIDC 段的 issuer discovery 端点可达且合法。

func AdminTestSMTP

func AdminTestSMTP(ctx context.Context, c *app.RequestContext)

AdminTestSMTP POST /admin/notify/smtp/test {"to":"you@example.com"} 用当前生效的 notify.smtp 配置向指定邮箱发送测试邮件。

func AdminTransferLogs

func AdminTransferLogs(ctx context.Context, c *app.RequestContext)

AdminTransferLogs 传输日志分页查询 GET /admin/logs/transfer?page=&page_size=&operation=&keyword=

func AdminUpdateFile

func AdminUpdateFile(ctx context.Context, c *app.RequestContext)

AdminUpdateFile 编辑文件(延期 / 改剩余次数) PUT /admin/files/:id {expire_value, expire_style, expired_count}

func AdminUpdateUser

func AdminUpdateUser(ctx context.Context, c *app.RequestContext)

AdminUpdateUser 更新用户(昵称/角色/状态/配额) PUT /admin/users/:id {nickname,role,status,max_storage_quota,max_upload_size}

func AdminUpdateUserSettings

func AdminUpdateUserSettings(ctx context.Context, c *app.RequestContext)

AdminUpdateUserSettings 在线更新"用户配置"段:写穿 DB 并即时生效 (注册开关/配额默认/会话时长)。 PUT /admin/config/user

func BatchDeleteUserShares

func BatchDeleteUserShares(ctx context.Context, c *app.RequestContext)

BatchDeleteUserShares 批量软删除我的分享 POST /api/v1/user/shares/batch-delete

func BatchExtendUserShares

func BatchExtendUserShares(ctx context.Context, c *app.RequestContext)

BatchExtendUserShares 批量延期我的分享 POST /api/v1/user/shares/batch-extend

func BuildOpenAPISpec

func BuildOpenAPISpec(routes []OpenAPIRoute, info SpecInfo) []byte

BuildOpenAPISpec 从路由表生成 OpenAPI 3.0 骨架规范

func FederationResolve

func FederationResolve(ctx context.Context, c *app.RequestContext)

FederationResolve 口令联邦解析。

func GetFileRequestPublic

func GetFileRequestPublic(ctx context.Context, c *app.RequestContext)

GetFileRequestPublic 访客取链接信息(GET /request/:token)

func GuestSubmitFiles

func GuestSubmitFiles(ctx context.Context, c *app.RequestContext)

GuestSubmitFiles 访客投递(POST /api/v1/request/:token/upload,multipart files[])。 显式受邀上传:不走 upload.open_upload 总闸(与 Gokapi File Requests 同策略)。

func HardDeleteUserShare

func HardDeleteUserShare(ctx context.Context, c *app.RequestContext)

HardDeleteUserShare 永久删除(仅已软删除的) DELETE /api/v1/user/shares/:code/hard

func ListMyNotifications

func ListMyNotifications(ctx context.Context, c *app.RequestContext)

ListMyNotifications 我的通知列表(含广播 + 定向) GET /api/v1/notifies/mine?page=1&page_size=20

func ListPublicNotifies added in v0.14.5

func ListPublicNotifies(ctx context.Context, c *app.RequestContext)

ListPublicNotifies 站级公告(匿名公开端点,对标上游首页通知条)。 notify.Active 已限定 target_user_id 为空的全站公告;匿名可访问, 前端 SiteNotice 组件消费(可关闭,localStorage 记忆已读)。

func ListUserShares

func ListUserShares(ctx context.Context, c *app.RequestContext)

ListUserShares 我的分享列表 GET /api/v1/user/shares?status=active&search=&page=1&page_size=20

func MarkNotifyRead

func MarkNotifyRead(ctx context.Context, c *app.RequestContext)

MarkNotifyRead 标记已读 POST /api/v1/notifies/mark-read

func MergeWithIDLSpec

func MergeWithIDLSpec(skeleton, idl []byte) []byte

MergeWithIDLSpec 骨架规范 × contracts IDL 规范(openapi.Spec)合并。

设计(2026-10-06 IDL/hz 治理链路):

  • IDL 治理域:paths 下的 operation 以 IDL 条目为准(带完整 request/response schema),但保留骨架独有的 security/tags 字段(认证矩阵真相源在运行时);
  • customizedRegister 手写路由:骨架独有路径/方法原样保留(骨架级、无 schema);
  • components:骨架的 securitySchemes 与 IDL 的 schemas 深并,键冲突 IDL 优先。

任一侧解析失败均回退骨架(可用性优先)。

func MultiShareBind

func MultiShareBind(ctx context.Context, c *app.RequestContext)

MultiShareBind 把多个已上传的 chunk 会话(或 presign 对象 key)绑定为 一个多文件分享。请求体:

{
  "entries": [{"upload_id": "..."} | {"object_key": "...", "file_name": "..."}],
  "expire_value": 1, "expire_style": "day", "require_auth": false, "password": ""
}

@router /api/v1/share/multi-bind [POST]

func MultiShareDirect

func MultiShareDirect(ctx context.Context, c *app.RequestContext)

MultiShareDirect 多文件直传建分享。 @router /api/v1/share/multi-direct [POST]

func OIDCCallback

func OIDCCallback(ctx context.Context, c *app.RequestContext)

OIDCCallback IdP 回调:换发本站 JWT 并 302 回前端(GET /api/v1/user/oidc/callback)

func OIDCLogin

func OIDCLogin(ctx context.Context, c *app.RequestContext)

OIDCLogin 302 跳转到 IdP 授权页(GET /api/v1/user/oidc/login)

func OpenAPISpec

func OpenAPISpec(_ context.Context, c *app.RequestContext)

OpenAPISpec 返回 OpenAPI 3.0 规范 GET /openapi.json 主路径:bootstrap 在路由注册完成后由运行时路由表生成(openapi_gen.go), 与实际注册路由零漂移。文件探测仅作兜底(./static/openapi.json = server 镜像布局;保留以兼容外置 spec 的部署方式)。

func RestoreUserShare

func RestoreUserShare(ctx context.Context, c *app.RequestContext)

RestoreUserShare 恢复软删除的分享 POST /api/v1/user/shares/:code/restore

func SetFederationService

func SetFederationService(s *federation.Service)

SetFederationService 注入联邦服务(bootstrap 调用;nil = 未启用)

func SetManageServices

func SetManageServices(svc *adminapp.Service, userSvc *userapp.Service, st storage.StorageInterface)

SetManageServices 注入管理端增强服务(bootstrap 调用)

func SetNotifyService

func SetNotifyService(s *notifyapp.Service)

SetNotifyService 注入 notify service

func SetOIDCService

func SetOIDCService(s *oidcApp.Service)

SetOIDCService 注入 OIDC 服务(bootstrap 调用)

func SetOpenAPISpecBytes

func SetOpenAPISpecBytes(b []byte)

SetOpenAPISpecBytes 注入生成的规范

func SetRequestService

func SetRequestService(s *requestApp.Service)

SetRequestService 注入寄件码服务(bootstrap 调用)

func SetShareService

func SetShareService(s *share.Service)

SetShareService 注入 share service(bootstrap 调用)

func ShareMetadata

func ShareMetadata(ctx context.Context, c *app.RequestContext)

ShareMetadata 元数据查询:供取件页渲染文件名/大小/有效期/剩余次数

func UnreadNotifyCount

func UnreadNotifyCount(ctx context.Context, c *app.RequestContext)

UnreadNotifyCount 未读数 GET /api/v1/notifies/unread-count

func UserCreateFileRequest

func UserCreateFileRequest(ctx context.Context, c *app.RequestContext)

UserCreateFileRequest 创建投递链接

func UserDeleteFileRequest

func UserDeleteFileRequest(ctx context.Context, c *app.RequestContext)

UserDeleteFileRequest 撤销投递链接

func UserImportLocal

func UserImportLocal(ctx context.Context, c *app.RequestContext)

UserImportLocal 本地文件导入为分享(POST /api/v1/user/shares/import-local)。 请求体:{path, expire_value, expire_style, require_auth, password, custom_code} 仅登录用户可用;路径必须落在 upload.local_import.roots 白名单内。

func UserListFileRequests

func UserListFileRequests(ctx context.Context, c *app.RequestContext)

UserListFileRequests 我的投递链接列表

Types

type BatchDeleteUserSharesReq

type BatchDeleteUserSharesReq struct {
	Codes []string `json:"codes"`
}

BatchDeleteUserSharesReq 批量删除请求体

type BatchExtendUserSharesReq

type BatchExtendUserSharesReq struct {
	Codes   []string `json:"codes"`
	Hours   int      `json:"hours"`   // 延长小时数(>0),0 = 永久
	Forever bool     `json:"forever"` // true = 设为永久
}

BatchExtendUserSharesReq 批量延期请求

type MarkNotifyReq

type MarkNotifyReq struct {
	All bool `json:"all"` // true=全部已读;忽略下面的 ids
}

MarkNotifyReq 标记已读请求

type OpenAPIRoute

type OpenAPIRoute struct {
	Method string
	Path   string
}

OpenAPIRoute 参与生成的最小路由信息(与 hertz 路由表类型解耦)

type SpecInfo

type SpecInfo struct {
	Version string // API 版本号(bootstrap 注入)
	BaseURL string // 空则省略 servers
}

SpecInfo 规范元信息

type UserSharesListData

type UserSharesListData struct {
	Items      []*share.UserShareListItem `json:"items"`
	Total      int64                      `json:"total"`
	Page       int                        `json:"page"`
	PageSize   int                        `json:"page_size"`
	TotalPages int64                      `json:"total_pages"`
	HasNext    bool                       `json:"has_next"`
	HasPrev    bool                       `json:"has_prev"`
}

type UserSharesResp

type UserSharesResp struct {
	Code    int                 `json:"code"`
	Message string              `json:"message"`
	Data    *UserSharesListData `json:"data,omitempty"`
}

UserSharesResp 列表响应

Jump to

Keyboard shortcuts

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