FTPLite Extension V1 - Server & Client

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.* and java.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
  • 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

  1. Build or obtain FtpLite.aix.
  2. In Kodular Creator / MIT App Inventor:
  • Import the extension (Extensions → Import).
  • Drag FtpLite (non-visible component) onto your project.
  1. 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

  1. Choose a port ≥ 1024 (e.g., 2121).
  2. Set root directory (leave blank to use the app files directory).
  3. Call:
  • ServerStart(2121, "<rootPath>", "user", "pass", true, "192.168.1.10")
    • allowAnonymous = true allows USER 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

  1. ClientConnect("192.168.1.10", 2121, 5000)
  2. ClientLogin("user", "pass")
  3. Optionally: ClientType(true) for binary.
  4. List: ClientList("")
  5. Download: ClientDownload("/remote.txt", "local.txt")
  6. Upload: ClientUpload("/sdcard/input.txt", "uploaded.txt")
  7. 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.
  • ServerStop()
    • Stops the server (closes the listening socket).
  • ServerSetAllowOverwrite(allow)
    • Controls whether STOR overwrites existing files.
  • ServerIsRunning() → boolean
    • Returns current server state.

Client API

  • ClientConnect(host, port, timeoutMs)
    • Opens control connection.
  • ClientLogin(user, pass)
    • Sends USER/PASS.
  • ClientType(binary)
    • true → TYPE I (binary), false → TYPE A (ASCII).
  • ClientNoop()
    • Sends NOOP.
  • ClientList(path)
    • Performs PASV → LIST path.
    • Result in ClientListResult.
  • 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)

  1. On phone (server):
  • ServerStart(2121, "", "user", "pass", true, "192.168.1.10")
  1. On PC (client app like FileZilla):
  • Host: 192.168.1.10, Port: 2121, Protocol: FTP, Passive mode.
  • Login with user/pass or anonymous (if allowed).
  1. Transfer files within the server root.

Upload a file to a remote FTP

  1. ClientConnect("ftp.remoteHost.com", 21, 8000)
  2. ClientLogin("user", "pass")
  3. ClientType(true)
  4. ClientUpload("/sdcard/Download/photo.jpg", "photo.jpg")
  5. Watch ClientTransferProgress → ClientTransferDone.

Directory listing & navigation

  • ClientPwd() → check current working directory.
  • ClientCwd("/folder")
  • ClientList("") → parse listing text in ClientListResult.

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):
    Ensure pasvHostIp in ServerStart 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.

3 Likes

i want to upload video in public_html directory but in namecheap ftp accounts did’nt set default to public_html, how can i upload to public_html by using your extention please gauid thanks

Hi.
I saw your extension, but I’d like to ask you a few questions to see if I fully understand what it can do.

I would like to explain the application I am trying to build and I would like to ask you if your extension could be suitable for me.

I created an app for managing a restaurant, including command entry and so on, and I’d like to create a PDA with your extension. Would it be possible to set up communication via the internal Wi-Fi, where I can transfer data from the PDA to the main tablet?