Forráskód Böngészése

let ErrTimeout implements net.Error

fatedier 3 éve
szülő
commit
cc6f3dfc95
2 módosított fájl, 33 hozzáadás és 2 törlés
  1. 23 1
      const.go
  2. 10 1
      session_test.go

+ 23 - 1
const.go

@@ -5,6 +5,25 @@ import (
 	"fmt"
 )
 
+// NetError implements net.Error
+type NetError struct {
+	err       error
+	timeout   bool
+	temporary bool
+}
+
+func (e *NetError) Error() string {
+	return e.err.Error()
+}
+
+func (e *NetError) Timeout() bool {
+	return e.timeout
+}
+
+func (e *NetError) Temporary() bool {
+	return e.temporary
+}
+
 var (
 	// ErrInvalidVersion means we received a frame with an
 	// invalid version
@@ -30,7 +49,10 @@ var (
 	ErrRecvWindowExceeded = fmt.Errorf("recv window exceeded")
 
 	// ErrTimeout is used when we reach an IO deadline
-	ErrTimeout = fmt.Errorf("i/o deadline reached")
+	ErrTimeout = &NetError{
+		err:     fmt.Errorf("i/o deadline reached"),
+		timeout: true,
+	}
 
 	// ErrStreamClosed is returned when using a closed stream
 	ErrStreamClosed = fmt.Errorf("stream closed")

+ 10 - 1
session_test.go

@@ -6,6 +6,7 @@ import (
 	"io"
 	"io/ioutil"
 	"log"
+	"net"
 	"reflect"
 	"runtime"
 	"strings"
@@ -763,9 +764,17 @@ func TestReadDeadline(t *testing.T) {
 	}
 
 	buf := make([]byte, 4)
-	if _, err := stream.Read(buf); err != ErrTimeout {
+	_, err = stream.Read(buf)
+	if err != ErrTimeout {
 		t.Fatalf("err: %v", err)
 	}
+	// See https://github.com/hashicorp/yamux/issues/90
+	// Standard http server package will read from connections in background to detect if it's alive.
+	// It sets read deadline on connections and detect if the returned error is timeout error which implements net.Error.
+	// HTTP server will cancel all server requests if it isn't timeout error from connections.
+	if netErr, ok := err.(net.Error); !ok || !netErr.Timeout() {
+		t.Fatalf("error of reading timeout is expected to implement net.Error and return true when calling Timeout(), but not")
+	}
 }
 
 func TestReadDeadline_BlockedRead(t *testing.T) {