valyala / fasthttp

Fast HTTP package for Go. Tuned for high performance. Zero memory allocations in hot paths. Up to 10x faster than net/http
MIT License
21.91k stars 1.76k forks source link

add two export func to get gzip writer object from pool #1625

Closed ahfuzhang closed 1 year ago

ahfuzhang commented 1 year ago

Add two export func to get gzip writer object from pool(so we can gzip data streamly).

When I want to output gzip data to response, I wrote code like this:

buf := bytebufferpool.Get()
WriteHTML(buf, myParams)  // write all html to a buffer
ctx.Response.Header.Add("Content-Encoding", "gzip")
_, _ = fasthttp.WriteGzipLevel(ctx.Response.BodyWriter(), buf.Bytes(), fasthttp.CompressBestSpeed)
bytebufferpool.Put(buf)

But up way will copy data from bytebuffer to gzip object. I can not use API like this:

_, _ = fasthttp.WriteGzipLevel(ctx.Response.BodyWriter(), []byte("first time"), fasthttp.CompressBestSpeed)
_, _ = fasthttp.WriteGzipLevel(ctx.Response.BodyWriter(), []byte("second time"), fasthttp.CompressBestSpeed)

Browser can't read response.

So, I export those two func: GetGzipWriter and ReleaseGzipWriter. Then I can write data many times:

gzipWriter := fasthttp.GetGzipWriter(ctx.Response.BodyWriter(), fasthttp.CompressBestSpeed)
_,_ = gzipWriter.Write([]byte("first time"))
_,_ = gzipWriter.Write([]byte("second time"))
fasthttp.ReleaseGzipWriter(gzipWriter, fasthttp.CompressBestSpeed)

Thanks.

erikdubbelboer commented 1 year ago

Just to make sure I understand. You want to get rid of the overhead of having to write to a bytesbuffer first before compressing the contents?

I'm thinking a better API would be if you could enable compression on a Response and it would then automatically do this for every Write to the response. But I'm not sure how we could easily implement this with the various ways of writing responses we already have.

If we're going with your route we should also expose the methods for Brotli I guess.

ahfuzhang commented 1 year ago

Yes, if we can set gzip flag, that is better. Like this:

func handle(ctx *fasthttp.RequestCtx){
     ctx.SetGzipOutput()  // when call this api, context write become a gzip writer
     ctx.WriteString("first time")
     ctx.WriteString("second time")
}

Colud you supply a API like ctx.SetGzipOutput() ? Thanks.

erikdubbelboer commented 1 year ago

A pull request for something like this would be very welcome. I would make it ctx.Response.SetEnableCompression(true). And when it's enabled a call like ctx.Response.WriteGzip() should return an error.

ahfuzhang commented 1 year ago

I test again, this way not works. sorry