Add the WithMaxTxPacket and WithRSMaxTxPacket server options to increase
the maximum tx packet size to a value above 32K. This allows to send
bigger chunks of data to the client as response to a read request. As
the client specifies the wanted length, it should be safe to increase
the server maximum value.
This in particular allows the implemented Client with the
MaxPacketUnchecked option to retrieve data in larger chunks.
Signed-off-by: Peter Verraedt <peter@verraedt.be>
The ListerAt is stored in the Request state and reused across requests.
Some implementations don't store the entire []os.FileInfo buffer in the
ListerAt implementation but instead return an open file and get/return
[]os.FileInfo on request. For these implementation calling Close is
required
ReadlinkFileLister with its Readlink method allows returning paths without
misusing the os.FileInfo interface, whose Name() method should only return
the base name of a file.
By implementing ReadlinkFileLister, it is possible to easily return
symlinks of any kind (absolute, relative, multiple directory levels)
Add LstatFileLister, an optional interface for FileLister, if this
interface is implemented Lstat requests will call it otherwirse they
will be handled in the same way as Stat, as before
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
When fstat is called it now uses the handle to get the opened request,
pulls the filepath from that and creates a new request for the fstat
call. This eliminates the need to change the Method on the request
object and furthers the goal of eliminating post-creation mutation of
the request object to open up the possibility to eliminate or at least
reduce the use of the global request lock.
Just like with files, the call to the hander to create the Lister is
done when the OPENDIR packet is received. This eliminates the need for
the lock in the filelist() method and opens the path for eliminating
more locks.
Testing feasibility of creating the reader/writer when first receiving
the Open packet instead of waiting for the Get/Put.
This work is meant to make the Request locks easier to manage and
ultimately reducing/eliminating them as much as possible.
This fixes the concurrent access/locking race in both fileget and
fileput when accessing the saved readerAt/writerAt. It eliminates the
dedicated functions and moves the access/locking inline where they were
called to make it clearer.
Thanks to Marshall Brekka (@marshallbrekka) for the original bug report
and outline for the fix.
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.
When I moved the context below the close calls to fix the issue with
cancel interfering with file finalizing, I didn't take into account
the returns. The context cancel needed to be done regardless which this
does by moving it into a defer.
Don't return until FileLister returns io.EOF and 0 results. Fixes issue
where FileLister would return 0 results in one batch, but still have
more results to go.
Fixes#240
File reading/writeing might block on close until finished. If the
context's cancel is run first it can cancel the session before that
finishes. So the context's cancel should always be run last.
Create a master Context in the per-session ReqeustServer.Serve method
that is then used as the parent for all Context's created in that
server. Its cancelFunc is then always called when Serve exits. This is
in line which out the http.serve code works.
Each Request gets a child WithCancel context created in the
requestFromPacket call. This Context is still closed on request.close().
packet_data structure was a leftover from previous code and it is no
longer necessary as the packets are available to use. I kept
packetData() to simplify grabing the data off the packets.
When the SSH_FXP_OPEN packet has the SSH_FXF_CREAT pflag set the file
should get created even if no data is sent. We do this by having the
Open method call through to the FilePut Handler with empty packet data.
Fixes#214