diff --git a/cmd/client/client.go b/cmd/client/client.go index 54611f9..89e026f 100644 --- a/cmd/client/client.go +++ b/cmd/client/client.go @@ -1,7 +1,106 @@ package main -import "fmt" +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() { - fmt.Println("Starting gpaste client") + 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) + req.Header.Add("Content-Type", mw.FormDataContentType()) + if err != nil { + return err + } + 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 } diff --git a/http.go b/http.go index 9bcc962..cb866d5 100644 --- a/http.go +++ b/http.go @@ -104,7 +104,7 @@ func (s *HTTPServer) processMultiPartFormUpload(w http.ResponseWriter, r *http.R var responses []resp if err := r.ParseMultipartForm(1024 * 1024 * 10); err != nil { - s.Logger.Warnw("Error parsin multipart form.", "err", err) + s.Logger.Warnw("Error parsing multipart form.", "err", err) } for k := range r.MultipartForm.File { ff, fh, err := r.FormFile(k)