123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- package webmail
- import (
- "compress/gzip"
- "compress/zlib"
- "fmt"
- "github.com/mailru/easyjson"
- "golang.org/x/net/html/charset"
- "io"
- "net/http"
- "net/url"
- "strings"
- "time"
- )
- type client struct {
- http *http.Client
- endpoint string
- }
- func NewClient(endpoint string, timeout time.Duration) Client {
- t := http.DefaultTransport.(*http.Transport)
- t.Proxy = http.ProxyFromEnvironment
- cli := &client{
- endpoint: endpoint,
- http: &http.Client{
- Transport: t,
- Timeout: timeout,
- },
- }
- return cli
- }
- func (cli *client) Close() error {
- return nil
- }
- func (cli *client) CreateAlias(alias string) error {
- return cli.action(CreateAlias, alias)
- }
- func (cli *client) RemoveAlias(alias string) error {
- return cli.action(RemoveAlias, alias)
- }
- func (cli *client) action(e Action, alias string) error {
- alias = strings.TrimSpace(alias)
- if alias == "" {
- return fmt.Errorf("illegal arguments: alias must not be an empty string")
- }
- var (
- d []byte
- result = new(Result)
- err error
- )
- if d, err = cli.do(e, alias); err != nil {
- return err
- }
- if err = easyjson.Unmarshal(d, result); err != nil {
- return err
- }
- var errNo int64
- if errNo, err = result.Error.Int64(); err != nil {
- return err
- }
- if result.Ok != "ok" || errNo > 0 {
- return fmt.Errorf("got unexpected result: `%s`", string(d))
- }
- return nil
- }
- func (cli *client) ListAliases() ([]string, error) {
- var (
- d []byte
- result = ResultList{}
- err error
- )
- if d, err = cli.do(ListAliases, ""); err != nil {
- return nil, err
- }
- if err = easyjson.Unmarshal(d, &result); err != nil {
- return nil, err
- }
- return result, nil
- }
- func (cli *client) do(action Action, alias string) ([]byte, error) {
- var (
- request *http.Request
- response *http.Response
- err error
- )
- values := url.Values{}
- values.Set("act", string(action))
- if ListAliases != action {
- values.Set("alias", alias)
- }
- if request, err = http.NewRequest(http.MethodPost, cli.endpoint, strings.NewReader(values.Encode())); err != nil {
- return nil, err
- }
- request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
- if response, err = cli.http.Do(request); err != nil {
- return nil, err
- }
- if response.StatusCode < 200 || response.StatusCode > 299 {
- return nil, fmt.Errorf("got unexpected http status code [%d] %s",
- response.StatusCode, response.Status)
- }
- if response.ContentLength != -1 && response.ContentLength < 1 {
- return nil, nil
- }
- var (
- contentEncoding = response.Header.Get("Content-Encoding")
- contentType = response.Header.Get("Content-Type")
- contentReader io.Reader = response.Body
- )
- if "gzip" == contentEncoding {
- if r, err := gzip.NewReader(response.Body); err == nil {
- defer r.Close()
- contentReader = r
- }
- } else if "deflate" == contentEncoding {
- if r, err := zlib.NewReader(response.Body); err == nil {
- defer r.Close()
- contentReader = r
- }
- }
- if "application/octet-stream" != contentType {
- if r, err := charset.NewReader(contentReader, contentType); err == nil {
- contentReader = r
- } else {
- return nil, err
- }
- }
- return io.ReadAll(contentReader)
- }
|