1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
package proton
import (
"net/http"
"time"
"github.com/ProtonMail/gluon/async"
"github.com/go-resty/resty/v2"
)
const (
// DefaultHostURL is the default host of the API.
DefaultHostURL = "https://mail.proton.me/api"
// DefaultAppVersion is the default app version used to communicate with the API.
// This must be changed (using the WithAppVersion option) for production use.
DefaultAppVersion = "go-proton-api"
// DefaultUserAgent is the default user agent used to communicate with the API.
// See: https://github.com/emersion/hydroxide/issues/252
DefaultUserAgent = ""
)
type managerBuilder struct {
hostURL string
appVersion string
userAgent string
transport http.RoundTripper
verifyProofs bool
cookieJar http.CookieJar
retryCount int
logger resty.Logger
debug bool
panicHandler async.PanicHandler
}
func newManagerBuilder() *managerBuilder {
return &managerBuilder{
hostURL: DefaultHostURL,
appVersion: DefaultAppVersion,
userAgent: DefaultUserAgent,
transport: http.DefaultTransport,
verifyProofs: true,
cookieJar: nil,
retryCount: 3,
logger: nil,
debug: false,
panicHandler: async.NoopPanicHandler{},
}
}
func (builder *managerBuilder) build() *Manager {
m := &Manager{
rc: resty.New(),
errHandlers: make(map[Code][]Handler),
verifyProofs: builder.verifyProofs,
panicHandler: builder.panicHandler,
}
// Set the API host.
m.rc.SetBaseURL(builder.hostURL)
// Set the transport.
m.rc.SetTransport(builder.transport)
// Set the cookie jar.
m.rc.SetCookieJar(builder.cookieJar)
// Set the logger.
if builder.logger != nil {
m.rc.SetLogger(builder.logger)
}
// Set the debug flag.
m.rc.SetDebug(builder.debug)
// Set app version in header.
m.rc.OnBeforeRequest(func(_ *resty.Client, req *resty.Request) error {
req.SetHeader("x-pm-appversion", builder.appVersion)
req.SetHeader("User-Agent", builder.userAgent)
return nil
})
// Set middleware.
m.rc.OnAfterResponse(catchAPIError)
m.rc.OnAfterResponse(updateTime)
m.rc.OnAfterResponse(m.checkConnUp)
m.rc.OnError(m.checkConnDown)
m.rc.OnError(m.handleError)
// Configure retry mechanism.
m.rc.SetRetryCount(builder.retryCount)
m.rc.SetRetryMaxWaitTime(time.Minute)
m.rc.AddRetryCondition(catchTooManyRequests)
m.rc.AddRetryCondition(catchDialError)
m.rc.AddRetryCondition(catchDropError)
m.rc.SetRetryAfter(catchRetryAfter)
// Set the data type of API errors.
m.rc.SetError(&APIError{})
return m
}
|