Hakula

Naive-FTP: A Simple FTP Server and Client
Computer Networks @ Fudan University, fall 2020.
扫描右侧二维码阅读全文
11
2021/01

Naive-FTP: A Simple FTP Server and Client

Computer Networks @ Fudan University, fall 2020.

封面:「カラスの集め物」/「MISSILE228」

Naive-FTP

A simple FTP server and client, written in TypeScript and Python 3.

Naive-FTP GUI

Overview

  • The front-end is developed with Vue 3, and designed based on Ant Design of Vue
  • A local server for client GUI is built with Express for Node.js
  • The back-end implements a subset of the File Transfer Protocol (FTP) with pure socket module in Python
  • Axios and Flask are utilized as middleware to support client side and server side respectively; communications are based on REST APIs, and all transferring data is compressed with Gzip
  • Support multithreading, taking advantage of the threading module in Python

Getting Started

0. Prerequisites

To set up the environment, you need to have the following dependencies installed.

1. Installation

First, obtain the Naive-FTP package.

git clone https://github.com/hakula139/Naive-FTP.git
cd Naive-FTP

Before installing, it's recommended to set up a virtual environment, so that any changes will not affect your global configuration.

python -m venv venv
./venv/Scripts/activate

Now you can build the project using setup.py.

python setup.py install

Make sure you have the latest version of setuptools installed.

python -m pip install --upgrade setuptools

1.1 GUI support

A GUI is optional for Naive-FTP, so if you prefer to use a CLI, you can safely skip this step.

Here we use yarn to build the client GUI. It may take some time, so perhaps there's time for you to make yourself a cup of coffee... if you like.

cd app
yarn
yarn build
cd ..

Besides, the following dependencies are required for the client handler, which provides REST APIs for the client GUI to communicate with the server. Install these packages using pip.

pip install flask waitress

2. Usage

2.1 Server

After a successful installation, you can start the Naive-FTP server using the command below. The server will listen to port 2121 by default.

python ./naive_ftp/server/server.py

You should see the following welcome message. Press q to exit.

Welcome to Naive-FTP server! Press q to exit.

2.2 Client CLI

If you just want to use a CLI, use this command to start one. The client will attempt to establish a connection to localhost:2121 by default.

python ./naive_ftp/client/client.py

To get started, try the command help to show all available commands. All commands are case-insensitive.

> help

Currently, we support the commands as follows.

HELP                         Show a list of available commands.      
OPEN                         Open a connection to server.
QUIT                         Close all connections and quit.
EXIT                         Close all connections and quit.
LIST <server_path>           List information of a file or directory.
LS   <server_path>           List information of a file or directory.
RETR <server_path>           Retrieve a file from server.
GET  <server_path>           Retrieve a file from server.
STOR <local_path>            Store a file to server.
PUT  <local_path>            Store a file to server.
DELE <server_path>           Delete a file from server.
DEL  <server_path>           Delete a file from server.
RM   <server_path>           Delete a file from server.
CWD  <server_path>           Change working directory.
CD   <server_path>           Change working directory.
PWD                          Print working directory.
MKD  <server_path>           Make a directory recursively.
MKDI <server_path>           Make a directory recursively.
RMD  <server_path>           Remove a directory.
RMDI <server_path>           Remove a directory.
RMDA <server_path>           Remove a directory recursively.

2.3 Client handler

To make the GUI work in a proper way, you need to launch the client handler beforehand.

python ./naive_ftp/client_handler/run.py

You should see something like:

Serving on http://Hakula-DELL:5000

2.4 Client GUI

Finally, start the local server and check the web page at http://localhost:8181.

cd app
node server.mjs

The server files and local files are located in ./server_files and ./local_files by default. You may need to manually create them if not exist.

cd ..
mkdir server_files
mkdir local_files

By far, we support these features in our GUI:

  • List the files in a directory
    • Along with their information, namely, file name, file size, file type, last modified time, permissions and owner
    • Hidden files will not be displayed
    • FTP command: LIST /dir_path
  • Change directory to another path
    • FTP command sequence: CWD /dir_path, LIST /dir_path
  • Upload a file
    • FTP command: STOR /file_path
  • Download a file
    • FTP command: RETR /file_path
  • Create a new folder
    • Recursively
    • FTP command: MKDIR /dir_path
  • Mass delete files and directories
    • Directories will be removed recursively
    • FTP commands: DELE /path (for files), RMDA /dir_path (for directories)

How it works

The entire communication process is illustrated as follows.

1. Client GUI

Client GUI

To start with, we suppose that a user is interacting with the client GUI in a browser, and somehow performs an operation (e.g. create a directory).

2. Client GUI -> Axios -> Client handler

The user operation is processed by Vue, interpreted into HTTP requests, and then sent to a local API server using Axios.

Client GUI -> Client handler

Here we call the API server a client handler, which helps the client to communicate with the server.

3. Client handler -> Server -> Client handler

Next, the client handler processes the HTTP request from Axios, and sends FTP requests to the server. The server understands the request and does some operations (here it creates a directory), and consequently returns a FTP response based on the status of this operation.

Serving on http://Hakula-DELL:5000
[INFO ] open_ctrl_conn: Connected to server.
[INFO ] cwd: Changed directory to: /
[INFO ] mkdir: Created directory: Hakula

We can see more details in development mode (using the command flask run).

 * Serving Flask app "./naive_ftp/client_handler/client_handler.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 164-557-715
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [08/Jan/2021 03:11:27] "OPTIONS /api/dir HTTP/1.1" 200 -
[INFO ] open_ctrl_conn: Connected to server.
[INFO ] cwd: Changed directory to: /
127.0.0.1 - - [08/Jan/2021 03:11:27] "POST /api/dir HTTP/1.1" 200 -
127.0.0.1 - - [08/Jan/2021 03:11:28] "GET /api/dir?path=%2F HTTP/1.1" 200 -
127.0.0.1 - - [08/Jan/2021 03:11:35] "OPTIONS /api/dir HTTP/1.1" 200 -
[INFO ] mkdir: Created directory: Hakula
127.0.0.1 - - [08/Jan/2021 03:11:35] "PUT /api/dir HTTP/1.1" 200 -
127.0.0.1 - - [08/Jan/2021 03:11:35] "GET /api/dir?path=%2F HTTP/1.1" 200 -

Besides, you may check the logs on server side to see how the server reacts to the FTP requests.

Welcome to Naive-FTP server! Press q to exit.
[INFO ] open_ctrl_sock: Server started, listening at ('192.168.56.1', 2121)
[INFO ] open_ctrl_conn: Accept connection: ('192.168.56.1', 53225)
[DEBUG] router: Operation: PING
[DEBUG] router: Operation: CWD /
[DEBUG] cwd: Changing working directory to E:\Github\Naive-FTP\server_files
[INFO ] cwd: Changed working directory to /
[DEBUG] router: Operation: PING
[DEBUG] router: Operation: PING
[DEBUG] router: Operation: LIST /
[DEBUG] ls: Listing information of E:\Github\Naive-FTP\server_files
[INFO ] open_data_sock: Data server started, listening at ('192.168.56.1', 53227)
[INFO ] open_data_conn: Data connection opened: ('192.168.56.1', 53228)
[INFO ] ls: Finished listing information of E:\Github\Naive-FTP\server_files
[DEBUG] router: Operation: PING
[DEBUG] router: Operation: PING
[DEBUG] router: Operation: MKD Hakula
[DEBUG] mkdir: Creating directory: E:\Github\Naive-FTP\server_files\Hakula
[INFO ] mkdir: Created directory: E:\Github\Naive-FTP\server_files\Hakula
[DEBUG] router: Operation: PING
[DEBUG] router: Operation: PING
[DEBUG] router: Operation: LIST /
[DEBUG] ls: Listing information of E:\Github\Naive-FTP\server_files

4. Client handler -> Axios -> Client GUI

Finally, the client handler parses the server response (sometimes along with data) to JSON format, and returns back to the client GUI. Some messages may be shown on client side to indicate whether the operation is successful or not.

You may try Postman to inspect how the API works.

Postman

TODO

  • Add more features (if I had time) ;(
    • Rename
    • Download a folder
    • Batch download
    • Upload a folder
    • Batch upload
    • Upload through selecting a file instead of manually inputting a path

Contributors

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.


版权声明:本文为原创文章,版权归 Hakula 所有。

本文链接:https://hakula.xyz/project/naive-ftp.html

本文采用 CC BY-NC-SA 4.0 许可协议 进行许可。

最后修改:2021-01-19
如果我的文章对你有帮助,欢迎赞赏,谢谢你!111

发表评论 取消回复

2 条评论

  1. citronsky   Windows 10 x64 Edition  Google Chrome 87.0.4280.141

    爷关更 ٩(ˊᗜˋ*)و

    1. Hakula   iOS 14.3  Google Chrome for iOS 87.0.4280.77