mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-17 05:42:09 +08:00
add DataFromStream
This commit is contained in:
parent
680be7d928
commit
7da03c2a5d
31
README.md
31
README.md
@ -1308,6 +1308,37 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Streaming data
|
||||||
|
|
||||||
|
```go
|
||||||
|
func main() {
|
||||||
|
router := gin.Default()
|
||||||
|
router.GET("/someDataFromStream", func(c *gin.Context) {
|
||||||
|
pr, pw := io.Pipe()
|
||||||
|
defer pr.Close()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer pw.Close()
|
||||||
|
var counter int
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-c.Done():
|
||||||
|
return
|
||||||
|
case <-time.Tick(500 * time.Millisecond):
|
||||||
|
if _, err := fmt.Fprintf(pw, "message: %d\n", counter); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
contentType := "text/plain"
|
||||||
|
c.DataFromStream(http.StatusOK, contentType, pr, nil)
|
||||||
|
})
|
||||||
|
router.Run(":8080")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### HTML rendering
|
### HTML rendering
|
||||||
|
|
||||||
Using LoadHTMLGlob() or LoadHTMLFiles()
|
Using LoadHTMLGlob() or LoadHTMLFiles()
|
||||||
|
13
context.go
13
context.go
@ -1018,6 +1018,19 @@ func (c *Context) DataFromReader(code int, contentLength int64, contentType stri
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DataFromStream streams the specified reader into the body stream without delay and updates the HTTP code.
|
||||||
|
func (c *Context) DataFromStream(code int, contentType string, reader io.Reader, extraHeaders map[string]string) {
|
||||||
|
sr := render.StreamReader{
|
||||||
|
Reader: render.Reader{
|
||||||
|
Headers: extraHeaders,
|
||||||
|
ContentType: contentType,
|
||||||
|
ContentLength: -1,
|
||||||
|
Reader: reader,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
c.Render(code, sr)
|
||||||
|
}
|
||||||
|
|
||||||
// File writes the specified file into the body stream in an efficient way.
|
// File writes the specified file into the body stream in an efficient way.
|
||||||
func (c *Context) File(filepath string) {
|
func (c *Context) File(filepath string) {
|
||||||
http.ServeFile(c.Writer, c.Request, filepath)
|
http.ServeFile(c.Writer, c.Request, filepath)
|
||||||
|
@ -26,6 +26,7 @@ var (
|
|||||||
_ Render = HTML{}
|
_ Render = HTML{}
|
||||||
_ HTMLRender = HTMLDebug{}
|
_ HTMLRender = HTMLDebug{}
|
||||||
_ HTMLRender = HTMLProduction{}
|
_ HTMLRender = HTMLProduction{}
|
||||||
|
_ Render = StreamReader{}
|
||||||
_ Render = YAML{}
|
_ Render = YAML{}
|
||||||
_ Render = Reader{}
|
_ Render = Reader{}
|
||||||
_ Render = AsciiJSON{}
|
_ Render = AsciiJSON{}
|
||||||
|
31
render/stream_reader.go
Normal file
31
render/stream_reader.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2018 Gin Core Team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package render
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StreamReader contains the IO reader and its length, and custom ContentType and other headers.
|
||||||
|
type StreamReader struct {
|
||||||
|
Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
type writerFlusher struct {
|
||||||
|
http.ResponseWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *writerFlusher) Write(buf []byte) (n int, err error) {
|
||||||
|
n, err = w.ResponseWriter.Write(buf)
|
||||||
|
if err == nil {
|
||||||
|
w.ResponseWriter.(http.Flusher).Flush()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render (StreamReader) writes data with custom ContentType and headers.
|
||||||
|
func (r StreamReader) Render(w http.ResponseWriter) (err error) {
|
||||||
|
return r.Reader.Render(&writerFlusher{w})
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user