package main import ( "bytes" "context" "encoding/json" "fmt" "io" "mime/multipart" "net/http" "os" "time" "github.com/google/uuid" "github.com/urfave/cli/v2" ) var ( version = "dev" commit = "none" date = "unknown" ) func main() { cli.VersionFlag = &cli.BoolFlag{Name: "version"} app := cli.App{ Name: "gpaste", Version: fmt.Sprintf("gpaste %s-%s (%s)", version, commit, date), Flags: []cli.Flag{ &cli.StringFlag{ Name: "config", Usage: "Path to config-file.", }, }, Commands: []*cli.Command{ { Name: "upload", Usage: "Upload file(s)", ArgsUsage: "FILE [FILE]...", Flags: []cli.Flag{ &cli.StringFlag{ Name: "url", Usage: "Base url of gpaste server", }, }, Action: ActionUpload, }, }, } app.Run(os.Args) } func ActionUpload(c *cli.Context) error { url := fmt.Sprintf("%s/api/file", c.String("url")) client := &http.Client{} // TODO: Change timeout ctx, cancel := context.WithTimeout(c.Context, 10*time.Minute) defer cancel() buf := &bytes.Buffer{} mw := multipart.NewWriter(buf) for _, arg := range c.Args().Slice() { f, err := os.Open(arg) if err != nil { return err } defer f.Close() fw, err := mw.CreateFormFile(uuid.Must(uuid.NewRandom()).String(), arg) if err != nil { return err } if _, err := io.Copy(fw, f); err != nil { return err } } mw.Close() req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, buf) if err != nil { return err } req.Header.Add("Content-Type", mw.FormDataContentType()) resp, err := client.Do(req) if err != nil { return err } defer resp.Body.Close() var expectedResp []struct { Message string `json:"message"` ID string `json:"id"` URL string `json:"url"` } decoder := json.NewDecoder(resp.Body) if err := decoder.Decode(&expectedResp); err != nil { return fmt.Errorf("error decoding response: %w", err) } for _, r := range expectedResp { fmt.Printf("Uploaded file %s\n", r.ID) } return nil }