Documentation
¶
Overview ¶
Package ftp is a Storage Driver fronting a plain FTP (or FTPS) server.
Connection lazy: the underlying control connection is established on first operation. A single shared connection is reused; if a server-side error indicates a dead session, the next operation will redial. FTP is not safe for concurrent use on a single connection so all calls go through one lock — which a caller whose context ends stops waiting for.
Every wait on the server is bounded (issue #73, timeout.go): before, only the TCP connect was, and a server that stopped answering held the lock — and so the whole storage — forever.
Index ¶
- type Driver
- func (d *Driver) Capabilities() storage.Capabilities
- func (d *Driver) Close() error
- func (d *Driver) Copy(ctx context.Context, src, dst string) error
- func (d *Driver) Delete(ctx context.Context, p string) error
- func (d *Driver) Init(_ context.Context, cfg map[string]any) error
- func (d *Driver) List(ctx context.Context, p string) ([]storage.Object, error)
- func (d *Driver) Mkdir(ctx context.Context, p string) error
- func (d *Driver) Move(ctx context.Context, src, dst string) error
- func (d *Driver) Name() string
- func (d *Driver) Read(ctx context.Context, p string) (io.ReadCloser, error)
- func (d *Driver) ReadRange(ctx context.Context, p string, off, length int64) (io.ReadCloser, error)
- func (d *Driver) Stat(ctx context.Context, p string) (storage.Object, error)
- func (d *Driver) Write(ctx context.Context, p string, r io.Reader, _ int64) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Driver ¶
type Driver struct {
// contains filtered or unexported fields
}
Driver is the FTP / FTPS storage driver.
func (*Driver) Capabilities ¶
func (d *Driver) Capabilities() storage.Capabilities
Capabilities — FTP supports read/write/move/copy/delete/mkdir. Presign, multipart and watcher are not available.
func (*Driver) Close ¶
Close releases the underlying FTP session — called on shutdown. It waits for a download that holds the session to be closed.
func (*Driver) Copy ¶
Copy implements storage.Copier. FTP has no native server-side copy command, so we stream the file through the control host: download the source on one data connection, upload to the destination on the next.
func (*Driver) Init ¶
Init configures the driver. Required: host, user, password, root. Optional: port (default 21), tls (default false), passive (default true), and the three timeout settings (timeout.go).
The config keys are declared in descriptor.go — keep the two in step, there is a test that fails when they drift. Legacy spellings are read through the descriptor's aliases ("username" for user, "base_path" / "remote_path" for root) so rows written by older surfaces keep working.
func (*Driver) Move ¶
Move implements storage.Mover via RNFR + RNTO (the library's Rename wraps both commands).
func (*Driver) Read ¶
Read implements storage.Driver. The returned ReadCloser holds the driver lock until Close — keep reads short or buffer the body if long-lived locks are a concern.
func (*Driver) ReadRange ¶
ReadRange implements storage.RangeReader via the REST command (`RetrFrom`), so the server skips the first off bytes instead of filex reading and discarding them. RetrFrom requires the server to answer 350 to REST — a server without REST support errors here rather than quietly restarting at byte 0.
⚠ Unlike local/S3, an offset past EOF is server-dependent (many answer 550 → ErrNotFound instead of an empty transfer). Callers that know the size should not ask for it; the download seeker never does.