# Client-Server Protocol Protocol version: "0.3" Every json message must be minimized (i.e. must not contain newlines) and be followed by a newline. This rule makes receiving and parsing the messages easier because you can read until a newline comes and you will parse every json message seperately because you won't read multiple json messages from the buffer at a time. ## 1. Start a connection To start a connection you have to check the versions and verify the login or signup. Only if step 1.1 and 1.2 have been accomplished a usable connection is negotiated. You can close the connection by sending a cancel message. ### 1.1 Version check Client: ``` { "major": int, "minor": int } ``` (For example, if the version number is 42.1, then major is 42, minor is 1.) Server: ``` { "major": int, "minor": int, "accept": bool } ``` If `accept` is `true` the connection is valid. Else the connection will be terminated after the server answered. ## 1.2 Login / Signup The client is supposed to always send every field used for the login requests: `login`, `user`, `pass` and `cancel`. The server is supposed to always send every field used for the login answer: `accept` and `error`. ### 1.2.1 Login Client: ``` { "login": true, "user": string, "pass": string, "cancel": false } ``` Server: ``` { "accept": bool, "error": string } ``` If `accept` is `true` the connection is valid and the user is logged in. Else `error` has an error string and the connection will be terminated after the server answered. ### 1.2.2 Signup Client: ``` { "login": false, "user": string, "pass": string, "cancel": false } ``` Server: ``` { "accept": bool, "error": string } ``` If `accept` is `true` the connection is valid and the user is logged in and signed up. Else `error` has an error string and the connection will be terminated after the server answered. ### 1.2.3 Cancel login Client: ``` { "login": bool, "user": string, "pass": string, "cancel": true } ``` After the cancel message was sent the connection will be closed. ## 2. Sending commands Commands can be sent by the client after a connection has been negotiated (See 1). Commands can be used unrelated to each other. ### 2.1 Status command Client: ``` { "command": "status" } ``` Server: ``` { "command": "status", "response": string } ``` ### 2.2 List command List is split in two commands. `list` to request a list download and `listdata` to download the list. #### 2.2.1 list - request file list download Client: ``` { "command": "list" } ``` Server: ``` { "command": "list", "accept": bool, "items": int, "chunks": int, "error": string } ``` `chunks` is the number of chunks that will be sent. #### 2.2.2 listdata - download file list Client: ``` { "command": "listdata", "chunk": int, "cancel": bool } ``` Here `chunk` is the number of remaining chunks. (Thus, when requesting the first chunk the number of chunks - 1 is expected.)

Server: ``` { "command": "listdata", "remaining": int, "cancel": bool, "names": string[], "error": string } ``` The client has to request every chunk until all names have been sent and `remaining` hits `0`. ### 2.3 Put command Put is split in two commands. `put` to request a file upload and `putdata` to upload the data. #### 2.3.1 put - request upload Client: ``` { "command": "put", "file": string, "size": int, "chunks": int } ``` `chunks` is the number of chunks of the file to send.

Server: ``` { "command": "put", "file": string, "accept": bool, "error": string } ``` If `accept` is `true` the connection is valid and the client can start sending the file. Else the put request was rejected and is hereby canceled. `error` should contain an error string if the request was rejected. #### 2.3.2 putdata - upload data Client: ``` { "command": "putdata", "file": string, "data": string, "remaining": int, "cancel": bool } ``` `data` is a base64 string and contains a piece of the file. The client will loop this until the file is completely sent and the server has to send and received message for every chunk. `remaining` is a counter how many chunks will follow and the transfer is over after it hits `0`. If `cancel` is `true` the file transfer will be canceled.

Server: ``` { "command": "putdata", "file": string, "recieved": int, "cancel": bool, "error": string } ``` If `cancel` is `true` then the upload of the file is canceled and an error message should be in `error`.
Note that `received` is the number of remaining (!!!) chunks, here the server responds with the `remaining` value originally sent in the request. ### 2.4 Get command Get is split in two commands. `get` to request a file download and `getdata` to download the data. #### 2.4.1 get - request download Client: ``` { "command": "get", "file": string } ``` Server: ``` { "command": "get", "file": string, "accept": bool, "chunks": int, "error": string } ``` If `accept` is `true` the connection is valid and the server can start sending the file. Else the get request was rejected and is hereby canceled. `error` should contain an error string if the request was rejected. `chunks` is the number of chunks of the file. #### 2.4.2 getdata - download data Client: ``` { "command": "getdata", "file": string, "chunk": int, "cancel": bool } ``` Here `chunk` is a counter how many chunks will follow. (Thus, when requesting the first chunk, the number of chunks - 1 is expected.) If `cancel` is `true` then cancel the download of the file.

Server: ``` { "command": "getdata", "file": string, "data": string, "remaining": int, "cancel": bool, "error": string } ``` `data` is a base64 string and contains a piece of the file. The client must request every chunk. `remaining` is a counter how many chunks will follow (so it equals the `chunk` value originally sent in the request) and the transfer is over after it hits `0`. If `cancel` is `true` then the download of the file is canceled and an error message should be in `error`. ### 2.5 Head command The `head` command requests the first 32 bytes of `file` from the server for further inspection by the client. If the file is smaller than 32 bytes, the first 4 bytes are sent instead. If the file is even too small for this, `data` stays empty, and an error is sent. Client: ``` { "command": "head", "file": string } ``` Server: ``` { "command": "head", "accept": bool, "file": string, "data": string, "error": string } ``` `data` is a base64 encoded string containing the requested bytes of the file. ### 2.6 Deleteme command The `deleteme` command allows a logged in user to delete their account on the server. This action needs to be confirmed with the users password. Client: ``` { "command": "deleteme", "pass": string } ``` Server: ``` { "command": "deleteme", "accept": bool, "error": string } ``` If `accept` is true the user has been deleted and the connection will be closed by the server. ### 2.7 Deletefile The `deletefile` command deletes a file from the server if its allowed to in config. Client: ``` { "command": "deletefile", "file": string } ``` Server: ``` { "command": "deletefile", "file": string, "accept": bool, "error": string } ``` ### 2.8 Notifications The `notifications` command allows the logged in user to get a list of notifications since the last time. Client: ``` { "command": "notifications" } ``` Server: ``` { "command": "notifications", "accept": bool, "messages": string[], "error": string } ``` ### 2.9 ExtendedStatus The `extendedstatus` command allows the client to request detailed information about ongoing transfers at the server. Client: ``` { "command": "extendedstatus" } ``` Server: ``` { "command": "extendedstatus", "accept": bool, "error": string, "transfersclientserver": { "upload": bool, "file": string, "progress": int }[], "transfersserverserver": { "type": string, "file": string, "progress": int, "speed": float, "method": string }[] } ``` The answer consists of an array of objects, each representing a transfer.
In case of client-server transfers, `upload` indicates wether the transfer is an up- or download. In case of server-server transfers, `type` indicates wether the file is `upload`ing, `download`ing or `queued` for upload.
`file` contains the name of the file being transferred.
`progress` contains the percentage completed.
`speed` contains the speed in bytes per second.
`method` contains the covert channel method being used. ### 2.10 Queue command To add a file that is already on the server to the queue for sending with the covert channel, the client uses the `queue` command. Client: ``` { "command": "queue", "file": string } ``` Server: ``` { "command": "queue", "file": string, "accept": bool, "error": string } ``` ### 2.11 Dequeue command To remove a file from the queue for sending with the covert channel, the client uses the `dequeue` command. Client: ``` { "command": "dequeue", "file": string } ``` Server: ``` { "command": "dequeue", "file": string, "accept": bool, "error": string } ``` ### 2.12 Extendedlist command Extendedlist is split in two commands. `extendedlist` to request a list download and `extendedlistdata` to download the list. #### 2.12.1 extendedlist - request file list download Client: ``` { "command": "extendedlist" } ``` Server: ``` { "command": "extendedlist", "accept": bool, "items": int, "chunks": int, "error": string } ``` `chunks` is the number of chunks that will be sent. #### 2.12.2 extendedlistdata - download file list Client: ``` { "command": "extendedlistdata", "chunk": int, "cancel": bool } ``` Here `chunk` is the number of remaining chunks. (Thus, when requesting the first chunk the number of chunks - 1 is expected.)

Server: ``` { "command": "extendedlistdata", "remaining": int, "cancel": bool, "files": { "name": string, "head": string, "size": float }[], "error": string } ``` The client has to request every chunk until all names have been sent and `remaining` hits `0`.
The list contains the name of a file and the `head` as specified by the `data` field of the head command (section 2.5), and its `size` in kByte. ## 3. Close connection ### 3.1 Close command Client: ``` { "command": "close" } ``` Server: ``` { "command": "close", "response": "bye" } ```