commit 96685398ad2e88374a8f84863c6f48085eeb8e7a
Author: selfhoster1312 <selfhoster1312@kl.netlib.re>
Date: Sat Dec 06 20:42:19 2025 +0000
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() {