The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/2757
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com>
From 1f2133a9cba692175d2ead6314499c81511a87cc Mon Sep 17 00:00:00 2001 From: Tycho Andersen <tycho.ander...@canonical.com> Date: Thu, 22 Dec 2016 08:38:03 -0700 Subject: [PATCH] allow passing in-memory buffers to a FileResponse Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com> --- lxd/response.go | 56 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/lxd/response.go b/lxd/response.go index 1116857..ec3ea59 100644 --- a/lxd/response.go +++ b/lxd/response.go @@ -9,6 +9,7 @@ import ( "mime/multipart" "net/http" "os" + "time" "github.com/mattn/go-sqlite3" @@ -106,6 +107,7 @@ type fileResponseEntry struct { identifier string path string filename string + buffer []byte /* either a path or a buffer must be provided */ } type fileResponse struct { @@ -129,24 +131,38 @@ func (r *fileResponse) Render(w http.ResponseWriter) error { // For a single file, return it inline if len(r.files) == 1 { - f, err := os.Open(r.files[0].path) - if err != nil { - return err - } - defer f.Close() + var rs io.ReadSeeker + var mt time.Time + var sz int64 + + if r.files[0].path == "" { + rs = bytes.NewReader(r.files[0].buffer) + mt = time.Now() + sz = int64(len(r.files[0].buffer)) + } else { + f, err := os.Open(r.files[0].path) + if err != nil { + return err + } + defer f.Close() - fi, err := f.Stat() - if err != nil { - return err + fi, err := f.Stat() + if err != nil { + return err + } + + mt = fi.ModTime() + sz = fi.Size() + rs = f } w.Header().Set("Content-Type", "application/octet-stream") - w.Header().Set("Content-Length", fmt.Sprintf("%d", fi.Size())) + w.Header().Set("Content-Length", fmt.Sprintf("%d", sz)) w.Header().Set("Content-Disposition", fmt.Sprintf("inline;filename=%s", r.files[0].filename)) - http.ServeContent(w, r.req, r.files[0].filename, fi.ModTime(), f) - if r.removeAfterServe { - err = os.Remove(r.files[0].path) + http.ServeContent(w, r.req, r.files[0].filename, mt, rs) + if r.files[0].path != "" && r.removeAfterServe { + err := os.Remove(r.files[0].path) if err != nil { return err } @@ -160,18 +176,24 @@ func (r *fileResponse) Render(w http.ResponseWriter) error { mw := multipart.NewWriter(body) for _, entry := range r.files { - fd, err := os.Open(entry.path) - if err != nil { - return err + var rd io.Reader + if entry.path != "" { + fd, err := os.Open(entry.path) + if err != nil { + return err + } + defer fd.Close() + rd = fd + } else { + rd = bytes.NewReader(entry.buffer) } - defer fd.Close() fw, err := mw.CreateFormFile(entry.identifier, entry.filename) if err != nil { return err } - _, err = io.Copy(fw, fd) + _, err = io.Copy(fw, rd) if err != nil { return err }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel