aboutsummaryrefslogtreecommitdiffstats
path: root/worker/imap
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2022-04-30 01:08:54 +0200
committerRobin Jarry <robin@jarry.cc>2022-05-04 14:07:15 +0200
commit4d75137b20664cbdf90159c78d1fbf78779f3416 (patch)
treef12f127c46539502ebe764f03075a03a4fe5ff4a /worker/imap
parenta1b75a99bd277eb1f65a0483359af8e411b124d5 (diff)
downloadaerc-4d75137b20664cbdf90159c78d1fbf78779f3416.tar.gz
imap: extract imap config and configure handling
Extract the imap config and move the configure part out of the message handler. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'worker/imap')
-rw-r--r--worker/imap/configure.go99
-rw-r--r--worker/imap/worker.go121
2 files changed, 123 insertions, 97 deletions
diff --git a/worker/imap/configure.go b/worker/imap/configure.go
new file mode 100644
index 00000000..ac1d606d
--- /dev/null
+++ b/worker/imap/configure.go
@@ -0,0 +1,99 @@
+package imap
+
+import (
+ "fmt"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+
+ "git.sr.ht/~rjarry/aerc/worker/types"
+ "golang.org/x/oauth2"
+)
+
+func (w *IMAPWorker) handleConfigure(msg *types.Configure) error {
+ u, err := url.Parse(msg.Config.Source)
+ if err != nil {
+ return err
+ }
+
+ w.config.scheme = u.Scheme
+ if strings.HasSuffix(w.config.scheme, "+insecure") {
+ w.config.scheme = strings.TrimSuffix(w.config.scheme, "+insecure")
+ w.config.insecure = true
+ }
+
+ if strings.HasSuffix(w.config.scheme, "+oauthbearer") {
+ w.config.scheme = strings.TrimSuffix(w.config.scheme, "+oauthbearer")
+ w.config.oauthBearer.Enabled = true
+ q := u.Query()
+
+ oauth2 := &oauth2.Config{}
+ if q.Get("token_endpoint") != "" {
+ oauth2.ClientID = q.Get("client_id")
+ oauth2.ClientSecret = q.Get("client_secret")
+ oauth2.Scopes = []string{q.Get("scope")}
+ oauth2.Endpoint.TokenURL = q.Get("token_endpoint")
+ }
+ w.config.oauthBearer.OAuth2 = oauth2
+ }
+
+ w.config.addr = u.Host
+ if !strings.ContainsRune(w.config.addr, ':') {
+ w.config.addr += ":" + w.config.scheme
+ }
+
+ w.config.user = u.User
+ w.config.folders = msg.Config.Folders
+ w.config.idle_timeout = 10 * time.Second
+ w.config.connection_timeout = 30 * time.Second
+ w.config.keepalive_period = 0 * time.Second
+ w.config.keepalive_probes = 3
+ w.config.keepalive_interval = 3
+ for key, value := range msg.Config.Params {
+ switch key {
+ case "idle-timeout":
+ val, err := time.ParseDuration(value)
+ if err != nil || val < 0 {
+ return fmt.Errorf(
+ "invalid idle-timeout value %v: %v",
+ value, err)
+ }
+ w.config.idle_timeout = val
+ case "connection-timeout":
+ val, err := time.ParseDuration(value)
+ if err != nil || val < 0 {
+ return fmt.Errorf(
+ "invalid connection-timeout value %v: %v",
+ value, err)
+ }
+ w.config.connection_timeout = val
+ case "keepalive-period":
+ val, err := time.ParseDuration(value)
+ if err != nil || val < 0 {
+ return fmt.Errorf(
+ "invalid keepalive-period value %v: %v",
+ value, err)
+ }
+ w.config.keepalive_period = val
+ case "keepalive-probes":
+ val, err := strconv.Atoi(value)
+ if err != nil || val < 0 {
+ return fmt.Errorf(
+ "invalid keepalive-probes value %v: %v",
+ value, err)
+ }
+ w.config.keepalive_probes = val
+ case "keepalive-interval":
+ val, err := time.ParseDuration(value)
+ if err != nil || val < 0 {
+ return fmt.Errorf(
+ "invalid keepalive-interval value %v: %v",
+ value, err)
+ }
+ w.config.keepalive_interval = int(val.Seconds())
+ }
+ }
+
+ return nil
+}
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index cc9434f5..ad083333 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -6,15 +6,12 @@ import (
"math"
"net"
"net/url"
- "strconv"
- "strings"
"time"
"github.com/emersion/go-imap"
sortthread "github.com/emersion/go-imap-sortthread"
"github.com/emersion/go-imap/client"
"github.com/pkg/errors"
- "golang.org/x/oauth2"
"git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/logging"
@@ -28,7 +25,11 @@ func init() {
handlers.RegisterWorkerFactory("imaps", NewIMAPWorker)
}
-var errUnsupported = fmt.Errorf("unsupported command")
+var (
+ errUnsupported = fmt.Errorf("unsupported command")
+ errNotConnected = fmt.Errorf("not connected")
+ errAlreadyConnected = fmt.Errorf("already connected")
+)
type imapClient struct {
*client.Client
@@ -36,20 +37,23 @@ type imapClient struct {
sort *sortthread.SortClient
}
+type imapConfig struct {
+ scheme string
+ insecure bool
+ addr string
+ user *url.Userinfo
+ folders []string
+ oauthBearer lib.OAuthBearer
+ idle_timeout time.Duration
+ // tcp connection parameters
+ connection_timeout time.Duration
+ keepalive_period time.Duration
+ keepalive_probes int
+ keepalive_interval int
+}
+
type IMAPWorker struct {
- config struct {
- scheme string
- insecure bool
- addr string
- user *url.Userinfo
- folders []string
- oauthBearer lib.OAuthBearer
- // tcp connection parameters
- connection_timeout time.Duration
- keepalive_period time.Duration
- keepalive_probes int
- keepalive_interval int
- }
+ config imapConfig
client *imapClient
idleStop chan struct{}
@@ -103,91 +107,14 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
case *types.Unsupported:
// No-op
case *types.Configure:
- u, err := url.Parse(msg.Config.Source)
- if err != nil {
- reterr = err
- break
- }
-
- w.config.scheme = u.Scheme
- if strings.HasSuffix(w.config.scheme, "+insecure") {
- w.config.scheme = strings.TrimSuffix(w.config.scheme, "+insecure")
- w.config.insecure = true
- }
-
- if strings.HasSuffix(w.config.scheme, "+oauthbearer") {
- w.config.scheme = strings.TrimSuffix(w.config.scheme, "+oauthbearer")
- w.config.oauthBearer.Enabled = true
- q := u.Query()
-
- oauth2 := &oauth2.Config{}
- if q.Get("token_endpoint") != "" {
- oauth2.ClientID = q.Get("client_id")
- oauth2.ClientSecret = q.Get("client_secret")
- oauth2.Scopes = []string{q.Get("scope")}
- oauth2.Endpoint.TokenURL = q.Get("token_endpoint")
- }
- w.config.oauthBearer.OAuth2 = oauth2
- }
-
- w.config.addr = u.Host
- if !strings.ContainsRune(w.config.addr, ':') {
- w.config.addr += ":" + w.config.scheme
- }
-
- w.config.user = u.User
- w.config.folders = msg.Config.Folders
- w.config.connection_timeout = 30 * time.Second
- w.config.keepalive_period = 0 * time.Second
- w.config.keepalive_probes = 3
- w.config.keepalive_interval = 3
- for key, value := range msg.Config.Params {
- switch key {
- case "connection-timeout":
- val, err := time.ParseDuration(value)
- if err != nil || val < 0 {
- reterr = fmt.Errorf(
- "invalid connection-timeout value %v: %v",
- value, err)
- break
- }
- w.config.connection_timeout = val
- case "keepalive-period":
- val, err := time.ParseDuration(value)
- if err != nil || val < 0 {
- reterr = fmt.Errorf(
- "invalid keepalive-period value %v: %v",
- value, err)
- break
- }
- w.config.keepalive_period = val
- case "keepalive-probes":
- val, err := strconv.Atoi(value)
- if err != nil || val < 0 {
- reterr = fmt.Errorf(
- "invalid keepalive-probes value %v: %v",
- value, err)
- break
- }
- w.config.keepalive_probes = val
- case "keepalive-interval":
- val, err := time.ParseDuration(value)
- if err != nil || val < 0 {
- reterr = fmt.Errorf(
- "invalid keepalive-interval value %v: %v",
- value, err)
- break
- }
- w.config.keepalive_interval = int(val.Seconds())
- }
- }
+ reterr = w.handleConfigure(msg)
case *types.Connect:
if w.client != nil && w.client.State() == imap.SelectedState {
if !w.autoReconnect {
w.autoReconnect = true
checkConn(0)
}
- reterr = fmt.Errorf("Already connected")
+ reterr = errAlreadyConnected
break
}
@@ -233,7 +160,7 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
w.autoReconnect = false
w.stopConnectionObserver()
if w.client == nil || w.client.State() != imap.SelectedState {
- reterr = fmt.Errorf("Not connected")
+ reterr = errNotConnected
break
}