ghttpserver

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2025 License: MIT Imports: 24 Imported by: 0

README

GMC HTTP Server

简介

GMC HTTP Server 是一个功能强大的 HTTP 服务器实现,提供了完整的 Web 服务和 API 服务功能。支持路由、模板、会话、中间件、静态文件服务、HTTPS、HTTP/2 等特性。

功能特性

  • 双服务器模式:支持 HTTPServer(完整 Web 功能)和 APIServer(轻量级 API)
  • 强大的路由:基于高性能的 httprouter,支持 RESTful 路由
  • 模板引擎:支持多种模板引擎和自定义函数
  • 会话管理:内置会话支持,多种存储后端
  • 中间件系统:4 级中间件,灵活的请求处理流程
  • 静态文件服务:支持静态文件、嵌入式文件、Gzip 压缩
  • HTTPS/HTTP2:完整的 TLS 和 HTTP/2 支持
  • 优雅关闭:支持优雅关闭和重启
  • i18n 支持:内置国际化支持
  • 错误处理:可自定义 404、500 错误处理
  • 连接统计:实时连接数统计

安装

go get github.com/snail007/gmc

快速开始

创建简单的 Web 服务器
package main

import (
    "github.com/snail007/gmc"
)

func main() {
    // 创建应用
    app := gmc.New.App()
    
    // 加载配置
    cfg := app.Config()
    cfg.SetConfigFile("app.toml")
    cfg.ReadInConfig()
    
    // 创建 HTTP 服务器
    s := gmc.New.HTTPServer(app.Ctx())
    s.Init(cfg)
    
    // 配置路由
    s.Router().HandlerFunc("GET", "/", func(c gmc.C) {
        c.Write("Hello GMC!")
    })
    
    // 添加服务到应用
    app.AddService(gmc.ServiceItem{
        Service: s,
    })
    
    // 运行应用
    app.Run()
}
创建 API 服务器
package main

import (
    "github.com/snail007/gmc"
    gcore "github.com/snail007/gmc/core"
)

func main() {
    app := gmc.New.App()
    cfg := app.Config()
    cfg.SetConfigFile("app.toml")
    cfg.ReadInConfig()
    
    // 创建 API 服务器(轻量级,没有模板等功能)
    api, err := gmc.New.APIServer(app.Ctx(), ":8080")
    if err != nil {
        panic(err)
    }
    
    // 配置路由
    r := api.Router()
    r.HandlerFunc("GET", "/api/users", func(c gmc.C) {
        c.JSON(gcore.M{
            "users": []string{"Alice", "Bob"},
        })
    })
    
    // 添加服务
    app.AddService(gmc.ServiceItem{
        Service: api,
    })
    
    app.Run()
}
使用控制器
package main

import (
    "github.com/snail007/gmc"
)

type UserController struct {
    gmc.Controller
}

func (c *UserController) List() {
    c.Write("User list")
}

func (c *UserController) Detail() {
    id := c.Query("id")
    c.Write("User detail: " + id)
}

func main() {
    app := gmc.New.App()
    cfg := app.Config()
    cfg.SetConfigFile("app.toml")
    cfg.ReadInConfig()
    
    s := gmc.New.HTTPServer(app.Ctx())
    s.Init(cfg)
    
    // 绑定控制器
    // 访问: /user/list, /user/detail
    s.Router().Controller("/user", new(UserController))
    
    app.AddService(gmc.ServiceItem{Service: s})
    app.Run()
}

配置文件

app.toml 基本配置
[httpserver]
# 监听地址
listen = ":8080"

# 优雅关闭超时时间(秒)
graceshutdowntimeout = 15

# 静态文件目录
static = "./static"

# 模板目录
template = "./views"

# 会话配置
[session]
ttl = 3600
store = "memory"

# 日志配置
[log]
level = "info"
output = "stdout"
HTTPS 配置
[httpserver]
listen = ":8443"

# TLS 配置
[httpserver.tls]
# 启用 TLS
enable = true
# 证书文件
cert = "./cert.pem"
# 密钥文件
key = "./key.pem"
# 客户端证书认证
[httpserver.tls.clientauth]
enable = false
ca = ""
HTTP/2 配置

HTTP/2 在启用 TLS 后自动启用,无需额外配置。

中间件系统

GMC 提供 4 级中间件,按执行顺序:

Middleware0 - 路由前中间件

在路由匹配之前执行,可以用于全局过滤:

s.AddMiddleware0(func(c gmc.C) (isStop bool) {
    // 记录所有请求
    c.Logger().Info(c.Request().URL.Path)
    
    // 返回 true 停止后续处理
    if c.Request().URL.Path == "/blocked" {
        c.WriteHeader(403)
        c.Write("Forbidden")
        return true
    }
    
    return false
})
Middleware1 - 路由后、控制器前

路由匹配后、控制器方法执行前:

s.AddMiddleware1(func(c gmc.C) (isStop bool) {
    // 身份验证
    token := c.Header("Authorization")
    if token == "" {
        c.WriteHeader(401)
        c.JSON(gcore.M{"error": "Unauthorized"})
        return true
    }
    
    return false
})
Middleware2 - 控制器后

控制器方法执行后:

s.AddMiddleware2(func(c gmc.C) (isStop bool) {
    // 添加响应头
    c.SetHeader("X-Powered-By", "GMC")
    return false
})
Middleware3 - 最后执行

所有处理完成后,适合日志记录:

s.AddMiddleware3(func(c gmc.C) (isStop bool) {
    // 记录响应状态和耗时
    c.Logger().Infof("%s %d %dms", 
        c.Request().URL.Path, 
        c.StatusCode(), 
        c.TimeUsed()/1000000)
    return false
})
使用内置中间件
import "github.com/snail007/gmc/module/middleware/accesslog"

func InitRouter(s *gmc.HTTPServer) {
    // 访问日志中间件
    s.AddMiddleware3(accesslog.NewFromConfig(s.Config()))
    
    // 其他路由配置...
}

静态文件服务

提供静态文件
// 方法 1:配置文件
// app.toml
// [httpserver]
// static = "./static"
// staticurlpath = "/static"

// 方法 2:代码设置
s.SetStaticDir("./static")
s.SetStaticUrlPath("/static")

// 访问: http://localhost:8080/static/css/style.css
// 映射到: ./static/css/style.css
嵌入式静态文件
package main

import (
    "embed"
    "github.com/snail007/gmc"
)

//go:embed static/*
var staticFS embed.FS

func main() {
    app := gmc.New.App()
    s := gmc.New.HTTPServer(app.Ctx())
    
    // 从嵌入式文件系统提供静态文件
    s.Ext(".html")
    s.Router().HandlerAny("/static/*filepath", func(c gmc.C) {
        filepath := c.Param("filepath")
        data, _ := staticFS.ReadFile("static" + filepath)
        c.Write(string(data))
    })
    
    app.AddService(gmc.ServiceItem{Service: s})
    app.Run()
}

模板渲染

使用模板
type HomeController struct {
    gmc.Controller
}

func (c *HomeController) Index() {
    data := gcore.M{
        "title": "Welcome",
        "name":  "GMC",
    }
    c.View("index", data)
}
添加模板函数
s.AddFuncMap(map[string]interface{}{
    "add": func(a, b int) int {
        return a + b
    },
    "upper": func(s string) string {
        return strings.ToUpper(s)
    },
})

模板中使用:

<h1>{{.title}}</h1>
<p>{{upper .name}}</p>
<p>Sum: {{add 1 2}}</p>

会话管理

type LoginController struct {
    gmc.Controller
}

func (c *LoginController) Login() {
    username := c.PostForm("username")
    password := c.PostForm("password")
    
    // 验证...
    
    // 启动会话
    c.SessionStart()
    defer c.SessionDestroy()
    
    // 设置会话数据
    c.Session().Set("user_id", "123")
    c.Session().Set("username", username)
    
    c.JSON(gcore.M{"status": "ok"})
}

func (c *LoginController) Profile() {
    c.SessionStart()
    defer c.SessionDestroy()
    
    // 读取会话数据
    userID, ok := c.Session().Get("user_id")
    if !ok {
        c.WriteHeader(401)
        c.JSON(gcore.M{"error": "Not logged in"})
        return
    }
    
    c.JSON(gcore.M{
        "user_id": userID,
    })
}

错误处理

自定义 404 处理
s.SetNotFoundHandler(func(c gmc.C, tpl gcore.Template) {
    c.WriteHeader(404)
    c.View("404", gcore.M{
        "path": c.Request().URL.Path,
    })
})
自定义 500 处理
s.SetErrorHandler(func(c gmc.C, tpl gcore.Template, err interface{}) {
    c.WriteHeader(500)
    c.Logger().Errorf("Internal error: %v", err)
    c.View("500", gcore.M{
        "error": err,
    })
})

HTTPS 和 HTTP/2

启用 HTTPS
[httpserver]
listen = ":8443"

[httpserver.tls]
enable = true
cert = "./cert.pem"
key = "./key.pem"
生成自签名证书(测试用)
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
客户端证书认证
[httpserver.tls]
enable = true
cert = "./server.pem"
key = "./server-key.pem"

[httpserver.tls.clientauth]
enable = true
ca = "./ca.pem"

高级功能

自定义监听器
s.SetListenerFactory(func(addr string) (net.Listener, error) {
    // 自定义 Listener 配置
    lc := net.ListenConfig{
        KeepAlive: 30 * time.Second,
    }
    return lc.Listen(context.Background(), "tcp", addr)
})
连接计数
count := s.ActiveConnCount()
fmt.Printf("Active connections: %d\n", count)
优雅关闭
// 配置文件设置超时
[httpserver]
graceshutdowntimeout = 15

// 或代码设置
s.SetConfig(cfg)

// 服务器会在接收到 SIGTERM/SIGINT 信号时优雅关闭

API 参考

HTTPServer 主要方法
// 初始化
func (s *HTTPServer) Init(cfg gcore.Config) error

// 路由
func (s *HTTPServer) Router() gcore.HTTPRouter

// 中间件
func (s *HTTPServer) AddMiddleware0(m gcore.Middleware)
func (s *HTTPServer) AddMiddleware1(m gcore.Middleware)
func (s *HTTPServer) AddMiddleware2(m gcore.Middleware)
func (s *HTTPServer) AddMiddleware3(m gcore.Middleware)

// 静态文件
func (s *HTTPServer) SetStaticDir(dir string)
func (s *HTTPServer) SetStaticUrlPath(path string)

// 错误处理
func (s *HTTPServer) SetNotFoundHandler(fn func(ctx gcore.Ctx, tpl gcore.Template))
func (s *HTTPServer) SetErrorHandler(fn func(ctx gcore.Ctx, tpl gcore.Template, err interface{}))

// 模板
func (s *HTTPServer) AddFuncMap(f map[string]interface{})

// 配置
func (s *HTTPServer) Config() gcore.Config
func (s *HTTPServer) SetConfig(c gcore.Config)

// 其他
func (s *HTTPServer) Logger() gcore.Logger
func (s *HTTPServer) ActiveConnCount() int64
func (s *HTTPServer) Close()
APIServer

APIServer 是 HTTPServer 的轻量级版本,移除了模板、会话等功能,适合纯 API 服务:

// 创建 API 服务器
func NewAPIServer(ctx gcore.Ctx, address string) (gcore.APIServer, error)

// API 服务器有相同的路由和中间件功能,但没有:
// - 模板引擎
// - 会话管理
// - 静态文件服务

最佳实践

1. 项目结构
myapp/
├── main.go              # 入口
├── app.toml            # 配置
├── controller/         # 控制器
│   ├── user.go
│   └── product.go
├── router/             # 路由配置
│   └── router.go
├── initialize/         # 初始化
│   └── init.go
├── model/              # 数据模型
├── views/              # 模板
└── static/             # 静态文件
2. 路由组织
// router/router.go
package router

import "github.com/snail007/gmc"

func InitRouter(s *gmc.HTTPServer) {
    r := s.Router()
    
    // 静态页面
    r.Controller("/", new(controller.Home))
    
    // API 路由
    api := r.Group("/api")
    {
        api.Controller("/users", new(controller.User))
        api.Controller("/products", new(controller.Product))
    }
    
    // 管理后台
    admin := r.Group("/admin")
    {
        admin.Controller("/dashboard", new(controller.Dashboard))
    }
}
3. 中间件使用
// 按需使用不同级别的中间件
s.AddMiddleware0(corsMiddleware)      // 全局 CORS
s.AddMiddleware1(authMiddleware)      // 需要路由信息的认证
s.AddMiddleware2(responseMiddleware)  // 修改响应
s.AddMiddleware3(accesslog.NewFromConfig(s.Config())) // 访问日志
4. 错误恢复

控制器中的 panic 会被自动捕获,触发 500 错误处理器。

性能优化

  1. 启用 Gzip:自动压缩响应(配置 gzip = true
  2. 静态文件缓存:设置适当的 Cache-Control 头
  3. 连接池:数据库连接池配置
  4. 异步日志:使用异步日志减少 I/O 阻塞
  5. HTTP/2:启用 HTTP/2 提升性能

注意事项

  1. 端口权限:监听 1024 以下端口需要 root 权限
  2. 优雅关闭:设置合理的 graceshutdowntimeout
  3. 日志记录:生产环境使用异步日志
  4. HTTPS:生产环境务必使用 HTTPS
  5. 会话安全:使用 HttpOnly 和 Secure Cookie

相关链接

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SetBinBase64

func SetBinBase64(data map[string]string)

SetBinBase64 key is file path no slash prefix, value is file base64 encoded bytes contents.

func SetBinBytes

func SetBinBytes(data map[string][]byte)

SetBinBytes key is file path no slash prefix, value is file's bytes contents.

Types

type APIServer

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

func NewAPIServer

func NewAPIServer(ctx gcore.Ctx, address string) *APIServer

func NewAPIServerForProvider

func NewAPIServerForProvider(ctx gcore.Ctx, address string) (*APIServer, error)

func NewDefaultAPIServer

func NewDefaultAPIServer(ctx gcore.Ctx, config gcore.Config) (api *APIServer, err error)

func (*APIServer) API

func (this *APIServer) API(path string, handle func(ctx gcore.Ctx), ext ...string)

func (*APIServer) ActiveConnCount

func (s *APIServer) ActiveConnCount() int64

func (*APIServer) AddMiddleware0

func (this *APIServer) AddMiddleware0(m gcore.Middleware)

func (*APIServer) AddMiddleware1

func (this *APIServer) AddMiddleware1(m gcore.Middleware)

func (*APIServer) AddMiddleware2

func (this *APIServer) AddMiddleware2(m gcore.Middleware)

func (*APIServer) AddMiddleware3

func (this *APIServer) AddMiddleware3(m gcore.Middleware)

func (*APIServer) Address

func (this *APIServer) Address() string

func (*APIServer) Ctx

func (this *APIServer) Ctx() gcore.Ctx

func (*APIServer) Ext

func (this *APIServer) Ext(ext string)

func (*APIServer) GracefulStop

func (this *APIServer) GracefulStop()

GracefulStop implements gcore.Service GracefulStop

func (*APIServer) Group

func (this *APIServer) Group(path string) gcore.APIServer

func (*APIServer) Init

func (s *APIServer) Init(cfg gcore.Config) (err error)

Init implements gcore.Service Init

func (*APIServer) InjectListeners

func (this *APIServer) InjectListeners(l []net.Listener)

InjectListeners implements gcore.Service InjectListeners

func (*APIServer) Listener

func (this *APIServer) Listener() net.Listener

func (*APIServer) ListenerFactory

func (this *APIServer) ListenerFactory() func(addr string) (net.Listener, error)

func (*APIServer) Listeners

func (this *APIServer) Listeners() []net.Listener

Listeners implements gcore.Service Listeners

func (*APIServer) Logger

func (this *APIServer) Logger() gcore.Logger

func (*APIServer) PrintRouteTable

func (this *APIServer) PrintRouteTable(w io.Writer)

PrintRouteTable dump all routes into `w`, if `w` is nil, os.Stdout will be used.

func (*APIServer) Router

func (this *APIServer) Router() gcore.HTTPRouter

func (*APIServer) Run

func (this *APIServer) Run() (err error)

func (*APIServer) ServeEmbedFS

func (s *APIServer) ServeEmbedFS(fs embed.FS, urlPath string)

func (*APIServer) ServeFiles

func (s *APIServer) ServeFiles(rootPath, urlPath string)

func (*APIServer) ServeHTTP

func (this *APIServer) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*APIServer) Server

func (this *APIServer) Server() *http.Server

func (*APIServer) SetErrorHandler

func (this *APIServer) SetErrorHandler(handle func(ctx gcore.Ctx, err interface{}))

func (*APIServer) SetListenerFactory

func (this *APIServer) SetListenerFactory(listenerFactory func(addr string) (net.Listener, error))

func (*APIServer) SetLog

func (this *APIServer) SetLog(l gcore.Logger)

SetLog implements gcore.Service SetLog

func (*APIServer) SetLogger

func (this *APIServer) SetLogger(l gcore.Logger)

func (*APIServer) SetNotFoundHandler

func (this *APIServer) SetNotFoundHandler(handle func(ctx gcore.Ctx))

func (*APIServer) SetTLSFile

func (this *APIServer) SetTLSFile(certFile, keyFile string)

func (*APIServer) ShowErrorStack

func (this *APIServer) ShowErrorStack(isShow bool)

func (*APIServer) Start

func (this *APIServer) Start() (err error)

Start implements gcore.Service Start

func (*APIServer) Stop

func (this *APIServer) Stop()

Stop implements gcore.Service Stop

type HTTPServer

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

func NewHTTPServer

func NewHTTPServer(ctx gcore.Ctx) *HTTPServer

func (*HTTPServer) ActiveConnCount

func (s *HTTPServer) ActiveConnCount() int64

func (*HTTPServer) AddFuncMap

func (s *HTTPServer) AddFuncMap(f map[string]interface{})

AddFuncMap adds helper functions to template

func (*HTTPServer) AddMiddleware0

func (s *HTTPServer) AddMiddleware0(m gcore.Middleware)

func (*HTTPServer) AddMiddleware1

func (s *HTTPServer) AddMiddleware1(m gcore.Middleware)

func (*HTTPServer) AddMiddleware2

func (s *HTTPServer) AddMiddleware2(m gcore.Middleware)

func (*HTTPServer) AddMiddleware3

func (s *HTTPServer) AddMiddleware3(m gcore.Middleware)

func (*HTTPServer) Close

func (s *HTTPServer) Close()

func (*HTTPServer) Config

func (s *HTTPServer) Config() gcore.Config

func (*HTTPServer) Ctx

func (s *HTTPServer) Ctx() gcore.Ctx

func (*HTTPServer) GracefulStop

func (s *HTTPServer) GracefulStop()

GracefulStop implements service.Service GracefulStop

func (*HTTPServer) Init

func (s *HTTPServer) Init(cfg gcore.Config) (err error)

Init implements service.Service Init

func (*HTTPServer) InjectListeners

func (s *HTTPServer) InjectListeners(l []net.Listener)

InjectListeners implements service.Service InjectListeners

func (*HTTPServer) Listen

func (s *HTTPServer) Listen() (err error)

func (*HTTPServer) ListenTLS

func (s *HTTPServer) ListenTLS() (err error)

func (*HTTPServer) Listener

func (s *HTTPServer) Listener() net.Listener

func (*HTTPServer) ListenerFactory

func (this *HTTPServer) ListenerFactory() func(addr string) (net.Listener, error)

func (*HTTPServer) Listeners

func (s *HTTPServer) Listeners() []net.Listener

Listeners implements service.Service Listeners

func (*HTTPServer) Logger

func (s *HTTPServer) Logger() gcore.Logger

func (*HTTPServer) PrintRouteTable

func (s *HTTPServer) PrintRouteTable(w io.Writer)

PrintRouteTable dump all routes into `w`, if `w` is nil, os.Stdout will be used.

func (*HTTPServer) Router

func (s *HTTPServer) Router() gcore.HTTPRouter

func (*HTTPServer) ServeEmbedFS

func (s *HTTPServer) ServeEmbedFS(fs embed.FS, urlPath string)

func (*HTTPServer) ServeFiles

func (s *HTTPServer) ServeFiles(rootPath, urlPath string)

func (*HTTPServer) ServeHTTP

func (s *HTTPServer) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*HTTPServer) Server

func (s *HTTPServer) Server() *http.Server

func (*HTTPServer) SessionStore

func (s *HTTPServer) SessionStore() gcore.SessionStorage

func (*HTTPServer) SetBinBytes

func (s *HTTPServer) SetBinBytes(binData map[string][]byte)

SetBinBytes key is file path no slash prefix, value is file's bytes contents.

func (*HTTPServer) SetConfig

func (s *HTTPServer) SetConfig(c gcore.Config)

func (*HTTPServer) SetCtx

func (s *HTTPServer) SetCtx(ctx gcore.Ctx)

func (*HTTPServer) SetErrorHandler

func (s *HTTPServer) SetErrorHandler(fn func(ctx gcore.Ctx, tpl gcore.Template, err interface{}))

func (*HTTPServer) SetListenerFactory

func (this *HTTPServer) SetListenerFactory(listenerFactory func(addr string) (net.Listener, error))

func (*HTTPServer) SetLog

func (s *HTTPServer) SetLog(l gcore.Logger)

SetLog implements service.Service SetLog

func (*HTTPServer) SetLogger

func (s *HTTPServer) SetLogger(l gcore.Logger)

func (*HTTPServer) SetNotFoundHandler

func (s *HTTPServer) SetNotFoundHandler(fn func(ctx gcore.Ctx, tpl gcore.Template))

func (*HTTPServer) SetRouter

func (s *HTTPServer) SetRouter(r gcore.HTTPRouter)

func (*HTTPServer) SetSessionStore

func (s *HTTPServer) SetSessionStore(st gcore.SessionStorage)

func (*HTTPServer) SetTpl

func (s *HTTPServer) SetTpl(t gcore.Template)

func (*HTTPServer) Start

func (s *HTTPServer) Start() (err error)

Start implements service.Service Start

func (*HTTPServer) Stop

func (s *HTTPServer) Stop()

Stop implements service.Service Stop

func (*HTTPServer) Tpl

func (s *HTTPServer) Tpl() gcore.Template

Jump to

Keyboard shortcuts

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