From ff91ea2882806acbaa87524054a010abc30a22bf Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Wed, 19 Sep 2018 11:55:25 +0200 Subject: [PATCH] Add stdin sharing and allow content-type being specified Signed-off-by: Knut Ahlers --- http.go | 2 +- main.go | 39 +++++++++++++++++++++++++++++++-------- upload.go | 6 +++++- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/http.go b/http.go index fb8081c..7a9f0b5 100644 --- a/http.go +++ b/http.go @@ -19,7 +19,7 @@ func simpleFilePost(res http.ResponseWriter, r *http.Request) { return } - url, err := executeUpload(fh.Filename, f, true) + url, err := executeUpload(fh.Filename, f, true, "") if err != nil { log.WithError(err).Error("Uploading file from HTTP request failed") http.Error(res, "Failed to upload file. For details see the log.", http.StatusInternalServerError) diff --git a/main.go b/main.go index 8f8ea7e..af6e483 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "bytes" "errors" "fmt" + "io" "os" "github.com/Luzifer/rconfig" @@ -18,6 +19,7 @@ var ( BasePath string `flag:"base-path" env:"BASE_PATH" default:"file/{{ printf \"%.2s\" .Hash }}/{{.Hash}}" description:"Path to upload the file to"` Bootstrap bool `flag:"bootstrap" default:"false" description:"Upload frontend files into bucket"` Bucket string `flag:"bucket" env:"BUCKET" default:"" description:"S3 bucket to upload files to" validate:"nonzero"` + ContentType string `flag:"content-type,c" default:"" description:"Force content-type to be set to this value"` Listen string `flag:"listen" env:"LISTEN" default:"" description:"Enable HTTP server if set to IP/Port (e.g. ':3000')"` VersionAndExit bool `flag:"version" default:"false" description:"Prints current version and exits"` }{} @@ -26,6 +28,7 @@ var ( ) func init() { + rconfig.AutoEnv(true) if err := rconfig.ParseAndValidate(&cfg); err != nil { log.Fatalf("Unable to parse commandline options: %s", err) } @@ -67,14 +70,34 @@ func doCLIUpload() error { log.Warn("No BaseURL configured, output will be no complete URL") } - inFileName := rconfig.Args()[1] - inFileHandle, err := os.Open(inFileName) - if err != nil { - return fmt.Errorf("Unable to open source file: %s", err) - } - defer inFileHandle.Close() + var inFile io.ReadSeeker - url, err := executeUpload(inFileName, inFileHandle, true) + inFileName := rconfig.Args()[1] + + if inFileName == "-" { + inFileName = "stdin" + if cfg.ContentType == "" { + // If we don't have an explicitly set content-type assume stdin contains text + cfg.ContentType = "text/plain" + } + + // Stdin is not seekable, so we need to buffer it + buf := new(bytes.Buffer) + if _, err := io.Copy(buf, os.Stdin); err != nil { + log.WithError(err).Fatal("Could not read stdin") + } + + inFile = bytes.NewReader(buf.Bytes()) + } else { + inFileHandle, err := os.Open(inFileName) + if err != nil { + return fmt.Errorf("Unable to open source file: %s", err) + } + defer inFileHandle.Close() + inFile = inFileHandle + } + + url, err := executeUpload(inFileName, inFile, true, cfg.ContentType) if err != nil { return fmt.Errorf("Unable to upload file: %s", err) } @@ -85,7 +108,7 @@ func doCLIUpload() error { func doBootstrap() error { for _, asset := range []string{"index.html", "app.js"} { - if _, err := executeUpload(asset, bytes.NewReader(MustAsset("frontend/"+asset)), false); err != nil { + if _, err := executeUpload(asset, bytes.NewReader(MustAsset("frontend/"+asset)), false, ""); err != nil { return fmt.Errorf("Unable to upload bootstrap asset %q: %s", asset, err) } } diff --git a/upload.go b/upload.go index 3dfac29..79e0b40 100644 --- a/upload.go +++ b/upload.go @@ -17,7 +17,7 @@ import ( log "github.com/sirupsen/logrus" ) -func executeUpload(inFileName string, inFileHandle io.ReadSeeker, useCalculatedFilename bool) (string, error) { +func executeUpload(inFileName string, inFileHandle io.ReadSeeker, useCalculatedFilename bool, overrideMimeType string) (string, error) { var ( upFile = inFileName err error @@ -34,6 +34,10 @@ func executeUpload(inFileName string, inFileHandle io.ReadSeeker, useCalculatedF mimeType = "application/octet-stream" } + if overrideMimeType != "" { + mimeType = overrideMimeType + } + log.Debugf("Uploading file to %q with type %q", upFile, mimeType) sess := session.Must(session.NewSession())