Thumbnail

rani/matterbridge.git

Clone URL: https://git.buni.party/rani/matterbridge.git

commit 96685398ad2e88374a8f84863c6f48085eeb8e7a Author: selfhoster1312 <selfhoster1312@kl.netlib.re> Date: Sat Dec 06 20:42:19 2025 +0000 feat: Instantiate a single HTTP client per bridge diff --git a/bridge/bridge.go b/bridge/bridge.go index 62e55f9..3511693 100644 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -26 +28 @@ package bridge    import (   "log" + "net/http" + "net/url"   "strings"   "sync"   "time" @@ -306 +327 @@ type Bridge struct {   Log *logrus.Entry   Config config.Config   General *config.Protocol + HttpClient *http.Client // Unique HTTP settings per bridge  }    type Config struct { @@ -416 +448 @@ type Config struct {  // Factory is the factory function to create a bridge  type Factory func(*Config) Bridger   +// New is a basic constructor. More important fields are populated +// in gateway/gateway.go (AddBridge method).  func New(bridge *config.Bridge) *Bridge {   accInfo := strings.Split(bridge.Account, ".")   if len(accInfo) != 2 { @@ -1333 +13835 @@ func (b *Bridge) GetStringSlice2D(key string) [][]string {   }   return val  } + +// NewHttpClient produces a single unified http.Client per bridge. +// +// This allows to have project-wide defaults (timeout) as well as +// bridge-configurable values (`http_proxy`). +// +// This method is left public so that if that's needed, a bridge can +// override this constructor. +// +// TODO: maybe protocols without HTTP downloads at all could override +// this method and return nil? Or the other way around? +func (b *Bridge) NewHttpClient(http_proxy string) (*http.Client, error) { + if http_proxy != "" { + proxyUrl, err := url.Parse(b.GetString("http_proxy")) + if err != nil { + return nil, err + } + + b.Log.Debugf("%s using HTTP proxy %s", b.Protocol, proxyUrl) + + return &http.Client{ + Timeout: time.Second * 15, + Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}, + }, nil + } + + b.Log.Debugf("%s not using HTTP proxy", b.Protocol) + + return &http.Client{ + Timeout: time.Second * 5, + }, nil +} diff --git a/gateway/gateway.go b/gateway/gateway.go index a4b8759..a23b3b3 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -827 +8210 @@ func (gw *Gateway) FindCanonicalMsgID(protocol string, mID string) string {   return ""  }   -// AddBridge sets up a new bridge in the gateway object with the specified configuration. +// AddBridge sets up a new bridge on startup. +// +// It's added in the gateway object with the specified configuration, and is +// not triggered again on config change.  func (gw *Gateway) AddBridge(cfg *config.Bridge) error {   br := gw.Router.getBridge(cfg.Account)   if br == nil { @@ -916 +9415 @@ func (gw *Gateway) AddBridge(cfg *config.Bridge) error {   br.Config = gw.Router.Config   br.General = &gw.BridgeValues().General   br.Log = gw.logger.WithFields(logrus.Fields{"prefix": br.Protocol}) + + // Instantiate bridge's HTTP client + http_client, err := br.NewHttpClient(br.GetString("http_proxy")) + if err != nil { + br.Log.Fatalf("config failure for account %s, HTTP settings incorrect", br.Account) + } + + br.HttpClient = http_client +   brconfig := &bridge.Config{   Remote: gw.Message,   Bridge: br, @@ -1066 +1189 @@ func (gw *Gateway) AddBridge(cfg *config.Bridge) error {   return nil  }   +// checkConfig checks a bridge config, on startup. +// +// This is not triggered when config is reloaded from disk.  func (gw *Gateway) checkConfig(cfg *config.Bridge) {   match := false   for _, key := range gw.Router.Config.Viper().AllKeys() {