ftp

package
v0.45.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 25, 2026 License: MIT Imports: 16 Imported by: 0

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

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

func (d *Driver) Close() error

Close releases the underlying FTP session — called on shutdown. It waits for a download that holds the session to be closed.

func (*Driver) Copy

func (d *Driver) Copy(ctx context.Context, src, dst string) error

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) Delete

func (d *Driver) Delete(ctx context.Context, p string) error

Delete implements storage.Deleter — tries DELE first, falls back to RMD.

func (*Driver) Init

func (d *Driver) Init(_ context.Context, cfg map[string]any) error

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) List

func (d *Driver) List(ctx context.Context, p string) ([]storage.Object, error)

List implements storage.Driver.

func (*Driver) Mkdir

func (d *Driver) Mkdir(ctx context.Context, p string) error

Mkdir implements storage.Mkdirer.

func (*Driver) Move

func (d *Driver) Move(ctx context.Context, src, dst string) error

Move implements storage.Mover via RNFR + RNTO (the library's Rename wraps both commands).

func (*Driver) Name

func (d *Driver) Name() string

Name implements storage.Driver.

func (*Driver) Read

func (d *Driver) Read(ctx context.Context, p string) (io.ReadCloser, error)

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

func (d *Driver) ReadRange(ctx context.Context, p string, off, length int64) (io.ReadCloser, error)

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.

func (*Driver) Stat

func (d *Driver) Stat(ctx context.Context, p string) (storage.Object, error)

Stat implements storage.Driver.

FTP has no portable stat operation. We try GetEntry first (RFC 3659 MLST — supported by modern servers) and fall back to listing the parent directory and matching the basename.

func (*Driver) Write

func (d *Driver) Write(ctx context.Context, p string, r io.Reader, _ int64) error

Write implements storage.Writer. Not sent again once it reached the server: r is the caller's stream (see run).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL