fix(ogtags): cache SNI clients and simplify request handling

This commit is contained in:
Jason Cameron
2025-11-16 03:03:03 -05:00
parent 95b027c480
commit 116a349697
3 changed files with 56 additions and 27 deletions

View File

@@ -2,7 +2,6 @@ package ogtags
import ( import (
"context" "context"
"crypto/tls"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@@ -28,42 +27,26 @@ func (c *OGTagCache) fetchHTMLDocumentWithCache(ctx context.Context, urlStr stri
} }
// Set the Host header to the original host // Set the Host header to the original host
var hostForRequest string
switch { switch {
case c.targetHost != "": case c.targetHost != "":
req.Host = c.targetHost hostForRequest = c.targetHost
case originalHost != "": case originalHost != "":
req.Host = originalHost hostForRequest = originalHost
}
if hostForRequest != "" {
req.Host = hostForRequest
} }
// Add proxy headers // Add proxy headers
req.Header.Set("X-Forwarded-Proto", "https") req.Header.Set("X-Forwarded-Proto", "https")
req.Header.Set("User-Agent", "Anubis-OGTag-Fetcher/1.0") // For tracking purposes req.Header.Set("User-Agent", "Anubis-OGTag-Fetcher/1.0") // For tracking purposes
client := c.client serverName := hostForRequest
if serverName == "" {
if c.targetSNIAuto { serverName = req.URL.Hostname()
serverName := originalHost
if c.targetHost != "" {
serverName = c.targetHost
}
if serverName != "" {
transport := c.transport.Clone()
if transport.TLSClientConfig == nil {
transport.TLSClientConfig = &tls.Config{}
}
transport.TLSClientConfig.ServerName = serverName
if c.insecureSkipVerify {
transport.TLSClientConfig.InsecureSkipVerify = true
}
client = &http.Client{
Timeout: httpTimeout,
Transport: transport,
}
defer transport.CloseIdleConnections()
}
} }
client := c.clientForSNI(serverName)
// Send the request // Send the request
resp, err := client.Do(req) resp, err := client.Do(req)

View File

@@ -8,6 +8,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
"sync"
"time" "time"
"github.com/TecharoHQ/anubis/lib/policy/config" "github.com/TecharoHQ/anubis/lib/policy/config"
@@ -40,6 +41,8 @@ type OGTagCache struct {
targetSNI string targetSNI string
targetSNIAuto bool targetSNIAuto bool
insecureSkipVerify bool insecureSkipVerify bool
sniClients map[string]*http.Client
transportMu sync.RWMutex
} }
type TargetOptions struct { type TargetOptions struct {
@@ -124,6 +127,7 @@ func NewOGTagCache(target string, conf config.OpenGraph, backend store.Interface
targetSNI: targetOpts.SNI, targetSNI: targetOpts.SNI,
targetSNIAuto: targetSNIAuto, targetSNIAuto: targetSNIAuto,
insecureSkipVerify: targetOpts.InsecureSkipVerify, insecureSkipVerify: targetOpts.InsecureSkipVerify,
sniClients: make(map[string]*http.Client),
} }
} }

42
internal/ogtags/sni.go Normal file
View File

@@ -0,0 +1,42 @@
package ogtags
import (
"crypto/tls"
"net/http"
)
// clientForSNI returns a cached client for the given server name, creating one if needed.
func (c *OGTagCache) clientForSNI(serverName string) *http.Client {
if !c.targetSNIAuto || serverName == "" {
return c.client
}
c.transportMu.RLock()
cli, ok := c.sniClients[serverName]
c.transportMu.RUnlock()
if ok {
return cli
}
c.transportMu.Lock()
defer c.transportMu.Unlock()
if cli, ok := c.sniClients[serverName]; ok {
return cli
}
tr := c.transport.Clone()
if tr.TLSClientConfig == nil {
tr.TLSClientConfig = &tls.Config{}
}
tr.TLSClientConfig.ServerName = serverName
if c.insecureSkipVerify {
tr.TLSClientConfig.InsecureSkipVerify = true
}
cli = &http.Client{
Timeout: httpTimeout,
Transport: tr,
}
c.sniClients[serverName] = cli
return cli
}