mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-28 05:46:36 +08:00
aa4faddade
Result: {"status":"keep","total_issues":8,"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_exhaustive":0,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":1,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":8,"golint_test_testifylint":0,"golint_test_thelper":0,"golint_test_usetesting":0,"golint_test_total":0,"golint_vetx_total":0,"eslint_problems":0,"eslint_errors":0,"eslint_warnings":0,"tsc_errors":0,"vitest_failed":0,"vitest_total":116,"measure_s":81}
155 lines
6.8 KiB
Go
155 lines
6.8 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package openresty
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type routeCertPartition struct {
|
|
httpOnlyDomains []string
|
|
domainsByCertID map[uint][]string
|
|
}
|
|
|
|
func partitionRouteDomainsByCert(domains []string, certIDs, domainCertIDs []uint) routeCertPartition {
|
|
httpOnlyDomains := make([]string, 0, len(domains))
|
|
domainsByCertID := make(map[uint][]string, len(certIDs))
|
|
for index, domain := range domains {
|
|
if index >= len(domainCertIDs) || domainCertIDs[index] == 0 {
|
|
httpOnlyDomains = append(httpOnlyDomains, domain)
|
|
continue
|
|
}
|
|
domainsByCertID[domainCertIDs[index]] = append(domainsByCertID[domainCertIDs[index]], domain)
|
|
}
|
|
return routeCertPartition{
|
|
httpOnlyDomains: httpOnlyDomains,
|
|
domainsByCertID: domainsByCertID,
|
|
}
|
|
}
|
|
|
|
func validateRouteCertificates(route Route, displayName string, certIDs []uint, partition routeCertPartition, certificates map[uint]string) error {
|
|
for _, certID := range certIDs {
|
|
assignedDomains := partition.domainsByCertID[certID]
|
|
if len(assignedDomains) == 0 {
|
|
continue
|
|
}
|
|
certPEM, ok := certificates[certID]
|
|
if !ok {
|
|
return fmt.Errorf("route %s certificate %d does not exist", route.SiteName, certID)
|
|
}
|
|
if err := validateCertificateCoverage(certPEM, assignedDomains); err != nil {
|
|
return fmt.Errorf("site %s certificate validation failed: %w", displayName, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func renderPagesRouteHTTPS(
|
|
builder *strings.Builder,
|
|
serverNames, displayName string,
|
|
route Route,
|
|
partition routeCertPartition,
|
|
certIDs []uint,
|
|
limitConfig routeLimitConfig,
|
|
powEnabled bool,
|
|
cfg ConfigSnapshot,
|
|
) {
|
|
if route.RedirectHTTP {
|
|
if len(partition.httpOnlyDomains) > 0 {
|
|
builder.WriteString(renderHTTPPagesServer(renderServerNames(partition.httpOnlyDomains), displayName, route.PagesDeployment, limitConfig, powEnabled, route.BasicAuthEnabled, route.BasicAuthUsername, route.BasicAuthPassword, false, cfg))
|
|
}
|
|
for _, certID := range certIDs {
|
|
if assignedDomains := partition.domainsByCertID[certID]; len(assignedDomains) > 0 {
|
|
builder.WriteString(renderHTTPRedirectServer(renderServerNames(assignedDomains)))
|
|
}
|
|
}
|
|
} else {
|
|
builder.WriteString(renderHTTPPagesServer(serverNames, displayName, route.PagesDeployment, limitConfig, powEnabled, route.BasicAuthEnabled, route.BasicAuthUsername, route.BasicAuthPassword, false, cfg))
|
|
}
|
|
for _, certID := range certIDs {
|
|
if assignedDomains := partition.domainsByCertID[certID]; len(assignedDomains) > 0 {
|
|
builder.WriteString(renderHTTPSPagesServer(renderServerNames(assignedDomains), displayName, certID, route.PagesDeployment, limitConfig, powEnabled, route.BasicAuthEnabled, route.BasicAuthUsername, route.BasicAuthPassword, routeSWEnabled(assignedDomains, cfg), cfg))
|
|
}
|
|
}
|
|
}
|
|
|
|
func renderProxyRouteHTTPS(
|
|
builder *strings.Builder,
|
|
serverNames, displayName string,
|
|
route Route,
|
|
partition routeCertPartition,
|
|
certIDs []uint,
|
|
cacheConfig routeCacheConfig,
|
|
limitConfig routeLimitConfig,
|
|
upstreamConfig routeUpstreamConfig,
|
|
powEnabled bool,
|
|
cfg ConfigSnapshot,
|
|
) {
|
|
if route.RedirectHTTP {
|
|
if len(partition.httpOnlyDomains) > 0 {
|
|
builder.WriteString(renderHTTPProxyServer(renderServerNames(partition.httpOnlyDomains), displayName, route.OriginURL, route.OriginHost, route.CustomHeaders, cacheConfig, limitConfig, upstreamConfig, powEnabled, route.BasicAuthEnabled, route.BasicAuthUsername, route.BasicAuthPassword, false, cfg))
|
|
}
|
|
for _, certID := range certIDs {
|
|
if assignedDomains := partition.domainsByCertID[certID]; len(assignedDomains) > 0 {
|
|
builder.WriteString(renderHTTPRedirectServer(renderServerNames(assignedDomains)))
|
|
}
|
|
}
|
|
} else {
|
|
builder.WriteString(renderHTTPProxyServer(serverNames, displayName, route.OriginURL, route.OriginHost, route.CustomHeaders, cacheConfig, limitConfig, upstreamConfig, powEnabled, route.BasicAuthEnabled, route.BasicAuthUsername, route.BasicAuthPassword, false, cfg))
|
|
}
|
|
for _, certID := range certIDs {
|
|
if assignedDomains := partition.domainsByCertID[certID]; len(assignedDomains) > 0 {
|
|
builder.WriteString(renderHTTPSServer(renderServerNames(assignedDomains), displayName, route.OriginURL, route.OriginHost, certID, route.CustomHeaders, cacheConfig, limitConfig, upstreamConfig, powEnabled, route.BasicAuthEnabled, route.BasicAuthUsername, route.BasicAuthPassword, routeSWEnabled(assignedDomains, cfg), cfg))
|
|
}
|
|
}
|
|
}
|
|
|
|
func renderPagesRoute(builder *strings.Builder, route Route, displayName, serverNames string, certificates map[uint]string, limitConfig routeLimitConfig, powEnabled bool, cfg ConfigSnapshot) error {
|
|
if route.PagesDeployment == nil {
|
|
return fmt.Errorf("route %s pages deployment is missing", route.SiteName)
|
|
}
|
|
if !route.EnableHTTPS {
|
|
builder.WriteString(renderHTTPPagesServer(serverNames, displayName, route.PagesDeployment, limitConfig, powEnabled, route.BasicAuthEnabled, route.BasicAuthUsername, route.BasicAuthPassword, false, cfg))
|
|
return nil
|
|
}
|
|
certIDs := certificateIDsFromDomainCertIDs(route.DomainCertIDs)
|
|
domainCertIDs := route.DomainCertIDs
|
|
if len(certIDs) == 0 {
|
|
return fmt.Errorf("路由 %s 未配置证书", route.SiteName)
|
|
}
|
|
partition := partitionRouteDomainsByCert(normalizedRouteDomains(route), certIDs, domainCertIDs)
|
|
if err := validateRouteCertificates(route, displayName, certIDs, partition, certificates); err != nil {
|
|
return err
|
|
}
|
|
renderPagesRouteHTTPS(builder, serverNames, displayName, route, partition, certIDs, limitConfig, powEnabled, cfg)
|
|
return nil
|
|
}
|
|
|
|
func renderProxyRoute(builder *strings.Builder, route Route, displayName, serverNames string, certificates map[uint]string, cacheConfig routeCacheConfig, limitConfig routeLimitConfig, powEnabled bool, cfg ConfigSnapshot) error {
|
|
upstreams := route.Upstreams
|
|
if len(upstreams) == 0 && strings.TrimSpace(route.OriginURL) != "" {
|
|
upstreams = []string{route.OriginURL}
|
|
}
|
|
upstreamConfig := buildRouteUpstreamConfig(route, upstreams)
|
|
if upstreamConfig.UsesNamedUpstream {
|
|
builder.WriteString(renderNamedUpstreamBlock(upstreamConfig))
|
|
}
|
|
if !route.EnableHTTPS {
|
|
builder.WriteString(renderHTTPProxyServer(serverNames, displayName, route.OriginURL, route.OriginHost, route.CustomHeaders, cacheConfig, limitConfig, upstreamConfig, powEnabled, route.BasicAuthEnabled, route.BasicAuthUsername, route.BasicAuthPassword, false, cfg))
|
|
return nil
|
|
}
|
|
certIDs := certificateIDsFromDomainCertIDs(route.DomainCertIDs)
|
|
domainCertIDs := route.DomainCertIDs
|
|
if len(certIDs) == 0 {
|
|
return fmt.Errorf("路由 %s 未配置证书", route.SiteName)
|
|
}
|
|
partition := partitionRouteDomainsByCert(normalizedRouteDomains(route), certIDs, domainCertIDs)
|
|
if err := validateRouteCertificates(route, displayName, certIDs, partition, certificates); err != nil {
|
|
return err
|
|
}
|
|
renderProxyRouteHTTPS(builder, serverNames, displayName, route, partition, certIDs, cacheConfig, limitConfig, upstreamConfig, powEnabled, cfg)
|
|
return nil
|
|
}
|