bradfitz/http2

Server.handleConn hangs

dvyukov opened this issue · 3 comments

The following test hangs in Server.handleConn while the connection is already effectively closed.

package http2

import (
    "io"
    "net"
    "net/http"
    "testing"
    "time"
)

var data = "PRI * HTTP/2.0\r\n\r\nSM" +
    "\r\n\r\n\x00\x00\x00\x01\ainfinfin\ad"

func TestFuzz(t *testing.T) {
    s := &http.Server{}
    s2 := &Server{MaxReadFrameSize: 1 << 16, PermitProhibitedCipherSuites: true}
    c := &MyConn{[]byte(data), false, false}
    s2.handleConn(s, c, http.HandlerFunc(handler))
    if !c.closed {
        panic("connection is not closed")
    }
}

func handler(w http.ResponseWriter, req *http.Request) {
    w.Write([]byte("hello"))
}

type MyConn struct {
    data    []byte
    closed  bool
    written bool
}

func (c *MyConn) Read(b []byte) (n int, err error) {
    if len(c.data) == 0 {
        return 0, io.EOF
    }
    n = copy(b, c.data)
    c.data = c.data[n:]
    return
}

func (c *MyConn) Write(b []byte) (n int, err error) {
    c.written = true
    return len(b), nil
}

func (c *MyConn) Close() error {
    c.closed = true
    return nil
}

func (c *MyConn) LocalAddr() net.Addr {
    return &net.TCPAddr{net.IP{127, 0, 0, 1}, 49706, ""}
}

func (c *MyConn) RemoteAddr() net.Addr {
    return &net.TCPAddr{net.IP{127, 0, 0, 1}, 49706, ""}
}

func (c *MyConn) SetDeadline(t time.Time) error {
    return nil
}

func (c *MyConn) SetReadDeadline(t time.Time) error {
    return nil
}

func (c *MyConn) SetWriteDeadline(t time.Time) error {
    return nil
}

on commit 8348f2f

@bradfitz, do these new bugs look legit to you?

Yes, there are wrong assumptions of the API contact between the Framer and the server loop around what type of errors can be returned. Stream-level errors are being lost and causing these problems.

I just haven't had time to fix yet.