lolly/internal/server/vhost.go
xfy 92cd93d4c0 refactor: 代码改进与注释补充
- logging: 补充包文档说明
- pool: 修复 workers 计数器并发安全 (atomic 操作)
- stream: 完善注释与错误处理
- handler/static: 添加预压缩文件支持接口
- loadbalance: 补充算法注释
- vhost: 改进虚拟主机路由逻辑
- ssl: 优化证书加载注释
- main: 补充启动流程注释

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-03 16:57:59 +08:00

131 lines
3.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package server 提供 HTTP 服务器的核心实现,支持单服务器和虚拟主机两种运行模式。
//
// 该文件包含虚拟主机管理相关的核心逻辑,包括:
// - 虚拟主机管理器的创建和配置
// - 基于 Host 头的请求分发
// - 默认主机 fallback 机制
//
// 主要用途:
//
// 用于支持多域名虚拟主机场景,根据请求的 Host 头分发到不同的处理器。
//
// 注意事项:
// - 所有方法均为并发安全
// - 未匹配的 Host 头请求由默认主机处理
//
// 作者xfy
package server
import (
"github.com/valyala/fasthttp"
)
// VHostManager 虚拟主机管理器。
//
// 管理多个虚拟主机,根据请求的 Host 头分发到对应的处理器。
// 支持默认主机作为未匹配请求的 fallback。
type VHostManager struct {
// hosts 虚拟主机映射,按 server name 索引
hosts map[string]*VirtualHost
// defaultHost 默认主机,处理未匹配的 Host 头请求
defaultHost *VirtualHost
}
// VirtualHost 虚拟主机。
//
// 代表一个虚拟主机配置,包含名称和对应的请求处理器。
type VirtualHost struct {
// name 虚拟主机名称(域名)
name string
// handler 请求处理器
handler fasthttp.RequestHandler
}
// NewVHostManager 创建虚拟主机管理器。
//
// 返回值:
// - *VHostManager: 新创建的管理器实例
func NewVHostManager() *VHostManager {
return &VHostManager{
hosts: make(map[string]*VirtualHost),
}
}
// AddHost 添加虚拟主机。
//
// 参数:
// - name: 虚拟主机名称(域名)
// - handler: 请求处理器
func (v *VHostManager) AddHost(name string, handler fasthttp.RequestHandler) {
v.hosts[name] = &VirtualHost{
name: name,
handler: handler,
}
}
// SetDefault 设置默认主机。
//
// 参数:
// - handler: 默认主机的请求处理器
func (v *VHostManager) SetDefault(handler fasthttp.RequestHandler) {
v.defaultHost = &VirtualHost{
name: "default",
handler: handler,
}
}
// Handler 返回虚拟主机选择器。
//
// 返回值:
// - fasthttp.RequestHandler: 根据 Host 头分发请求的处理器
func (v *VHostManager) Handler() fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) {
host := stripPort(string(ctx.Host()))
if vhost, ok := v.hosts[host]; ok {
vhost.handler(ctx)
} else if v.defaultHost != nil {
v.defaultHost.handler(ctx)
} else {
ctx.Error("Host not found", fasthttp.StatusNotFound)
}
}
}
// stripPort 从 Host 头中移除端口号。
//
// 支持 IPv4 和 IPv6 格式:
// - example.com:8080 -> example.com
// - [::1]:8080 -> [::1]
// - [2001:db8::1]:443 -> [2001:db8::1]
// - example.com -> example.com
func stripPort(host string) string {
// 空字符串直接返回
if len(host) == 0 {
return host
}
// IPv6 格式:以 '[' 开头,找 ']:' 作为分隔点
if host[0] == '[' {
// 查找 ']:' 分隔符
for i := 0; i < len(host)-1; i++ {
if host[i] == ']' && host[i+1] == ':' {
return host[:i+1] // 返回包含 ']' 的部分,如 "[::1]"
}
}
// 没有 ']:' 分隔符,可能是纯 IPv6 地址(如 "[::1]"
return host
}
// IPv4 或域名格式:找第一个 ':' 作为分隔点
for i := 0; i < len(host); i++ {
if host[i] == ':' {
return host[:i]
}
}
return host
}