Added streaming

This commit is contained in:
Eduard Urbach 2024-03-22 14:37:21 +01:00
parent 084407038c
commit f65c34ea78
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
3 changed files with 46 additions and 0 deletions

View File

@ -7,6 +7,7 @@ import (
// Response is the interface for an HTTP response. // Response is the interface for an HTTP response.
type Response interface { type Response interface {
Flush()
Header(key string) string Header(key string) string
SetHeader(key string, value string) SetHeader(key string, value string)
Write([]byte) (int, error) Write([]byte) (int, error)
@ -18,6 +19,15 @@ type response struct {
http.ResponseWriter http.ResponseWriter
} }
// Flush flushes the response buffers to the client.
func (res response) Flush() {
flusher, ok := res.ResponseWriter.(http.Flusher)
if ok {
flusher.Flush()
}
}
// Header returns the header value for the given key. // Header returns the header value for the given key.
func (res response) Header(key string) string { func (res response) Header(key string) string {
return res.ResponseWriter.Header().Get(key) return res.ResponseWriter.Header().Get(key)

View File

@ -52,6 +52,13 @@ func TestRouter(t *testing.T) {
return ctx.File("testdata/file.txt") return ctx.File("testdata/file.txt")
}) })
s.Get("/flush", func(ctx server.Context) error {
ctx.Response().WriteString("Hello 1\n")
ctx.Response().WriteString("Hello 2\n")
ctx.Response().Flush()
return nil
})
s.Get("/echo", func(ctx server.Context) error { s.Get("/echo", func(ctx server.Context) error {
return ctx.Copy(ctx.Request()) return ctx.Copy(ctx.Request())
}) })
@ -123,6 +130,7 @@ func TestRouter(t *testing.T) {
{Method: "GET", URL: "/error", Body: "", Status: http.StatusUnauthorized, Response: "Not logged in"}, {Method: "GET", URL: "/error", Body: "", Status: http.StatusUnauthorized, Response: "Not logged in"},
{Method: "GET", URL: "/error2", Body: "", Status: http.StatusUnauthorized, Response: "Not logged in\nMissing auth token"}, {Method: "GET", URL: "/error2", Body: "", Status: http.StatusUnauthorized, Response: "Not logged in\nMissing auth token"},
{Method: "GET", URL: "/file", Body: "", Status: http.StatusOK, Response: "Hello File"}, {Method: "GET", URL: "/file", Body: "", Status: http.StatusOK, Response: "Hello File"},
{Method: "GET", URL: "/flush", Body: "", Status: http.StatusOK, Response: "Hello 1\nHello 2\n"},
{Method: "GET", URL: "/not-found", Body: "", Status: http.StatusNotFound, Response: http.StatusText(http.StatusNotFound)}, {Method: "GET", URL: "/not-found", Body: "", Status: http.StatusNotFound, Response: http.StatusText(http.StatusNotFound)},
{Method: "GET", URL: "/request/data", Body: "", Status: http.StatusOK, Response: "GET HTTP/1.1 example.com /request/data"}, {Method: "GET", URL: "/request/data", Body: "", Status: http.StatusOK, Response: "GET HTTP/1.1 example.com /request/data"},
{Method: "GET", URL: "/request/header", Body: "", Status: http.StatusOK, Response: ""}, {Method: "GET", URL: "/request/header", Body: "", Status: http.StatusOK, Response: ""},

28
examples/stream/main.go Normal file
View File

@ -0,0 +1,28 @@
package main
import (
"time"
"git.akyoto.dev/go/server"
)
func main() {
s := server.New()
s.Get("/", func(ctx server.Context) error {
ticker := time.NewTicker(time.Second)
for {
select {
case <-ctx.Request().Context().Done():
return nil
case <-ticker.C:
ctx.Response().WriteString("Hello\n")
ctx.Response().Flush()
}
}
})
s.Run(":8080")
}