[lxc-devel] [lxd/master] allow passing in-memory buffers to a FileResponse
tych0 on Github
lxc-bot at linuxcontainers.org
Thu Dec 22 17:47:10 UTC 2016
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 361 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20161222/b2ba9646/attachment.bin>
-------------- next part --------------
From 1f2133a9cba692175d2ead6314499c81511a87cc Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at 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.andersen at 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
}
More information about the lxc-devel
mailing list