SSFTP is an acronym of Super Simple File Transfer Protocol. This is an implementation of a simple file transfer application over TCP using Rust programming language. The protocol is designed for client-server model.
SSFTP is an application layer protocol that allows file transfer from server to client, similar to the celebrated FTP, just simpler. It does not allow users to upload, delete, modify, rename the files and directories on the server side. Users only allowed to download and getting information about a file on the server side. It is also stateless since it does not need to remember any state.
Take example by the HTTP, SSFTP make use of the idea of request methods, specifying the main purpose of the request. SSFTP only have three request methods: GET, INFO, DIR:
-
GET
User sends a GET request when they want to download a file from the server.
-
INFO
User sends a INFO request when they want to get only information of a file from the server.
-
DIR
User sends a DIR request when they want to get the contents of a directory on server side.
GET <path>\n
where path
is the file path on server.
INFO <path>\n
where path
is the file path on server.
DIR <path>\n
where path
is the file path on server.
Every response from server has the following format
<status-code>\n
<headers>\n
<payload>
status code indicates the response type. The available status codes are:
OK
- Everything is OK.NOT-EXIST
- Requested file or directory not exist.NOT-FILE
-path
in a GET request is not a.NOT-DIRECTORY
-path
in a DIR request is a not a directory.SERVER-ERROR
- server error.BAD-REQUEST
- client provided a malformed request.
Headers is a one-line json code, giving the information of the related to the response.
When the request is GET and status code is OK
, the available headers are:
content-length
: An integer, size of thepayload
in bytes.
When the request is DIR and status code is OK
, the available headers are:
content-length
: An integer, size of thepayload
in bytes.count
: An integer, number of files + directories in the requested directory.
When the request is INFO and status code is OK
, the available headers are:
-
type
: A string, either'directory'
or'file'
. -
content-length
: An integer, iftype
is'file'
, size of the file in bytes.
When the request is GET and status code is OK
, the payload
field contains full content of the file in raw bytes.
When the request is DIR and status code is OK
, the payload
field contains many lines of entries, where each line is a JSON escaped file name or directory name. If it is a directory name, the entry ends with a '/'.
An example of payload
field:
file-a\n
file-b\n
dir-c/\n
file-d
Empty (0 bytes).
Suppose the directory /home/myname/Pictures/
contains:
/home/myname/Pictures/:
baby.jpg
帅气的男银.jpg
cute-dogs/
dog_a.jpg
dog_b.jpg
dog_c.jpg
That is, /home/myname/Pictures
contains 2 files and 1 directory containing 3 files.
And the server listening and serve on the directory /home/myname/Pictures/
.
If an incoming request is
GET /baby.jpg\n
Then the server return a response
OK\n
{"content-length": <size of baby.jpg>}\n
<content of baby.jpg>
If an incoming request is
GET /girl.jpg\n
Then the server return a response
NOT-EXIST\n
{}\n
If an incoming request is
DIR /\n
Then the server return a response
OK\n
{"content-length": 29, "count": 3}\n
baby.jpg\n
帅气的男银.jpg\n
cute-dogs/