// 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 }