Previously, the Server.Serve method would never return nil,
because the infinite for-loop handling request packets would
only break if reading a packet reported an error.
A common termination condition is when the underlying connection
is closed and recvPacket returns io.EOF.
In which case Serve should ignore io.EOF and
treat it as a normal shutdown.
However, this means that recvPacket must correctly handle io.EOF
such that it never reports io.EOF if a packet is partially read.
There are two calls to io.ReadFull in recvPacket.
The first call correctly forwards an io.EOF error
if no additional bytes of the next packet are read.
However, the second call incorrectly forwards io.EOF
when no bytes of the payload could be read.
This is incorrect since we already read the length and
should convert the io.EOF into an io.ErrUnexpectedEOF.
This commit allows the working directory for the (old) Server
implementation to be changed without doing a `os.Chdir` first.
The feature can be enabled with `sftp.WithServerWorkingDirectory(dir)`
passed as an option to `sftp.NewServer`.
It is useful when the `sftp` is used as part of a larger service that
does more than just serve `sftp` and using `os.Chdir` is not an option.
The fallback behavior (when the option is not specified) is that the
path remains unmodified (as before).
Always use os.IsNotExist to identify any OS specific error types that
represent missing files or directories. This resolves an issue on
Windows where some system errors (ENOTDIR) were not being identified as
'not found' errors and mapped to sshFxNoSuchFile.
fixes#381
after processing a packet we keep in memory the allocated slices and we reuse
them for new packets.
Slices are allocated in:
- recvPacket
- when we receive a sshFxpReadPacket (downloads)
The allocated slices have a fixed size = maxMsgLength.
Allocated slices are referenced to the request order id and are marked for reuse
after a request is served in maybeSendPackets.
The allocator is added to the packetManager struct and it is cleaned at the end
of the Serve() function.
This allocation mode is optional and disabled by default
Fixes issue with append uploads. Was opening the file with O_APPEND, but
it uses WriteAt() to write the data which doesn't work with a file
opened in append mode. Removing the append flag fixes the issue as the
client is sending the offsets anyways.
Also added a note to the Request server's FileWriter interface on
handling append flags.
Previous code used the request ids to do ordering. This worked until a
client came along that used un-ordered request ids. This reworks the
ordering to use an internal counter (per session) to order all packets
ensuring that responses are sent in the same order as the requests were
received.
Fixes#260
Instead of sendPacket/sendError being sprayed all over the place, this
change has all those places instead return a responsePacket (eventually)
back to the main handling function which then calls sendPacket in one
place.
Behaviour of the code should remain exactly the same.
This makes it much easier to work with the response packets (eg. for the
packet ordering issue I'm working on).
sendError takes a requestPacket but was simplifying it to an ider
interface. Future work needed it to be requestPacket but I wanted to fix
didn't up type usage in its own commit.
Instead of accepting a more general type and then asserting it to the
proper type, just take the proper type as the argument.
Also clean up some of the use of it where it checked old direct sending
code's return error (error is now always nil).
The initial Opendir packet is supposed to repond with an error status if
the directory wasn't found. It was just returning a handle without
checking, now it does a Stat on the path and only returns the handle if
the Stat is successful and it indicates it is a directory, otherwise it
returns an error.
Add errors for all the SSH_FXP_STATUS codes to give the developer
implementing request server handlers greater control over the returned
codes. Most helpful in cases where nothing currently would work (eg.
unsupported).
Fixes#223
Splitted cleanPath into cleanPacketPath and cleanPath for better handling of slashes in file paths
Added test for cleanPath func
Removed code duplication => filepath.ToSlash(filepath.Clean(...)) => cleanPath(...)
Fixed tests for runLs to match year or time
Renamed constants to fit hound rules