client.go raw

   1  package internal
   2  
   3  import (
   4  	"context"
   5  	"fmt"
   6  	"net/http"
   7  	"net/url"
   8  	"strings"
   9  	"time"
  10  
  11  	"github.com/go-acme/lego/v4/providers/dns/internal/errutils"
  12  )
  13  
  14  const defaultBaseURL = "https://www.mydns.jp/directedit.html"
  15  
  16  // Client the MyDNS.jp client.
  17  type Client struct {
  18  	masterID string
  19  	password string
  20  
  21  	baseURL    *url.URL
  22  	HTTPClient *http.Client
  23  }
  24  
  25  // NewClient Creates a new Client.
  26  func NewClient(masterID, password string) *Client {
  27  	baseURL, _ := url.Parse(defaultBaseURL)
  28  
  29  	return &Client{
  30  		masterID:   masterID,
  31  		password:   password,
  32  		baseURL:    baseURL,
  33  		HTTPClient: &http.Client{Timeout: 5 * time.Second},
  34  	}
  35  }
  36  
  37  func (c *Client) AddTXTRecord(ctx context.Context, domain, value string) error {
  38  	return c.doRequest(ctx, domain, value, "REGIST")
  39  }
  40  
  41  func (c *Client) DeleteTXTRecord(ctx context.Context, domain, value string) error {
  42  	return c.doRequest(ctx, domain, value, "DELETE")
  43  }
  44  
  45  func (c *Client) buildRequest(ctx context.Context, domain, value, cmd string) (*http.Request, error) {
  46  	params := url.Values{}
  47  	params.Set("CERTBOT_DOMAIN", domain)
  48  	params.Set("CERTBOT_VALIDATION", value)
  49  	params.Set("EDIT_CMD", cmd)
  50  
  51  	req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL.String(), strings.NewReader(params.Encode()))
  52  	if err != nil {
  53  		return nil, fmt.Errorf("unable to create request: %w", err)
  54  	}
  55  
  56  	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  57  
  58  	return req, nil
  59  }
  60  
  61  func (c *Client) doRequest(ctx context.Context, domain, value, cmd string) error {
  62  	req, err := c.buildRequest(ctx, domain, value, cmd)
  63  	if err != nil {
  64  		return err
  65  	}
  66  
  67  	req.SetBasicAuth(c.masterID, c.password)
  68  
  69  	resp, err := c.HTTPClient.Do(req)
  70  	if err != nil {
  71  		return errutils.NewHTTPDoError(req, err)
  72  	}
  73  
  74  	defer func() { _ = resp.Body.Close() }()
  75  
  76  	if resp.StatusCode/100 != 2 {
  77  		return errutils.NewUnexpectedResponseStatusCodeError(req, resp)
  78  	}
  79  
  80  	return nil
  81  }
  82