# Client-Server Protocol
Protocol version: "0.3"
Every json message must be minimized 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"
}
```