diff --git a/.travis.yml b/.travis.yml index 5f43e03..f4e67b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,10 @@ go: before_install: - go get -u github.com/golang/lint/golint + - if [[ $TRAVIS_GO_VERSION == 1.5* ]]; then go get -u github.com/kisielk/errcheck; fi before_script: - '! gofmt -s -l . | read' - golint ./... + - echo $TRAVIS_GO_VERSION + - if [[ $TRAVIS_GO_VERSION == 1.5* ]]; then errcheck ./...; fi diff --git a/cmux.go b/cmux.go index f9e6907..33055b6 100644 --- a/cmux.go +++ b/cmux.go @@ -117,17 +117,17 @@ func (m *cMux) serve(c net.Conn) { select { case sl.l.connc <- muc: case <-sl.l.donec: - c.Close() + _ = c.Close() } return } } } - c.Close() + _ = c.Close() err := ErrNotMatched{c: c} if !m.handleErr(err) { - m.root.Close() + _ = m.root.Close() } } diff --git a/cmux_test.go b/cmux_test.go index 6b950ce..9432344 100644 --- a/cmux_test.go +++ b/cmux_test.go @@ -36,11 +36,13 @@ func (h *testHTTP1Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, testHTTP1Resp) } -func runTestHTTPServer(l net.Listener) { +func runTestHTTPServer(t *testing.T, l net.Listener) { s := &http.Server{ Handler: &testHTTP1Handler{}, } - s.Serve(l) + if err := s.Serve(l); err != nil { + t.Log(err) + } } func runTestHTTP1Client(t *testing.T, addr string) { @@ -49,7 +51,11 @@ func runTestHTTP1Client(t *testing.T, addr string) { t.Fatal(err) } - defer r.Body.Close() + defer func() { + if err := r.Body.Close(); err != nil { + t.Log(err) + } + }() b, err := ioutil.ReadAll(r.Body) if err != nil { t.Error(err) @@ -67,16 +73,18 @@ func (r TestRPCRcvr) Test(i int, j *int) error { return nil } -func runTestRPCServer(l net.Listener) { +func runTestRPCServer(t *testing.T, l net.Listener) { s := rpc.NewServer() - s.Register(TestRPCRcvr{}) - + if err := s.Register(TestRPCRcvr{}); err != nil { + t.Fatal(err) + } for { c, err := l.Accept() if err != nil { + t.Log(err) return } - s.ServeConn(c) + go s.ServeConn(c) } } @@ -100,21 +108,36 @@ func runTestRPCClient(t *testing.T, addr string) { func TestAny(t *testing.T) { l, addr := testListener(t) - defer l.Close() + defer func() { + if err := l.Close(); err != nil { + t.Log(err) + } + }() muxl := New(l) httpl := muxl.Match(Any()) - go runTestHTTPServer(httpl) - go muxl.Serve() + go runTestHTTPServer(t, httpl) + go func() { + if err := muxl.Serve(); err != nil { + t.Log(err) + } + }() r, err := http.Get("http://" + addr) if err != nil { t.Fatal(err) } - defer r.Body.Close() + defer func() { + if err := r.Body.Close(); err != nil { + t.Log(err) + } + }() b, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Error(err) + } if string(b) != testHTTP1Resp { t.Errorf("invalid response: want=%s got=%s", testHTTP1Resp, b) } @@ -122,15 +145,23 @@ func TestAny(t *testing.T) { func TestHTTPGoRPC(t *testing.T) { l, addr := testListener(t) - defer l.Close() + defer func() { + if err := l.Close(); err != nil { + t.Log(err) + } + }() muxl := New(l) httpl := muxl.Match(HTTP2(), HTTP1Fast()) rpcl := muxl.Match(Any()) - go runTestHTTPServer(httpl) - go runTestRPCServer(rpcl) - go muxl.Serve() + go runTestHTTPServer(t, httpl) + go runTestRPCServer(t, rpcl) + go func() { + if err := muxl.Serve(); err != nil { + t.Log(err) + } + }() runTestHTTP1Client(t, addr) runTestRPCClient(t, addr) @@ -138,13 +169,21 @@ func TestHTTPGoRPC(t *testing.T) { func TestErrorHandler(t *testing.T) { l, addr := testListener(t) - defer l.Close() + defer func() { + if err := l.Close(); err != nil { + t.Log(err) + } + }() muxl := New(l) httpl := muxl.Match(HTTP2(), HTTP1Fast()) - go runTestHTTPServer(httpl) - go muxl.Serve() + go runTestHTTPServer(t, httpl) + go func() { + if err := muxl.Serve(); err != nil { + t.Log(err) + } + }() firstErr := true muxl.HandleError(func(err error) bool { diff --git a/example_recursive_test.go b/example_recursive_test.go index ccbf04f..87c02f9 100644 --- a/example_recursive_test.go +++ b/example_recursive_test.go @@ -8,6 +8,7 @@ import ( "net" "net/http" "net/rpc" + "strings" "github.com/soheilhy/cmux" ) @@ -24,7 +25,9 @@ func recursiveServeHTTP(l net.Listener) { s := &http.Server{ Handler: &recursiveHTTPHandler{}, } - s.Serve(l) + if err := s.Serve(l); err != cmux.ErrListenerClosed { + panic(err) + } } func tlsListener(l net.Listener) net.Listener { @@ -53,8 +56,19 @@ func (r *RecursiveRPCRcvr) Cube(i int, j *int) error { func recursiveServeRPC(l net.Listener) { s := rpc.NewServer() - s.Register(&RecursiveRPCRcvr{}) - s.Accept(l) + if err := s.Register(&RecursiveRPCRcvr{}); err != nil { + panic(err) + } + for { + conn, err := l.Accept() + if err != nil { + if err != cmux.ErrListenerClosed { + panic(err) + } + return + } + go s.ServeConn(conn) + } } // This is an example for serving HTTP, HTTPS, and GoRPC/TLS on the same port. @@ -80,11 +94,16 @@ func Example_recursiveCmux() { tlsm := cmux.New(tlsl) httpsl := tlsm.Match(cmux.HTTP1Fast()) gorpcl := tlsm.Match(cmux.Any()) - go recursiveServeHTTP(httpl) go recursiveServeHTTP(httpsl) go recursiveServeRPC(gorpcl) - go tlsm.Serve() - tcpm.Serve() + go func() { + if err := tlsm.Serve(); err != cmux.ErrListenerClosed { + panic(err) + } + }() + if err := tcpm.Serve(); !strings.Contains(err.Error(), "use of closed network connection") { + panic(err) + } } diff --git a/example_test.go b/example_test.go index 9a32b5f..d3b91d5 100644 --- a/example_test.go +++ b/example_test.go @@ -7,6 +7,7 @@ import ( "net" "net/http" "net/rpc" + "strings" "google.golang.org/grpc" @@ -27,18 +28,24 @@ func serveHTTP(l net.Listener) { s := &http.Server{ Handler: &exampleHTTPHandler{}, } - s.Serve(l) + if err := s.Serve(l); err != cmux.ErrListenerClosed { + panic(err) + } } func EchoServer(ws *websocket.Conn) { - io.Copy(ws, ws) + if _, err := io.Copy(ws, ws); err != nil { + panic(err) + } } func serveWS(l net.Listener) { s := &http.Server{ Handler: websocket.Handler(EchoServer), } - s.Serve(l) + if err := s.Serve(l); err != cmux.ErrListenerClosed { + panic(err) + } } type ExampleRPCRcvr struct{} @@ -50,8 +57,19 @@ func (r *ExampleRPCRcvr) Cube(i int, j *int) error { func serveRPC(l net.Listener) { s := rpc.NewServer() - s.Register(&ExampleRPCRcvr{}) - s.Accept(l) + if err := s.Register(&ExampleRPCRcvr{}); err != nil { + panic(err) + } + for { + conn, err := l.Accept() + if err != nil { + if err != cmux.ErrListenerClosed { + panic(err) + } + return + } + go s.ServeConn(conn) + } } type grpcServer struct{} @@ -65,7 +83,9 @@ func (s *grpcServer) SayHello(ctx context.Context, in *grpchello.HelloRequest) ( func serveGRPC(l net.Listener) { grpcs := grpc.NewServer() grpchello.RegisterGreeterServer(grpcs, &grpcServer{}) - grpcs.Serve(l) + if err := grpcs.Serve(l); err != cmux.ErrListenerClosed { + panic(err) + } } func Example() { @@ -94,5 +114,7 @@ func Example() { go serveHTTP(httpl) go serveRPC(rpcl) - m.Serve() + if err := m.Serve(); !strings.Contains(err.Error(), "use of closed network connection") { + panic(err) + } } diff --git a/example_tls_test.go b/example_tls_test.go index 7733969..d1f639b 100644 --- a/example_tls_test.go +++ b/example_tls_test.go @@ -7,6 +7,7 @@ import ( "log" "net" "net/http" + "strings" "github.com/soheilhy/cmux" ) @@ -21,7 +22,9 @@ func serveHTTP1(l net.Listener) { s := &http.Server{ Handler: &anotherHTTPHandler{}, } - s.Serve(l) + if err := s.Serve(l); err != cmux.ErrListenerClosed { + panic(err) + } } func serveHTTPS(l net.Listener) { @@ -66,5 +69,7 @@ func Example_bothHTTPAndHTTPS() { go serveHTTP1(httpl) go serveHTTPS(tlsl) - m.Serve() + if err := m.Serve(); !strings.Contains(err.Error(), "use of closed network connection") { + panic(err) + } } diff --git a/matchers.go b/matchers.go index 987b6dc..599f4b8 100644 --- a/matchers.go +++ b/matchers.go @@ -144,7 +144,9 @@ func matchHTTP2Field(r io.Reader, name, value string) (matched bool) { switch f := f.(type) { case *http2.HeadersFrame: - hdec.Write(f.HeaderBlockFragment()) + if _, err := hdec.Write(f.HeaderBlockFragment()); err != nil { + return false + } if matched { return true }