Skip to content

Commit

Permalink
handle errors in file creation from open packet
Browse files Browse the repository at this point in the history
open packet w/ the create flag would create the file but was ignoring
any errors from that. this fixes that and adds a test for it.
  • Loading branch information
eikenb committed Jan 8, 2018
1 parent 1a8a095 commit 30b632c
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 18 deletions.
13 changes: 2 additions & 11 deletions packet-typing.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ type hasHandle interface {
getHandle() string
}

type isOpener interface {
hasPath
isOpener()
}

type notReadOnly interface {
notReadOnly()
}
Expand All @@ -52,15 +47,11 @@ func (p sshFxpStatvfsPacket) getPath() string { return p.Path }
func (p sshFxpRemovePacket) getPath() string { return p.Filename }
func (p sshFxpRenamePacket) getPath() string { return p.Oldpath }
func (p sshFxpSymlinkPacket) getPath() string { return p.Targetpath }
func (p sshFxpOpendirPacket) getPath() string { return p.Path }
func (p sshFxpOpenPacket) getPath() string { return p.Path }

func (p sshFxpExtendedPacketPosixRename) getPath() string { return p.Oldpath }

// Openers implement hasPath and isOpener
func (p sshFxpOpendirPacket) getPath() string { return p.Path }
func (p sshFxpOpendirPacket) isOpener() {}
func (p sshFxpOpenPacket) getPath() string { return p.Path }
func (p sshFxpOpenPacket) isOpener() {}

// hasHandle
func (p sshFxpFstatPacket) getHandle() string { return p.Handle }
func (p sshFxpFsetstatPacket) getHandle() string { return p.Handle }
Expand Down
22 changes: 17 additions & 5 deletions request-server.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,19 @@ func (rs *RequestServer) packetWorker(pktChan chan requestPacket) error {
rpkt = statusFromError(pkt, rs.closeRequest(handle))
case *sshFxpRealpathPacket:
rpkt = cleanPacketPath(pkt)
case isOpener:
case *sshFxpOpendirPacket:
request := requestFromPacket(pkt)
handle := rs.nextRequest(request)
rpkt = sshFxpHandlePacket{pkt.id(), handle}
case *sshFxpOpenPacket:
request := requestFromPacket(pkt)
handle := rs.nextRequest(request)
p, ok := pkt.(*sshFxpOpenPacket)
if ok && p.hasPflags(ssh_FXF_CREAT) {
request.call(rs.Handlers, pkt)
}
rpkt = sshFxpHandlePacket{pkt.id(), handle}
if pkt.hasPflags(ssh_FXF_CREAT) {
if p := request.call(rs.Handlers, pkt); !isOk(p) {
rpkt = p // if error in write, return it
}
}
case hasHandle:
handle := pkt.getHandle()
request, ok := rs.getRequest(handle, requestMethod(pkt))
Expand All @@ -182,6 +187,13 @@ func (rs *RequestServer) packetWorker(pktChan chan requestPacket) error {
return nil
}

// True is responsePacket is an OK status packet
func isOk(rpkt responsePacket) bool {
p, ok := rpkt.(sshFxpStatusPacket)
return ok && p.StatusError.Code == ssh_FX_OK
}

// clean and return name packet for file
func cleanPacketPath(pkt *sshFxpRealpathPacket) responsePacket {
path := cleanPath(pkt.getPath())
return &sshFxpNamePacket{
Expand Down
9 changes: 7 additions & 2 deletions request-server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,21 +131,26 @@ func TestRequestWriteEmpty(t *testing.T) {
p := clientRequestServerPair(t)
defer p.Close()
n, err := putTestFile(p.cli, "/foo", "")
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, 0, n)
r := p.testHandler()
f, err := r.fetch("/foo")
if assert.Nil(t, err) {
assert.False(t, f.isdir)
assert.Equal(t, f.content, []byte(""))
}
// lets test with an error
writeErr = os.ErrInvalid
n, err = putTestFile(p.cli, "/bar", "")
assert.Error(t, err)
writeErr = nil
}

func TestRequestFilename(t *testing.T) {
p := clientRequestServerPair(t)
defer p.Close()
_, err := putTestFile(p.cli, "/foo", "hello")
assert.Nil(t, err)
assert.NoError(t, err)
r := p.testHandler()
f, err := r.fetch("/foo")
assert.NoError(t, err)
Expand Down

0 comments on commit 30b632c

Please sign in to comment.