cabinet/cabinet.go

117 lines
2.1 KiB
Go

package cabinet
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
)
type Client struct {
BaseURL string
HTTP *http.Client
Token string
}
func New(baseURL string, opts ...ClientOption) *Client {
c := &Client{
BaseURL: baseURL,
HTTP: http.DefaultClient,
}
for _, opt := range opts {
opt(c)
}
return c
}
type ClientOption func(*Client)
func WithHTTPClient(client *http.Client) ClientOption {
return func(c *Client) {
c.HTTP = client
}
}
func WithToken(token string) ClientOption {
return func(c *Client) {
c.Token = token
}
}
func (c *Client) Redirect(u string) (string, *http.Response, error) {
vals := url.Values{
"url": []string{u},
}
if c.Token != "" {
vals["token"] = []string{c.Token}
}
resp, err := c.HTTP.PostForm(fmt.Sprintf("%s/r", c.BaseURL), vals)
if err != nil {
return "", nil, err
}
if resp.StatusCode != 200 {
return "", resp, fmt.Errorf("non-200 status code: %s", resp.Status)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", resp, err
}
resp.Body = io.NopCloser(bytes.NewReader(body))
return string(body), resp, nil
}
func (c *Client) File(name string, f io.Reader) (string, *http.Response, error) {
var buf bytes.Buffer
mp := multipart.NewWriter(&buf)
token, err := mp.CreateFormField("token")
if err != nil {
return "", nil, err
}
if _, err := token.Write([]byte(c.Token)); err != nil {
return "", nil, err
}
file, err := mp.CreateFormFile("file", name)
if err != nil {
return "", nil, err
}
if _, err := io.Copy(file, f); err != nil {
return "", nil, err
}
if err := mp.Close(); err != nil {
return "", nil, err
}
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/f", c.BaseURL), &buf)
if err != nil {
return "", nil, err
}
req.Header.Set("Content-Type", mp.FormDataContentType())
resp, err := c.HTTP.Do(req)
if err != nil {
return "", nil, err
}
if resp.StatusCode != 200 {
return "", resp, fmt.Errorf("non-200 status code: %s", resp.Status)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", resp, err
}
resp.Body = io.NopCloser(bytes.NewReader(body))
return string(body), resp, nil
}