mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 08:49:13 +00:00
feat: add support for proxies to use with IRC and Indexers (#1421)
* feat: add support for proxies * fix(http): release handler * fix(migrations): define proxy early * fix(migrations): pg proxy * fix(proxy): list update delete * fix(proxy): remove log and imports * feat(irc): use proxy * feat(irc): tests * fix(web): update imports for ProxyForms.tsx * fix(database): migration * feat(proxy): test * feat(proxy): validate proxy type * feat(proxy): validate and test * feat(proxy): improve validate and test * feat(proxy): fix db schema * feat(proxy): add db tests * feat(proxy): handle http errors * fix(http): imports * feat(proxy): use proxy for indexer downloads * feat(proxy): indexerforms select proxy * feat(proxy): handle torrent download * feat(proxy): skip if disabled * feat(proxy): imports * feat(proxy): implement in Feeds * feat(proxy): update helper text indexer proxy * feat(proxy): add internal cache
This commit is contained in:
parent
472d327308
commit
bc0f4cc055
59 changed files with 2533 additions and 371 deletions
|
@ -6,6 +6,8 @@ package irc
|
|||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"golang.org/x/net/proxy"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -220,6 +222,37 @@ func (h *Handler) Run() (err error) {
|
|||
Log: subLogger,
|
||||
}
|
||||
|
||||
if h.network.UseProxy && h.network.Proxy != nil {
|
||||
if !h.network.Proxy.Enabled {
|
||||
h.log.Debug().Msgf("proxy disabled, skip")
|
||||
} else {
|
||||
if h.network.Proxy.Addr == "" {
|
||||
return errors.New("proxy addr missing")
|
||||
}
|
||||
|
||||
proxyUrl, err := url.Parse(h.network.Proxy.Addr)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not parse proxy url: %s", h.network.Proxy.Addr)
|
||||
}
|
||||
|
||||
// set user and pass if not empty
|
||||
if h.network.Proxy.User != "" && h.network.Proxy.Pass != "" {
|
||||
proxyUrl.User = url.UserPassword(h.network.Proxy.User, h.network.Proxy.Pass)
|
||||
}
|
||||
|
||||
proxyDialer, err := proxy.FromURL(proxyUrl, proxy.Direct)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not create proxy dialer from url: %s", h.network.Proxy.Addr)
|
||||
}
|
||||
proxyContextDialer, ok := proxyDialer.(proxy.ContextDialer)
|
||||
if !ok {
|
||||
return errors.Wrap(err, "proxy dialer does not expose DialContext(): %v", proxyDialer)
|
||||
}
|
||||
|
||||
client.DialContext = proxyContextDialer.DialContext
|
||||
}
|
||||
}
|
||||
|
||||
if h.network.Auth.Mechanism == domain.IRCAuthMechanismSASLPlain {
|
||||
if h.network.Auth.Account != "" && h.network.Auth.Password != "" {
|
||||
client.SASLLogin = h.network.Auth.Account
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/autobrr/autobrr/internal/indexer"
|
||||
"github.com/autobrr/autobrr/internal/logger"
|
||||
"github.com/autobrr/autobrr/internal/notification"
|
||||
"github.com/autobrr/autobrr/internal/proxy"
|
||||
"github.com/autobrr/autobrr/internal/release"
|
||||
"github.com/autobrr/autobrr/pkg/errors"
|
||||
|
||||
|
@ -47,8 +48,10 @@ type service struct {
|
|||
releaseService release.Service
|
||||
indexerService indexer.Service
|
||||
notificationService notification.Service
|
||||
indexerMap map[string]string
|
||||
handlers map[int64]*Handler
|
||||
proxyService proxy.Service
|
||||
|
||||
indexerMap map[string]string
|
||||
handlers map[int64]*Handler
|
||||
|
||||
stopWG sync.WaitGroup
|
||||
lock sync.RWMutex
|
||||
|
@ -56,7 +59,7 @@ type service struct {
|
|||
|
||||
const sseMaxEntries = 1000
|
||||
|
||||
func NewService(log logger.Logger, sse *sse.Server, repo domain.IrcRepo, releaseSvc release.Service, indexerSvc indexer.Service, notificationSvc notification.Service) Service {
|
||||
func NewService(log logger.Logger, sse *sse.Server, repo domain.IrcRepo, releaseSvc release.Service, indexerSvc indexer.Service, notificationSvc notification.Service, proxySvc proxy.Service) Service {
|
||||
return &service{
|
||||
log: log.With().Str("module", "irc").Logger(),
|
||||
sse: sse,
|
||||
|
@ -64,6 +67,7 @@ func NewService(log logger.Logger, sse *sse.Server, repo domain.IrcRepo, release
|
|||
releaseService: releaseSvc,
|
||||
indexerService: indexerSvc,
|
||||
notificationService: notificationSvc,
|
||||
proxyService: proxySvc,
|
||||
handlers: make(map[int64]*Handler),
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +83,15 @@ func (s *service) StartHandlers() {
|
|||
continue
|
||||
}
|
||||
|
||||
if network.ProxyId != 0 {
|
||||
networkProxy, err := s.proxyService.FindByID(context.Background(), network.ProxyId)
|
||||
if err != nil {
|
||||
s.log.Error().Err(err).Msgf("failed to get proxy for network: %s", network.Server)
|
||||
return
|
||||
}
|
||||
network.Proxy = networkProxy
|
||||
}
|
||||
|
||||
channels, err := s.repo.ListChannels(network.ID)
|
||||
if err != nil {
|
||||
s.log.Error().Err(err).Msgf("failed to list channels for network: %s", network.Server)
|
||||
|
@ -215,6 +228,14 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
|
|||
restartNeeded = true
|
||||
fieldsChanged = append(fieldsChanged, "bot mode")
|
||||
}
|
||||
if handler.UseProxy != network.UseProxy {
|
||||
restartNeeded = true
|
||||
fieldsChanged = append(fieldsChanged, "use proxy")
|
||||
}
|
||||
if handler.ProxyId != network.ProxyId {
|
||||
restartNeeded = true
|
||||
fieldsChanged = append(fieldsChanged, "proxy id")
|
||||
}
|
||||
if handler.Auth.Mechanism != network.Auth.Mechanism {
|
||||
restartNeeded = true
|
||||
fieldsChanged = append(fieldsChanged, "auth mechanism")
|
||||
|
@ -476,12 +497,16 @@ func (s *service) GetNetworksWithHealth(ctx context.Context) ([]domain.IrcNetwor
|
|||
BouncerAddr: n.BouncerAddr,
|
||||
UseBouncer: n.UseBouncer,
|
||||
BotMode: n.BotMode,
|
||||
UseProxy: n.UseProxy,
|
||||
ProxyId: n.ProxyId,
|
||||
Connected: false,
|
||||
Channels: []domain.ChannelWithHealth{},
|
||||
ConnectionErrors: []string{},
|
||||
}
|
||||
|
||||
s.lock.RLock()
|
||||
handler, ok := s.handlers[n.ID]
|
||||
s.lock.RUnlock()
|
||||
if ok {
|
||||
handler.ReportStatus(&netw)
|
||||
}
|
||||
|
@ -566,6 +591,18 @@ func (s *service) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork)
|
|||
}
|
||||
s.log.Debug().Msgf("irc.service: update network: %s", network.Name)
|
||||
|
||||
network.Proxy = nil
|
||||
|
||||
// attach proxy
|
||||
if network.UseProxy && network.ProxyId != 0 {
|
||||
networkProxy, err := s.proxyService.FindByID(context.Background(), network.ProxyId)
|
||||
if err != nil {
|
||||
s.log.Error().Err(err).Msgf("failed to get proxy for network: %s", network.Server)
|
||||
return errors.Wrap(err, "could not get proxy for network: %s", network.Server)
|
||||
}
|
||||
network.Proxy = networkProxy
|
||||
}
|
||||
|
||||
// stop or start network
|
||||
// TODO get current state to see if enabled or not?
|
||||
if network.Enabled {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue