|
@@ -512,7 +512,7 @@ func (sc *serverConn) readPreface() error {
|
|
|
// The provided ch is used to avoid allocating new channels for each
|
|
// The provided ch is used to avoid allocating new channels for each
|
|
|
// write operation. It's expected that the caller reuses req and ch
|
|
// write operation. It's expected that the caller reuses req and ch
|
|
|
// over time.
|
|
// over time.
|
|
|
-func (sc *serverConn) writeData(stream *stream, req *dataWriteRequest, ch chan error) error {
|
|
|
|
|
|
|
+func (sc *serverConn) writeData(stream *stream, data *dataWriteParams, ch chan error) error {
|
|
|
sc.serveG.checkNotOn() // otherwise could deadlock in sc.writeFrame
|
|
sc.serveG.checkNotOn() // otherwise could deadlock in sc.writeFrame
|
|
|
|
|
|
|
|
// TODO: wait for flow control tokens. instead of writing a
|
|
// TODO: wait for flow control tokens. instead of writing a
|
|
@@ -522,10 +522,10 @@ func (sc *serverConn) writeData(stream *stream, req *dataWriteRequest, ch chan e
|
|
|
// once in one frame.
|
|
// once in one frame.
|
|
|
sc.writeFrame(frameWriteMsg{
|
|
sc.writeFrame(frameWriteMsg{
|
|
|
write: (*serverConn).writeDataFrame,
|
|
write: (*serverConn).writeDataFrame,
|
|
|
- cost: uint32(len(req.p)),
|
|
|
|
|
|
|
+ cost: uint32(len(data.p)),
|
|
|
stream: stream,
|
|
stream: stream,
|
|
|
- endStream: req.end,
|
|
|
|
|
- v: req,
|
|
|
|
|
|
|
+ endStream: data.end,
|
|
|
|
|
+ v: data,
|
|
|
done: ch,
|
|
done: ch,
|
|
|
})
|
|
})
|
|
|
select {
|
|
select {
|
|
@@ -716,11 +716,6 @@ func (sc *serverConn) shutDownIn(d time.Duration) {
|
|
|
sc.shutdownTimerCh = sc.shutdownTimer.C
|
|
sc.shutdownTimerCh = sc.shutdownTimer.C
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-type goAwayParams struct {
|
|
|
|
|
- maxStreamID uint32
|
|
|
|
|
- code ErrCode
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
func (sc *serverConn) writeGoAwayFrame(_ uint32, v interface{}) error {
|
|
func (sc *serverConn) writeGoAwayFrame(_ uint32, v interface{}) error {
|
|
|
sc.writeG.check()
|
|
sc.writeG.check()
|
|
|
p := v.(*goAwayParams)
|
|
p := v.(*goAwayParams)
|
|
@@ -1357,7 +1352,7 @@ func (sc *serverConn) write100ContinueHeadersFrame(streamID uint32, _ interface{
|
|
|
|
|
|
|
|
func (sc *serverConn) writeDataFrame(streamID uint32, v interface{}) error {
|
|
func (sc *serverConn) writeDataFrame(streamID uint32, v interface{}) error {
|
|
|
sc.writeG.check()
|
|
sc.writeG.check()
|
|
|
- req := v.(*dataWriteRequest)
|
|
|
|
|
|
|
+ req := v.(*dataWriteParams)
|
|
|
return sc.framer.WriteData(streamID, req.end, req.p)
|
|
return sc.framer.WriteData(streamID, req.end, req.p)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1463,11 +1458,11 @@ type responseWriterState struct {
|
|
|
// mutated by http.Handler goroutine:
|
|
// mutated by http.Handler goroutine:
|
|
|
handlerHeader http.Header // nil until called
|
|
handlerHeader http.Header // nil until called
|
|
|
snapHeader http.Header // snapshot of handlerHeader at WriteHeader time
|
|
snapHeader http.Header // snapshot of handlerHeader at WriteHeader time
|
|
|
- wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
|
|
|
|
|
status int // status code passed to WriteHeader
|
|
status int // status code passed to WriteHeader
|
|
|
|
|
+ wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
|
|
|
sentHeader bool // have we sent the header frame?
|
|
sentHeader bool // have we sent the header frame?
|
|
|
handlerDone bool // handler has finished
|
|
handlerDone bool // handler has finished
|
|
|
- curWrite dataWriteRequest
|
|
|
|
|
|
|
+ curWrite dataWriteParams
|
|
|
frameWriteCh chan error // re-used whenever we need to block on a frame being written
|
|
frameWriteCh chan error // re-used whenever we need to block on a frame being written
|
|
|
|
|
|
|
|
closeNotifierMu sync.Mutex // guards closeNotifierCh
|
|
closeNotifierMu sync.Mutex // guards closeNotifierCh
|
|
@@ -1480,11 +1475,6 @@ func (rws *responseWriterState) writeData(p []byte, end bool) error {
|
|
|
return rws.stream.conn.writeData(rws.stream, &rws.curWrite, rws.frameWriteCh)
|
|
return rws.stream.conn.writeData(rws.stream, &rws.curWrite, rws.frameWriteCh)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-type dataWriteRequest struct {
|
|
|
|
|
- p []byte
|
|
|
|
|
- end bool
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
type chunkWriter struct{ rws *responseWriterState }
|
|
type chunkWriter struct{ rws *responseWriterState }
|
|
|
|
|
|
|
|
func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
|
|
func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
|