Merge pull request #392 from drakkan/transfereof

request-server: don't return EOF if there is an unexpected error
This commit is contained in:
Nicola Murino 2020-11-18 12:51:23 +01:00 committed by GitHub
commit 7230c61342
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 4 deletions

View File

@ -167,6 +167,9 @@ func (rs *RequestServer) Serve() error {
// make sure all open requests are properly closed
// (eg. possible on dropped connections, client crashes, etc.)
for handle, req := range rs.openRequests {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
req.transferError(err)
delete(rs.openRequests, handle)

View File

@ -19,6 +19,7 @@ var _ = fmt.Print
type csPair struct {
cli *Client
svr *RequestServer
svrResult chan error
}
// these must be closed in order, else client.Close will hang
@ -39,6 +40,9 @@ func clientRequestServerPair(t *testing.T) *csPair {
skipIfPlan9(t)
ready := make(chan bool)
os.Remove(sock) // either this or signal handling
pair := &csPair{
svrResult: make(chan error, 1),
}
var server *RequestServer
go func() {
l, err := net.Listen("unix", sock)
@ -55,7 +59,8 @@ func clientRequestServerPair(t *testing.T) *csPair {
options = append(options, WithRSAllocator())
}
server = NewRequestServer(fd, handlers, options...)
server.Serve()
err = server.Serve()
pair.svrResult <- err
}()
<-ready
defer os.Remove(sock)
@ -65,7 +70,9 @@ func clientRequestServerPair(t *testing.T) *csPair {
if err != nil {
t.Fatalf("%+v\n", err)
}
return &csPair{client, server}
pair.svr = server
pair.cli = client
return pair
}
func checkRequestServerAllocator(t *testing.T, p *csPair) {
@ -718,6 +725,34 @@ func TestRequestReaddir(t *testing.T) {
checkRequestServerAllocator(t, p)
}
func TestCleanDisconnect(t *testing.T) {
p := clientRequestServerPair(t)
defer p.Close()
err := p.cli.conn.Close()
require.NoError(t, err)
// server must return io.EOF after a clean client close
// with no pending open requests
err = <-p.svrResult
require.EqualError(t, err, io.EOF.Error())
checkRequestServerAllocator(t, p)
}
func TestUncleanDisconnect(t *testing.T) {
p := clientRequestServerPair(t)
defer p.Close()
foo := NewRequest("", "foo")
p.svr.nextRequest(foo)
err := p.cli.conn.Close()
require.NoError(t, err)
// the foo request above is still open after the client disconnects
// so the server will convert io.EOF to io.ErrUnexpectedEOF
err = <-p.svrResult
require.EqualError(t, err, io.ErrUnexpectedEOF.Error())
checkRequestServerAllocator(t, p)
}
func TestCleanPath(t *testing.T) {
assert.Equal(t, "/", cleanPath("/"))
assert.Equal(t, "/", cleanPath("."))