Why http.ResponseWriter.Flush() cause chuncked format error

1,169 views
Skip to first unread message

buzzlight

unread,
May 20, 2013, 4:27:59 AM5/20/13
to golan...@googlegroups.com
I am refactoring gwk (https://github.com/sdming/wk), moved FilesBundle & 
Bigpipe from demo project to master. I encountered confused thing when test ChanResult (chan.go, /demo/basic/model/bigpipe.go)

if I call Flush() at the end of function (chan.go, line 62)

... 
ctx.Write(c.End)
//ctx.Flush()

return nil

//actually,  ctx.Write call ResponseWriter.Write, ctx.Flish call ResponseWriter.Flush
...

browser show error "chuncked body did not terminate property with 0-siezd chunk"

if i remove ctx.Flush(), it works fine.

below is html output when call Flush(), it write c.End twice? (captured by Fillder)

HTTP/1.1 200 OK
Content-Type: text/html
Server: go web server
Set-Cookie: _go_session_=7HcT5D-WSiKIqRnVEHCOs52x3g0=; Path=/; HttpOnly
Date: Mon, 20 May 2013 08:16:01 GMT
Content-Length: 833

<!DOCTYPE html>
    <head>       
    </head>
    <body>
       
        <div id="panel">
        </div>

        <script>
       function p(s) {
           var panel = document.getElementById('panel');
           var n = document.createElement('div');
           n.innerHTML = s + " -- at " + new Date().toTimeString();
           panel.appendChild(n);
       }
        </script>
        

<script>
       p("goroutine 0 delay 4")
   </script>

<script>
       p("goroutine 4 delay 4")
   </script>

<script>
       p("goroutine 1 delay 10")
   </script>

<script>
       p("goroutine 2 delay 10")
   </script>

<script>
       p("goroutine 3 delay 12")
   </script>


<script>
    p("end")
    </script>

    </body>
</html>


<script>
    p("end")
    </script>

    </body>
</html>

Dave Cheney

unread,
May 20, 2013, 4:30:35 AM5/20/13
to buzzlight, golang-nuts
Umm, if your response has a Content-Length, then it isn't a
Transfer-Encoding: chunked response.

Can you please post a full working code sample that demonstrates the problem.
> --
> 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...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Dianming Song

unread,
May 20, 2013, 4:59:13 AM5/20/13
to Dave Cheney, golang-nuts
It simulate HTTP long-pull response ,so I can't set Content-Length

source code:

or 
and run .demo/basic/basic.go

it works on IE, sometime panic when open with chrome, haven't find reason. 

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x20 pc=0x4a05df]

goroutine 95 [running]:
net/http.(*switchWriter).Write(0xc08018e600, 0xc080195800, 0x3e, 0x800, 0x7d5e10
, ...)
.....
      /go/src/pkg/net/http/chunked.go:0 +0x5f
bufio.(*Writer).Flush(0xc080180280, 0x1, 0x437534)
       /go/src/pkg/bufio/bufio.go:465 +0xbc
net/http.(*response).Flush(0xc0801943f0)
       /go/src/pkg/net/http/server.go:952 +0x4d



2013/5/20 Dave Cheney <da...@cheney.net>

Dave Cheney

unread,
May 20, 2013, 5:54:52 AM5/20/13
to Dianming Song, golang-nuts
Yup, I've got not idea what is going on there, however the error handling in this package could do with some work. I suggest fixing that first, then seeing if the panic continues. 


Brad Fitzpatrick

unread,
May 20, 2013, 10:02:06 AM5/20/13
to Dave Cheney, Dianming Song, golang-nuts
I also think there might be a data race here.  It looks like you potentially have multiple goroutines interacting with the ResponseWriter.

If you narrow it down to a small example, though, I'd love to investigate.

But first: check error values, and run with the Go 1.1 -race option, to see detect any data races first.

Also, no need to call:

     close(waitchan)

In your chan.go ... it will just get GCed automatically.  No need to close channels.

Dianming Song

unread,
May 20, 2013, 10:34:18 PM5/20/13
to Brad Fitzpatrick, Dave Cheney, golang-nuts
I post code at 

please run code and open open [http://localhost:8080/test.html ]

Maybe line 61 is the reason of  panic

sometime,  code 

log.Println("read chan", s)
w.Write([]byte(s))

run before

log.Println("Write End")
log.Println(w.Write(c.End))




2013/5/20 Brad Fitzpatrick <brad...@golang.org>

Brad Fitzpatrick

unread,
May 20, 2013, 10:57:57 PM5/20/13
to Dianming Song, Dave Cheney, golang-nuts
Yeah, this is a data race.  You can't Write to the ResponseWriter from two different goroutines without coordinating who's in charge.

Dianming Song

unread,
May 21, 2013, 1:43:35 AM5/21/13
to Brad Fitzpatrick, Dave Cheney, golang-nuts
Thanks, should wait goroutine finish, then write the rest of  response.

It works on IE now.

output of IE
----------
goroutine 1 delay 3 -- at 13:36:59 UTC+0800
goroutine 3 delay 6 -- at 13:37:02 UTC+0800
goroutine 4 delay 6 -- at 13:37:02 UTC+0800
goroutine 0 delay 6 -- at 13:37:02 UTC+0800
goroutine 2 delay 7 -- at 13:37:03 UTC+0800
end -- at 13:37:03 UTC+0800

output of chrome
----------
goroutine 2 delay 4 -- at 13:36:52 UTC+0800 
goroutine 3 delay 8 -- at 13:36:52 UTC+0800 
goroutine 0 delay 9 -- at 13:36:52 UTC+0800 
goroutine 4 delay 9 -- at 13:36:52 UTC+0800 
goroutine 1 delay 10 -- at 13:36:52 UTC+0800 
end -- at 13:36:52 UTC+0800 

Reply all
Reply to author
Forward
0 new messages