A multipart.Writer exists in one of three states currently:

1. CreatePart has not been called.
2. CreatePart has been called at least once, but Close has not been called 
yet.
3. Close has been called.

This proposal would introduce a fourth state:

4. FlushLastPart has been called. CreatePart or Close have not been called 
since then.

This needs to be a distinct state, since FlushLastPart (perhaps better 
called ClosePart?) would write the boundary separator terminating the 
previous part. If we call Close in this state, we need to write "--\r\n", 
not "\r\n--BOUNDARY--\r\n".

Given how simple multipart.Writer is, I wonder if it isn't better to just 
write the multipart message manually in your case.
On Friday, May 7, 2021 at 11:11:59 AM UTC-7 Ohad Lutzky wrote:

> Hi all, I'm looking at multipart/x-mixed-replace-based image streaming 
> (mjpeg-style, but with PNG in my case), and would like to allow code to 
> push a new image immediately. This look roughly like this (error handling 
> elided for brevity):
>
> m := multipart.NewWriter()
> defer m.Close()
> w.Header().Set("Content-Type", "multipart/x-mixed-replace; 
> boundary="+m.Boundary())
> h := textproto.MIMEHeader{}
> h.Set("Content-Type", "image/png")
> for {
> buf := <-c // Channel with PNG data
> h.Set("Content-Length", fmt.Sprint(len(buf)))
> mw, _ := m.CreatePart(h)
> mw.Write(buf)
> w.(http.Flusher).Flush()
> }
>
> Writing PNGs to channel c will indeed display the image to the screen, but 
> one image later. Specifically, it's the m.CreatePart 
> <https://golang.org/src/mime/multipart/writer.go?s=2406:2481#L87> call 
> that completes the last part by emitting the final --BOUNDARY\r\n. 
> Unfortunately, I can't call it immediately after mw.Write, because I don't 
> necessarily know the Content-Length for the next image. A workaround that 
> does work is this:
>
> mw, _ := m.CreatePart(h)
> mw.Write(buf)
> mw, _ = m.CreatePart(h) // Yes, again
> mw.Write(buf)
> w.(http.Flusher).Flush()
>
> Notably, calling m.Close() wouldn't be appropriate here. While CreatePart 
> write \r\n--BOUNDARY\r\n, Close would write \r\n--BOUNDARY--\r\n. 
> Apparently that extra -- is enough to make the browser disregard everything 
> that follows.
>
> While this can be worked around by not using the mime/multipart library, I 
> think it's a reasonable API change (but an API change nonetheless) to add a 
> FlushLastPart method to Writer. WDYT?
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/35b58218-11f6-4376-a61f-b80c470d8b98n%40googlegroups.com.

Reply via email to