Serve easily dynamic files with DataFromReader
context method (#1304)
* Add DataFromReader context method * Replace fmt by strconv.FormatInt * Add pull request link to README
This commit is contained in:
committed by
Bo-Yi Wu
parent
5636afe02d
commit
bf7803815b
36
render/reader.go
Normal file
36
render/reader.go
Normal file
@ -0,0 +1,36 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Reader struct {
|
||||
ContentType string
|
||||
ContentLength int64
|
||||
Reader io.Reader
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
// Render (Reader) writes data with custom ContentType and headers.
|
||||
func (r Reader) Render(w http.ResponseWriter) (err error) {
|
||||
r.WriteContentType(w)
|
||||
r.Headers["Content-Length"] = strconv.FormatInt(r.ContentLength, 10)
|
||||
r.writeHeaders(w, r.Headers)
|
||||
_, err = io.Copy(w, r.Reader)
|
||||
return
|
||||
}
|
||||
|
||||
func (r Reader) WriteContentType(w http.ResponseWriter) {
|
||||
writeContentType(w, []string{r.ContentType})
|
||||
}
|
||||
|
||||
func (r Reader) writeHeaders(w http.ResponseWriter, headers map[string]string) {
|
||||
header := w.Header()
|
||||
for k, v := range headers {
|
||||
if val := header[k]; len(val) == 0 {
|
||||
header[k] = []string{v}
|
||||
}
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ var (
|
||||
_ HTMLRender = HTMLProduction{}
|
||||
_ Render = YAML{}
|
||||
_ Render = MsgPack{}
|
||||
_ Render = Reader{}
|
||||
)
|
||||
|
||||
func writeContentType(w http.ResponseWriter, value []string) {
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -384,3 +386,24 @@ func TestRenderHTMLDebugPanics(t *testing.T) {
|
||||
}
|
||||
assert.Panics(t, func() { htmlRender.Instance("", nil) })
|
||||
}
|
||||
|
||||
func TestRenderReader(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
body := "#!PNG some raw data"
|
||||
headers := make(map[string]string)
|
||||
headers["Content-Disposition"] = `attachment; filename="filename.png"`
|
||||
|
||||
err := (Reader{
|
||||
ContentLength: int64(len(body)),
|
||||
ContentType: "image/png",
|
||||
Reader: strings.NewReader(body),
|
||||
Headers: headers,
|
||||
}).Render(w)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, body, w.Body.String())
|
||||
assert.Equal(t, "image/png", w.HeaderMap.Get("Content-Type"))
|
||||
assert.Equal(t, strconv.Itoa(len(body)), w.HeaderMap.Get("Content-Length"))
|
||||
assert.Equal(t, headers["Content-Disposition"], w.HeaderMap.Get("Content-Disposition"))
|
||||
}
|
||||
|
Reference in New Issue
Block a user