A webmail client. Forked from https://git.sr.ht/~migadu/alps
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

75 lignes
1.2 KiB

  1. package koushin
  2. import (
  3. "crypto/rand"
  4. "encoding/base64"
  5. "errors"
  6. "sync"
  7. imapclient "github.com/emersion/go-imap/client"
  8. )
  9. func generateToken() (string, error) {
  10. b := make([]byte, 32)
  11. _, err := rand.Read(b)
  12. if err != nil {
  13. return "", err
  14. }
  15. return base64.URLEncoding.EncodeToString(b), nil
  16. }
  17. var ErrSessionExpired = errors.New("session expired")
  18. // TODO: expiration timer
  19. type ConnPool struct {
  20. locker sync.Mutex
  21. conns map[string]*imapclient.Client
  22. }
  23. func NewConnPool() *ConnPool {
  24. return &ConnPool{
  25. conns: make(map[string]*imapclient.Client),
  26. }
  27. }
  28. func (pool *ConnPool) Get(token string) (*imapclient.Client, error) {
  29. pool.locker.Lock()
  30. defer pool.locker.Unlock()
  31. conn, ok := pool.conns[token]
  32. if !ok {
  33. return nil, ErrSessionExpired
  34. }
  35. return conn, nil
  36. }
  37. func (pool *ConnPool) Put(conn *imapclient.Client) (token string, err error) {
  38. pool.locker.Lock()
  39. defer pool.locker.Unlock()
  40. for {
  41. var err error
  42. token, err = generateToken()
  43. if err != nil {
  44. conn.Logout()
  45. return "", err
  46. }
  47. if _, ok := pool.conns[token]; !ok {
  48. break
  49. }
  50. }
  51. pool.conns[token] = conn
  52. go func() {
  53. <-conn.LoggedOut()
  54. pool.locker.Lock()
  55. delete(pool.conns, token)
  56. pool.locker.Unlock()
  57. }()
  58. return token, nil
  59. }