package client import ( "fmt" "io" "mime/multipart" "net/http" "os" "strings" "git.towk2.me/towk/makeshift/pkg/util" "github.com/cavaliergopher/grab/v3" ) type HTTPBody []byte type HTTPHeader map[string]string type HTTPEnvelope struct { Path string Method string Header HTTPHeader Body HTTPBody CACert string } type Client struct { http.Client BaseURI string AccessToken string } func New(uri string) Client { return Client{ BaseURI: strings.TrimSuffix(uri, "/"), } } func NewHTTPEnvelope() HTTPEnvelope { return HTTPEnvelope{ Path: "", Method: http.MethodGet, Header: nil, Body: nil, CACert: "", } } func (c *Client) MakeRequest(env HTTPEnvelope) (*http.Response, []byte, error) { return util.MakeRequest(c.BaseURI+env.Path, env.Method, env.Body, env.Header) } func (c *Client) Download(out string, env HTTPEnvelope) (*grab.Response, error) { if out == "" { return grab.Get(out, c.BaseURI+env.Path) } return grab.Get(out, c.BaseURI+env.Path) } func (c *Client) UploadMultipartFile(uri, key, path string) (*http.Response, error) { body, writer := io.Pipe() req, err := http.NewRequest(http.MethodPost, uri, body) if err != nil { return nil, err } mwriter := multipart.NewWriter(writer) req.Header.Add("Content-Type", mwriter.FormDataContentType()) errchan := make(chan error) go func() { defer close(errchan) defer writer.Close() defer mwriter.Close() w, err := mwriter.CreateFormFile(key, path) if err != nil { errchan <- err return } in, err := os.Open(path) if err != nil { errchan <- err return } defer in.Close() if written, err := io.Copy(w, in); err != nil { errchan <- fmt.Errorf("error copying %s (%d bytes written): %v", path, written, err) return } if err := mwriter.Close(); err != nil { errchan <- err return } }() resp, err := c.Do(req) merr := <-errchan if err != nil || merr != nil { return resp, fmt.Errorf("http error: %v, multipart error: %v", err, merr) } return resp, nil } func mustOpen(f string) *os.File { r, err := os.Open(f) if err != nil { panic(err) } return r }