From 237b94cd03f941ffdf9b7b07b8155228ccd76839 Mon Sep 17 00:00:00 2001 From: thinkerou Date: Mon, 20 Aug 2018 20:35:35 +0800 Subject: [PATCH] support chunked mode --- context.go | 21 +++++++++++++++++++++ render/reader.go | 27 +++++++++++++++++++++++++++ render/render.go | 1 + 3 files changed, 49 insertions(+) diff --git a/context.go b/context.go index 6d80284e..49b32b2d 100644 --- a/context.go +++ b/context.go @@ -5,6 +5,7 @@ package gin import ( + "bytes" "errors" "io" "io/ioutil" @@ -820,6 +821,26 @@ func (c *Context) DataFromReader(code int, contentLength int64, contentType stri }) } +func (c *Context) DataFromReaderStream(code int, offset int, contentType string, reader io.Reader, extraHeaders map[string]string) { + p := make([]byte, offset) + for { + n, err := reader.Read(p) + if err != nil { + if err == io.EOF { + break + } + panic(err) + } + + c.Render(code, render.ReaderStream{ + Headers: extraHeaders, + ContentType: contentType, + Reader: bytes.NewReader(p[:n]), + }) + c.Writer.Flush() + } +} + // File writes the specified file into the body stream in a efficient way. func (c *Context) File(filepath string) { http.ServeFile(c.Writer, c.Request, filepath) diff --git a/render/reader.go b/render/reader.go index 7a06cce4..f394dcf6 100644 --- a/render/reader.go +++ b/render/reader.go @@ -38,3 +38,30 @@ func (r Reader) writeHeaders(w http.ResponseWriter, headers map[string]string) { } } } + +type ReaderStream struct { + ContentType string + Reader io.Reader + Headers map[string]string +} + +// Render (ReaderStream) writes data with custom ContentType and headers. +func (r ReaderStream) Render(w http.ResponseWriter) (err error) { + r.WriteContentType(w) + r.writeHeaders(w, r.Headers) + _, err = io.Copy(w, r.Reader) + return +} + +func (r ReaderStream) WriteContentType(w http.ResponseWriter) { + writeContentType(w, []string{r.ContentType}) +} + +func (r ReaderStream) 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} + } + } +} diff --git a/render/render.go b/render/render.go index df0d1d7c..7fc99bac 100644 --- a/render/render.go +++ b/render/render.go @@ -26,6 +26,7 @@ var ( _ Render = YAML{} _ Render = MsgPack{} _ Render = Reader{} + _ Render = ReaderStream{} _ Render = AsciiJSON{} _ Render = ProtoBuf{} )