func (conn *http2Connection) makeStream(id uint32) (*HTTP2Stream, error) { if conn.isServer { if id%2 != 1 || id <= conn.maxStreamID { return nil, fmt.Errorf( "Server received illegal stream ID %v when maxStreamID is %v", id, conn.maxStreamID) } conn.maxStreamID = id } flowControl := &inFlow{ limit: initialWindowSize, connInFlow: conn.flowControl, } stream := &HTTP2Stream{ id: id, conn: conn, receiveBuffer: leverutil.NewUnboundedChannel(), flowControl: flowControl, sendQuotaPool: newQuotaPool(int(conn.streamSendQuota)), shutdownChan: make(chan struct{}), } return stream, nil }
func newHTTP2Connection( isServer bool, netConn net.Conn, serverStreamHandler StreamHandler) (*http2Connection, error) { var hpackBuffer bytes.Buffer writer := bufio.NewWriterSize(netConn, http2IOBufSize) conn := &http2Connection{ isServer: isServer, serverStreamHandler: serverStreamHandler, netConn: netConn, writer: writer, framer: http2.NewFramer(writer, netConn), hpackBuffer: &hpackBuffer, hpackEncoder: hpack.NewEncoder(&hpackBuffer), controlBuffer: leverutil.NewUnboundedChannel(), flowControl: &inFlow{limit: initialConnWindowSize}, sendQuotaPool: newQuotaPool(defaultWindowSize), writableChan: make(chan int, 1), shutdownChan: make(chan struct{}), closedChan: make(chan struct{}), streamSendQuota: defaultWindowSize, streams: make(map[uint32]*HTTP2Stream), } if !isServer { conn.nextStreamID = 1 // Odd numbers for client-initiated streams. n, err := netConn.Write(clientPreface) if err != nil { return nil, err } if n != len(clientPreface) { return nil, fmt.Errorf("Preface length mismatch") } } var settings []http2.Setting if initialWindowSize != defaultWindowSize { settings = append( settings, http2.Setting{ ID: http2.SettingInitialWindowSize, Val: uint32(initialWindowSize), }) } err := conn.framer.WriteSettings(settings...) if err != nil { return nil, err } windowDelta := uint32(initialConnWindowSize - defaultWindowSize) if windowDelta > 0 { err := conn.framer.WriteWindowUpdate(0, windowDelta) if err != nil { return nil, err } } conn.writer.Flush() conn.writableChan <- 0 // The controller is responsible with writing frames on the wire. go conn.controller() // The reader reads in frames from the wire, handles stream 0 / // control frames and dispatches frames for the rest of the streams. go conn.reader() return conn, nil }