FTPLite Extension V1
A lightweight FTP Server & Client for Kodular / MIT App Inventor, built with pure Java 7 (no external JARs).
Implements essential FTP commands over PASV (passive) data connections. Ideal for local LAN transfers, learning, and utility tasks.
List Block
Highlights
- Two-in-one: FTP Server and Client components in one extension.
- Zero dependencies: uses only
java.net.*
andjava.io.*
. - Java 7 compatible: compiles cleanly on Kodular/AI2 toolchains.
- Passive mode (PASV): simple firewall/NAT-friendly data transfer.
- Core commands:
- Server:
USER
,PASS
,SYST
,NOOP
,TYPE
,PWD
,CWD
,MKD
,RMD
,DELE
,PASV
,LIST
,RETR
,STOR
,QUIT
- Client:
USER
,PASS
,TYPE
,NOOP
,PWD
,CWD
,LIST
,RETR
,STOR
,QUIT
- Server:
- Events for connection status, list results, transfer progress, and errors.
Requirements
- Kodular or MIT App Inventor (Companion/Compiler with Internet permission).
- Android 5.0+ recommended.
- LAN/Wi-Fi for local transfers (or reachable network between peers).
Installation
- Build or obtain
FtpLite.aix
. - In Kodular Creator / MIT App Inventor:
- Import the extension (
Extensions → Import
). - Drag FtpLite (non-visible component) onto your project.
- Add UI (optional) for logs, buttons, and inputs.
Permissions
The extension requests:
INTERNET
ACCESS_NETWORK_STATE
READ_EXTERNAL_STORAGE
/WRITE_EXTERNAL_STORAGE
(for file I/O; on modern Android, writes are to the app’s files directory by default).
Tip: For broad storage on Android 10+, consider using app-internal directories or SAF pickers. FTPLite saves to the app’s files directory by default when acting as a client.
Quick Start
Start a server on Android
- Choose a port ≥ 1024 (e.g., 2121).
- Set root directory (leave blank to use the app files directory).
- Call:
ServerStart(2121, "<rootPath>", "user", "pass", true, "192.168.1.10")
allowAnonymous = true
allowsUSER anonymous
.pasvHostIp
should be the Android device’s LAN IP for PASV replies.
Typical flow (blocks):
- On button “Start Server”:
ServerStart(2121, "", "user", "pass", true, "192.168.1.10")
- Handle:
ServerStarted(port, rootPath)
ServerError(message)
ServerStopped()
Connect from a desktop FTP client (FileZilla/WinSCP) to 192.168.1.10:2121
(use Passive mode).
Connect as a client
ClientConnect("192.168.1.10", 2121, 5000)
ClientLogin("user", "pass")
- Optionally:
ClientType(true)
for binary. - List:
ClientList("")
- Download:
ClientDownload("/remote.txt", "local.txt")
- Upload:
ClientUpload("/sdcard/input.txt", "uploaded.txt")
- Quit:
ClientQuit()
Listen to events:
ClientConnected(greetingLine)
ClientResponse(code, line)
ClientListResult(success, listing, error)
ClientTransferProgress(cmd, transferred, total)
ClientTransferDone(cmd, success, detail)
ClientError(message)
Blocks Reference
Server API
- ServerStart(port, rootDirPath, username, password, allowAnonymous, pasvHostIp)
- Starts a PASV-only FTP server bound to
port
. - Root directory is
rootDirPath
or the app’s files directory if blank. - Use
pasvHostIp
= device LAN IP (e.g.,192.168.1.x
) so clients can connect to PASV ports.
- Starts a PASV-only FTP server bound to
- ServerStop()
- Stops the server (closes the listening socket).
- ServerSetAllowOverwrite(allow)
- Controls whether
STOR
overwrites existing files.
- Controls whether
- ServerIsRunning() → boolean
- Returns current server state.
Client API
- ClientConnect(host, port, timeoutMs)
- Opens control connection.
- ClientLogin(user, pass)
- Sends
USER/PASS
.
- Sends
- ClientType(binary)
true
→TYPE I
(binary),false
→TYPE A
(ASCII).
- ClientNoop()
- Sends
NOOP
.
- Sends
- ClientList(path)
- Performs
PASV
→LIST path
. - Result in
ClientListResult
.
- Performs
- ClientDownload(remotePath, localFileName)
PASV
→RETR
. Saves into app files directory.
- ClientUpload(localFilePath, remotePath)
PASV
→STOR
.
- ClientCwd(path) / ClientPwd()
- Change / print working directory.
- ClientQuit()
QUIT
and close control connection.
Events
Server
- ServerStarted(port, rootPath)
- ServerStopped()
- ServerError(message)
Client
- ClientConnected(greetingLine)
- ClientResponse(code, line)
- ClientListResult(success, listing, error)
- ClientTransferProgress(cmd, transferred, total)
- ClientTransferDone(cmd, success, detail)
- ClientError(message)
Usage Recipes
LAN file sharing (Phone ↔ PC)
- On phone (server):
ServerStart(2121, "", "user", "pass", true, "192.168.1.10")
- On PC (client app like FileZilla):
- Host:
192.168.1.10
, Port:2121
, Protocol: FTP, Passive mode. - Login with
user/pass
oranonymous
(if allowed).
- Transfer files within the server root.
Upload a file to a remote FTP
ClientConnect("ftp.remoteHost.com", 21, 8000)
ClientLogin("user", "pass")
ClientType(true)
ClientUpload("/sdcard/Download/photo.jpg", "photo.jpg")
- Watch
ClientTransferProgress
→ClientTransferDone
.
Directory listing & navigation
ClientPwd()
→ check current working directory.ClientCwd("/folder")
ClientList("")
→ parselisting
text inClientListResult
.
File Paths & Storage
- By default, downloads go to the app’s files directory, e.g.:
/storage/emulated/0/Android/data/<your.package>/files/
(external)- or the app’s internal files dir if external is unavailable.
- When running the server, set
rootDirPath
to a folder you control.
The server enforces a canonical path check to prevent directory traversal above the root.
Security Notes
- LAN use recommended. This is a minimal FTP implementation without TLS/FTPS.
- Avoid exposing your server to the public Internet.
- Use strong credentials; disable
allowAnonymous
unless necessary. - Be mindful of overwrite behavior (
ServerSetAllowOverwrite
). - Consider running on non-standard port (e.g. 2121) and behind a firewall.
Limitations
- PASV only. Active mode (PORT/EPRT) is not implemented.
- No TLS/FTPS. Plain FTP (credentials in clear text).
- Basic directory listing format (UNIX-like text).
- No resume/
REST
support. - Not optimized for extremely large files or thousands of concurrent clients.
Troubleshooting
- Client can’t list or transfer (hangs on PASV):
EnsurepasvHostIp
inServerStart
equals the LAN IP of the Android device; both devices must be on the same subnet. - “Address already in use” on ServerStart:
Pick another port ≥ 1024 (e.g., 2221, 2323). - Permission errors writing files:
Use the app’s files directory (default) or ensure your target path is writable on your Android version. - Slow transfers:
Prefer 5 GHz Wi-Fi; avoid mobile data; keep files reasonable in size.
Download
com.rasitech.ftplite.aix (44.7 KB)
FAQ
Q: Can I run the server on port 21?
A: Typically no on Android (privileged port). Use ports ≥ 1024 like 2121.
Q: Does it support SSL/TLS (FTPS)?
A: No. Use LAN or a VPN if you need confidentiality.
Q: Where are downloads saved?
A: In the app’s files directory; the absolute path is under your package folder. You can move files after transfer if needed.
Q: How do I enable Passive mode in desktop clients?
A: Most GUI clients default to Passive (PASV). Ensure it’s enabled to match FTPLite.
Changelog
- V1
- Initial release: FTP Server (PASV), FTP Client (LIST/RETR/STOR), basic auth, minimal directory ops, transfer progress events.
License
Provided “as is,” without warranty. You may bundle or modify within your apps.
Please credit FTPLite by rasi tech when sharing or forking.