fix(ftp): fix STARTTLS, error visibility, and robustness

Problem: `curl_ftp_url` emitted `ftps://` (implicit TLS) for
`oil-ftps://` URLs, causing listing to fail against STARTTLS servers
while Python mutations worked — the two paths spoke different TLS
modes. curl's `-s` flag silenced all error output, producing "Unknown
error" on any curl failure. File creation used `/dev/null` (breaks on
Windows, diverges from S3). The Python TLS context didn't honour
`--insecure`/`-k` from `extra_curl_args`. Deleting non-empty dirs on
servers without MLSD gave a cryptic `500 Unknown command`.

Solution: Always emit `ftp://` in `curl_ftp_url`; TLS is enforced
solely via `--ssl-reqd`, making STARTTLS consistent between curl and
Python. Add `-S` to expose curl errors. Replace `/dev/null` with
`curl -T -` + `stdin='null'` (matches `s3fs` pattern). Mirror
`--insecure`/`-k` into the Python SSL context. Wrap `mlsd()` in
try/except with a clear actionable message. Add `spec/ftp_spec.lua`
with 28 unit tests covering URL parsing, list parsing, and curl URL
building. Update `doc/oil.txt` to document STARTTLS and MLSD.
This commit is contained in:
Barrett Ruth 2026-03-17 23:41:54 -04:00
parent 0af52a0f6d
commit 27544d73e7
Signed by: barrett
GPG key ID: A6C96C9349D2FC81
3 changed files with 205 additions and 14 deletions

View file

@ -1001,8 +1001,9 @@ FTP *oil-adapter-ft
nvim oil-ftp://[username[:password]@]hostname[:port]/[path]/
nvim oil-ftps://[username[:password]@]hostname[:port]/[path]/
<
The `oil-ftps://` scheme connects with `--ssl-reqd`, requiring a valid TLS
certificate. Use `oil-ftp://` for plain FTP.
The `oil-ftps://` scheme uses explicit TLS (STARTTLS / AUTH TLS, RFC 4217).
The server must support the `AUTH TLS` command on port 21. Servers using
implicit TLS (port 990) are not supported. Use `oil-ftp://` for plain FTP.
Authentication ~
@ -1022,7 +1023,9 @@ FTP *oil-adapter-ft
Symbolic links cannot be created over FTP. Directory copies are not
supported (copy individual files instead). Moving or copying directories
across different FTP hosts is not supported.
across different FTP hosts is not supported. Deleting non-empty directories
requires MLSD support (RFC 3659); supported by vsftpd, ProFTPD, FileZilla
Server, and most servers from 2007 onwards.
Configuration ~